225 lines
5.9 KiB
Vue
225 lines
5.9 KiB
Vue
|
<template>
|
|||
|
<s-layout
|
|||
|
class="chat-wrap"
|
|||
|
:title="toUserName"
|
|||
|
navbar="inner"
|
|||
|
>
|
|||
|
<!-- 覆盖头部导航栏背景颜色 -->
|
|||
|
<view class="page-bg" :style="{ height: sys_navBar + 'px' }"></view>
|
|||
|
<!-- 聊天区域 -->
|
|||
|
<MessageList ref="messageListRef" :conversationId="conversationId" :useravatar="useravatar" :touserid="currId">
|
|||
|
<template #bottom>
|
|||
|
<message-input
|
|||
|
v-model="chat.msg"
|
|||
|
@on-tools="onTools"
|
|||
|
@send-message="onSendMessage"
|
|||
|
></message-input>
|
|||
|
</template>
|
|||
|
</MessageList>
|
|||
|
<!-- 聊天工具 -->
|
|||
|
<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>
|
|||
|
</tools-popup>
|
|||
|
<!-- 商品订单选择 -->
|
|||
|
<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';
|
|||
|
import { reactive, ref, toRefs,getCurrentInstance,onMounted } from 'vue';
|
|||
|
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';
|
|||
|
import {
|
|||
|
onLoad
|
|||
|
} from '@dcloudio/uni-app';
|
|||
|
|
|||
|
const sys_navBar = sheep.$platform.navbar;
|
|||
|
let conversationId = ref('')
|
|||
|
let touserId = ref('')
|
|||
|
let currId = ref('')
|
|||
|
let useravatar = ref('')
|
|||
|
let toUserName = ref('')
|
|||
|
onLoad((options)=>{
|
|||
|
console.log("路由参数",options)
|
|||
|
conversationId.value = options.userinfo
|
|||
|
touserId.value = options.userid
|
|||
|
useravatar.value = options.useravatar
|
|||
|
currId.value = options.id
|
|||
|
toUserName.value = options.touserName
|
|||
|
})
|
|||
|
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 }),
|
|||
|
receiverId:touserId.value,
|
|||
|
};
|
|||
|
console.log("send message",data)
|
|||
|
await KeFuApi.sendKefuMessage(data);
|
|||
|
await messageListRef.value.refreshMessageList();
|
|||
|
chat.msg = '';
|
|||
|
} finally {
|
|||
|
chat.showTools = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
const messageListRef = ref();
|
|||
|
|
|||
|
//======================= 聊天工具相关 start =======================
|
|||
|
|
|||
|
function handleToolsClose() {
|
|||
|
chat.showTools = false;
|
|||
|
chat.toolsMode = '';
|
|||
|
}
|
|||
|
|
|||
|
function onEmoji(item) {
|
|||
|
chat.msg += item.name;
|
|||
|
}
|
|||
|
|
|||
|
// 点击工具栏开关
|
|||
|
function onTools(mode) {
|
|||
|
if (isReconnecting.value) {
|
|||
|
sheep.$helper.toast('您已掉线!请返回重试');
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
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 }) {
|
|||
|
let msg;
|
|||
|
switch (type) {
|
|||
|
case 'image':
|
|||
|
const res = await FileApi.uploadFile(data.tempFiles[0].path);
|
|||
|
msg = {
|
|||
|
contentType: KeFuMessageContentTypeEnum.IMAGE,
|
|||
|
content: JSON.stringify({ picUrl: res.data }),
|
|||
|
};
|
|||
|
break;
|
|||
|
case 'goods':
|
|||
|
msg = {
|
|||
|
contentType: KeFuMessageContentTypeEnum.PRODUCT,
|
|||
|
content: JSON.stringify(data),
|
|||
|
};
|
|||
|
break;
|
|||
|
case 'order':
|
|||
|
msg = {
|
|||
|
contentType: KeFuMessageContentTypeEnum.ORDER,
|
|||
|
content: JSON.stringify(data),
|
|||
|
};
|
|||
|
break;
|
|||
|
}
|
|||
|
if (msg) {
|
|||
|
// 发送消息
|
|||
|
// scrollBottom();
|
|||
|
await KeFuApi.sendKefuMessage(msg);
|
|||
|
await messageListRef.value.refreshMessageList();
|
|||
|
chat.showTools = false;
|
|||
|
chat.showSelect = false;
|
|||
|
chat.selectMode = '';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//======================= 聊天工具相关 end =======================
|
|||
|
const { options } = useWebSocket({
|
|||
|
// 连接成功
|
|||
|
onConnected: async () => {},
|
|||
|
// 收到消息
|
|||
|
onMessage: async (data) => {
|
|||
|
const type = data.type;
|
|||
|
if (!type) {
|
|||
|
console.error('未知的消息类型:' + data);
|
|||
|
return;
|
|||
|
}
|
|||
|
// 2.2 消息类型:KEFU_MESSAGE_TYPE
|
|||
|
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_TYPE) {
|
|||
|
// 刷新消息列表
|
|||
|
await messageListRef.value.refreshMessageList(jsonParse(data.content));
|
|||
|
return;
|
|||
|
}
|
|||
|
// 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ
|
|||
|
if (type === WebSocketMessageTypeConstants.KEFU_MESSAGE_ADMIN_READ) {
|
|||
|
console.log('管理员已读消息');
|
|||
|
}
|
|||
|
},
|
|||
|
});
|
|||
|
const isReconnecting = toRefs(options).isReconnecting; // 重连状态
|
|||
|
</script>
|
|||
|
|
|||
|
<style scoped lang="scss">
|
|||
|
.chat-wrap {
|
|||
|
.page-bg {
|
|||
|
width: 100%;
|
|||
|
position: absolute;
|
|||
|
top: 0;
|
|||
|
left: 0;
|
|||
|
background-color: var(--ui-BG-Main);
|
|||
|
z-index: 1;
|
|||
|
}
|
|||
|
|
|||
|
.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>
|