diff --git a/src/api/customer.ts b/src/api/customer.ts index 950c740..807c1c8 100644 --- a/src/api/customer.ts +++ b/src/api/customer.ts @@ -21,6 +21,18 @@ export const getOnlineCustomers = async () => rows: Customer[] }>('/admin/customer/online') +/** حضور مشتریان دارای روم چت — برای نقطهٔ آنلاین لیست/هدر پشتیبانی */ +export const getCustomerChatPresence = async () => + await useAxios.get<{ + online_within_seconds: number + rows: Array<{ + id: number + chat_room_id?: string | null + chat_user_id?: string | null + last_seen_at?: string | null + }> + }>('/admin/customer/chat-presence') + export const getCustomer = async (id: number) => await useAxios.get(`/admin/customer/${id}`) diff --git a/src/pages/menuPages/customers/base/index.vue b/src/pages/menuPages/customers/base/index.vue index f140208..91dbfed 100644 --- a/src/pages/menuPages/customers/base/index.vue +++ b/src/pages/menuPages/customers/base/index.vue @@ -283,7 +283,7 @@ // import BasicInfoModal from '@/components/BasicInfoModal' import { inputLenRules, inputRules } from '@/utils/inputRules' import { useStaticApiListsStore } from '@/store/staticApisStore' -import { ref, watch, computed, onMounted } from 'vue' +import { ref, watch, computed, onMounted, nextTick } from 'vue' import tbl from './components/table.vue' import type { FormInstance } from 'ant-design-vue' import BasicInfoModal from '@/components/BasicInfoModal/index.vue' @@ -498,21 +498,76 @@ function infoOrder(val: Order) { userInfoOrderVisible.value = true } +/** جلوگیری از race وقتی چند بار پشت‌سرهم مدال باز می‌شود */ +let infoLoadSeq = 0 + +async function refetchCustomerProfile(customerId?: number | null) { + const id = customerId ?? userInfo.value?.id + if (id == null) return + const seq = ++infoLoadSeq + try { + const fresh = await getCustomer(id) + if (seq !== infoLoadSeq || !fresh) return + userInfo.value = cloneDeep(fresh) + } catch (e) { + console.error(e) + if (seq === infoLoadSeq) { + message.warning('به‌روزرسانی مشخصات مشتری ناموفق بود؛ داده‌های جدول نمایش داده شد') + } + } +} + +/** رفرش دادهٔ همان تب فعال داخل مدال مشخصات */ +async function refreshInfoTab(key: string) { + if (!userInfoVisible.value || !userInfo.value?.id) return + + switch (key) { + case 'اطلاعات جامع': + void loadInfoChargeTargets() + await Promise.allSettled([refetchCustomerProfile(), refreshWalletPanels()]) + break + case 'لیست سفارشات': + await nextTick() + refreshOrderTable() + break + case 'لیست تراکنش ها': + await nextTick() + refreshTransactionTable() + break + case 'پیامک ها': + await nextTick() + refreshSMSTable() + break + case 'معرفی کرده ها': + await nextTick() + refreshReferralTable() + break + case 'قلک ها': + await nextTick() + refreshFundTable() + break + case 'لاگ پرگار': + await nextTick() + refreshPargarLogsTable() + break + case 'سفارش شرطی': + await refetchCustomerProfile() + break + default: + break + } +} + async function info(val: Customer) { - activeKey.value = 'اطلاعات جامع' + // فوری از ردیف جدول نشان بده؛ بعد تکی از API تازه می‌گیریم userInfo.value = cloneDeep(val) userInfoVisible.value = true - void loadInfoChargeTargets() - await nextTick(() => { - loading.value = true - refreshFundTable() - refreshPargarLogsTable() - refreshReferralTable() - refreshSMSTable() - refreshTransactionTable() - refreshOrderTable() - loading.value = false - }) + // اگر تب از قبل «اطلاعات جامع» بود watch شلیک نمی‌کند — دستی رفرش کن + const alreadyOnOverview = activeKey.value === 'اطلاعات جامع' + activeKey.value = 'اطلاعات جامع' + if (alreadyOnOverview) { + await refreshInfoTab('اطلاعات جامع') + } } //edit @@ -598,6 +653,12 @@ watch( { immediate: true } ) +/** با هر عوض شدن تب داخل مدال، دادهٔ همان تب دوباره از API گرفته شود */ +watch(activeKey, (key) => { + if (!userInfoVisible.value) return + void refreshInfoTab(key) +}) + //add project modal const addUserVisible = ref(false) const userInfoVisible = ref(false) diff --git a/src/pages/support/components/AdminSupportHeader.vue b/src/pages/support/components/AdminSupportHeader.vue index 91470e9..e53dcfc 100644 --- a/src/pages/support/components/AdminSupportHeader.vue +++ b/src/pages/support/components/AdminSupportHeader.vue @@ -11,7 +11,11 @@
-