|
|
|
<template>
|
|
|
|
<div class="content-max">
|
|
|
|
<el-descriptions class="margin-top" :column="3" :size="size" border>
|
|
|
|
<el-descriptions-item>
|
|
|
|
<template #label>
|
|
|
|
<div class="cell-item">
|
|
|
|
<el-icon>
|
|
|
|
<user />
|
|
|
|
</el-icon>
|
|
|
|
订单自编号
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
{{ ListRow.waybillNumber }}
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item>
|
|
|
|
<template #label>
|
|
|
|
<div class="cell-item">
|
|
|
|
<el-icon>
|
|
|
|
<iphone />
|
|
|
|
</el-icon>
|
|
|
|
运单号
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
18100000000
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item>
|
|
|
|
<template #label>
|
|
|
|
<div class="cell-item">
|
|
|
|
<el-icon>
|
|
|
|
<location />
|
|
|
|
</el-icon>
|
|
|
|
车次号
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
Suzhou
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item>
|
|
|
|
<template #label>
|
|
|
|
<div class="cell-item">
|
|
|
|
<el-icon>
|
|
|
|
<tickets />
|
|
|
|
</el-icon>
|
|
|
|
工单号
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
School
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
|
|
<el-descriptions-item>
|
|
|
|
<template #label>
|
|
|
|
<div class="cell-item">
|
|
|
|
<el-icon>
|
|
|
|
<office-building />
|
|
|
|
</el-icon>
|
|
|
|
异常问题描述
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province
|
|
|
|
</el-descriptions-item>
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
|
|
<div class="content-msg">
|
|
|
|
<div class="content" ref="scrollContainer">
|
|
|
|
<!-- 用户 -->
|
|
|
|
<div
|
|
|
|
:class="{ YH: item.businessId != currentUser, KF: item.businessId == currentUser }"
|
|
|
|
v-for="item in ChatHistory"
|
|
|
|
:key="item.input"
|
|
|
|
>
|
|
|
|
<div class="box">
|
|
|
|
<div class="TX"></div>
|
|
|
|
<div class="name">
|
|
|
|
<span>{{ item.businessName }}</span>
|
|
|
|
<div class="input">
|
|
|
|
{{ item.content }}
|
|
|
|
</div>
|
|
|
|
<div class="time">{{ item.createTime }}</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="inputTextarea" v-loading="iconState" element-loading-text="正在处理中...">
|
|
|
|
<div class="fell">
|
|
|
|
<el-upload
|
|
|
|
ref="uploadRef"
|
|
|
|
class="upload-demo"
|
|
|
|
:action="doubledCount"
|
|
|
|
:headers="headers"
|
|
|
|
:on-success="fellSuccess"
|
|
|
|
>
|
|
|
|
<template #trigger>
|
|
|
|
<el-button type="primary">上传附件</el-button>
|
|
|
|
<div class="felltis" v-if="KFfeel">上传成功</div>
|
|
|
|
</template>
|
|
|
|
</el-upload>
|
|
|
|
<div class="el_footer">
|
|
|
|
<el-input
|
|
|
|
@keydown.enter="inputEnter"
|
|
|
|
v-model="KFinput"
|
|
|
|
:rows="4"
|
|
|
|
type="textarea"
|
|
|
|
placeholder="请输入内容"
|
|
|
|
/>
|
|
|
|
<div class="el_sed">
|
|
|
|
<el-button class="btn_fs" type="primary" @click="messagesend">发送</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
import { $_AddReply, $_getExchangeList } from '@/api/aftersales/aftersalesWorkOrder';
|
|
|
|
import { useRoute } from 'vue-router';
|
|
|
|
const ChatHistory = ref([]); // 消息记录
|
|
|
|
const scrollContainer = ref(null); //客服实例
|
|
|
|
const KFfeel = ref(''); //文件附件地址
|
|
|
|
const iconState = ref(false); //消息状态
|
|
|
|
const KFinput = ref(''); //客服发送消息
|
|
|
|
const ListRow = ref(); //当前行数据
|
|
|
|
const currentUser = ref(null); //存放当前的对话框必要Id
|
|
|
|
const $route = useRoute();
|
|
|
|
const Mydata = ref(null); //仓库关键信息
|
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
|
import { ElMessageBox } from 'element-plus';
|
|
|
|
import { getToken } from '@/utils/auth';
|
|
|
|
|
|
|
|
// 获取聊天记录
|
|
|
|
const FKList = () => {
|
|
|
|
iconState.value = true;
|
|
|
|
let data = { workOrderId: ListRow.value.id };
|
|
|
|
$_getExchangeList(data).then(res => {
|
|
|
|
iconState.value = false;
|
|
|
|
console.log(res, '查询的值');
|
|
|
|
ChatHistory.value = res.data.data;
|
|
|
|
setTimeout(() => {
|
|
|
|
const container = scrollContainer.value;
|
|
|
|
if (container) {
|
|
|
|
container.scrollTop = container.scrollHeight;
|
|
|
|
}
|
|
|
|
}, 0);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
// 页面初始化加载消息
|
|
|
|
const onLoad = () => {
|
|
|
|
ListRow.value = JSON.parse($route.query.row);
|
|
|
|
console.log();
|
|
|
|
Mydata.value = JSON.parse(localStorage.getItem('my_data')); //获取本地仓库信息
|
|
|
|
currentUser.value = Mydata.value.id;
|
|
|
|
console.log(ListRow.value, '路由参数');
|
|
|
|
FKList();
|
|
|
|
};
|
|
|
|
onLoad();
|
|
|
|
|
|
|
|
// 消息发送函数
|
|
|
|
const messagesendFn = () => {
|
|
|
|
iconState.value = true;
|
|
|
|
let data = {
|
|
|
|
workOrderId: ListRow.value.id,
|
|
|
|
businessName: Mydata.value.departmentName,
|
|
|
|
businessId: Mydata.value.id,
|
|
|
|
content: KFinput.value,
|
|
|
|
warehouseId: ListRow.value.warehouseId,
|
|
|
|
annex: KFfeel.value,
|
|
|
|
};
|
|
|
|
console.log(data, '处理好的数据');
|
|
|
|
// 获取当前时间
|
|
|
|
const currentTime = new Date();
|
|
|
|
// 获取年、月、日、小时、分钟、秒
|
|
|
|
const year = String(currentTime.getFullYear());
|
|
|
|
const month = String(currentTime.getMonth() + 1).padStart(2, '0');
|
|
|
|
const day = String(currentTime.getDate()).padStart(2, '0');
|
|
|
|
const hours = String(currentTime.getHours()).padStart(2, '0');
|
|
|
|
const minutes = String(currentTime.getMinutes()).padStart(2, '0');
|
|
|
|
const seconds = String(currentTime.getSeconds()).padStart(2, '0');
|
|
|
|
// 拼接时间字符串
|
|
|
|
const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
|
$_AddReply(data).then(res => {
|
|
|
|
|
|
|
|
console.log(res, '添加成功');
|
|
|
|
if (res.data.code == 200) {
|
|
|
|
// 添加成功
|
|
|
|
iconState.value = false;
|
|
|
|
ChatHistory.value.push({
|
|
|
|
businessId: Mydata.value.id,
|
|
|
|
businessName: Mydata.value.departmentName,
|
|
|
|
content: KFinput.value,
|
|
|
|
createTime: formattedTime,
|
|
|
|
});
|
|
|
|
// 聊天记录滚动到最后
|
|
|
|
setTimeout(() => {
|
|
|
|
const container = scrollContainer.value;
|
|
|
|
if (container) {
|
|
|
|
container.scrollTop = container.scrollHeight;
|
|
|
|
}
|
|
|
|
}, 0);
|
|
|
|
KFinput.value = ''; //清空内容
|
|
|
|
KFfeel.value = null; //清空文件
|
|
|
|
|
|
|
|
}
|
|
|
|
}).catch(res=>{
|
|
|
|
console.log('err');
|
|
|
|
KFinput.value = ''; //清空内容
|
|
|
|
KFfeel.value = null; //清空文件
|
|
|
|
iconState.value = false;
|
|
|
|
});
|
|
|
|
console.log(Mydata.value, '参数');
|
|
|
|
};
|
|
|
|
// 输入框回车
|
|
|
|
const inputEnter = () => {
|
|
|
|
messagesendFn();
|
|
|
|
};
|
|
|
|
// 客服刷新按钮
|
|
|
|
const KFRefresh = () => {
|
|
|
|
FKList();
|
|
|
|
};
|
|
|
|
// 发送按钮
|
|
|
|
const messagesend = () => {
|
|
|
|
messagesendFn();
|
|
|
|
};
|
|
|
|
// 图片上传接口
|
|
|
|
const doubledCount = computed(() => {
|
|
|
|
return '/api/blade-resource/oss/endpoint/put-file';
|
|
|
|
});
|
|
|
|
// 图片上传必须携带TOKEN
|
|
|
|
const headers = computed(() => {
|
|
|
|
return { 'Blade-Auth': 'Bearer ' + getToken() };
|
|
|
|
});
|
|
|
|
// 附件上传成功
|
|
|
|
const fellSuccess = (response, uploadFile) => {
|
|
|
|
console.log('上船成功');
|
|
|
|
console.log(response, uploadFile);
|
|
|
|
if (response.data.link) {
|
|
|
|
KFfeel.value = response.data.link;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.content {
|
|
|
|
height: 78%;
|
|
|
|
overflow-y: scroll;
|
|
|
|
scroll-behavior: smooth;
|
|
|
|
padding: 10px;
|
|
|
|
/* 添加平滑滚动效果 */
|
|
|
|
border-radius: 5px;
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
box-sizing: border-box;
|
|
|
|
margin: 4px;
|
|
|
|
.YH {
|
|
|
|
width: 100%;
|
|
|
|
min-height: 50px;
|
|
|
|
margin: 4px 0;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
.box {
|
|
|
|
width: 386px;
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
justify-content: space-between;
|
|
|
|
.name {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
span {
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-start;
|
|
|
|
padding-left: 10px;
|
|
|
|
margin-bottom: 10px;
|
|
|
|
}
|
|
|
|
.time {
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
padding: 0 10px;
|
|
|
|
margin-top: 4px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.input {
|
|
|
|
border: 1px solid;
|
|
|
|
width: 300px;
|
|
|
|
min-height: 30px;
|
|
|
|
box-sizing: border-box;
|
|
|
|
border-radius: 8px;
|
|
|
|
padding: 8px;
|
|
|
|
margin: 0 6px;
|
|
|
|
text-indent: 2em;
|
|
|
|
position: relative;
|
|
|
|
.ico {
|
|
|
|
position: absolute;
|
|
|
|
right: -6%;
|
|
|
|
bottom: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.KF {
|
|
|
|
width: 100%;
|
|
|
|
min-height: 50px;
|
|
|
|
margin: 4px 0;
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
.box {
|
|
|
|
width: 386px;
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
justify-content: space-between;
|
|
|
|
.name {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
span {
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
padding-right: 10px;
|
|
|
|
margin-bottom: 10px;
|
|
|
|
}
|
|
|
|
.time {
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-start;
|
|
|
|
padding: 0 10px;
|
|
|
|
margin-top: 4px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.input {
|
|
|
|
border: 1px solid;
|
|
|
|
width: 300px;
|
|
|
|
min-height: 30px;
|
|
|
|
box-sizing: border-box;
|
|
|
|
border-radius: 8px;
|
|
|
|
padding: 8px;
|
|
|
|
margin: 0 6px;
|
|
|
|
text-indent: 2em;
|
|
|
|
position: relative;
|
|
|
|
.ico {
|
|
|
|
position: absolute;
|
|
|
|
left: -16%;
|
|
|
|
bottom: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.TX {
|
|
|
|
height: 50px;
|
|
|
|
width: 50px;
|
|
|
|
border-radius: 50%;
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
background: url('../../../public/img/tx.png') no-repeat;
|
|
|
|
background-size: cover;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.el-descriptions {
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
.cell-item {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
.margin-top {
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
:deep(.el-descriptions__header) {
|
|
|
|
margin-bottom: 0 !important;
|
|
|
|
}
|
|
|
|
.content-max {
|
|
|
|
display: flex;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
flex-direction: column;
|
|
|
|
.content-msg {
|
|
|
|
flex: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.inputTextarea {
|
|
|
|
padding: 10px;
|
|
|
|
box-sizing: border-box;
|
|
|
|
}
|
|
|
|
.el_footer {
|
|
|
|
display: flex;
|
|
|
|
}
|
|
|
|
.el_sed {
|
|
|
|
width: 7%;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: flex-end;
|
|
|
|
}
|
|
|
|
</style>
|