diff --git a/src/views/payments/PaymentListView.vue b/src/views/payments/PaymentListView.vue
index bc94d37..349bab3 100644
--- a/src/views/payments/PaymentListView.vue
+++ b/src/views/payments/PaymentListView.vue
@@ -119,15 +119,28 @@
-
-
-
هشدار: برای این دانشجو قبلاً در این کلاس صورتحساب ثبت شده است.
-
- صورتحساب قبلی با کد {{ duplicateWarning.payments.map(p => p.uniqueCode || p._id).join('، ') }} موجود است.
+
+
+
+ توجه: برای این دانشجو قبلاً در این کلاس صورتحساب ثبت شده است.
+
+
+
+ کد صورتحساب: {{ p.uniqueCode || p._id }}
+ مبلغ: {{ toPersianDigits((p.amount || 0).toLocaleString()) }} تومان
+ تاریخ: {{ formatJalali(p.createdAt) }}
+
+
+
+
@@ -316,7 +329,7 @@ import DatePicker from 'vue3-persian-datetime-picker';
const { toPersianDigits, formatJalali, toGregorianIso, getTodayJalali } = usePersianDate();
-const { showSuccess, showError } = useToast();
+const { showSuccess, showError, showWarn } = useToast();
const {
items,
@@ -334,6 +347,7 @@ const usersList = ref([]);
const classesList = ref([]);
const isCreating = ref(false);
const duplicateWarning = ref(null);
+let lastDuplicateAlertKey = '';
const createForm = reactive({
user: null,
@@ -418,24 +432,43 @@ const checkDuplicateInvoice = async (userIdVal = null) => {
const targetUserId = extractId(userIdVal) || extractId(createForm.user);
if (!targetUserId || !createForm.classes || !createForm.classes.length) {
duplicateWarning.value = null;
+ lastDuplicateAlertKey = '';
return;
}
try {
const classIds = Array.isArray(createForm.classes)
- ? createForm.classes.map(extractId).filter(Boolean).join(',')
+ ? createForm.classes.map(extractId).filter(Boolean).sort().join(',')
: (extractId(createForm.classes) || '');
if (!classIds) {
duplicateWarning.value = null;
+ lastDuplicateAlertKey = '';
return;
}
+
+ const checkKey = `${targetUserId}_${classIds}`;
const res = await paymentApi.checkDuplicate({
userId: targetUserId,
classes: classIds
});
- duplicateWarning.value = res.data?.data || res.data || res;
+ const result = res.data?.data || res.data || res;
+ duplicateWarning.value = result;
+
+ if (result && result.hasDuplicate) {
+ if (lastDuplicateAlertKey !== checkKey) {
+ lastDuplicateAlertKey = checkKey;
+ const studentObj = usersList.value.find((u) => String(u._id || u.id) === String(targetUserId));
+ const studentName = studentObj?.name || studentObj?.fullName || 'این دانشجو';
+ const codes = (result.payments || []).map((p) => p.uniqueCode || p._id).filter(Boolean).join('، ');
+ const codeSuffix = codes ? ` (کد: ${codes})` : '';
+ showWarn(`برای ${studentName} قبلاً در این کلاس صورتحساب ثبت شده است${codeSuffix}.`, 'اطلاعیه صورتحساب قبلی');
+ }
+ } else {
+ lastDuplicateAlertKey = '';
+ }
} catch (err) {
console.error('checkDuplicateInvoice error:', err);
duplicateWarning.value = null;
+ lastDuplicateAlertKey = '';
}
};
@@ -446,6 +479,7 @@ watch(
await checkDuplicateInvoice(newUser);
} else {
duplicateWarning.value = null;
+ lastDuplicateAlertKey = '';
}
},
{ deep: true, immediate: true }
@@ -507,6 +541,7 @@ const resetCreateForm = () => {
createForm.dueDate = getTodayJalali();
hasDiscount.value = false;
duplicateWarning.value = null;
+ lastDuplicateAlertKey = '';
createNotify.sms = true;
createNotify.email = true;
createNotify.bot = true;
@@ -691,8 +726,12 @@ onMounted(() => {