You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
486 lines
13 KiB
486 lines
13 KiB
import dayjs from "dayjs"; |
|
|
|
const app = getApp<IAppOption>(); |
|
|
|
interface IMessageItem { |
|
msgId: string; |
|
contentType: "1" | "2" | "3" | "4" | "5"; // 1:文本 2: 语音 3. 图片 4. 视频 5. 提示信息 |
|
content: any; |
|
fromDoctorId: string; |
|
doctorImg: string; |
|
createTime: string; |
|
createTimeName?: string; |
|
isSelf: 1 | 2; |
|
isRead: 1 | 2; |
|
doctorName: string; |
|
hospitalName: string; |
|
showTime?: boolean; |
|
isPlay?: boolean; |
|
uniqueCode?: string; |
|
} |
|
|
|
Page({ |
|
data: { |
|
id: "", |
|
|
|
show1: false, |
|
|
|
focus: false, |
|
fold: true, |
|
scrollTop: 0, |
|
scrollIntoView: "", |
|
doctorDetail: {} as any, |
|
|
|
roomDoctors: [], |
|
newRoomDoctors: [], |
|
case: {} as any, |
|
chatGroupInfo: {} as any, |
|
chatDoctor: {} as any, |
|
|
|
isLoad: false, |
|
isFinish: false, |
|
messageList: [] as IMessageItem[], |
|
lastMsgId: "", |
|
unReadCount: 0, |
|
|
|
userInfo: {} as any, |
|
|
|
sendMessage: "", |
|
videoUrl: "", |
|
|
|
protocol: `<p><span style="color: rgb(38, 38, 38); font-size: 14px;">罕心守护平台向用户提供了“学习窗”功能,基于此服务,我们在此特别声明:</span></p><p><span style="color: rgb(38, 38, 38); font-size: 14px;">罕心守护平台非常重视您的个人信息保护及平台信息的隐私性,您同意在学习窗功能使用时遵守以下规则:</span></p><p><span style="color: rgb(38, 38, 38); font-size: 14px;"> </span></p><p><span style="color: rgb(38, 38, 38); font-size: 14px;">1.严禁在学习窗内讨论或分享任何患者的个人身份信息,包括但不限于姓名、性别等。群内发送的任何素材内容,必须去除所有可能识别患者身份的敏感信息;</span></p><p><span style="color: rgb(38, 38, 38); font-size: 14px;">2.不以截图、录音或以任何形式将内容传播;</span></p><p><span style="color: rgb(38, 38, 38); font-size: 14px;">3.讨论内容仅限于专业交流,不得用于任何商业目的; </span></p><p><span style="color: rgb(38, 38, 38); font-size: 14px;">4.保持讨论的专业性和尊重性,避免使用侮辱性或攻击性语言。</span></p><p><br></p>`, |
|
}, |
|
innerAudioContext: null as WechatMiniprogram.InnerAudioContext | null, |
|
videoContext: null as WechatMiniprogram.VideoContext | null, |
|
onLoad(options) { |
|
this.setData({ |
|
id: options.id, |
|
}); |
|
this.videoContext = wx.createVideoContext("video"); |
|
this.innerAudioContext = wx.createInnerAudioContext({ |
|
useWebAudioImplement: true, |
|
}); |
|
app.waitLogin().then(() => { |
|
this.getAgree(); |
|
|
|
app.getUserInfo(this); |
|
}); |
|
}, |
|
onUnload() { |
|
wx.WebIM.conn.close(); |
|
if (this.innerAudioContext) { |
|
this.innerAudioContext.stop(); |
|
} |
|
if (this.videoContext) { |
|
this.videoContext.stop(); |
|
} |
|
}, |
|
init() { |
|
this.getMessageList(); |
|
this.getDetail(); |
|
}, |
|
getAgree() { |
|
wx.ajax({ |
|
method: "GET", |
|
url: "?r=takeda/account/chat-room-notice", |
|
data: { |
|
roomId: this.data.id, |
|
}, |
|
}).then((res) => { |
|
this.setData({ |
|
show1: res.show === 1, |
|
}); |
|
if (res.show !== 1) { |
|
this.init(); |
|
} |
|
}); |
|
}, |
|
onAgreeClose() { |
|
wx.navigateBack(); |
|
}, |
|
handleSubmitAgree() { |
|
wx.ajax({ |
|
method: "POST", |
|
url: "?r=takeda/account/close-chat-room-notice", |
|
data: {}, |
|
}).then(() => { |
|
this.setData({ |
|
show1: false, |
|
}); |
|
this.init(); |
|
}); |
|
}, |
|
getDetail() { |
|
wx.ajax({ |
|
method: "GET", |
|
url: "?r=takeda/chat/get-room-detail", |
|
data: { roomId: this.data.id }, |
|
}).then((res) => { |
|
this.setData({ |
|
roomDoctors: res.roomDoctors, |
|
newRoomDoctors: { ...res }.roomDoctors.slice(0, 4), |
|
case: res.case, |
|
chatGroupInfo: res.chatGroupInfo, |
|
chatDoctor: res.chatDoctor, |
|
}); |
|
wx.setNavigationBarTitle({ |
|
title: `学习窗(${res.roomDoctorCount})`, |
|
}); |
|
|
|
this.WebIMLogin(); |
|
}); |
|
}, |
|
handleRoomDetail() { |
|
wx.navigateTo({ |
|
url: `/module1/pages/chatRoomInfo/index?id=${this.data.id}&cid=${this.data.case.caseId}`, |
|
}); |
|
}, |
|
handleCaseDetail() { |
|
wx.navigateTo({ |
|
url: `/module1/pages/casesDetail/index?id=${this.data.case.caseId}`, |
|
}); |
|
}, |
|
|
|
handleView(index = -1) { |
|
const time = setTimeout(() => { |
|
this.setData({ |
|
scrollIntoView: index > -1 ? `view${index}` : `place`, |
|
}); |
|
clearTimeout(time); |
|
}, 300); |
|
}, |
|
getMessageList() { |
|
if (this.data.isLoad || this.data.isFinish) return; |
|
this.setData({ |
|
isLoad: true, |
|
}); |
|
const lastMsgId = this.data.lastMsgId; |
|
wx.ajax({ |
|
method: "GET", |
|
url: "?r=takeda/chat/get-message-list", |
|
data: { |
|
lastMsgId, |
|
roomId: this.data.id, |
|
}, |
|
}).then((res) => { |
|
if (res.length === 0) { |
|
this.setData({ |
|
isFinite: true, |
|
}); |
|
return; |
|
} |
|
res.map((item) => { |
|
return this.formatMessage(item); |
|
}); |
|
this.setData({ |
|
messageList: [...res.reverse(), ...this.data.messageList], |
|
lastMsgId: res[0].msgId, |
|
isLoad: false, |
|
}); |
|
this.filterCreateTime(); |
|
|
|
if (!lastMsgId) { |
|
this.handleView(); |
|
} |
|
}); |
|
}, |
|
scrolltoupper(e) { |
|
if (e.detail.direction === "top") { |
|
this.getMessageList(); |
|
} |
|
}, |
|
handleSendMessage() { |
|
const { sendMessage, userInfo } = this.data; |
|
if (!sendMessage) { |
|
wx.showToast({ |
|
icon: "none", |
|
title: "请输入内容", |
|
}); |
|
return; |
|
} |
|
const message: IMessageItem = { |
|
msgId: "", |
|
contentType: "1", |
|
content: sendMessage, |
|
fromDoctorId: userInfo.DoctorId, |
|
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
|
isSelf: 1, |
|
isRead: 2, |
|
doctorImg: userInfo.Img, |
|
doctorName: userInfo.Name, |
|
hospitalName: userInfo.HospitalName, |
|
}; |
|
this.setData({ |
|
sendMessage: "", |
|
}); |
|
this.WebIMSendMessage(message); |
|
}, |
|
handleSendAudio(e) { |
|
const { userInfo } = this.data; |
|
const contentStr = JSON.stringify({ |
|
url: e.detail.fileUrl, |
|
duration: e.detail.duration, |
|
}); |
|
const message: IMessageItem = { |
|
msgId: "", |
|
contentType: "2", |
|
content: contentStr, |
|
fromDoctorId: userInfo.DoctorId, |
|
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
|
isSelf: 1, |
|
isRead: 2, |
|
doctorImg: userInfo.Img, |
|
doctorName: userInfo.Name, |
|
hospitalName: userInfo.HospitalName, |
|
}; |
|
this.WebIMSendMessage(message); |
|
}, |
|
handleSendPhoto(e) { |
|
const { userInfo } = this.data; |
|
const contentStr = JSON.stringify({ |
|
url: e.detail.fileUrl, |
|
}); |
|
const message: IMessageItem = { |
|
msgId: "", |
|
contentType: "3", |
|
content: contentStr, |
|
fromDoctorId: userInfo.DoctorId, |
|
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
|
isSelf: 1, |
|
isRead: 2, |
|
doctorImg: userInfo.Img, |
|
doctorName: userInfo.Name, |
|
hospitalName: userInfo.HospitalName, |
|
}; |
|
this.WebIMSendMessage(message); |
|
}, |
|
handleSendVideo(e) { |
|
const { userInfo } = this.data; |
|
const contentStr = JSON.stringify({ |
|
url: e.detail.fileUrl, |
|
imgUrl: e.detail.imgUrl, |
|
}); |
|
const message: IMessageItem = { |
|
msgId: "", |
|
contentType: "4", |
|
content: contentStr, |
|
fromDoctorId: userInfo.DoctorId, |
|
createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
|
isSelf: 1, |
|
isRead: 2, |
|
doctorImg: userInfo.Img, |
|
doctorName: userInfo.Name, |
|
hospitalName: userInfo.HospitalName, |
|
}; |
|
this.WebIMSendMessage(message); |
|
}, |
|
sendMessage({ uniqueCode, ...message }) { |
|
wx.ajax({ |
|
method: "POST", |
|
url: "?r=takeda/chat/send-message", |
|
data: { |
|
roomId: this.data.id, |
|
message: { |
|
contentType: message.contentType, |
|
content: message.content, |
|
uniqueCode, |
|
}, |
|
}, |
|
}); |
|
}, |
|
WebIMLogin() { |
|
const { chatDoctor } = this.data; |
|
wx.WebIM.conn |
|
.open({ |
|
user: chatDoctor.chatUserId, |
|
pwd: chatDoctor.chatUserPwd, |
|
}) |
|
.then(() => { |
|
this.listenMessage(); |
|
}); |
|
}, |
|
WebIMSendMessage(message: IMessageItem) { |
|
const { chatGroupInfo } = this.data; |
|
const option = { |
|
type: "txt", |
|
msg: message.content, |
|
to: chatGroupInfo.ChatGroupId, |
|
chatType: "groupChat", |
|
deliverOnlineOnly: "true", |
|
ext: { |
|
...message, |
|
}, |
|
}; |
|
const msg = wx.WebIM.message.create(option); |
|
wx.WebIM.conn |
|
.send(msg) |
|
.then((res) => { |
|
this.sendMessage({ ...message, uniqueCode: res.serverMsgId }); |
|
this.setData({ |
|
messageList: [...this.data.messageList, this.formatMessage(message)], |
|
}); |
|
this.handleView(); |
|
}) |
|
.catch(() => { |
|
wx.showToast({ |
|
icon: "none", |
|
title: "发送失败", |
|
}); |
|
}); |
|
}, |
|
listenMessage() { |
|
const { chatGroupInfo } = this.data; |
|
wx.WebIM.conn.addEventHandler("room", { |
|
onTextMessage: (message) => { |
|
if (message.error) { |
|
return; |
|
} |
|
if (message.to === chatGroupInfo.ChatGroupId) { |
|
this.setData({ |
|
messageList: [ |
|
...this.data.messageList, |
|
this.formatMessage({ |
|
...message.ext, |
|
isSelf: 2, |
|
}), |
|
], |
|
}); |
|
this.handleReadAll(); |
|
this.handleView(); |
|
} |
|
}, |
|
}); |
|
}, |
|
formatMessage(message: IMessageItem) { |
|
//消息内容类型,1-文本,2-语音,3-图片,4-视频,5-提示信息 |
|
if (["2", "3", "4"].includes(message.contentType)) { |
|
message.content = JSON.parse(message.content); |
|
} |
|
return message; |
|
}, |
|
formatTime(date: string) { |
|
let createTimeName = ""; |
|
if (dayjs().format("YYYY-MM-DD") === dayjs(date).format("YYYY-MM-DD")) { |
|
createTimeName = dayjs(date).format("HH:mm"); |
|
} else if (dayjs().format("YYYY-MM-DD") === dayjs(date).add(1, "day").format("YYYY-MM-DD")) { |
|
createTimeName = `昨天 ${dayjs(date).format("HH:mm")}`; |
|
} else if (dayjs().diff(date, "day") < 7) { |
|
createTimeName = dayjs(date).format(`dddd HH:mm`); |
|
} else { |
|
createTimeName = dayjs(date).format("YYYY-MM-DD HH:mm"); |
|
} |
|
return createTimeName; |
|
}, |
|
filterCreateTime() { |
|
const gapTime = 5 * 60 * 1000; |
|
const { messageList } = this.data; |
|
|
|
let preTime = 0; |
|
messageList.forEach((item, index) => { |
|
if (index === 0) { |
|
item.showTime = true; |
|
preTime = dayjs(item.createTime).valueOf(); |
|
item.createTimeName = this.formatTime(item.createTime); |
|
} else { |
|
const curTime = dayjs(item.createTime).valueOf(); |
|
if (curTime - preTime > gapTime) { |
|
item.showTime = true; |
|
item.createTimeName = this.formatTime(item.createTime); |
|
preTime = dayjs(item.createTime).valueOf(); |
|
} |
|
} |
|
}); |
|
this.setData({ |
|
messageList, |
|
}); |
|
}, |
|
handleFooter() { |
|
this.setData({ |
|
fold: !this.data.fold, |
|
}); |
|
if (!this.data.fold) { |
|
this.handleView(); |
|
} |
|
}, |
|
handleAudio(e) { |
|
const { index } = e.currentTarget.dataset; |
|
const { messageList } = this.data; |
|
const messageItem = messageList[index]; |
|
const { url } = messageItem.content; |
|
if (this.innerAudioContext) { |
|
if (messageItem.isPlay) { |
|
this.innerAudioContext.stop(); |
|
messageItem.isPlay = false; |
|
this.setData({ |
|
messageList, |
|
}); |
|
return; |
|
} |
|
this.innerAudioContext.stop(); |
|
this.innerAudioContext.src = url; |
|
this.innerAudioContext.play(); |
|
messageItem.isPlay = true; |
|
if (messageItem.isRead === 2 && messageItem.isSelf === 2) { |
|
messageItem.isRead = 1; |
|
this.handleReadAudio({ |
|
msgId: messageItem.msgId, |
|
uniqueCode: messageItem.uniqueCode, |
|
}); |
|
} |
|
this.innerAudioContext.onEnded(() => { |
|
messageItem.isPlay = false; |
|
this.setData({ |
|
messageList, |
|
}); |
|
}); |
|
this.setData({ |
|
messageList, |
|
}); |
|
} |
|
}, |
|
handleReadAudio({ msgId, uniqueCode }) { |
|
wx.ajax({ |
|
method: "POST", |
|
url: "?r=takeda/chat/read-message", |
|
data: { |
|
roomId: this.data.id, |
|
msgId, |
|
uniqueCode, |
|
}, |
|
}); |
|
}, |
|
handlePreview(e) { |
|
const { url } = e.currentTarget.dataset; |
|
wx.previewImage({ |
|
urls: [url], |
|
}); |
|
}, |
|
handleVideo(e) { |
|
const { url } = e.currentTarget.dataset; |
|
if (this.videoContext) { |
|
this.setData({ |
|
videoUrl: url, |
|
}); |
|
this.videoContext.play(); |
|
this.videoContext.requestFullScreen({}); |
|
} |
|
}, |
|
|
|
handleReadAll() { |
|
wx.ajax({ |
|
method: "POST", |
|
url: "?r=takeda/chat/read-all-message", |
|
data: { roomId: this.data.id }, |
|
}); |
|
}, |
|
handleFocus() { |
|
this.setData({ |
|
focus: true, |
|
}); |
|
}, |
|
handleBlur() { |
|
this.setData({ |
|
focus: false, |
|
}); |
|
}, |
|
});
|
|
|