chore: install prettier
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
<template>
|
||||
<div v-if="templateEmailContent" class="view-email">
|
||||
<Template1 v-bind="templateProps" previewMode />
|
||||
<div
|
||||
v-if="templateEmailContent"
|
||||
class="view-email"
|
||||
>
|
||||
<Template1
|
||||
v-bind="templateProps"
|
||||
previewMode
|
||||
/>
|
||||
|
||||
<div class="action mt-3">
|
||||
<button
|
||||
@@ -15,10 +21,10 @@
|
||||
<div v-else>Chưa có nội dung email</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { render } from '@vue-email/render';
|
||||
import { ref, computed } from "vue";
|
||||
import { render } from "@vue-email/render";
|
||||
|
||||
import Template1 from '@/lib/email/templates/Template1.vue';
|
||||
import Template1 from "@/lib/email/templates/Template1.vue";
|
||||
|
||||
const {
|
||||
$insertapi,
|
||||
@@ -44,19 +50,19 @@ const props = defineProps({
|
||||
scheduleItemId: Number,
|
||||
});
|
||||
|
||||
const isVietnamese = computed(() => $store.lang.toLowerCase() === 'vi');
|
||||
const isVietnamese = computed(() => $store.lang.toLowerCase() === "vi");
|
||||
|
||||
const paymentScheduleItem = ref(null);
|
||||
const contentPaymentQR = ref('');
|
||||
const contentPaymentQR = ref("");
|
||||
|
||||
const emailTemplate = await $getdata('emailtemplate', { id: props.idEmailTemplate }, undefined, false);
|
||||
const emailTemplate = await $getdata("emailtemplate", { id: props.idEmailTemplate }, undefined, false);
|
||||
|
||||
templateEmailContent.value = emailTemplate[0] ?? null;
|
||||
|
||||
let foundPaymentSchedule = $findapi('payment_schedule');
|
||||
let foundPaymentSchedule = $findapi("payment_schedule");
|
||||
foundPaymentSchedule.params = {
|
||||
values:
|
||||
'id,code,from_date,to_date,amount,cycle,paid_amount,remain_amount,txn_detail,txn_detail__transaction,txn_detail__transaction__customer,txn_detail__transaction__customer__type__code,txn_detail__transaction__customer__code,txn_detail__transaction__customer__fullname,txn_detail__transaction__customer__phone,txn_detail__transaction__customer__email,txn_detail__transaction__customer__contact_address,txn_detail__transaction__customer__address,txn_detail__transaction__customer__legal_code,txn_detail__transaction__product__trade_code',
|
||||
"id,code,from_date,to_date,amount,cycle,paid_amount,remain_amount,txn_detail,txn_detail__transaction,txn_detail__transaction__customer,txn_detail__transaction__customer__type__code,txn_detail__transaction__customer__code,txn_detail__transaction__customer__fullname,txn_detail__transaction__customer__phone,txn_detail__transaction__customer__email,txn_detail__transaction__customer__contact_address,txn_detail__transaction__customer__address,txn_detail__transaction__customer__legal_code,txn_detail__transaction__product__trade_code",
|
||||
filter: { id: props.scheduleItemId },
|
||||
};
|
||||
|
||||
@@ -67,8 +73,8 @@ async function paymentSchedule() {
|
||||
paymentScheduleItem.value = paymentScheduleRes?.data?.rows[0] || null;
|
||||
contentPaymentQR.value = buildContentPayment(paymentScheduleItem.value);
|
||||
} catch (error) {
|
||||
if ($mode === 'dev') {
|
||||
console.error('Call api product error', error);
|
||||
if ($mode === "dev") {
|
||||
console.error("Call api product error", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,22 +100,22 @@ const buildContentPayment = (data) => {
|
||||
cycle,
|
||||
} = data;
|
||||
|
||||
if (customerType.toLowerCase() === 'cn') {
|
||||
if (customerType.toLowerCase() === "cn") {
|
||||
if (customerName.length < 14) {
|
||||
return `${productCode} ${customerCode} ${customerName} TT ${cycle == 0 ? 'Dat Coc' : `Dot ${cycle}`}`;
|
||||
return `${productCode} ${customerCode} ${customerName} TT ${cycle == 0 ? "Dat Coc" : `Dot ${cycle}`}`;
|
||||
} else {
|
||||
return `${productCode} ${customerCode} ${$getFirstAndLastName(customerName)} TT ${cycle == 0 ? 'Dat Coc' : `Dot ${cycle}`}`;
|
||||
return `${productCode} ${customerCode} ${$getFirstAndLastName(customerName)} TT ${cycle == 0 ? "Dat Coc" : `Dot ${cycle}`}`;
|
||||
}
|
||||
} else {
|
||||
return `${productCode} ${customerCode} TT ${cycle == 0 ? 'Dat Coc' : `Dot ${cycle}`}`;
|
||||
return `${productCode} ${customerCode} TT ${cycle == 0 ? "Dat Coc" : `Dot ${cycle}`}`;
|
||||
}
|
||||
};
|
||||
|
||||
const templateProps = computed(() => {
|
||||
let content = templateEmailContent.value.content.content || '';
|
||||
let content = templateEmailContent.value.content.content || "";
|
||||
|
||||
// 1️⃣ XÓA TOÀN BỘ QR CŨ
|
||||
content = content.replace(/<div[^>]*>\s*<img[^>]*img\.vietqr\.io[^>]*>\s*<\/div>/g, '');
|
||||
content = content.replace(/<div[^>]*>\s*<img[^>]*img\.vietqr\.io[^>]*>\s*<\/div>/g, "");
|
||||
|
||||
// 2️⃣ CHỈ APPEND 1 QR CUỐI CÙNG (NẾU CÓ URL)
|
||||
if ($paymentQR(contentPaymentQR.value)) {
|
||||
@@ -122,14 +128,14 @@ const templateProps = computed(() => {
|
||||
|
||||
return {
|
||||
content: {
|
||||
subject: templateEmailContent.value.content.subject || 'Thông báo mới',
|
||||
message: replaceTemplateVars(content) || 'Bạn có một thông báo mới.',
|
||||
subject: templateEmailContent.value.content.subject || "Thông báo mới",
|
||||
message: replaceTemplateVars(content) || "Bạn có một thông báo mới.",
|
||||
imageUrl: templateEmailContent.value.content.imageUrl || null,
|
||||
linkUrl: templateEmailContent.value.content.linkUrl || [''],
|
||||
textLinkUrl: templateEmailContent.value.content.textLinkUrl || [''],
|
||||
linkUrl: templateEmailContent.value.content.linkUrl || [""],
|
||||
textLinkUrl: templateEmailContent.value.content.textLinkUrl || [""],
|
||||
keyword: Array.isArray(templateEmailContent.value.content.keyword)
|
||||
? templateEmailContent.value.content.keyword.map((k) => (typeof k === 'string' ? { keyword: k, value: '' } : k))
|
||||
: [{ keyword: '', value: '' }],
|
||||
? templateEmailContent.value.content.keyword.map((k) => (typeof k === "string" ? { keyword: k, value: "" } : k))
|
||||
: [{ keyword: "", value: "" }],
|
||||
},
|
||||
previewMode: true,
|
||||
};
|
||||
@@ -151,9 +157,9 @@ const handleSendEmail = async () => {
|
||||
let emailHtml = await render(Template1, tempEm.value);
|
||||
|
||||
// If no image URL provided, remove image section from HTML
|
||||
if ((templateProps.value.content.imageUrl ?? '').trim() === '') {
|
||||
emailHtml = emailHtml.replace(/<tr\s+class=["']header-row["'][^>]*>[\s\S]*?<\/tr>/gi, '');
|
||||
emailHtml = emailHtml.replace(/\n\s*\n\s*\n/g, '\n\n');
|
||||
if ((templateProps.value.content.imageUrl ?? "").trim() === "") {
|
||||
emailHtml = emailHtml.replace(/<tr\s+class=["']header-row["'][^>]*>[\s\S]*?<\/tr>/gi, "");
|
||||
emailHtml = emailHtml.replace(/\n\s*\n\s*\n/g, "\n\n");
|
||||
}
|
||||
|
||||
// Replace keywords in HTML
|
||||
@@ -161,18 +167,18 @@ const handleSendEmail = async () => {
|
||||
if (templateProps.value.content.keyword && templateProps.value.content.keyword.length > 0) {
|
||||
templateProps.value.content.keyword.forEach(({ keyword, value }) => {
|
||||
if (keyword && value) {
|
||||
const regex = new RegExp(`\\{\\{${keyword}\\}\\}`, 'g');
|
||||
const regex = new RegExp(`\\{\\{${keyword}\\}\\}`, "g");
|
||||
finalEmailHtml = finalEmailHtml.replace(regex, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const response = await $insertapi(
|
||||
'sendemail',
|
||||
"sendemail",
|
||||
{
|
||||
to: paymentScheduleItem.value?.txn_detail__transaction__customer__email,
|
||||
content: finalEmailHtml,
|
||||
subject: replaceTemplateVars(templateProps.value.content.subject) || 'Thông báo từ Utopia Villas & Resort',
|
||||
subject: replaceTemplateVars(templateProps.value.content.subject) || "Thông báo từ Utopia Villas & Resort",
|
||||
},
|
||||
undefined,
|
||||
false,
|
||||
@@ -189,9 +195,9 @@ const handleSendEmail = async () => {
|
||||
|
||||
function replaceTemplateVars(html) {
|
||||
return html
|
||||
.replace(/\[day]/g, String(new Date().getDate()).padStart(2, '0') || '')
|
||||
.replace(/\[month]/g, String(new Date().getMonth() + 1).padStart(2, '0') || '')
|
||||
.replace(/\[year]/g, new Date().getFullYear() || '')
|
||||
.replace(/\[day]/g, String(new Date().getDate()).padStart(2, "0") || "")
|
||||
.replace(/\[month]/g, String(new Date().getMonth() + 1).padStart(2, "0") || "")
|
||||
.replace(/\[year]/g, new Date().getFullYear() || "")
|
||||
.replace(/\[product\.trade_code\]/g, paymentScheduleItem.value?.txn_detail__transaction__product__trade_code)
|
||||
.replace(
|
||||
/\[product\.trade_code_payment\]/g,
|
||||
@@ -200,37 +206,37 @@ function replaceTemplateVars(html) {
|
||||
.replace(/\[customer\.fullname\]/g, paymentScheduleItem.value?.txn_detail__transaction__customer__fullname)
|
||||
.replace(
|
||||
/\[customer\.name\]/g,
|
||||
`${paymentScheduleItem.value?.txn_detail__transaction__customer__type__code.toLowerCase() == 'cn' ? (paymentScheduleItem.value?.txn_detail__transaction__customer__fullname.length < 14 ? paymentScheduleItem.value?.txn_detail__transaction__customer__fullname : $getFirstAndLastName(paymentScheduleItem.value.txn_detail__transaction__customer__fullname)) : ''}` ||
|
||||
'',
|
||||
`${paymentScheduleItem.value?.txn_detail__transaction__customer__type__code.toLowerCase() == "cn" ? (paymentScheduleItem.value?.txn_detail__transaction__customer__fullname.length < 14 ? paymentScheduleItem.value?.txn_detail__transaction__customer__fullname : $getFirstAndLastName(paymentScheduleItem.value.txn_detail__transaction__customer__fullname)) : ""}` ||
|
||||
"",
|
||||
)
|
||||
.replace(/\[customer\.code\]/g, paymentScheduleItem.value?.txn_detail__transaction__customer__code || '')
|
||||
.replace(/\[customer\.code\]/g, paymentScheduleItem.value?.txn_detail__transaction__customer__code || "")
|
||||
.replace(
|
||||
/\[customer\.legal_code\]/g,
|
||||
paymentScheduleItem.value?.txn_detail__transaction__customer__legal_code || '',
|
||||
paymentScheduleItem.value?.txn_detail__transaction__customer__legal_code || "",
|
||||
)
|
||||
.replace(
|
||||
/\[customer\.contact_address\]/g,
|
||||
paymentScheduleItem.value?.txn_detail__transaction__customer__contact_address ||
|
||||
paymentScheduleItem.value?.txn_detail__transaction__customer__address ||
|
||||
'',
|
||||
"",
|
||||
)
|
||||
.replace(/\[customer\.phone\]/g, paymentScheduleItem.value?.txn_detail__transaction__customer__phone || '')
|
||||
.replace(/\[payment_schedule\.from_date\]/g, $formatDateVN(paymentScheduleItem.value?.from_date) || '')
|
||||
.replace(/\[payment_schedule\.to_date\]/g, $formatDateVN(paymentScheduleItem.value?.to_date) || '')
|
||||
.replace(/\[payment_schedule\.amount\]/g, $numtoString(paymentScheduleItem.value?.remain_amount) || '')
|
||||
.replace(/\[customer\.phone\]/g, paymentScheduleItem.value?.txn_detail__transaction__customer__phone || "")
|
||||
.replace(/\[payment_schedule\.from_date\]/g, $formatDateVN(paymentScheduleItem.value?.from_date) || "")
|
||||
.replace(/\[payment_schedule\.to_date\]/g, $formatDateVN(paymentScheduleItem.value?.to_date) || "")
|
||||
.replace(/\[payment_schedule\.amount\]/g, $numtoString(paymentScheduleItem.value?.remain_amount) || "")
|
||||
.replace(
|
||||
/\[payment_schedule\.amount_in_word\]/g,
|
||||
$numberToVietnameseCurrency(paymentScheduleItem.value?.remain_amount) || '',
|
||||
$numberToVietnameseCurrency(paymentScheduleItem.value?.remain_amount) || "",
|
||||
)
|
||||
.replace(/\[payment_schedule\.cycle\]/g, $numtoString(paymentScheduleItem.value?.cycle) || '')
|
||||
.replace(/\[payment_schedule\.cycle\]/g, $numtoString(paymentScheduleItem.value?.cycle) || "")
|
||||
.replace(
|
||||
/\[payment_schedule\.cycle-in-words\]/g,
|
||||
`${paymentScheduleItem.value?.cycle == 0 ? 'đặt cọc' : `đợt thứ ${$numberToVietnamese(paymentScheduleItem.value?.cycle).toLowerCase()}`}` ||
|
||||
'',
|
||||
`${paymentScheduleItem.value?.cycle == 0 ? "đặt cọc" : `đợt thứ ${$numberToVietnamese(paymentScheduleItem.value?.cycle).toLowerCase()}`}` ||
|
||||
"",
|
||||
)
|
||||
.replace(
|
||||
/\[payment_schedule\.note\]/g,
|
||||
`${paymentScheduleItem.value?.cycle == 0 ? 'Dat coc' : `Dot ${paymentScheduleItem.value?.cycle}`}` || '',
|
||||
`${paymentScheduleItem.value?.cycle == 0 ? "Dat coc" : `Dot ${paymentScheduleItem.value?.cycle}`}` || "",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -244,23 +250,23 @@ function quillToEmailHtml(html) {
|
||||
.replace(/class="([^"]*?)ql-align-justify([^"]*?)"/g, 'style="text-align:justify;"')
|
||||
|
||||
// FONT SIZE
|
||||
.replace(/ql-size-small/g, '')
|
||||
.replace(/ql-size-large/g, '')
|
||||
.replace(/ql-size-huge/g, '')
|
||||
.replace(/ql-size-small/g, "")
|
||||
.replace(/ql-size-large/g, "")
|
||||
.replace(/ql-size-huge/g, "")
|
||||
|
||||
// REMOVE EMPTY CLASS
|
||||
.replace(/class=""/g, '')
|
||||
.replace(/class=""/g, "")
|
||||
);
|
||||
}
|
||||
|
||||
function sanitizeContentPayment(text, maxLength = 80) {
|
||||
if (!text) return '';
|
||||
if (!text) return "";
|
||||
|
||||
return text
|
||||
.normalize('NFD') // bỏ dấu tiếng Việt
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/[^a-zA-Z0-9 _-]/g, '') // bỏ ký tự lạ
|
||||
.replace(/\s+/g, ' ')
|
||||
.normalize("NFD") // bỏ dấu tiếng Việt
|
||||
.replace(/[\u0300-\u036f]/g, "")
|
||||
.replace(/[^a-zA-Z0-9 _-]/g, "") // bỏ ký tự lạ
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.slice(0, maxLength);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user