|
|
@ -1,6 +1,5 @@
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<div class="chat-container" @click="emojiVisible = false">
|
|
|
|
<div class="chat-container" @click="emojiVisible = false">
|
|
|
|
{{ $store.state.chat }}
|
|
|
|
|
|
|
|
<div class="header">
|
|
|
|
<div class="header">
|
|
|
|
<p>当前客服:小爱</p>
|
|
|
|
<p>当前客服:小爱</p>
|
|
|
|
<el-button type="text" @click="summaryVisible = !summaryVisible">
|
|
|
|
<el-button type="text" @click="summaryVisible = !summaryVisible">
|
|
|
@ -23,8 +22,8 @@
|
|
|
|
v-for="(item, index) in sessionList"
|
|
|
|
v-for="(item, index) in sessionList"
|
|
|
|
:key="index"
|
|
|
|
:key="index"
|
|
|
|
class="session-item"
|
|
|
|
class="session-item"
|
|
|
|
:class="{ active: state.currentIndex === index }"
|
|
|
|
:class="{ active: currentSessionId === item.id }"
|
|
|
|
@click="handleChangeSession(index)"
|
|
|
|
@click="handleChangeSession(item.id)"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<el-badge
|
|
|
|
<el-badge
|
|
|
|
class="session-count"
|
|
|
|
class="session-count"
|
|
|
@ -37,20 +36,24 @@
|
|
|
|
<div class="session-info">
|
|
|
|
<div class="session-info">
|
|
|
|
<div class="row">
|
|
|
|
<div class="row">
|
|
|
|
<div class="session-name">{{ item.fromNickname }}</div>
|
|
|
|
<div class="session-name">{{ item.fromNickname }}</div>
|
|
|
|
<div class="session-time">{{ parseTime(item.lastMessage.createTimeStamp) }}</div>
|
|
|
|
<div class="session-time">
|
|
|
|
|
|
|
|
{{ store.getters['chat/parseTime'](item.lastMessage.createTimeStamp) }}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="row">
|
|
|
|
<div class="session-content">{{ parseContent(item.lastMessage.payload) }}</div>
|
|
|
|
<div class="session-content">
|
|
|
|
|
|
|
|
{{ store.getters['chat/parseContent'](item.lastMessage.payload) }}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</li>
|
|
|
|
</li>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
|
|
<div v-if="currentSession" class="content">
|
|
|
|
<div class="content-header">
|
|
|
|
<div class="content-header">
|
|
|
|
<div class="content-header-left">
|
|
|
|
<div class="content-header-left">
|
|
|
|
<div class="name sex-1">
|
|
|
|
<div class="name" :class="{ [`sex-` + currentSession?.fromSex]: true }">
|
|
|
|
{{ currentSession?.name }}
|
|
|
|
{{ currentSession?.fromNickname }}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="content-header-right">
|
|
|
|
<div class="content-header-right">
|
|
|
@ -65,7 +68,12 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<el-scrollbar ref="refsMessageList" class="message-list">
|
|
|
|
<el-scrollbar ref="refsMessageList" class="message-list">
|
|
|
|
<message-item v-for="(item, index) in sessionMessageList" :key="index" :message="item" />
|
|
|
|
<message-item
|
|
|
|
|
|
|
|
v-for="(item, index) in sessionMessageList"
|
|
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
|
|
:message="item"
|
|
|
|
|
|
|
|
:session="currentSession"
|
|
|
|
|
|
|
|
/>
|
|
|
|
</el-scrollbar>
|
|
|
|
</el-scrollbar>
|
|
|
|
<div class="operation-bar">
|
|
|
|
<div class="operation-bar">
|
|
|
|
<el-button type="text" @click.stop="emojiVisible = !emojiVisible">
|
|
|
|
<el-button type="text" @click.stop="emojiVisible = !emojiVisible">
|
|
|
@ -104,6 +112,7 @@
|
|
|
|
<el-button type="primary" @click="handleSendMessage">发送</el-button>
|
|
|
|
<el-button type="primary" @click="handleSendMessage">发送</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-else class="content empty">请点击左侧会话列表与买家进行聊天</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
@ -125,106 +134,18 @@
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 会话
|
|
|
|
// 会话
|
|
|
|
|
|
|
|
const currentSessionId = computed(() => store.state.chat.currentSession);
|
|
|
|
const state = reactive({
|
|
|
|
const state = reactive({
|
|
|
|
currentIndex: 0,
|
|
|
|
|
|
|
|
message: '',
|
|
|
|
message: '',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const sessionList = computed(() => {
|
|
|
|
const sessionList = computed(() => {
|
|
|
|
return store.state.chat.sessionData?.sessionVOS || [];
|
|
|
|
return store.state.chat.sessionData?.sessionVOS || [];
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const currentSession = computed(() => {
|
|
|
|
const currentSession = computed(() => sessionList.value.find((item) => item.id === currentSessionId.value));
|
|
|
|
return sessionList[state.currentIndex];
|
|
|
|
const sessionMessageList = computed(() => store.state.chat.messageList);
|
|
|
|
});
|
|
|
|
const handleChangeSession = (id) => {
|
|
|
|
// 格式化时间戳
|
|
|
|
store.commit('chat/setCurrentSession', id);
|
|
|
|
const parseTime = (timestamp) => dayjs(new Date(timestamp)).format('MM-DD HH:mm:ss');
|
|
|
|
store.dispatch('chat/querySessionMessage');
|
|
|
|
|
|
|
|
|
|
|
|
const parseContent = (payload) => {
|
|
|
|
|
|
|
|
payload = JSON.parse(payload);
|
|
|
|
|
|
|
|
if ('text' in payload) {
|
|
|
|
|
|
|
|
payload = payload.text;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
payload = '[未知消息]';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return payload;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const sessionMessageList = reactive([
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type: 'text',
|
|
|
|
|
|
|
|
content: '你好,请问这个能有优惠吗?',
|
|
|
|
|
|
|
|
time: '2019-12-12',
|
|
|
|
|
|
|
|
from: 'customer',
|
|
|
|
|
|
|
|
avatar: 'https://placem.at/people',
|
|
|
|
|
|
|
|
name: '小可爱',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type: 'notify',
|
|
|
|
|
|
|
|
content: '小马 将该会话转移给 小艾,并留言:发货问题',
|
|
|
|
|
|
|
|
time: '2019-12-12',
|
|
|
|
|
|
|
|
from: 'system',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type: 'text',
|
|
|
|
|
|
|
|
content: '没有',
|
|
|
|
|
|
|
|
time: '2019-12-12',
|
|
|
|
|
|
|
|
from: 'employee',
|
|
|
|
|
|
|
|
avatar: 'https://placem.at/people',
|
|
|
|
|
|
|
|
name: '小爱',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type: 'product',
|
|
|
|
|
|
|
|
content: `{
|
|
|
|
|
|
|
|
"id": 18,
|
|
|
|
|
|
|
|
"name": "柏战K20青轴机械键盘 混光机械键盘青轴电竞网吧游戏键盘电脑键盘",
|
|
|
|
|
|
|
|
"categoryId": 51,
|
|
|
|
|
|
|
|
"startingPrice": 79.0,
|
|
|
|
|
|
|
|
"totalStock": 1200,
|
|
|
|
|
|
|
|
"mainPicture": "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/mall-product/productO1CN011nFEoP1DrheUNhNgU_!!3435280270-0-cib.jpg",
|
|
|
|
|
|
|
|
"remoteAreaPostage": 10.0,
|
|
|
|
|
|
|
|
"singleBuyLimit": 0,
|
|
|
|
|
|
|
|
"isEnable": true,
|
|
|
|
|
|
|
|
"remark": "柏战K20青轴机械键盘 混光机械键盘青轴电竞网吧游戏键盘电脑键盘"
|
|
|
|
|
|
|
|
}`,
|
|
|
|
|
|
|
|
time: '2019-12-12',
|
|
|
|
|
|
|
|
from: 'customer',
|
|
|
|
|
|
|
|
avatar: 'https://placem.at/people',
|
|
|
|
|
|
|
|
name: '小可爱',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
type: 'order',
|
|
|
|
|
|
|
|
content: `{
|
|
|
|
|
|
|
|
"orderId": 392016,
|
|
|
|
|
|
|
|
"orderNo": "6391f99d063e",
|
|
|
|
|
|
|
|
"userId": 513,
|
|
|
|
|
|
|
|
"userPhone": "17683712911",
|
|
|
|
|
|
|
|
"payAmount": 859.0,
|
|
|
|
|
|
|
|
"orderStatus": 2,
|
|
|
|
|
|
|
|
"orderStatusDesc": "已关闭",
|
|
|
|
|
|
|
|
"payType": 1,
|
|
|
|
|
|
|
|
"payTypeDesc": "未支付",
|
|
|
|
|
|
|
|
"orderSource": 2,
|
|
|
|
|
|
|
|
"orderSourceDesc": "安卓端APP",
|
|
|
|
|
|
|
|
"submitTime": "2022-05-10 20:36:59",
|
|
|
|
|
|
|
|
"product": {
|
|
|
|
|
|
|
|
"id": 18,
|
|
|
|
|
|
|
|
"name": "柏战K20青轴机械键盘 混光机械键盘青轴电竞网吧游戏键盘电脑键盘",
|
|
|
|
|
|
|
|
"categoryId": 51,
|
|
|
|
|
|
|
|
"startingPrice": 79.0,
|
|
|
|
|
|
|
|
"totalStock": 1200,
|
|
|
|
|
|
|
|
"mainPicture": "https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/mall-product/productO1CN011nFEoP1DrheUNhNgU_!!3435280270-0-cib.jpg",
|
|
|
|
|
|
|
|
"remoteAreaPostage": 10.0,
|
|
|
|
|
|
|
|
"singleBuyLimit": 0,
|
|
|
|
|
|
|
|
"isEnable": true,
|
|
|
|
|
|
|
|
"remark": "柏战K20青轴机械键盘 混光机械键盘青轴电竞网吧游戏键盘电脑键盘"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}`,
|
|
|
|
|
|
|
|
time: '2019-12-12',
|
|
|
|
|
|
|
|
from: 'customer',
|
|
|
|
|
|
|
|
avatar: 'https://placem.at/people',
|
|
|
|
|
|
|
|
name: '小可爱',
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
const handleChangeSession = (index) => {
|
|
|
|
|
|
|
|
state.currentIndex = index;
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 表情
|
|
|
|
// 表情
|
|
|
@ -384,6 +305,11 @@
|
|
|
|
flex: 1;
|
|
|
|
flex: 1;
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
&.empty {
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
|
|
}
|
|
|
|
.content-header {
|
|
|
|
.content-header {
|
|
|
|
height: 60px;
|
|
|
|
height: 60px;
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|