From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mall/promotion/kefu/index.vue |  136 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 136 insertions(+), 0 deletions(-)

diff --git a/src/views/mall/promotion/kefu/index.vue b/src/views/mall/promotion/kefu/index.vue
new file mode 100644
index 0000000..64b8aba
--- /dev/null
+++ b/src/views/mall/promotion/kefu/index.vue
@@ -0,0 +1,136 @@
+<template>
+  <el-container class="kefu-layout">
+    <!-- 浼氳瘽鍒楄〃 -->
+    <KeFuConversationList ref="keFuConversationRef" @change="handleChange" />
+    <!-- 浼氳瘽璇︽儏锛堥�変腑浼氳瘽鐨勬秷鎭垪琛級 -->
+    <KeFuMessageList ref="keFuChatBoxRef" />
+    <!-- 浼氬憳淇℃伅锛堥�変腑浼氳瘽鐨勪細鍛樹俊鎭級 -->
+    <MemberInfo ref="memberInfoRef" />
+  </el-container>
+</template>
+
+<script lang="ts" setup>
+import { KeFuConversationList, KeFuMessageList, MemberInfo } from './components'
+import { WebSocketMessageTypeConstants } from './components/tools/constants'
+import { KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
+import { getRefreshToken } from '@/utils/auth'
+import { useWebSocket } from '@vueuse/core'
+import { useMallKefuStore } from '@/store/modules/mall/kefu'
+
+defineOptions({ name: 'KeFu' })
+
+const message = useMessage() // 娑堟伅寮圭獥
+const kefuStore = useMallKefuStore() // 瀹㈡湇缂撳瓨
+
+// ======================= WebSocket start =======================
+const server = ref(
+  (import.meta.env.VITE_BASE_URL + '/infra/ws').replace('http', 'ws') +
+    '?token=' +
+    getRefreshToken() // 浣跨敤 getRefreshToken() 鏂规硶锛岃�屼笉浣跨敤 getAccessToken() 鏂规硶鐨勫師鍥狅細WebSocket 鏃犳硶鏂逛究鐨勫埛鏂拌闂护鐗�
+) // WebSocket 鏈嶅姟鍦板潃
+
+/** 鍙戣捣 WebSocket 杩炴帴 */
+const { data, close, open } = useWebSocket(server.value, {
+  autoReconnect: true,
+  heartbeat: true
+})
+
+/** 鐩戝惉 WebSocket 鏁版嵁 */
+watch(
+  () => data.value,
+  (newData) => {
+    if (!newData) return
+    try {
+      // 1. 鏀跺埌蹇冭烦
+      if (newData === 'pong') return
+
+      // 2.1 瑙f瀽 type 娑堟伅绫诲瀷
+      const jsonMessage = JSON.parse(newData)
+      const type = jsonMessage.type
+      if (!type) {
+        message.error('鏈煡鐨勬秷鎭被鍨嬶細' + newData)
+        return
+      }
+
+      // 2.2 娑堟伅绫诲瀷锛欿EFU_MESSAGE_TYPE
+      if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) {
+        const message = JSON.parse(jsonMessage.content)
+        // 鍒锋柊浼氳瘽鍒楄〃
+        kefuStore.updateConversation(message.conversationId)
+        // 鍒锋柊娑堟伅鍒楄〃
+        keFuChatBoxRef.value?.refreshMessageList(message)
+        return
+      }
+
+      // 2.3 娑堟伅绫诲瀷锛欿EFU_MESSAGE_ADMIN_READ
+      if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) {
+        // 鏇存柊浼氳瘽宸茶
+        const message = JSON.parse(jsonMessage.content)
+        kefuStore.updateConversationStatus(message.conversationId)
+      }
+    } catch (error) {
+      console.error(error)
+    }
+  },
+  {
+    immediate: false // 涓嶇珛鍗虫墽琛�
+  }
+)
+// ======================= WebSocket end =======================
+
+/** 鍔犺浇鎸囧畾浼氳瘽鐨勬秷鎭垪琛� */
+const keFuChatBoxRef = ref<InstanceType<typeof KeFuMessageList>>()
+const memberInfoRef = ref<InstanceType<typeof MemberInfo>>()
+const handleChange = (conversation: KeFuConversationRespVO) => {
+  keFuChatBoxRef.value?.getNewMessageList(conversation)
+  memberInfoRef.value?.initHistory(conversation)
+}
+
+const keFuConversationRef = ref<InstanceType<typeof KeFuConversationList>>()
+/** 鍒濆鍖� */
+onMounted(() => {
+  /** 鍔犺浇浼氳瘽鍒楄〃 */
+  kefuStore.setConversationList().then(() => {
+    keFuConversationRef.value?.calculationLastMessageTime()
+  })
+  // 鎵撳紑 websocket 杩炴帴
+  open()
+})
+
+/** 閿�姣� */
+onBeforeUnmount(() => {
+  // 鍏抽棴 websocket 杩炴帴
+  close()
+})
+</script>
+
+<style lang="scss">
+.kefu-layout {
+  position: absolute;
+  flex: 1;
+  top: 0;
+  left: 0;
+  height: 100%;
+  width: 100%;
+}
+
+/* 瀹氫箟婊氬姩鏉℃牱寮� */
+::-webkit-scrollbar {
+  width: 10px;
+  height: 6px;
+}
+
+/* 瀹氫箟婊氬姩鏉¤建閬� 鍐呴槾褰�+鍦嗚 */
+::-webkit-scrollbar-track {
+  box-shadow: inset 0 0 0 rgba(240, 240, 240, 0.5);
+  border-radius: 10px;
+  background-color: #fff;
+}
+
+/* 瀹氫箟婊戝潡 鍐呴槾褰�+鍦嗚 */
+::-webkit-scrollbar-thumb {
+  border-radius: 10px;
+  box-shadow: inset 0 0 0 rgba(240, 240, 240, 0.5);
+  background-color: rgba(240, 240, 240, 0.5);
+}
+</style>

--
Gitblit v1.8.0