added trigger for chat sms
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
import useAxios from '@core/utils/useAxios'
|
||||
|
||||
/** اعلام تمرکز ادمین روی اتاق پشتیبانی (برای جلوگیری از SMS وقتی ادمین همان چت را میبیند) */
|
||||
export const postAdminChatFocus = async (payload: {
|
||||
room_id?: string | null
|
||||
previous_room_id?: string | null
|
||||
}) =>
|
||||
await useAxios.post('/admin/chat/focus', {
|
||||
room_id: payload.room_id || '',
|
||||
previous_room_id: payload.previous_room_id || ''
|
||||
})
|
||||
|
||||
export const postAdminChatUnfocus = async (room_id: string) =>
|
||||
await useAxios.post('/admin/chat/unfocus', { room_id })
|
||||
|
||||
export const postAdminChatEnsureWebhook = async () =>
|
||||
await useAxios.post('/admin/chat/ensure-webhook')
|
||||
@@ -317,6 +317,7 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
|
||||
sms_notif_fund_withdraw_customer: 'switch',
|
||||
sms_notif_price_trigger: 'switch',
|
||||
sms_notif_wallet_alert: 'switch',
|
||||
sms_notif_support_admin: 'switch',
|
||||
group_sms: 'switch',
|
||||
montzar_closed: 'switch',
|
||||
montzar_open_buy: 'switch',
|
||||
@@ -798,6 +799,8 @@ const KEY_HELP_FALLBACK: Record<string, string> = {
|
||||
'روشن: وقتی هشدار قیمت مشتری (اقدام=پیامک) فعال شود، پیامک به مشتری میرود. خاموش: هشدار قیمت پیامک نمیفرستد.',
|
||||
sms_notif_wallet_alert:
|
||||
'روشن: وقتی اعتبار پنل پیامک صفر یا منفی شود، هشدار به سوپرادمین و ادمینها میرود. خاموش: این هشدار نمیرود.',
|
||||
sms_notif_support_admin:
|
||||
'روشن: وقتی مشتری اولین پیام خواندهنشده را در چت پشتیبانی میفرستد و ادمین همان گفتگو را باز و visible ندارد، پیامک به ادمینهای دارای «ارسال پیامک» میرود. خاموش: اعلان پیامک چت نمیرود.',
|
||||
group_sms:
|
||||
'روشن: امکان ارسال پیامک گروهی از پنل ادمین فعال است. خاموش: ارسال پیامک گروهی غیرفعال است.',
|
||||
profit_gold_api_enabled:
|
||||
@@ -977,6 +980,7 @@ export const KEY_LABEL_FALLBACK: Record<string, string> = {
|
||||
pargar_item_id_rial: 'کد کالای ریال پرگار',
|
||||
pargar_item_id_gold: 'کد کالای طلا پرگار',
|
||||
sms_notif_wallet_alert: 'پیامک هشدار اعتبار پنل پیامک',
|
||||
sms_notif_support_admin: 'پیامک پیام پشتیبانی به ادمین',
|
||||
auto_active_customer: 'فعالسازی خودکار پس از ثبتنام',
|
||||
balance_report_exclude_customer_id: 'حذف مشتری از گزارش تراز',
|
||||
chart_use_local_data: 'نمودار از داده داخلی',
|
||||
@@ -1097,7 +1101,7 @@ export const SETTING_EDITABLE_KEYS = new Set([
|
||||
'sms_notif_gateway_charge_admin', 'sms_notif_register_customer', 'sms_notif_register_admin',
|
||||
'sms_notif_jibit_admin', 'sms_notif_bank_card_admin', 'sms_notif_bank_card_customer',
|
||||
'sms_notif_fund_withdraw_admin', 'sms_notif_fund_withdraw_customer',
|
||||
'sms_notif_price_trigger', 'sms_notif_wallet_alert',
|
||||
'sms_notif_price_trigger', 'sms_notif_wallet_alert', 'sms_notif_support_admin',
|
||||
'deposit_sms_support_number', 'deposit_support_message_text',
|
||||
'deposit_account_holder', 'deposit_card_number', 'deposit_sheba',
|
||||
'endDay',
|
||||
|
||||
+83
-1
@@ -2,6 +2,7 @@ import { computed, ref, watch } from 'vue'
|
||||
import { useWebSocket } from '@vueuse/core'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { createUuid } from '@/utils/index'
|
||||
import { postAdminChatFocus, postAdminChatUnfocus, postAdminChatEnsureWebhook } from '@/api/chatFocus'
|
||||
|
||||
type RawChatRoom = Record<string, any>
|
||||
type RawChatMessage = Record<string, any>
|
||||
@@ -29,6 +30,7 @@ const MAX_RESEND_ATTEMPTS = 1
|
||||
const CONNECTING_TIMEOUT_MS = 12000
|
||||
const RECONNECT_WATCH_INTERVAL_MS = 5000
|
||||
const READ_SIGNAL_DEBOUNCE_MS = 1200
|
||||
const FOCUS_HEARTBEAT_MS = 20000
|
||||
|
||||
type AdminOutgoingMessageType = 'text' | 'image' | 'voice'
|
||||
|
||||
@@ -70,6 +72,8 @@ const lastReadSignalAt = ref(0)
|
||||
const lastReadSignalRoomId = ref('')
|
||||
let readSignalTimer: number | null = null
|
||||
let pendingAdminReadSignalRoomId = ''
|
||||
let focusHeartbeatTimer: number | null = null
|
||||
let lastReportedFocusRoomId = ''
|
||||
|
||||
let bootstrapPromise: Promise<void> | null = null
|
||||
|
||||
@@ -132,7 +136,12 @@ export const setAdminSupportPageOpen = (value: boolean) => {
|
||||
isAdminActiveRoomAtBottom.value = false
|
||||
clearReadSignalTimer()
|
||||
pendingAdminReadSignalRoomId = ''
|
||||
const previousRoom = activeRoomId.value || lastReportedFocusRoomId
|
||||
activeRoomId.value = ''
|
||||
stopFocusHeartbeat()
|
||||
if (previousRoom) {
|
||||
void syncAdminChatFocus(null, previousRoom)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -146,6 +155,8 @@ export const setAdminSupportPageOpen = (value: boolean) => {
|
||||
scheduleAdminReadSignal(80)
|
||||
}
|
||||
|
||||
refreshFocusHeartbeat()
|
||||
|
||||
if (value && !manuallyClosed && status.value !== 'OPEN') {
|
||||
safeReconnect('admin support page opened').catch((error) => {
|
||||
console.error('admin reconnect on page open failed:', error)
|
||||
@@ -164,6 +175,63 @@ const isViewingRoomNow = (roomId: string) => {
|
||||
)
|
||||
}
|
||||
|
||||
const syncAdminChatFocus = async (roomId: string | null, previousRoomId?: string) => {
|
||||
try {
|
||||
if (!roomId) {
|
||||
if (previousRoomId || lastReportedFocusRoomId) {
|
||||
await postAdminChatUnfocus(previousRoomId || lastReportedFocusRoomId)
|
||||
}
|
||||
lastReportedFocusRoomId = ''
|
||||
return
|
||||
}
|
||||
|
||||
await postAdminChatFocus({
|
||||
room_id: roomId,
|
||||
previous_room_id: previousRoomId && previousRoomId !== roomId ? previousRoomId : undefined
|
||||
})
|
||||
lastReportedFocusRoomId = roomId
|
||||
} catch (error) {
|
||||
console.error('admin chat focus sync failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const stopFocusHeartbeat = () => {
|
||||
if (focusHeartbeatTimer !== null) {
|
||||
window.clearInterval(focusHeartbeatTimer)
|
||||
focusHeartbeatTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
const refreshFocusHeartbeat = () => {
|
||||
stopFocusHeartbeat()
|
||||
|
||||
const roomId = activeRoomId.value
|
||||
if (!isViewingRoomNow(roomId)) {
|
||||
if (lastReportedFocusRoomId) {
|
||||
void syncAdminChatFocus(null, lastReportedFocusRoomId)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
void syncAdminChatFocus(
|
||||
roomId,
|
||||
lastReportedFocusRoomId && lastReportedFocusRoomId !== roomId
|
||||
? lastReportedFocusRoomId
|
||||
: undefined
|
||||
)
|
||||
|
||||
focusHeartbeatTimer = window.setInterval(() => {
|
||||
if (!isViewingRoomNow(activeRoomId.value)) {
|
||||
stopFocusHeartbeat()
|
||||
if (lastReportedFocusRoomId) {
|
||||
void syncAdminChatFocus(null, lastReportedFocusRoomId)
|
||||
}
|
||||
return
|
||||
}
|
||||
void syncAdminChatFocus(activeRoomId.value)
|
||||
}, FOCUS_HEARTBEAT_MS)
|
||||
}
|
||||
|
||||
const canTreatAdminRoomAsRead = (roomId = activeRoomId.value) => {
|
||||
return Boolean(
|
||||
roomId &&
|
||||
@@ -1032,7 +1100,13 @@ const bindNetworkListeners = () => {
|
||||
})
|
||||
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState !== 'visible') return
|
||||
if (document.visibilityState !== 'visible') {
|
||||
stopFocusHeartbeat()
|
||||
if (lastReportedFocusRoomId) {
|
||||
void syncAdminChatFocus(null, lastReportedFocusRoomId)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (isAdminSupportPageOpen.value && activeRoomId.value) {
|
||||
if (canTreatAdminRoomAsRead(activeRoomId.value)) {
|
||||
@@ -1041,6 +1115,8 @@ const bindNetworkListeners = () => {
|
||||
}
|
||||
}
|
||||
|
||||
refreshFocusHeartbeat()
|
||||
|
||||
if (!shouldKeepAdminSocketAlive()) return
|
||||
|
||||
if (status.value !== 'OPEN') {
|
||||
@@ -1435,6 +1511,8 @@ export const setAdminActiveRoom = async (
|
||||
pendingAdminReadSignalRoomId = ''
|
||||
}
|
||||
|
||||
refreshFocusHeartbeat()
|
||||
|
||||
if (isViewingRoomNow(roomId)) {
|
||||
clearRoomUnread(roomId)
|
||||
}
|
||||
@@ -1609,6 +1687,10 @@ export const bootstrapAdminChat = async (
|
||||
|
||||
bootstrapPromise = (async () => {
|
||||
try {
|
||||
void postAdminChatEnsureWebhook().catch((error) => {
|
||||
console.error('admin chat ensure webhook failed:', error)
|
||||
})
|
||||
|
||||
await fetchAdminRooms()
|
||||
|
||||
const shouldConnect = connectEvenIfNoRooms || rooms.value.length > 0
|
||||
|
||||
Reference in New Issue
Block a user