更新客服消息记录

This commit is contained in:
龙运模 2024-11-17 22:52:23 +08:00
parent ecb2bd247f
commit fbf370b609
4 changed files with 251 additions and 94 deletions

View File

@ -1,8 +1,5 @@
<template> <template>
<slot name="header"></slot> <div class="importBody">
<el-dialog v-bind="$attrs" :title="title" v-model="visible" :width="560" destroy-on-close draggable @closed="visible=false">
<div class="importBody" v-loading="saveLoading" element-loading-text="处理中...">
<el-upload <el-upload
class="upload" class="upload"
:action="oss.host" :action="oss.host"
@ -15,52 +12,42 @@
:on-exceed="handleExceed" :on-exceed="handleExceed"
:before-upload="beforeUpload" :before-upload="beforeUpload"
:http-request="uploadFile" :http-request="uploadFile"
drag :drag="false"
multiple multiple
:auto-upload="true" :auto-upload="true"
:limit="5" :limit="9"
> >
<div> <div class="el-upload-size">
<el-icon class="el-icon--upload"><sc-icon-Upload /></el-icon> <el-icon class="el-icon--upload" size="18"><sc-icon-Attachment /></el-icon>
<div class="el-upload__text">
<span class="laText">请将附件拖到此处或点击上传</span>
</div> </div>
</div> <!-- <template #tip>-->
<!-- <div class="el-upload__tip">-->
<template #tip> <!-- <span class="tip">最多上传5个文件,单个文件不要超过10M,请上传 图片/xlsx/docx/zip 格式文件</span>-->
<div class="el-upload__tip"> <!-- <span class="btn">-->
<span class="tip">最多上传5个文件,单个文件不要超过10M,请上传 图片/xlsx/docx/zip 格式文件</span> <!-- <slot name="download"></slot>-->
<span class="btn"> <!-- </span>-->
<slot name="download"></slot> <!-- </div>-->
</span> <!-- <div class="importBox" v-if="progressShow && (fileList.length>0 || listProgress.length>0)">-->
</div> <!-- <div v-if="uploadShow">-->
<div class="importBox" v-if="progressShow && (fileList.length>0 || listProgress.length>0)"> <!-- <div class="item" v-for="(item,index) in fileList" :key="item">-->
<div v-if="uploadShow"> <!-- <div class="name">{{item.name}}</div>-->
<div class="item" v-for="(item,index) in fileList" :key="item"> <!-- <el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="0" />-->
<div class="name">{{item.name}}</div> <!-- <div class="deleteFile" @click="deleteFileNum(index)"><el-icon class="icon"><el-icon-Close/></el-icon></div>-->
<el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="0" /> <!-- </div>-->
<div class="deleteFile" @click="deleteFileNum(index)"><el-icon class="icon"><el-icon-Close/></el-icon></div> <!-- </div>-->
</div> <!-- <div v-else>-->
</div> <!-- <div class="item" v-for="(item) in listProgress" :key="item">-->
<div v-else> <!-- <div class="name">{{item.client_file_name}}</div>-->
<div class="item" v-for="(item) in listProgress" :key="item"> <!-- <el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" />-->
<div class="name">{{item.client_file_name}}</div> <!-- </div>-->
<el-progress class="exportPopover" :text-inside="true" :stroke-width="12" :percentage="item.rate" /> <!-- </div>-->
</div> <!-- </div>-->
</div> <!-- </template>-->
</div>
</template>
</el-upload> </el-upload>
</div> </div>
<template #footer>
<el-button @click="close"> </el-button>
<el-button type="primary" @click="save" :disabled="saveLoading"> </el-button>
</template>
</el-dialog>
</template> </template>
<script> <script>
import {eventBus} from "@/utils/eventBus"
export default { export default {
name: "attachmentUpload", name: "attachmentUpload",
@ -71,7 +58,6 @@ export default {
}, },
data(){ data(){
return{ return{
visible: false,
saveLoading:false, saveLoading:false,
fileList:[], // fileList:[], //
listProgress:[], // listProgress:[], //
@ -97,10 +83,10 @@ export default {
}, },
mounted() { mounted() {
eventBus.$on('sockBack', this.getWsResult);
}, },
unmounted() { unmounted() {
eventBus.$off('sockBack', this.getWsResult);
}, },
methods:{ methods:{
getWsResult(res){ getWsResult(res){
@ -162,6 +148,8 @@ export default {
} }
formData.append('to_user_id', this.parentParams['to_user_id']); formData.append('to_user_id', this.parentParams['to_user_id']);
this.params = formData; this.params = formData;
this.save();
}, },
deleteFileNum(num){ deleteFileNum(num){
this.handleRemove(this.fileList[num], this.fileList); this.handleRemove(this.fileList[num], this.fileList);
@ -216,10 +204,23 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.importBody{ .importBody{
padding: 0 20px; padding: 0;
display: flex;
align-items: center;
}
.upload .el-upload-size{
display: flex;
align-items: center;
justify-content: center;
} }
.upload .el-icon--upload{ .upload .el-icon--upload{
width: 54px;height: 54px; margin-bottom: 0;
color: #333;
}
.upload ::v-deep .el-upload{
display: flex;
align-items: center;
justify-content: center;
} }
.upload ::v-deep .el-upload__text{ .upload ::v-deep .el-upload__text{
.trueIcon{ .trueIcon{
@ -261,6 +262,11 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.upload ::v-deep .el-upload-dragger{
border: 0;
border-radius: 0;
padding: 0;
}
.importBox{ .importBox{
border: 1px solid var(--el-border-color); border: 1px solid var(--el-border-color);
padding: 10px 5px; padding: 10px 5px;

View File

@ -1,12 +1,12 @@
<template> <template>
<el-dialog :title="titleMap[mode]" v-model="visible" :width="600" draggable destroy-on-close @closed="$emit('closed')"> <el-dialog :title="titleMap[mode]" v-model="visible" :width="600" draggable destroy-on-close @closed="$emit('closed')">
<el-input placeholder="搜索"></el-input> <el-input placeholder="搜索" v-model="keyWord"></el-input>
<el-tabs> <el-tabs v-loading="loading" element-loading-text="加载中..." v-model="tabName" @tab-change="tabChange">
<el-tab-pane label="全部"> <el-tab-pane label="全部" name="1">
<records-list></records-list> <records-list :recordsData="recordsDataList"></records-list>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="文档"> <el-tab-pane label="文档" name="2">
647658 <records-list :recordsData="recordsDataList"></records-list>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-dialog> </el-dialog>
@ -28,7 +28,14 @@ export default {
}, },
visible: false, visible: false,
isSave: false, isSave: false,
loading:false,
tabName:"1",
recordsDataList:[],
page: 1,
keyWord:"",
user_id:this.$TOOL.data.get('USER_INFO').id,
to_user_id:"",
} }
}, },
mounted() { mounted() {
@ -41,14 +48,43 @@ export default {
this.visible = true; this.visible = true;
return this return this
}, },
tabChange(){
this.setData();
},
// //
async setData(data) { setData(data) {
this.to_user_id = data;
this.getData();
},
async getData() {
let params = { let params = {
page:1, page: this.page,
pageSize: 100, pageSize: 100,
to_user_id:data creator_id: {
operator: "in",
value: [this.to_user_id, this.user_id]
},
send_message_type: {
operator: "=",
value: this.tabName === "1" ? "" : this.tabName
},
to_message: {
operator: "like",
value: this.keyWord === "" ? "" : "%" + this.keyWord + "%"
}
}
this.loading = true;
const res = await this.$API.customer.recordList.post(params);
this.loading = false;
if (res.code == 200) {
res.data.rows.forEach((item) => {
if (item.send_message_type == 2) {
item.to_message_list = JSON.parse(item.to_message);
}
})
// console.log(res.data.rows)
this.recordsDataList = res.data.rows;
} }
await this.$API.customer.recordList.post(params);
} }
} }
} }

View File

@ -1,23 +1,54 @@
<template> <template>
<div class="recordView"> <div class="recordView">
<!-- <div class="itemCol" v-for="(item,index) in list">--> <el-scrollbar max-height="420px">
<!-- <div class=""></div>--> <div class="itemCol" v-for="(item,index) in recordsData" :key="index">
<!-- </div>--> <div class="avatar">
<el-avatar :size="36" :src="item.from_user.avatar" fit="contain" v-if="item.from_user && item.from_user.avatar">
<img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"/>
</el-avatar>
<el-avatar :size="36" :src="item.to_user.avatar" fit="contain" v-else>
<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:'匿名'}}
<span class="time">{{item.created_at}}</span>
</div>
<div class="textCom" v-if="item.send_message_type === 1">
<div v-html="item.to_message"></div>
</div>
<div class="textCom textComNoneBack" v-if="item.send_message_type === 2">
<div v-for="(em,ind) in item.to_message_list" :key="ind">
<span v-if="em.extension === 'png' || em.extension === 'jpg' || em.extension === 'gif' || em.extension === 'jpeg'">
<el-image style="max-width: 140px;max-height: 140px;border-radius: 4px;" fit="cover" :src="em.file?em.file:em" preview-teleported :preview-src-list="[em.file?em.file:em]"></el-image>
</span>
<span class="fileView" v-else>
<fileType size="30px" :fileType="em.extension" />
</span>
</div>
</div>
</div>
</div>
</el-scrollbar>
</div> </div>
</template> </template>
<script> <script>
import fileType from "@/views/docsManager/fileType"
export default { export default {
name: "recordsList", name: "recordsList",
components:{
fileType
},
props:{ props:{
// list:{ recordsData:{
// type:Array, type:Array
// default:[] }
// }
}, },
data(){ data(){
return{ return{
user_id:this.$TOOL.data.get('USER_INFO').id
} }
}, },
mounted() { mounted() {
@ -30,5 +61,67 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.recordView{
padding: 10px 0;
.itemCol{
display: flex;
margin-bottom: 8px;
padding:0 10px 8px 0;
border-bottom: 1px solid #f4f4f4;
.avatar{
padding-right: 10px;
}
.msgText{
flex: 1;
.msgTitle{
padding:0 0 8px 0;
color: #888;
display: flex;
align-items: center;
justify-content: space-between;
.time{
margin-left: 8px;
font-size: 12px;
color: #888;
}
}
.textCom{
padding: 0;
display: inline-block;
text-align: left;
.fileView{
cursor: pointer;
}
}
.textComNoneBack{
background: none;
}
}
}
.msgRightItem{
justify-content: flex-end;
padding:0 0 0 40px;
.avatar{
padding-left: 10px;
padding-right: 0;
}
.msgText{
text-align: right;
.msgTitle{
text-align: right;
}
.textCom{
background: var(--el-color-primary);
color: var(--el-color-white);
text-align: left;
}
.textComNoneBack{
background: none;
.el-image{
border-radius: 4px;
}
}
}
}
}
</style> </style>

View File

@ -46,12 +46,13 @@
<div v-html="item.to_message"></div> <div v-html="item.to_message"></div>
</div> </div>
<div class="textCom textComNoneBack" v-if="item.send_message_type === 2"> <div class="textCom textComNoneBack" v-if="item.send_message_type === 2">
<div v-for="(em,ind) in item.to_message_list" :key="ind"> <div :class="user_id != item.to_user_id?'fileRightItem':''" v-for="(em,ind) in item.to_message_list" :key="ind">
<span v-if="em.extension === 'png' || em.extension === 'jpg' || em.extension === 'gif' || em.extension === 'jpeg'"> <span v-if="em.extension === 'png' || em.extension === 'jpg' || em.extension === 'gif' || em.extension === 'jpeg'">
<el-image style="max-width: 280px;max-height: 240px;" fit="contain" :src="em.file?em.file:em" preview-teleported :preview-src-list="[em.file?em.file:em]"></el-image> <el-image style="max-width: 280px;max-height: 240px;" fit="cover" :src="em.file?em.file:em" preview-teleported :preview-src-list="[em.file?em.file:em]"></el-image>
</span> </span>
<span class="fileView" v-else> <span class="fileView" v-else @click="linkFile(em)">
<fileType size="60px" :fileType="em.extension" /> <fileType size="26px" :fileType="em.extension" />
<span class="fileName">{{em.client_file_name?em.client_file_name:'未命名'}}</span>
</span> </span>
</div> </div>
</div> </div>
@ -67,7 +68,9 @@
</div> </div>
<div class="mainFooter"> <div class="mainFooter">
<div class="tagList"> <div class="tagList">
<div class="tagItem" @click="uploadFile"><el-icon size="18"><sc-icon-Attachment/></el-icon></div> <div class="tagItem" @click="uploadFile">
<uploadFile ref="uploadFile" @uploadFileSuccess="uploadFileSuccess" title="上传附件"></uploadFile>
</div>
<div class="tagItem" @click="recordsShow"><el-icon size="18"><sc-icon-Record/></el-icon></div> <div class="tagItem" @click="recordsShow"><el-icon size="18"><sc-icon-Record/></el-icon></div>
<div class="tagItem"><el-icon size="18"><sc-icon-Expression/></el-icon></div> <div class="tagItem"><el-icon size="18"><sc-icon-Expression/></el-icon></div>
</div> </div>
@ -110,7 +113,7 @@
</el-container> </el-container>
<customer-records-dialog v-if="dialog.show" ref="recordsMsgDialog" @closed="dialog.show=false"></customer-records-dialog> <customer-records-dialog v-if="dialog.show" ref="recordsMsgDialog" @closed="dialog.show=false"></customer-records-dialog>
<uploadFile ref="uploadFile" @uploadFileSuccess="uploadFileSuccess" title="上传附件"></uploadFile>
</template> </template>
<script> <script>
@ -140,7 +143,8 @@ export default {
dialog:{ dialog:{
show:false show:false
} },
mesList:false,
} }
}, },
created() { created() {
@ -152,6 +156,7 @@ export default {
setTimeout(()=>{ setTimeout(()=>{
this.getContactList(); this.getContactList();
},1000) },1000)
// //
eventBus.$on('sockBack', this.getWsResult); eventBus.$on('sockBack', this.getWsResult);
@ -175,7 +180,10 @@ export default {
this.to_user_id = res.data.contact_list[0].from_user.id; this.to_user_id = res.data.contact_list[0].from_user.id;
this.params.to_user_id = res.data.contact_list[0].from_user.id; this.params.to_user_id = res.data.contact_list[0].from_user.id;
this.contactsInfo = res.data.contact_list[0]; this.contactsInfo = res.data.contact_list[0];
if(!this.mesList){
this.getCustomerMsgList(); this.getCustomerMsgList();
this.mesList = true;
}
} }
break; break;
default: default:
@ -231,15 +239,18 @@ export default {
}) })
}, },
uploadFileSuccess(){ uploadFileSuccess(){
this.getCustomerMsgList(); // this.getCustomerMsgList();
}, },
recordsShow(){ recordsShow(){
this.dialog.show = true; this.dialog.show = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.recordsMsgDialog.open('show').setData(this.to_user_id); this.$refs.recordsMsgDialog.open('show').setData(this.to_user_id); // this.to_user_id
}) })
}, },
linkFile(em){
window.location.href = em.file;
},
scrollDown() { scrollDown() {
this.$nextTick(() => { this.$nextTick(() => {
@ -377,10 +388,21 @@ export default {
text-align: left; text-align: left;
.fileView{ .fileView{
cursor: pointer; cursor: pointer;
color: var(--el-color-primary);
display: flex;
align-items: center;
border: 1px solid #f4f4f4;
padding: 5px 10px;
border-radius: 4px;
background: #f8f6f6;
} }
} }
.textComNoneBack{ .textComNoneBack{
background: none; background: none;
padding: 10px 0;
.fileRightItem{
text-align: right;
}
} }
} }
} }