// 引入unocss css import '@/plugins/unocss' // 导入全局的svg图标 import '@/plugins/svgIcon' // 初始化多语言 import { setupI18n } from '@/plugins/vueI18n' // 引入状态管理 import { setupStore } from '@/store' // 全局组件 import { setupGlobCom } from '@/components' // 引入 element-plus import { setupElementPlus } from '@/plugins/elementPlus' // 引入 form-create import { setupFormCreate } from '@/plugins/formCreate' // 引入全局样式 import '@/styles/index.scss' // 引入动画 import '@/plugins/animate.css' // 路由 import router, { setupRouter } from '@/router' // 权限 import { setupAuth } from '@/directives' import { createApp } from 'vue' import App from './App.vue' import './permission' import '@/plugins/tongji' // 百度统计 import Logger from '@/utils/Logger' import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患 import { KeFuConversationList, KeFuMessageList, MemberBrowsingHistory } from '@/views/mall/promotion/kefu/components' import { WebSocketMessageTypeConstants } from '@/views/mall/promotion/kefu/components/tools/constants' import { KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation' import { getAccessToken } from '@/utils/auth' import { useWebSocket } from '@vueuse/core' import { ElMessage, ElMessageBox } from 'element-plus' import type { Action } from 'element-plus' // 创建实例 const setupAll = async () => { const app = createApp(App) await setupI18n(app) setupStore(app) setupGlobCom(app) setupElementPlus(app) setupFormCreate(app) setupRouter(app) setupAuth(app) await router.isReady() app.use(VueDOMPurifyHTML) app.mount('#app') } setupAll() Logger.prettyPrimary(`欢迎使用`, import.meta.env.VITE_APP_TITLE) const message = useMessage() // 消息弹窗 // ======================= WebSocket start ======================= const server = ref( (import.meta.env.VITE_BASE_URL + '/infra/ws').replace('http', 'ws') + '?token=' + getAccessToken() ) // WebSocket 服务地址 /** 发起 WebSocket 连接 */ const { data, close, open } = useWebSocket(server.value, { autoReconnect: true, heartbeat: true }) /** 监听 WebSocket 数据 */ watchEffect(() => { if (!data.value) { return } try { // 1. 收到心跳 if (data.value === 'pong') { return } // 2.1 解析 type 消息类型 const jsonMessage = JSON.parse(data.value) const type = jsonMessage.type const content = jsonMessage.content // const jsonObject = JSON.parse(content); // const sValue = ref(jsonObject); // console.log("content:", JSON.parse(jsonObject)); if(content === '"diskPull"'){ const open = () => { ElMessageBox.alert('This is a message', 'Title', { // if you want to disable its autofocus // autofocus: false, confirmButtonText: 'OK', callback: (action: Action) => { ElMessage({ type: 'info', message: `action: ${action}`, }) }, }) } open(); } if (!type) { message.error('未知的消息类型:' + data.value) return } // 2.2 消息类型:KEFU_MESSAGE_TYPE if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) { // 刷新会话列表 // TODO @puhui999:不应该刷新列表,而是根据消息,本地 update 列表的数据; getConversationList() // 刷新消息列表 keFuChatBoxRef.value?.refreshMessageList(JSON.parse(jsonMessage.content)) return } // 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) { // 刷新会话列表 // TODO @puhui999:不应该刷新列表,而是根据消息,本地 update 列表的数据; getConversationList() } } catch (error) { console.error(error) } }) // ======================= WebSocket end ======================= /** 加载会话列表 */ const keFuConversationRef = ref>() const getConversationList = () => { keFuConversationRef.value?.getConversationList() } /** 加载指定会话的消息列表 */ const keFuChatBoxRef = ref>() const memberBrowsingHistoryRef = ref>() const handleChange = (conversation: KeFuConversationRespVO) => { keFuChatBoxRef.value?.getNewMessageList(conversation) memberBrowsingHistoryRef.value?.initHistory(conversation) } /** 初始化 */ onMounted(() => { getConversationList() // 打开 websocket 连接 open() }) /** 销毁 */ onBeforeUnmount(() => { // 关闭 websocket 连接 close() })