feat(@vben/web-antd):迁移客服模块
This commit is contained in:
@@ -1,28 +1,132 @@
|
||||
<script lang="ts" setup>
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { defineOptions, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { Button } from 'ant-design-vue';
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { useWebSocket } from '@vueuse/core';
|
||||
import message from 'ant-design-vue';
|
||||
|
||||
import { useMallKefuStore } from '#/store/mall/kefu';
|
||||
|
||||
import {
|
||||
KeFuConversationList,
|
||||
KeFuMessageList,
|
||||
MemberInfo,
|
||||
} from './components';
|
||||
import { WebSocketMessageTypeConstants } from './components/tools/constants';
|
||||
|
||||
defineOptions({ name: 'KeFu' });
|
||||
|
||||
const accessStore = useAccessStore();
|
||||
const kefuStore = useMallKefuStore(); // 客服缓存
|
||||
|
||||
// ======================= WebSocket start =======================
|
||||
const url = `${`${import.meta.env.VITE_BASE_URL}/infra/ws`.replace(
|
||||
'http',
|
||||
'ws',
|
||||
)}?token=${accessStore.refreshToken}`; // 使用 refreshToken() :WebSocket 无法方便的刷新访问令牌
|
||||
const server = ref(url); // 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 解析 type 消息类型
|
||||
const jsonMessage = JSON.parse(newData);
|
||||
const type = jsonMessage.type;
|
||||
if (!type) {
|
||||
message.error(`未知的消息类型:${newData}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2.2 消息类型:KEFU_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 消息类型:KEFU_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>
|
||||
|
||||
<template>
|
||||
<Page>
|
||||
<Button
|
||||
danger
|
||||
type="link"
|
||||
target="_blank"
|
||||
href="https://github.com/yudaocode/yudao-ui-admin-vue3"
|
||||
>
|
||||
该功能支持 Vue3 + element-plus 版本!
|
||||
</Button>
|
||||
<br />
|
||||
<Button
|
||||
type="link"
|
||||
target="_blank"
|
||||
href="https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/mall/promotion/kefu/index"
|
||||
>
|
||||
可参考
|
||||
https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/mall/promotion/kefu/index
|
||||
代码,pull request 贡献给我们!
|
||||
</Button>
|
||||
<a-layout-content class="kefu-layout hrow">
|
||||
<!-- 会话列表 -->
|
||||
<KeFuConversationList ref="keFuConversationRef" @change="handleChange" />
|
||||
<!-- 会话详情(选中会话的消息列表) -->
|
||||
<KeFuMessageList ref="keFuChatBoxRef" />
|
||||
<!-- 会员信息(选中会话的会员信息) -->
|
||||
<MemberInfo ref="memberInfoRef" />
|
||||
</a-layout-content>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.kefu-layout {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hrow {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user