2022-11-22 07:45:36 +00:00
|
|
|
|
<template>
|
2024-11-10 10:53:26 +00:00
|
|
|
|
<s-layout
|
|
|
|
|
class="chat-wrap"
|
|
|
|
|
:title="!isReconnecting ? '连接客服成功' : '会话重连中'"
|
|
|
|
|
navbar="inner"
|
|
|
|
|
>
|
2024-06-12 09:05:14 +00:00
|
|
|
|
<!-- 覆盖头部导航栏背景颜色 -->
|
2022-11-22 07:45:36 +00:00
|
|
|
|
<div class="page-bg" :style="{ height: sys_navBar + 'px' }"></div>
|
2024-06-12 09:05:14 +00:00
|
|
|
|
<!-- 聊天区域 -->
|
2024-07-16 08:23:49 +00:00
|
|
|
|
<MessageList ref="messageListRef">
|
|
|
|
|
<template #bottom>
|
2024-11-10 10:53:26 +00:00
|
|
|
|
<message-input
|
|
|
|
|
v-model="chat.msg"
|
|
|
|
|
@on-tools="onTools"
|
|
|
|
|
@send-message="onSendMessage"
|
|
|
|
|
></message-input>
|
2024-07-16 08:23:49 +00:00
|
|
|
|
</template>
|
|
|
|
|
</MessageList>
|
2024-06-07 03:29:01 +00:00
|
|
|
|
<!-- 聊天工具 -->
|
2024-11-10 10:53:26 +00:00
|
|
|
|
<tools-popup
|
|
|
|
|
:show-tools="chat.showTools"
|
|
|
|
|
:tools-mode="chat.toolsMode"
|
|
|
|
|
@close="handleToolsClose"
|
|
|
|
|
@on-emoji="onEmoji"
|
|
|
|
|
@image-select="onSelect"
|
|
|
|
|
@on-show-select="onShowSelect"
|
|
|
|
|
>
|
|
|
|
|
<message-input
|
|
|
|
|
v-model="chat.msg"
|
|
|
|
|
@on-tools="onTools"
|
|
|
|
|
@send-message="onSendMessage"
|
|
|
|
|
></message-input>
|
2024-06-07 03:29:01 +00:00
|
|
|
|
</tools-popup>
|
2024-06-12 09:05:14 +00:00
|
|
|
|
<!-- 商品订单选择 -->
|
2022-11-22 07:45:36 +00:00
|
|
|
|
<SelectPopup
|
|
|
|
|
:mode="chat.selectMode"
|
|
|
|
|
:show="chat.showSelect"
|
|
|
|
|
@select="onSelect"
|
|
|
|
|
@close="chat.showSelect = false"
|
|
|
|
|
/>
|
|
|
|
|
</s-layout>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2024-07-16 08:23:49 +00:00
|
|
|
|
import MessageList from '@/pages/chat/components/messageList.vue';
|
2024-07-12 09:43:08 +00:00
|
|
|
|
import { reactive, ref, toRefs } from 'vue';
|
2022-11-22 07:45:36 +00:00
|
|
|
|
import sheep from '@/sheep';
|
2024-06-12 09:05:14 +00:00
|
|
|
|
import ToolsPopup from '@/pages/chat/components/toolsPopup.vue';
|
|
|
|
|
import MessageInput from '@/pages/chat/components/messageInput.vue';
|
|
|
|
|
import SelectPopup from '@/pages/chat/components/select-popup.vue';
|
2024-11-10 10:53:26 +00:00
|
|
|
|
import {
|
|
|
|
|
KeFuMessageContentTypeEnum,
|
|
|
|
|
WebSocketMessageTypeConstants,
|
|
|
|
|
} from '@/pages/chat/util/constants';
|
2024-06-17 09:33:30 +00:00
|
|
|
|
import FileApi from '@/sheep/api/infra/file';
|
|
|
|
|
import KeFuApi from '@/sheep/api/promotion/kefu';
|
|
|
|
|
import { useWebSocket } from '@/sheep/hooks/useWebSocket';
|
2024-11-10 09:56:58 +00:00
|
|
|
|
import { jsonParse } from '@/sheep/util';
|
2022-11-22 07:45:36 +00:00
|
|
|
|
|
2024-06-12 09:05:14 +00:00
|
|
|
|
const sys_navBar = sheep.$platform.navbar;
|
2022-11-22 07:45:36 +00:00
|
|
|
|
|
|
|
|
|
const chat = reactive({
|
|
|
|
|
msg: '',
|
|
|
|
|
scrollInto: '',
|
|
|
|
|
showTools: false,
|
|
|
|
|
toolsMode: '',
|
|
|
|
|
showSelect: false,
|
|
|
|
|
selectMode: '',
|
|
|
|
|
});
|
|
|
|
|
|
2024-06-12 09:05:14 +00:00
|
|
|
|
// 发送消息
|
2024-06-17 09:33:30 +00:00
|
|
|
|
async function onSendMessage() {
|
2024-06-12 09:05:14 +00:00
|
|
|
|
if (!chat.msg) return;
|
2024-06-17 09:33:30 +00:00
|
|
|
|
try {
|
|
|
|
|
const data = {
|
|
|
|
|
contentType: KeFuMessageContentTypeEnum.TEXT,
|
2024-11-10 09:56:58 +00:00
|
|
|
|
content: JSON.stringify({ text: chat.msg }),
|
2024-06-17 09:33:30 +00:00
|
|
|
|
};
|
2024-06-24 08:07:04 +00:00
|
|
|
|
await KeFuApi.sendKefuMessage(data);
|
2024-07-16 08:23:49 +00:00
|
|
|
|
await messageListRef.value.refreshMessageList();
|
2024-06-12 09:05:14 +00:00
|
|
|
|
chat.msg = '';
|
2024-06-17 09:33:30 +00:00
|
|
|
|
} finally {
|
|
|
|
|
chat.showTools = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-16 08:23:49 +00:00
|
|
|
|
const messageListRef = ref();
|
2024-06-12 09:05:14 +00:00
|
|
|
|
|
|
|
|
|
//======================= 聊天工具相关 start =======================
|
2024-06-07 03:29:01 +00:00
|
|
|
|
|
|
|
|
|
function handleToolsClose() {
|
|
|
|
|
chat.showTools = false;
|
|
|
|
|
chat.toolsMode = '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onEmoji(item) {
|
|
|
|
|
chat.msg += item.name;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-22 07:45:36 +00:00
|
|
|
|
// 点击工具栏开关
|
|
|
|
|
function onTools(mode) {
|
2024-07-12 09:43:08 +00:00
|
|
|
|
if (isReconnecting.value) {
|
2024-07-16 08:23:49 +00:00
|
|
|
|
sheep.$helper.toast('您已掉线!请返回重试');
|
2024-07-12 09:43:08 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2022-11-22 07:45:36 +00:00
|
|
|
|
|
|
|
|
|
if (!chat.toolsMode || chat.toolsMode === mode) {
|
|
|
|
|
chat.showTools = !chat.showTools;
|
|
|
|
|
}
|
|
|
|
|
chat.toolsMode = mode;
|
|
|
|
|
if (!chat.showTools) {
|
|
|
|
|
chat.toolsMode = '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function onShowSelect(mode) {
|
|
|
|
|
chat.showTools = false;
|
|
|
|
|
chat.showSelect = true;
|
|
|
|
|
chat.selectMode = mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function onSelect({ type, data }) {
|
2024-07-02 09:32:36 +00:00
|
|
|
|
let msg;
|
2022-11-22 07:45:36 +00:00
|
|
|
|
switch (type) {
|
|
|
|
|
case 'image':
|
2024-06-17 09:33:30 +00:00
|
|
|
|
const res = await FileApi.uploadFile(data.tempFiles[0].path);
|
2022-11-22 07:45:36 +00:00
|
|
|
|
msg = {
|
2024-06-17 09:33:30 +00:00
|
|
|
|
contentType: KeFuMessageContentTypeEnum.IMAGE,
|
2024-11-10 10:53:26 +00:00
|
|
|
|
content: JSON.stringify({ picUrl: res.data }),
|
2022-11-22 07:45:36 +00:00
|
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
case 'goods':
|
|
|
|
|
msg = {
|
2024-06-17 09:33:30 +00:00
|
|
|
|
contentType: KeFuMessageContentTypeEnum.PRODUCT,
|
2024-07-16 08:23:49 +00:00
|
|
|
|
content: JSON.stringify(data),
|
2022-11-22 07:45:36 +00:00
|
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
case 'order':
|
|
|
|
|
msg = {
|
2024-06-17 09:33:30 +00:00
|
|
|
|
contentType: KeFuMessageContentTypeEnum.ORDER,
|
2024-07-09 09:34:18 +00:00
|
|
|
|
content: JSON.stringify(data),
|
2022-11-22 07:45:36 +00:00
|
|
|
|
};
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (msg) {
|
2024-06-17 09:33:30 +00:00
|
|
|
|
// 发送消息
|
2022-11-22 07:45:36 +00:00
|
|
|
|
// scrollBottom();
|
2024-07-02 09:32:36 +00:00
|
|
|
|
await KeFuApi.sendKefuMessage(msg);
|
2024-07-16 08:23:49 +00:00
|
|
|
|
await messageListRef.value.refreshMessageList();
|
2022-11-22 07:45:36 +00:00
|
|
|
|
chat.showTools = false;
|
|
|
|
|
chat.showSelect = false;
|
|
|
|
|
chat.selectMode = '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-12 09:05:14 +00:00
|
|
|
|
//======================= 聊天工具相关 end =======================
|
2024-07-16 08:23:49 +00:00
|
|
|
|
const { options } = useWebSocket({
|
2024-07-11 09:19:21 +00:00
|
|
|
|
// 连接成功
|
2024-11-10 10:53:26 +00:00
|
|
|
|
onConnected: async () => {},
|
2024-07-11 09:19:21 +00:00
|
|
|
|
// 收到消息
|
2024-07-16 08:23:49 +00:00
|
|
|
|
onMessage: async (data) => {
|
|
|
|
|
const type = data.type;
|
2024-07-12 09:43:08 +00:00
|
|
|
|
if (!type) {
|
2024-11-10 09:56:58 +00:00
|
|
|
|
console.error('未知的消息类型:' + data);
|
2024-07-16 08:23:49 +00:00
|
|
|
|
return;
|
2024-07-12 09:43:08 +00:00
|
|
|
|
}
|
|
|
|
|
// 2.2 消息类型:KEFU_MESSAGE_TYPE
|
|
|
|
|
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) {
|
|
|
|
|
// 刷新消息列表
|
2024-11-10 09:56:58 +00:00
|
|
|
|
await messageListRef.value.refreshMessageList(jsonParse(data.content));
|
2024-07-16 08:23:49 +00:00
|
|
|
|
return;
|
2024-07-12 09:43:08 +00:00
|
|
|
|
}
|
|
|
|
|
// 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ
|
|
|
|
|
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) {
|
2024-07-16 08:23:49 +00:00
|
|
|
|
console.log('管理员已读消息');
|
2024-07-12 09:43:08 +00:00
|
|
|
|
}
|
2024-07-16 08:23:49 +00:00
|
|
|
|
},
|
2024-07-11 09:19:21 +00:00
|
|
|
|
});
|
2024-07-16 08:23:49 +00:00
|
|
|
|
const isReconnecting = toRefs(options).isReconnecting; // 重连状态
|
2022-11-22 07:45:36 +00:00
|
|
|
|
</script>
|
|
|
|
|
|
2024-06-12 09:05:14 +00:00
|
|
|
|
<style scoped lang="scss">
|
2022-11-22 07:45:36 +00:00
|
|
|
|
.chat-wrap {
|
2024-06-12 09:05:14 +00:00
|
|
|
|
.page-bg {
|
|
|
|
|
width: 100%;
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
2024-07-17 08:45:03 +00:00
|
|
|
|
background-color: var(--ui-BG-Main);
|
2024-06-12 09:05:14 +00:00
|
|
|
|
z-index: 1;
|
|
|
|
|
}
|
2022-11-22 07:45:36 +00:00
|
|
|
|
|
|
|
|
|
.status {
|
|
|
|
|
position: relative;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
z-index: 3;
|
|
|
|
|
height: 70rpx;
|
|
|
|
|
padding: 0 30rpx;
|
|
|
|
|
background: var(--ui-BG-Main-opacity-1);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
color: var(--ui-BG-Main);
|
|
|
|
|
}
|
2023-07-14 03:14:26 +00:00
|
|
|
|
}
|
|
|
|
|
</style>
|