mall-uniapp/pages/chat/index.vue

208 lines
5.4 KiB
Vue
Raw Normal View History

2022-11-22 07:45:36 +00:00
<template>
<s-layout
class="chat-wrap"
:title="!isReconnecting ? '连接客服成功' : '会话重连中'"
navbar="inner"
>
<!-- 覆盖头部导航栏背景颜色 -->
2022-11-22 07:45:36 +00:00
<div class="page-bg" :style="{ height: sys_navBar + 'px' }"></div>
<!-- 聊天区域 -->
<MessageList ref="messageListRef">
<template #bottom>
<message-input
v-model="chat.msg"
@on-tools="onTools"
@send-message="onSendMessage"
></message-input>
</template>
</MessageList>
2024-06-07 03:29:01 +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>
<!-- 商品订单选择 -->
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>
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';
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';
import {
KeFuMessageContentTypeEnum,
WebSocketMessageTypeConstants,
} from '@/pages/chat/util/constants';
import FileApi from '@/sheep/api/infra/file';
import KeFuApi from '@/sheep/api/promotion/kefu';
import { useWebSocket } from '@/sheep/hooks/useWebSocket';
import { jsonParse } from '@/sheep/util';
2022-11-22 07:45:36 +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: '',
});
// 发送消息
async function onSendMessage() {
if (!chat.msg) return;
try {
const data = {
contentType: KeFuMessageContentTypeEnum.TEXT,
content: JSON.stringify({ text: chat.msg }),
};
2024-06-24 08:07:04 +00:00
await KeFuApi.sendKefuMessage(data);
await messageListRef.value.refreshMessageList();
chat.msg = '';
} finally {
chat.showTools = false;
}
}
const messageListRef = ref();
//======================= 聊天工具相关 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) {
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':
const res = await FileApi.uploadFile(data.tempFiles[0].path);
2022-11-22 07:45:36 +00:00
msg = {
contentType: KeFuMessageContentTypeEnum.IMAGE,
content: JSON.stringify({ picUrl: res.data }),
2022-11-22 07:45:36 +00:00
};
break;
case 'goods':
msg = {
contentType: KeFuMessageContentTypeEnum.PRODUCT,
content: JSON.stringify(data),
2022-11-22 07:45:36 +00:00
};
break;
case 'order':
msg = {
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) {
// 发送消息
2022-11-22 07:45:36 +00:00
// scrollBottom();
2024-07-02 09:32:36 +00:00
await KeFuApi.sendKefuMessage(msg);
await messageListRef.value.refreshMessageList();
2022-11-22 07:45:36 +00:00
chat.showTools = false;
chat.showSelect = false;
chat.selectMode = '';
}
}
//======================= 聊天工具相关 end =======================
const { options } = useWebSocket({
2024-07-11 09:19:21 +00:00
// 连接成功
onConnected: async () => {},
2024-07-11 09:19:21 +00:00
// 收到消息
onMessage: async (data) => {
const type = data.type;
2024-07-12 09:43:08 +00:00
if (!type) {
console.error('未知的消息类型:' + data);
return;
2024-07-12 09:43:08 +00:00
}
// 2.2 消息类型KEFU_MESSAGE_TYPE
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) {
// 刷新消息列表
await messageListRef.value.refreshMessageList(jsonParse(data.content));
return;
2024-07-12 09:43:08 +00:00
}
// 2.3 消息类型KEFU_MESSAGE_ADMIN_READ
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) {
console.log('管理员已读消息');
2024-07-12 09:43:08 +00:00
}
},
2024-07-11 09:19:21 +00:00
});
const isReconnecting = toRefs(options).isReconnecting; // 重连状态
2022-11-22 07:45:36 +00:00
</script>
<style scoped lang="scss">
2022-11-22 07:45:36 +00:00
.chat-wrap {
.page-bg {
width: 100%;
position: absolute;
top: 0;
left: 0;
background-color: var(--ui-BG-Main);
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);
}
}
</style>