提交 47fa17f0 编写于 作者: huangwensu's avatar huangwensu

创建问诊后台

上级 3bf6fbde
......@@ -13,6 +13,15 @@
"regenerator-runtime": "^0.13.4"
}
},
"@babel/runtime-corejs2": {
"version": "7.13.10",
"resolved": "http://192.168.110.93:4873/@babel%2fruntime-corejs2/-/runtime-corejs2-7.13.10.tgz",
"integrity": "sha1-MbpmuVHL1EVp1+cMtYp7PahmlRo=",
"requires": {
"core-js": "^2.6.5",
"regenerator-runtime": "^0.13.4"
}
},
"abbrev": {
"version": "1.1.1",
"resolved": "http://192.168.110.93:4873/abbrev/-/abbrev-1.1.1.tgz",
......@@ -2405,6 +2414,11 @@
"integrity": "sha1-EODRh/ERsWfyj9q5GIQ859gY8Tw=",
"dev": true
},
"exif-js": {
"version": "2.3.0",
"resolved": "http://192.168.110.93:4873/exif-js/-/exif-js-2.3.0.tgz",
"integrity": "sha1-nRCBm/Vx+HOBPnZAJBJVq5zhqBQ="
},
"exit-hook": {
"version": "1.1.1",
"resolved": "http://192.168.110.93:4873/exit-hook/-/exit-hook-1.1.1.tgz",
......@@ -6404,6 +6418,16 @@
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
"qiniu-js": {
"version": "3.1.2",
"resolved": "http://192.168.110.93:4873/qiniu-js/-/qiniu-js-3.1.2.tgz",
"integrity": "sha1-tG5eHtgG11eoG1QqwTQuBEIdHUU=",
"requires": {
"@babel/runtime-corejs2": "^7.10.2",
"exif-js": "^2.3.0",
"spark-md5": "^3.0.0"
}
},
"qs": {
"version": "6.7.0",
"resolved": "http://192.168.110.93:4873/qs/-/qs-6.7.0.tgz",
......@@ -7680,6 +7704,11 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"spark-md5": {
"version": "3.0.1",
"resolved": "http://192.168.110.93:4873/spark-md5/-/spark-md5-3.0.1.tgz",
"integrity": "sha1-g6DiVXNPKrTlxGblos/JuiqiEk0="
},
"spdx-correct": {
"version": "3.1.1",
"resolved": "http://192.168.110.93:4873/spdx-correct/-/spdx-correct-3.1.1.tgz",
......
import App from '../App'
// 等待会话
const waitingSessionList = r => require.ensure([], () => r(require('../views/IM/waiting-session/list.vue')), 'waitingSessionList')
// // 消息查询
// const searchMessageList = r => require.ensure([], () => r(require('../views/IM/search-message/list.vue')), 'searchMessageList')
// const searchMessageDetail = r => require.ensure([], () => r(require('../views/IM/search-message/detail.vue')), 'searchMessageDetail')
// 消息查询
const searchMessageList = r => require.ensure([], () => r(require('../views/IM/search-message/list.vue')), 'searchMessageList')
const searchMessageDetail = r => require.ensure([], () => r(require('../views/IM/search-message/detail.vue')), 'searchMessageDetail')
// // 当前会话
// const currentSessionList = r => require.ensure([], () => r(require('../views/IM/current-session/index.vue')), 'currentMessageIndex')
// 当前会话
const currentSessionList = r => require.ensure([], () => r(require('../views/IM/current-session/index.vue')), 'currentMessageIndex')
// // 我要群发
// const chainMessage = r => require.ensure([], () => r(require('../views/IM/chain-message/index.vue')), 'chainMessage')
// 我要群发
const chainMessage = r => require.ensure([], () => r(require('../views/IM/chain-message/index.vue')), 'chainMessage')
// 历史群发
const chainHistoryList = r => require.ensure([], () => r(require('../views/IM/chain-history/list.vue')), 'chainHistoryList')
const chainHistoryDetail = r => require.ensure([], () => r(require('../views/IM/chain-history/detail.vue')), 'chainHistoryDetail')
// // 历史群发
// const chainHistoryList = r => require.ensure([], () => r(require('../views/IM/chain-history/list.vue')), 'chainHistoryList')
// const chainHistoryDetail = r => require.ensure([], () => r(require('../views/IM/chain-history/detail.vue')), 'chainHistoryDetail')
// 问诊订单管理
const diagnosisList = r => require.ensure([], () => r(require('../views/IM/diagnosis-admin/diagnosis-list.vue')), 'diagnosisList')
const diagnosisIm = r => require.ensure([], () => r(require('../views/IM/diagnosis-admin/diagnosis-im.vue')), 'diagnosisIm')
export default [{
path: '/',
......@@ -24,29 +24,33 @@ export default [{
children: [
{
path: '',
redirect: '/waiting-session-list'
}, {
path: '/waiting-session-list',
component: waitingSessionList
}, {
path: '/search-message-list',
component: searchMessageList
}, {
path: '/search-message-detail',
component: searchMessageDetail
}, {
path: '/current-session-list',
component: currentSessionList
}, {
path: '/chain-message',
component: chainMessage
}, {
path: '/chain-history-list',
component: chainHistoryList
}, {
path: '/chain-history-detail',
component: chainHistoryDetail
}
redirect: '/diagnosisList'
},{
path: '/diagnosis-list',
component: diagnosisList
},{
path: '/diagnosis-im',
component: diagnosisIm
}
// {
// path: '/search-message-list',
// component: searchMessageList
// }, {
// path: '/search-message-detail',
// component: searchMessageDetail
// }, {
// path: '/current-session-list',
// component: currentSessionList
// }, {
// path: '/chain-message',
// component: chainMessage
// }, {
// path: '/chain-history-list',
// component: chainHistoryList
// }, {
// path: '/chain-history-detail',
// component: chainHistoryDetail
// }
]
}]
\ No newline at end of file
<template>
<div class="current-session-wrap">
<section class="component-content screenSet" id="screenSet">
<article
v-show="sessionListData.sessionList.length"
class="center"
v-loadmore="getOldMSGHistory"
>
<section class="c-header">
<div class="c-header-l">
<img :src="currentSession.avatarImageUrl" alt />
<span class="name">{{doctorInfo.name}}</span>
<span class="time-tip">当前会话时长:{{currentContinueTimes | continueTimesFilter}}</span>
</div>
</section>
<p class="refreshText"></p>
<section id="msgContentId" class="msg-content scroll-box">
<article
v-for="(item, index) in messageList"
:key="index"
:style="{'text-align': item.sendOrReceive ? 'right' : 'left'}"
>
<div class="split-line" v-if="item.sessionFlag">本次会话结束</div>
<div class="msg-item" :class="{'cr': item.sendOrReceive}">
<div class="msg-item-img">
<img :src="item.avatarImg" alt />
</div>
<div class="msg-item-detail">
<span class="mid-time">{{item.timestampStr}}</span>
<div class="send-warpper">
<img
v-if="item.sendOrReceive && item.isShowErrorIcon"
class="icon"
src="../../../assets/image/IM/icon-no-send.png"
alt
/>
<img
v-if="item.sendOrReceive && item.isShowLoadingIcon"
class="icon ld"
src="../../../assets/image/IM/loading-icon-new.png"
alt
/>
<div v-if="item.showType == 1" class="mid-text-wrapper" style="max-width: 520px;">
<!-- <img v-show="item.sendFlag" src="../../../assets/image/IM/icon-no-send.png" alt /> -->
<div class="mid-text">{{item.text}}</div>
</div>
<div v-if="item.showType == 2" class="mid-img" v-viewer>
<div class="img-box">
<img
class="img"
:src="item.url"
:style="{width: item.newW + 'px', height: item.newH + 'px' }"
alt
/>
</div>
</div>
<div v-if="item.showType == 3" class="mid-pdf" @click="openPDF(item)">
<div class="midp-left">
<span class="name">{{item.text | shortName(23)}}</span>
<span class="size">{{fileSizeChange(item.size)}}</span>
</div>
<div class="midp-icon">
<img src="../../../assets/image/IM/icon-pdf.png" alt />
</div>
</div>
<div v-if="item.showType == 4" class="mid-text">
{{item.text}}
<span class="link">{{item.suffix}}</span>
</div>
<div v-if="item.showType == 5" class="mid-text no-support">
<img src="../../../assets/image/IM/icon-warning-circle.png" alt />
<span>该消息类型PC端暂不支持</span>
</div>
</div>
</div>
</div>
<span
v-if="item.sendOrReceive && item.isShowErrorMsg"
class="error-mg"
:class="{'mr': item.sendOrReceive}"
>{{item.errorMsg}}</span>
</article>
</section>
<section class="c-bottom">
<el-input type="textarea" placeholder="请输入内容" v-model="sendText" maxlength="499"></el-input>
<div class="cb-icon-wrapper">
<el-upload
class="bg-uploader"
action="#"
accept=".jpg, .png, .pdf"
:show-file-list="false"
:before-upload="beforeUploadFile"
>
<img src="../../../assets/image/IM/icon-folder-open.png" alt />
</el-upload>
<img src="../../../assets/image/IM/icon-link.png" @click="preSendLinkMsg" alt />
</div>
<div class="send-btn" :class="{'active': canSend}" @click="sendTextMsg">
<img v-show="canSend" src="../../../assets/image/IM/send-yes.png" alt />
<img v-show="!canSend" src="../../../assets/image/IM/send-no.png" alt />
</div>
</section>
</article>
</section>
<!-- 选择链接弹窗 -->
<el-dialog
title="选择链接"
:show-close="true"
:visible.sync="showSelectDialog"
:close-on-click-modal="false"
width="500px"
class="link-form"
>
<el-form ref="linkFormRef" :rules="rules" :model="linkForm" label-width="100px">
<el-form-item label="普通文本">
<el-col :span="20">
<el-input v-model="linkForm.remark" size="small" maxlength="300"></el-input>
</el-col>
</el-form-item>
<el-form-item label="链接文案" prop="info">
<el-col :span="20">
<el-input v-model="linkForm.info" size="small" maxlength="100"></el-input>
</el-col>
</el-form-item>
<el-form-item label="链接地址" prop="url">
<el-col :span="20">
<el-select
size="small"
style="width: 300px"
clearable
filterable
v-model="linkForm.url"
placeholder="请选择"
>
<el-option
v-for="item in linkList"
:key="item.id"
:label="item.title"
:value="item.id"
></el-option>
</el-select>
</el-col>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer" style="text-align: right;">
<el-button size="small" @click="showSelectDialog = false">取 消</el-button>
<el-button size="small" type="primary" @click="sendLinkMsg">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
import BreadCrumb from "@/components/breadcrumb.vue";
import { doUpload, getFilePath } from "@/utils/qiniu-util";
import { openLoading, closeLoading, betaHandle } from "@/utils/utils";
import { getPicaKFAccid, getPhomeDemain } from "@/utils";
const CONTAINER_HEIGHT = 700;
let forwardMsgIntervalId = null,
sessionIntervalId = null,
continueIntervalId = null,
autoCompletionIntervalId = null,
cacheMap = {};
let _this = null;
export default {
components: {
BreadCrumb,
},
data() {
return {
curmbFirst: "云鹊客服",
curmbSecond: "当前会话",
sendText: "",
sessionListData: {
currentTimestamp: 0,
myTaskCount: 0,
sessionList: [],
waitingTaskCount: 0
},
currentContinueTimes: 0,
currentSessionIndex: 0, // 当前会话序号
currentSession: {},
currentTaskLogId: "", // 当前会话ID
currentToAccId: "",
picakfAccId: "",
historyTimestamp: 0,
realTimestamp: 0,
doctorInfo: {
name: "",
mobilePhone: "",
isShowCopyBtn: true
},
containerHeight: CONTAINER_HEIGHT,
showSelectDialog: false,
linkForm: {
remark: "",
info: "",
url: ""
},
linkList: [],
// 消息列表 showType 1: 文本; 2: 图片; 3: PDF; 4: 链接; 5: 不支持类型;
messageList: [],
rules: {
info: [
{ required: true, message: "请填写链接显示文案", trigger: "blur" }
],
url: [{ required: true, message: "请选择链接", trigger: "change" }]
},
imgWidth: 0,
imgHeight: 0,
imgProportion: 0,
hasNoHistoryData: false,
};
},
computed: {
// ...mapGetters(["isFromAssignTask"]),
canSend() {
return !!this.sendText;
}
},
watch: {
// 监听消息列表的变化,添加sessionFlag(会话结束标志)
messageList: {
handler(newMsgList) {
let l = newMsgList.length;
if (l >= 2) {
for (let i = 1; i < l; i++) {
if (newMsgList[i - 1].taskLogId !== newMsgList[i].taskLogId) {
newMsgList[i].sessionFlag = true;
}
}
}
},
deep: true
},
// 监听到有变化,就缓存一下
sendText(newText) {
cacheMap[this.currentSession.id] = newText || "";
}
},
created() {
_this = this;
this.picakfAccId = getPicaKFAccid();
this.kfAvatar = require("../../../assets/image/IM/kf-avatar.png");
this.getSessionList();
sessionIntervalId && clearInterval(sessionIntervalId);
sessionIntervalId = setInterval(() => {
this.getSessionList();
}, 3000);
this.getFiveContentList();
autoCompletionIntervalId && clearInterval(autoCompletionIntervalId);
autoCompletionIntervalId = setInterval(() => {
this.autoCompletionInterval();
}, 2000);
// 监听键盘的回车按键(回车时发送消息,并阻止其在textarea中的回车换行行为)
document.onkeydown = function(ev) {
var event = ev || event;
if (event.keyCode == 13) {
_this.sendTextMsg();
event.preventDefault();
}
};
},
mounted() {
cacheMap = {};
this.$nextTick(() => {
_this.containerHeight = document.body.clientHeight - 80;
_this.getElmByID("screenSet").style.height =
_this.containerHeight - 76 + "px";
// console.log('_this.containerHeight', _this.containerHeight);
// _this.getElmByID("sessionListId").style.height =
// _this.containerHeight - 176 + "px";
// _this.getElmByID("userInfoId").style.height =
// _this.containerHeight - 76 + "px";
_this.getElmByID("msgContentId").style.height =
_this.containerHeight - 211 + "px";
});
},
methods: {
//
// ...mapMutations(["SET_IS_FROM_ASSIGN_TASK"]),
// 含有敏感信息的消息,自行补全提示文案
// 每30秒监测敏感信息
autoCompletionInterval() {
if (!this.messageList.length) return;
// console.log('in autoCompletionInterval');
// 将带有loading的消息转成失败的
this.messageList.forEach(item => {
if (item.isShowLoadingIcon) {
item.isShowLoadingIcon = false;
item.isShowErrorIcon = true;
}
});
let flag = false,
msg;
for (let i = 0; i < this.messageList.length; i++) {
msg = this.messageList[i];
if (msg.isShowErrorIcon && !msg.isShowErrorMsg) {
flag = true;
break;
}
}
if (flag) {
this.getMSGForwardForAC(msg);
}
},
// 查询医生和居民的消息 - 向前查找
getMSGForwardForAC(msg) {
let session = this.currentSession;
let params = {
doctorAccId: this.currentToAccId,
includeFlag: 0,
lastClientIdServer: session.lastMsgIdClient,
lastMsgIdServer: session.lastMsgIdServer,
lastMsgTimestamp: msg.realTimestamp,
limit: 50,
patientAccId: this.picakfAccId,
unionId: ""
};
this.POST("/im/msg/forward", params).then(res => {
if (res.code === "000000") {
this.contactForwardMessage(res.data, false);
}
});
},
// 获取元素
getElmByID(elmId) {
return document.getElementById(elmId);
},
// 处理发送消息
// 1: 先将消息体直接显示在对话框中
// 2: 设置一个时间戳,以便再次找回
// 3: 保存再次发送的数据
// 4: 设置各种状态(1:isShowErrorIcon; 2:isShowLoadingIcon; 3:isShowErrorMsg)
handleSendMsg(params, sendId) {
let text = "";
let msg = Object.assign({}, params);
msg.fromAccount = this.currentToAccId;
msg.toAccount = this.picakfAccId;
// type: 0, // 类型 0文本 1图片 2pdf 3链接
msg.text = params.info || "";
msg.suffix = params.remark || "";
if (msg.type == 3) {
msg.suffix = params.info;
msg.text = params.remark || "";
}
msg.size = params.fileSize;
msg.url = params.url;
msg.showType = params.type - 0 + 1;
msg.sessionFlag = false;
msg.isShowLoadingIcon = true;
msg.isShowErrorIcon = false;
msg.isShowErrorMsg = false; // 只有在下次拉取新数据时才有可能是为ture
msg.extData = Object.assign({}, params); // 再将发送时的数据
msg.sendId = sendId; //
msg.sendOrReceive = true;
msg.avatarImg = this.kfAvatar;
msg.timestampStr = new Date().format("hh:mm");
msg.realTimestamp = this.realTimestamp;
msg.taskLogId = this.currentTaskLogId;
console.log("####msg####", msg);
//
if(msg.type == 1) {
this.imgSizeHandleNew(msg, msg.width, msg.height);
}
this.messageList.push(msg);
this.$nextTick(() => {
var element = document.querySelector(".scroll-box");
element.scrollTop = element.scrollHeight;
});
},
// 查询医生和居民的消息历史(下拉刷新时调用)
getOldMSGHistory() {
console.log('this.hasNoHistoryData', this.hasNoHistoryData);
if(this.hasNoHistoryData) return;
let session = this.currentSession;
let params = {
doctorAccId: this.currentToAccId,
includeFlag: 0, // 不带本条消息
lastClientIdServer: session.lastMsgIdClient,
lastMsgIdServer: session.lastMsgIdServer,
lastMsgTimestamp: this.historyTimestamp,
limit: 20,
patientAccId: this.picakfAccId,
unionId: ""
};
this.POST("/im/msg/history", params).then(res => {
if (res.code === "000000") {
// 将新消息合并到之前的消息中, 并且重置最后一条消息
if(res.data && res.data.length > 0) {
this.convertMessageList(res.data, 3);
} else {
this.hasNoHistoryData = true;
}
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 查询医生和居民的消息历史(第一次进来时就调用)
getMSGHistory(session) {
let params = {
doctorAccId: this.currentToAccId,
includeFlag: 1, // 带本条消息
lastClientIdServer: session.lastMsgIdClient,
lastMsgIdServer: session.lastMsgIdServer,
lastMsgTimestamp: session.lastMsgTime,
limit: 20,
patientAccId: this.picakfAccId,
unionId: ""
};
this.POST("/im/msg/history", params).then(res => {
if (res.code === "000000") {
this.convertMessageList(res.data, 1);
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 查询医生和居民的消息 - 向前查找
// 将获取消息列表插入到当前消息列表的最后
getMSGForward() {
let session = this.currentSession;
let params = {
doctorAccId: this.currentToAccId,
includeFlag: 0,
lastClientIdServer: session.lastMsgIdClient,
lastMsgIdServer: session.lastMsgIdServer,
lastMsgTimestamp: this.realTimestamp,
limit: 20,
patientAccId: this.picakfAccId,
unionId: ""
};
this.POST("/im/msg/forward", params).then(res => {
if (res.code === "000000") {
this.convertMessageList(res.data, 2);
if (res.data.length) {
this.readAllMsg();
}
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 转换消息格式
// 处理的消息类型只有5种:
// type == TEXT(showType:1)
// type == image 或 picture(showType:2)
// type == custom时,18: PDF文件(showType:3); 19: 链接信息(showType:4); 1 ~ 17: 不支持的消息类型(showType:5);
// directFlag 1: 第一次取数据; 2: 拼接实时消息(push); 3: 拼接历史消息(unshift);
convertMessageList(messageList, directFlag = 1) {
messageList.sort((a, b) => {
return a.timestamp - b.timestamp;
});
let msg = null,
content = null,
text = "",
suffix = "",
showType = 1,
size = 0,
url = "",
cMessageList = [];
messageList.forEach((rawMsg, index) => {
text = "";
suffix = "";
showType = 1;
size = 0;
url = "";
msg = Object.assign({}, rawMsg);
msg.sendOrReceive = rawMsg.fromAccId !== this.currentToAccId;
msg.avatarImg = msg.sendOrReceive
? this.kfAvatar
: this.currentSession.avatarImageUrl;
if (msg.type.toLowerCase() == "custom") {
content = JSON.parse(msg.content);
text = content.content;
// 系统消息:消息由于违规未发送成功(可以不处理)
if (content.bizType == -1) {
showType = -1;
text = content.content;
} else if (content.bizType == 18) {
showType = 3;
text = content.name;
size = content.size;
url = content.url;
} else if (content.bizType == 19) {
showType = 4;
text = content.content;
suffix = content.suffix;
} else {
showType = 5;
}
} else if (
msg.type.toLowerCase() == "image" ||
msg.type.toLowerCase() == "picture"
) {
content = JSON.parse(msg.content);
url = content.url;
text = content.name;
showType = 2;
this.imgSizeHandleNew(msg, content.w, content.h);
} else {
showType = 1;
text = msg.content;
}
msg.text = text;
msg.showType = showType;
msg.suffix = suffix;
msg.size = size;
msg.url = url;
msg.sessionFlag = false;
cMessageList.push(msg);
});
if (directFlag === 1) {
this.messageList = [];
this.$forceUpdate();
forwardMsgIntervalId && clearInterval(forwardMsgIntervalId);
this.messageList = cMessageList;
this.$forceUpdate();
setTimeout(() => {
this.$nextTick(() => {
const scrollBoxDom = document.querySelector(".scroll-box");
scrollBoxDom.scrollTop = scrollBoxDom.scrollHeight;
});
}, 100);
this.currentContinueTimes =
this.sessionListData.currentTimestamp -
this.currentSession.handleStartTime;
continueIntervalId && clearInterval(continueIntervalId);
continueIntervalId = setInterval(() => {
this.currentContinueTimes += 1000;
}, 1000);
// 最新消息,要合并CUSTOM类型中,bizType是-1的数据(系统消息)
} else if (directFlag === 2) {
this.contactForwardMessage(cMessageList);
} else {
if (cMessageList.length) {
this.messageList.unshift(...cMessageList);
this.$nextTick(() => {
const scrollBoxDom = document.querySelector(".scroll-box");
scrollBoxDom.scrollTop = 1000;
});
}
}
// 重新设置历史与实时的时间戳
if (this.messageList.length) {
this.historyTimestamp = this.messageList[0].timestamp;
let timestamp = this.messageList[this.messageList.length - 1].timestamp;
if (timestamp) {
this.realTimestamp = timestamp;
}
}
// 自己发送消息时,暂时不刷新消息
if (directFlag == 1) {
forwardMsgIntervalId = setInterval(() => {
this.getMSGForward();
}, 3000);
}
this.$forceUpdate();
},
// 接接数据
contactForwardMessage(cMessageList, canPush = true) {
let content = {},
signature = "",
msgIndex = -1,
newMsgList = [],
flag = false;
cMessageList.forEach(item => {
content = {};
signature = "";
msgIndex = -1;
newMsgList = [];
if (item.type.toLowerCase() == "custom") {
content = JSON.parse(item.content);
if (content.bizType == -1) {
signature = content.signature;
msgIndex = this.messageList.findIndex(m => {
return m.signature == signature && !m.isShowErrorMsg;
});
if (msgIndex > -1) {
flag = true;
this.messageList[msgIndex].errorMsg = content.content;
this.messageList[msgIndex].isShowErrorMsg = true;
}
this.$forceUpdate();
} else {
flag = true;
canPush && this.messageList.push(item);
}
} else {
flag = true;
canPush && this.messageList.push(item);
}
});
if (flag) {
this.$nextTick(() => {
var element = document.querySelector(".scroll-box");
if (
element.scrollTop >=
element.scrollHeight - element.offsetHeight - 300
) {
element.scrollTop = element.scrollHeight - element.offsetHeight;
}
});
}
},
// 打开PDF
openPDF(item) {
window.open(item.url, "__blank");
},
// 获取会话列表
getSessionList() {
this.GET("/im/session/kf/list").then(res => {
if (res.code === "000000") {
this.sessionListData = res.data || {
currentTimestamp: 0,
myTaskCount: 0,
sessionList: [],
waitingTaskCount: 0
};
let sLength = this.sessionListData.sessionList.length;
let cIndex = sLength - 1;
// if (!this.isFromAssignTask) {
// this.SET_IS_FROM_ASSIGN_TASK(false);
// cIndex = 0;
// }
// 第一次进入页面
if (sLength && !this.currentTaskLogId) {
// this.currentSession = this.sessionListData.sessionList[0];
// this.currentSessionIndex = 0;
this.currentSession = this.sessionListData.sessionList[cIndex];
this.currentSessionIndex = cIndex;
this.sendText = cacheMap[this.currentSession.id];
this.currentTaskLogId = this.currentSession.taskLogId;
this.currentToAccId = this.currentSession.toAccId;
this.getDoctorInfo(this.currentToAccId);
this.getMSGHistory(this.currentSession);
this.readAllMsg();
// 如果是点击“再来一个”或“给我一个任务吧”按钮分配的任务,则要滚动到最后
// if (this.isFromAssignTask) {
// this.$nextTick(() => {
// let element = this.getElmByID("sessionListId");
// if (element) {
// element.scrollTop = element.scrollHeight;
// }
// });
// }
}
if (sLength) {
this.convertSessions(this.sessionListData.sessionList);
this.$forceUpdate();
}
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 将会话列表的数据进行处理,主要是显示文本(text)字段
convertSessions(sessions) {
let convertSessionList = [];
let text = "",
cc;
sessions.forEach((session, index) => {
if (session.lastMsgType.toLowerCase() == "custom") {
cc = JSON.parse(session.lastMsgContent);
text = cc.suffix || cc.content || cc.title || cc.name;
} else if (
session.lastMsgType.toLowerCase() == "image" ||
session.lastMsgType.toLowerCase() == "picture"
) {
text = "[图片]";
} else {
text = session.lastMsgContent;
}
session.text = text;
convertSessionList.push(session);
});
this.sessionListData.sessionList = convertSessionList;
},
// 根据云信id获取医生信息
getDoctorInfo(accId) {
this.GET(`/im/account/accid/doctorinfo?accId=${accId}`).then(res => {
if (res.code === "000000") {
this.doctorInfo = res.data || {};
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 设置全部消息已读
readAllMsg() {
let fromAccount = this.currentToAccId,
toAccount = this.picakfAccId;
let params = {
fromAccount,
toAccount
};
this.POST(`/im/msg/read/all`, params).then(res => {
if (res.code === "000000") {
this.currentSession.unreadCount = 0;
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 根据字段名及其值,从数组中查找对象
findItemByKeyAndVal(arr, key, value, flag = 0) {
if (flag == 0) {
return arr.find(item => {
return item[key] == value;
});
} else if (flag == 1) {
return arr.findIndex(item => {
return item[key] == value;
});
}
},
// 获取积木列表
getFiveContentList() {
this.GET(
"/contents/admin/template/queryTemplate?publishFlag=5&pageNo=1&pageSize=99999"
).then(res => {
if (res.code === "000000") {
this.linkList = res.data.templateList || [];
} else {
this.$message({
message: res.message,
type: "error"
});
}
});
},
// 上传文件
beforeUploadFile(file) {
console.log("file", file);
let fileSize = file.size / (1024 * 1024);
if (fileSize > 5) {
this.$message({
message: "请上传小于5M的文件",
type: "warning"
});
return;
}
openLoading(_this);
doUpload(
_this,
file,
getFilePath(file, null),
"preview4",
"progress",
""
).then(function(resData) {
closeLoading(_this);
let params = {};
params.fileSize = resData.size;
params.fileExt = resData.ext;
params.url = resData.fullPath;
params.info = resData.name;
params.type = 2;
// 如果是图片,则要获取其宽与高
if (
params.fileExt.toLowerCase() === ".jpg" ||
params.fileExt.toLowerCase() === ".jpeg" ||
params.fileExt.toLowerCase() === ".png"
) {
params.type = 1;
let image = new Image();
image.src = params.url;
image.onload = function() {
let _img = this;
params.width = _img.width;
params.height = _img.height;
_this.sendCommonMsg(params);
};
} else {
_this.sendCommonMsg(params);
}
});
},
// 打开发送链接弹框
preSendLinkMsg() {
this.linkForm = {
remark: "",
info: "",
url: ""
};
this.showSelectDialog = true;
},
// 发送带链接消息
sendLinkMsg() {
this.$refs["linkFormRef"].validate(valid => {
if (valid) {
let params = Object.assign({}, this.linkForm);
params.url = getPhomeDemain() + `/template_v2/?id=${params.url}`;
params.type = 3;
this.sendCommonMsg(params);
this.showSelectDialog = false;
}
});
},
// 发送文本消息
sendTextMsg() {
if (!this.canSend) return;
this.sendCommonMsg({ info: this.sendText });
this.sendText = "";
},
// 发送通用消息
async sendCommonMsg(params) {
let sendMsgParams = {
fromAccount: this.picakfAccId,
toAccount: this.currentToAccId,
fileExt: "", // 文件扩展名称图片或PDF文件)
fileSize: 0, // 文件大小(图片或PDF文件)
height: 0, // 图片高度(仅图片)
width: 0, // 图片宽度(仅图片)
info: "", // 文本内容,图片的名称,pdf的名称,链接显示内容
md5: "", // 图片或文件MD5 暂时由后台生成
remark: "", // 其他信息(链接中的前缀文案)
type: 0, // 类型 0文本 1图片 2pdf 3链接
url: "" // url地址(图片、pdf,链接)
};
params = Object.assign(sendMsgParams, params);
// 将获取新数据的定时器关闭
forwardMsgIntervalId && clearInterval(forwardMsgIntervalId);
let sendId = new Date().getTime();
this.handleSendMsg(params, sendId);
// console.log("sendMsgParams", params);
await this.POST("/im/msg/sendMessage", params)
.then(res => {
if (res.code === "000000") {
// 校验结果:1校验通过 2校验不通过
// console.log(res.data.checkFlag);
let msg = this.messageList[this.messageList.length - 1];
if (msg.sendId !== sendId) {
msg = this.getMsgBySendId(sendId);
}
if (res.data.checkFlag == 1) {
this.realTimestamp = res.data.timetag;
msg.isShowLoadingIcon = false;
msg.isShowErrorIcon = false;
msg.isShowErrorMsg = false; // 只有在下次拉取新数据时才有可能是为ture
} else {
msg.signature = res.data.signature;
msg.isShowLoadingIcon = false;
msg.isShowErrorIcon = true;
msg.isShowErrorMsg = false; // 只有在下次拉取新数据时才有可能是为ture
}
} else {
this.$message({
message: res.message,
type: "error"
});
}
})
.catch(error => {
let msg = this.messageList[this.messageList.length - 1];
if (msg.sendId !== sendId) {
msg = this.getMsgBySendId(sendId);
}
msg.isShowLoadingIcon = false;
msg.isShowErrorIcon = true;
msg.isShowErrorMsg = false; // 只有在下次拉取新数据时才有可能是为ture
msg.canRepeatSend = true;
});
this.$forceUpdate();
// 重新开启定时器
forwardMsgIntervalId = setInterval(() => {
this.getMSGForward();
}, 3000);
},
// 根据sendId,查找到对应的消息
getMsgBySendId(sendId) {
console.log("------------getMsgBySendId------------");
let l = this.messageList.length,
i = l - 1;
for (; i > 0; i--) {
if (this.messageList[i].sendId == sendId) {
break;
}
}
return this.messageList[i];
},
// 文件大小单位转换
fileSizeChange(val) {
return betaHandle(val);
},
},
beforeDestroy() {
sessionIntervalId && clearInterval(sessionIntervalId);
forwardMsgIntervalId && clearInterval(forwardMsgIntervalId);
autoCompletionIntervalId && clearInterval(autoCompletionIntervalId);
}
};
</script>
<style lang="scss" scoped>
@import "./im.scss";
</style>
\ No newline at end of file
<template>
<div class="diagnosis-list-content">
<div class="component-content screenSet" id="screenSet">
<div class="title">咨询订单管理后台</div>
<el-form ref="form" :inline="true" :model="searchParam" label-suffix=":" label-width="120px" label-position="right" style="width:100%;">
<el-row :gutter="30" type="flex" style="margin-bottom:0;">
<el-col :span="21">
<el-form-item label="搜索">
<el-input
v-model="searchParam.content"
clearable
placeholder="支付订单、医生姓名、运营姓名搜索"
style="width:200px;"></el-input>
</el-form-item>
<el-form-item label="">
<el-select v-model="searchParam.orderStatu" clearable placeholder="订单状态" style="width:200px">
<el-option
v-for="(eItem,eIndex) in orderSelect"
:key="eIndex"
:label="eItem.name"
:value="eItem.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="">
<el-select v-model="searchParam.diagnosisStatu" clearable placeholder="问诊状态" style="width:200px">
<el-option
v-for="(eItem,eIndex) in diagnosisSelect"
:key="eIndex"
:label="eItem"
:value="eItem">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="">
<el-select v-model="searchParam.diagnosisType" clearable placeholder="问诊类型" style="width:200px">
<el-option
v-for="(eItem,eIndex) in diagnosisSelect"
:key="eIndex"
:label="eItem.value"
:value="eItem.no">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="3" style="padding:0;text-align:right;padding-right:15px;">
<el-button type="primary" size="small" @click="search(1)">搜索</el-button>
</el-col>
</el-row>
</el-form>
<!-- 表格 -->
<el-table
class="search-table"
:data="tableData"
style="width: 100%">
<el-table-column prop="name" label="订单ID" min-width="100" align="left"></el-table-column>
<el-table-column prop="stepStartName" label="运营人员" min-width="100" align="left"></el-table-column>
<el-table-column prop="stepEndName" label="专区名称" min-width="120" align="left"></el-table-column>
<el-table-column prop="name" label="问诊类型" min-width="80" align="left"></el-table-column>
<el-table-column prop="stepStartName" label="接诊医生" min-width="100" align="left"></el-table-column>
<el-table-column prop="stepEndName" label="接诊电话" min-width="100" align="left"></el-table-column>
<el-table-column prop="stepStartName" label="问诊患者" min-width="100" align="left"></el-table-column>
<el-table-column prop="stepEndName" label="问诊电话" min-width="100" align="left"></el-table-column>
<el-table-column prop="stepStartName" label="价格" min-width="80" align="left"></el-table-column>
<el-table-column prop="stepEndName" label="订单状态" min-width="80" align="left"></el-table-column>
<el-table-column prop="stepStartName" label="预约时间" min-width="120" align="left"></el-table-column>
<el-table-column prop="stepEndName" label="问诊状态" min-width="80" align="left"></el-table-column>
<el-table-column label="操作" fixed="right" align="center" min-width="350">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="timeHandle(scope.row)">预约时间</el-button>
<el-button type="primary" size="small" @click="endChat(scope.row)">结束</el-button>
<el-button type="primary" size="small" @click="callAll(scope.row)">呼叫双方</el-button>
<el-button type="primary" size="small" @click="sendMessage(scope.row)">发送消息</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="searchParam.pageNo"
:page-sizes="[15, 30, 50, 100, 200, 500, 700, 1000, 1500, 2000]"
:page-size="searchParam.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalRows">
</el-pagination>
</div>
<!-- 预约时间 -->
<el-dialog
title="预约时间"
:visible.sync="timeVisible"
width="40%">
<el-row :gutter="30" class="row search" type="flex" style="margin-bottom:0;">
<el-form ref="tagForm"
:rules="timeRules"
:model="timeForm"
label-width="150px"
label-suffix=":"
label-position="right"
size="mini"
style="width: 100%;">
<el-col :span="24">
<el-form-item label="年月日" prop="yearTime">
<el-date-picker
v-model="timeForm.time"
type="datetime"
placeholder="请选择年月日">
</el-date-picker>
</el-form-item>
<el-form-item label="音视频时长">
<el-select v-model="timeForm.timeLength" clearable placeholder="音视频时长" style="width:200px">
<el-option
v-for="(eItem,eIndex) in timeSelect"
:key="eIndex"
:label="eItem"
:value="eItem">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-form>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="timeVisible = false">取 消</el-button>
<el-button type="primary" @click="confirmTime">确 定</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
export default {
data(){
return {
timeVisible: false,
searchParam: {
content: '',
orderStatu: '',
diagnosisStatu: '',
diagnosisType: '',
pageSize: 15,
pageNo: 1
},
timeForm:{
time: '',
timeLength: ''
},
timeSelect: [],
orderSelect: [],
diagnosisSelect: [],
tableData: [{}],
totalRows: 0,
timeRules: {
}
}
},
mounted() {
},
methods: {
search() {
},
// 预约时间
timeHandle() {
this.timeVisible = true;
},
confirmTime() {
},
// 结束聊天
endChat() {
},
// 结束
callAll() {
},
// 发送消息
sendMessage() {
this.$router.push('/diagnosis-im')
},
handleSizeChange(value) {
this.searchParam.pageSize = value;
this.search();
},
handleCurrentChange(value) {
this.searchParam.pageNo = value;
this.search();
}
}
}
</script>
<style lang="scss" scoped>
.diagnosis-list-content {
.component-content {
padding: 10px;
background: #fff;
.title {
margin-bottom: 30px;
}
}
}
</style>
\ No newline at end of file
.current-session-wrap {
.component-content {
display: flex;
flex-direction: row;
// min-width: 1200px;
background: none !important;
font-size: 14px;
.left {
display: none;
width: 270px;
// padding: 0 25px 15px;
border-right: 2px solid #f5f5f5;
.l-header {
display: flex;
flex-direction: row;
height: 52px;
justify-content: space-between;
align-items: center;
padding: 0 12px 0 25px;
p {
display: flex;
flex-direction: row;
align-items: center;
color: #0d9078;
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 4px;
}
span {
font-size: 14px;
color: #0d9078;
}
}
// & > span:first-child {
// font-size: 14px;
// }
// & > span:last-child {
// color: #0d9078;
// cursor: pointer;
// }
}
.c-num {
padding: 0 25px;
height: 40px;
line-height: 40px;
font-size: 12px;
background: #fffbe6;
}
.session-list {
width: 100%;
height: 100%;
overflow: scroll;
& > .item {
width: 100%;
display: flex;
height: 72px;
flex-direction: row;
align-items: center;
padding: 0 12px 0 25px;
cursor: pointer;
.img-wrapper {
// position: relative;
// top: 0;
// left: 0;
width: 24px;
height: 24px;
margin-right: 10px;
img {
width: 100%;
height: 100%;
border-radius: 20px;
}
}
& > .desc {
flex: 1;
.top {
display: flex;
flex-direction: row;
justify-content: space-between;
.name {
}
}
.bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: #999999;
.num {
display: inline-block;
min-width: 16px;
padding: 2px 4px;
border-radius: 8px;
text-align: center;
color: #ffffff;
background: #ff4d4f;
}
& > img {
display: block;
width: 15px;
height: 15px;
padding: 2px 0 2px 4px;
}
}
}
&.current {
background: #f8f9fa;
}
}
}
}
.center {
margin-left: 240px;
margin-right: 240px;
flex: 1;
background: #fff;
.c-header {
padding: 0 25px;
height: 56px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid #f5f5f5;
& > .c-header-l {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
& > img {
display: inline-block;
width: 24px;
height: 24px;
border-radius: 12px;
margin-right: 8px;
}
& > .name {
margin-right: 25px;
color: #333333;
}
& > .time-tip {
font-size: 12px;
color: #999999;
}
}
.close-btn {
width: 100px;
color: #c7c8c9;
cursor: pointer;
}
}
.msg-content {
// width: 100%;
// height: 650px;
word-break: break-all;
overflow: scroll;
display: flex;
flex-direction: column;
margin: 10px 20px;
.msg-item {
display: flex;
flex-direction: row;
margin: 12px 0;
.msg-item-img {
width: 36px;
height: 36px;
margin-right: 12px;
& > img {
width: 100%;
height: 100%;
border-radius: 22px;
}
}
.msg-item-detail {
display: flex;
flex-direction: column;
text-align: left;
font-size: 13px;
& > :first-child {
color: #999999;
margin-bottom: 8px;
}
.send-warpper {
display: flex;
flex-direction: row;
align-items: center;
& > .icon {
width: 20px;
height: 20px;
margin-right: 10px;
}
.mid-text-wrapper {
display: flex;
flex-direction: row;
align-items: center;
& > img {
width: 18px;
height: 18px;
margin-right: 8px;
cursor: pointer;
}
}
.mid-text {
padding: 12px 16px;
display: inline-block;
max-width: 520px;
border-radius: 8px;
background: #ebf5fc;
text-align: justify;
color: #333333;
&.no-support {
display: flex;
align-items: center;
& > img {
width: 14px;
height: 14px;
margin-right: 3px;
}
}
}
.link {
color: #2f86f6;
}
& > .mid-pdf {
width: 260px;
display: flex;
flex-direction: row;
justify-content: space-between;
text-align: left;
padding: 10px 15px;
background: #f0f1f2;
border-radius: 8px;
min-height: 80px;
cursor: pointer;
.midp-left {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-right: 10px;
.name {
font-size: 13px;
color: #333333;
word-break: break-word;
}
.size {
font-size: 12px;
color: #999999;
}
}
.midp-icon {
width: 36px;
height: 44px;
& > img {
width: 36px;
height: 100%;
border-radius: 3px;
}
}
}
& > .mid-img {
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
// & > .icon {
// width: 20px;
// height: 20px;
// }
// & > .img {
// width: 170px;
// height: 108px;
// border-radius: 8px;
// }
.img-box {
max-width: 192px;
max-height: 320px;
overflow: hidden;
}
}
}
}
&.cr {
flex-direction: row-reverse;
.msg-item-img {
margin-right: 0;
margin-left: 8px;
}
.msg-item-detail {
text-align: right;
& > .mid-text {
background: #f0f1f2;
}
}
}
}
.split-line {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
margin: 15px 0;
font-size: 14px;
color: #999999;
&::before {
flex: 1;
content: '';
height: 1px;
margin-right: 18px;
background: #f0f1f2;
}
&::after {
flex: 1;
content: '';
height: 1px;
margin-left: 18px;
background: #f0f1f2;
}
}
.error-mg {
display: inline-block;
max-width: 520px;
// height: 24px;
max-width: 520px;
line-height: 16px;
text-align: left;
border-radius: 20px;
opacity: 0.45;
margin: -2px 0 10px;
padding: 4px 12px;
color: #FFFFFF;
background: #000000;
margin-left: 50px;
&.mr {
margin-left: 0;
margin-right: 50px;
}
}
}
.c-bottom {
position: relative;
top: -8px;
left: 0;
display: flex;
flex-direction: row;
margin: 16px 12px 16px 25px;
.cb-icon-wrapper {
position: absolute;
top: 0;
right: 70px;
display: flex;
align-items: center;
height: 44px;
img {
width: 20px;
height: 20px;
margin-right: 16px;
cursor: pointer;
}
}
.send-btn {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 60px;
height: 44px;
background: #f3f6f7;
margin-left: 12px;
border-radius: 8px;
cursor: pointer;
& > img {
width: 24px;
height: 24px;
}
&.active {
background: #0d9078;
}
}
}
&.no-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
img {
display: block;
width: 120px;
height: 100px;
}
p {
margin-top: 10px;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
}
}
.right {
display: none;
width: 240px;
border-left: 2px solid #f5f5f5;
overflow: scroll;
}
background: #fff;
.time {
color: #999999;
}
.small {
font-size: 12px;
}
.ld{
-webkit-transition-property: -webkit-transform;
-webkit-transition-duration: 1s;
-moz-transition-property: -moz-transform;
-moz-transition-duration: 1s;
-webkit-animation: rotate 3s linear infinite;
-moz-animation: rotate 3s linear infinite;
-o-animation: rotate 3s linear infinite;
animation: rotate 3s linear infinite;
}
@-webkit-keyframes rotate{from{-webkit-transform: rotate(0deg)}
to{-webkit-transform: rotate(360deg)}
}
@-moz-keyframes rotate{from{-moz-transform: rotate(0deg)}
to{-moz-transform: rotate(359deg)}
}
@-o-keyframes rotate{from{-o-transform: rotate(0deg)}
to{-o-transform: rotate(359deg)}
}
@keyframes rotate{from{transform: rotate(0deg)}
to{transform: rotate(359deg)}
}
}
}
\ No newline at end of file
......@@ -101,7 +101,7 @@ export default {
this.GET('/im/session/kf/fetchOneTask').then((res) => {
if( res.code === '000000') {
this.SET_IS_FROM_ASSIGN_TASK(true);
this.$router.push({ path: `/current-session-list` });
this.$router.push({ path: `/diagnosis-list` });
} else {
this.$message({
message: res.message,
......
......@@ -66,35 +66,16 @@ export default {
getNav() {
this.POST("/basic-data/menu/list", { systemType: this.systemType }).then(res => {
if (res.code == "000000") {
let { vueMenuDtos } = res.data;
//let { vueMenuDtos } = res.data;
let vueMenuDtos = [];
// TODO 开发调试时写死, 发布时去掉
// vueMenuDtos = [{
// icon: 'el-icon-setting',
// index: "waiting-session-list",
// subs: [],
// title: "等待会话"
// },{
// icon: 'el-icon-setting',
// index: "current-session-list",
// subs: [],
// title: "当前会话"
// },{
// icon: 'el-icon-setting',
// index: "search-message-list",
// subs: [],
// title: "消息查询"
// },{
// icon: 'el-icon-setting',
// index: "chain-message",
// subs: [],
// title: "我要群发"
// },{
// icon: 'el-icon-setting',
// index: "chain-history-list",
// subs: [],
// title: "历史群发"
// }];
vueMenuDtos = [{
icon: 'el-icon-setting',
index: "diagnosis-list",
subs: [],
title: "订单管理"
}];
this.items = vueMenuDtos;
sessionStorage.setItem(
"ADMIN_IM_CENTER_NAVS",
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册