优化客服消息

This commit is contained in:
龙运模 2024-11-12 19:07:26 +08:00
parent 2e332c8986
commit 8e660fd657
5 changed files with 161 additions and 40 deletions

View File

@ -7,26 +7,30 @@
<div class="title">智能客服
<el-icon class="close" size="18" @click="closeCustomer"><el-icon-Close/></el-icon>
</div>
<div class="bodyMain">
<el-scrollbar>
<div class="tagList">
<div class="tagItem" v-for="(item,index) in tagList" :key="index" @click="typeActive(item)">{{item.label}}</div>
</div>
<div class="msgList">
<div class="msgItem" :class="user_id != item.to_user_id?'msgRightItem':''" v-for="(item,index) in msgList" :key="index">
<div class="avatar" v-if="user_id === item.to_user_id">
<el-avatar :size="36" :src="item.from_user.avatar" fit="contain">
<img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"/>
</el-avatar>
</div>
<div class="msgText">
<div class="msgTitle">{{item.from_user && item.from_user.name?item.from_user.name:'匿名'}}</div>
<div class="textCom">{{item.to_message}}</div>
</div>
<div class="avatar" v-if="user_id != item.to_user_id">
<el-avatar :size="36" :src="item.avatar" fit="contain">
<img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"/>
</el-avatar>
<div class="bodyMain affix-container">
<el-scrollbar ref="scrollbar" height="100%" @scroll="scroll">
<div class="innerRefCom">
<div class="tagList" ref="tagList">
<div class="tagItem" v-for="(item,index) in tagList" :key="index" @click="typeActive(item)">{{item.label}}</div>
</div>
<div class="msgList">
<div class="msgItem" :class="user_id != item.to_user_id?'msgRightItem':''" v-for="(item,index) in msgList" :key="index">
<div class="avatar" v-if="user_id === item.to_user_id">
<el-avatar :size="36" :src="item.from_user.avatar" fit="cover">
<img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"/>
</el-avatar>
</div>
<div class="msgText">
<div class="msgTitle">{{item.from_user && item.from_user.name?item.from_user.name:'匿名'}}</div>
<div class="textCom">
<div v-html="item.to_message"></div>
</div>
</div>
<div class="avatar" v-if="user_id != item.to_user_id">
<el-avatar :size="36" :src="item.from_user.avatar" fit="cover">
<img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"/>
</el-avatar>
</div>
</div>
</div>
</div>
@ -53,7 +57,6 @@ export default {
type:"",
to_user_id:"",
to_message:"",
},
tagList:[],
msgList:[],
@ -79,22 +82,32 @@ export default {
switch(res.data.type) {
case 36:
this.msgList = res.data.rows;
this.scrollDown();
break;
case 37:
this.params.to_user_id = res.data.user.uid;
this.msgList = [{
to_user_id:this.user_id,
from_user:{
name:res.data.user.user_info.name,
avatar:res.data.user.user_info.avatar
},
to_message:res.data.to_message
}]
break;
default:
break;
}
}
},
openCustomer(){
this.customerShow = !this.customerShow;
if(this.customerShow){
this.getAssign();
this.getRecordList();
this.customerType();
//
this.scrollDown();
}
},
closeCustomer(){
@ -107,14 +120,6 @@ export default {
async getRecordList() {
await this.$API.customer.list.post();
},
async sendCustomer() {
if(this.params.to_message =="") return
const res = await this.$API.customer.send.post(this.params);
if(res.code == 200){
this.tagList.push({});
this.params.to_message = "";
}
},
async customerType() {
const res = await this.$API.customer.typeList.post();
if (res.code == 200) {
@ -123,20 +128,57 @@ export default {
},
typeActive(item){
this.params.type = item.value;
}
},
async sendCustomer() {
if(this.params.to_message =="") return
const res = await this.$API.customer.send.post(this.params);
if(res.code == 200){
const userInfo = this.$TOOL.data.get("USER_INFO");
this.msgList.push({
to_user_id:-1,
from_user:{
name:userInfo.name,
avatar:userInfo.avatar
},
to_message:this.params.to_message
});
this.params.to_message = "";
this.scrollDown();
}
},
scroll({scrollTop}){
if(scrollTop>10){
this.$refs.tagList.style.position = "absolute";
this.$refs.tagList.style.background = "#fff";
}else{
this.$refs.tagList.style.position = "relative";
this.$refs.tagList.style.background = "";
}
},
scrollDown() {
this.$nextTick(() => {
const wrap = this.$refs.scrollbar;
if(wrap){
const e = wrap.$el.querySelector('.el-scrollbar__wrap')
e.scrollTop = e.scrollHeight;
}
})
},
}
}
</script>
<style scoped lang="scss">
.customerBox{
position: fixed;
position: absolute;
right: 40px;
bottom: 80px;
z-index: 10;
bottom: 40px;
z-index: 1000;
.img{
width: 56px;
height: 56px;
cursor: pointer;
}
.customerView{
width: 380px;
@ -165,19 +207,26 @@ export default {
cursor: pointer;
}
}
.affix-container {
position: relative;
}
.bodyMain{
flex: 1;
overflow: hidden;
.tagList{
position: relative;
left: 0;
z-index: 0;
display: flex;
flex-wrap: wrap;
padding: 0 10px;
padding: 0 10px 10px 10px;
.tagItem{
background: #F4F4F4;
padding: 10px;
border-radius: 4px;
margin: 10px 10px 0 0;
color: #555;
cursor: pointer;
}
}
.msgList{
@ -190,7 +239,7 @@ export default {
}
.msgText{
.msgTitle{
padding: 6px 0;
padding: 0 0 8px 0;
color: #555;
}
.textCom{

View File

@ -0,0 +1,39 @@
// 自定义拖拉指令
export default{
mounted(el) {
let startX, startY, initialMouseX, initialMouseY;
const parent = el.parentElement;
function onMouseMove(event) {
const dx = event.clientX - initialMouseX;
const dy = event.clientY - initialMouseY;
let newLeft = startX + dx;
let newTop = startY + dy;
// 确保拖拽元素不会超出父级容器的范围
const maxX = parent.clientWidth - el.offsetWidth;
const maxY = parent.clientHeight - el.offsetHeight;
newLeft = Math.max(0, Math.min(newLeft, maxX));
newTop = Math.max(0, Math.min(newTop, maxY));
el.style.left = newLeft + 'px';
el.style.top = newTop + 'px';
}
function onMouseUp() {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}
el.addEventListener('mousedown', (event) => {
startX = el.offsetLeft;
startY = el.offsetTop;
initialMouseX = event.clientX;
initialMouseY = event.clientY;
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
}
}

View File

@ -43,6 +43,7 @@ import time from './directives/time'
import copy from './directives/copy'
import number from './directives/number'
import focus from './directives/focus'
import draggable from './directives/draggable'
import errorHandler from './utils/errorHandler'
import * as elIcons from '@element-plus/icons-vue'
@ -100,6 +101,7 @@ export default {
app.directive('copy', copy)
app.directive('number', number)
app.directive('focus', focus)
app.directive('draggable', draggable)
//统一注册el-icon图标
for(let icon in elIcons){

View File

@ -140,6 +140,7 @@ export default {
overflow: hidden;
padding: 0;
border-radius: 0;
position: relative;
.pageBody{
height: 100%;
display: flex;
@ -273,4 +274,11 @@ export default {
}
}
.customerBoxView{
position: absolute;
right: 15px;
top: 80%;
z-index: 2000;
cursor: move;
}
</style>

View File

@ -26,7 +26,7 @@
<div class="mainBody">
<div class="mainTitle">龙隆</div>
<div class="mainView">
<el-scrollbar>
<el-scrollbar ref="scrollbar">
<div class="msgList">
<div class="msgItem" :class="user_id === item.to_user_id?'msgRightItem':''" v-for="(item,index) in msgList" :key="index">
<div class="avatar" v-if="user_id != item.to_user_id">
@ -36,7 +36,9 @@
</div>
<div class="msgText">
<div class="msgTitle">{{item.from_user && item.from_user.name?item.from_user.name:'匿名'}}</div>
<div class="textCom">{{item.to_message}}</div>
<div class="textCom">
<div v-html="item.to_message"></div>
</div>
</div>
<div class="avatar" v-if="user_id === item.to_user_id">
<el-avatar :size="36" :src="item.from_user.avatar" fit="contain">
@ -102,7 +104,7 @@ export default {
contactsList:[
{name:"龙隆",msg:"嘻嘻"},
{name:"骁骁",msg:"测试信息"},
{name:"",msg:"怎么能快速挣够一百万"},
{name:"管理员",msg:"怎么能快速挣够一百万"},
{name:"",msg:"真机运行不需要检查更新真机运行时appid固定为'HBuilder'"},
{name:"",msg:"真机运行不需要检查更新真机运行时appid固定为'HBuilder'"},
],
@ -129,6 +131,7 @@ export default {
switch(res.data.type) {
case 36:
this.msgList = res.data.rows;
this.scrollDown();
break;
case 37:
this.params.to_user_id = res.data.user.uid;
@ -143,9 +146,29 @@ export default {
if(this.params.to_message =="") return
const res = await this.$API.customer.send.post(this.params);
if(res.code == 200){
const userInfo = this.$TOOL.data.get("USER_INFO");
this.msgList.push({
to_user_id:userInfo.id,
from_user:{
name:userInfo.name,
avatar:userInfo.avatar
},
to_message:this.params.to_message
});
this.params.to_message = "";
this.scrollDown();
}
},
scrollDown() {
this.$nextTick(() => {
const wrap = this.$refs.scrollbar;
if(wrap){
const e = wrap.$el.querySelector('.el-scrollbar__wrap')
e.scrollTop = e.scrollHeight;
}
})
},
}
}
</script>
@ -247,7 +270,7 @@ export default {
}
.msgText{
.msgTitle{
padding: 6px 0;
padding:0 0 8px 0;
color: #555;
}
.textCom{