Browse Source

聊天室部分

main
kola-web 4 months ago
parent
commit
12cff902a9
  1. 14
      project.private.config.json
  2. 3
      src/app.json
  3. 3
      src/app.ts
  4. 3
      src/module1/pages/chatRoom/index.json
  5. 57
      src/module1/pages/chatRoom/index.scss
  6. 456
      src/module1/pages/chatRoom/index.ts
  7. 72
      src/module1/pages/chatRoom/index.wxml
  8. 31
      src/module1/pages/chatRoomInfo/index.ts
  9. 14
      src/module1/pages/chatRoomInfo/index.wxml
  10. 3
      src/module1/pages/setCaseDoctor/index.json
  11. 22
      src/module1/pages/setCaseDoctor/index.ts
  12. 5
      src/module1/pages/setCaseDoctor/index.wxml
  13. 1
      src/pages/cases/index.scss
  14. 2
      src/pages/cases/index.ts
  15. 5
      src/pages/chatRoomList/index.json
  16. 270
      src/pages/chatRoomList/index.scss
  17. 408
      src/pages/chatRoomList/index.ts
  18. 291
      src/pages/chatRoomList/index.wxml
  19. 2
      typings/index.d.ts

14
project.private.config.json

@ -9,6 +9,13 @@
"miniprogram": { "miniprogram": {
"list": [ "list": [
{ {
"name": "聊天室",
"pathName": "module1/pages/chatRoom/index",
"query": "id=2",
"launchMode": "default",
"scene": null
},
{
"name": "病历详情", "name": "病历详情",
"pathName": "module1/pages/casesDetail/index", "pathName": "module1/pages/casesDetail/index",
"query": "id=25", "query": "id=25",
@ -51,13 +58,6 @@
"scene": null "scene": null
}, },
{ {
"name": "聊天室",
"pathName": "module1/pages/chatRoom/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "聊天室信息", "name": "聊天室信息",
"pathName": "module1/pages/chatRoomInfo/index", "pathName": "module1/pages/chatRoomInfo/index",
"query": "", "query": "",

3
src/app.json

@ -31,7 +31,8 @@
"pages/casesDetail/index", "pages/casesDetail/index",
"pages/casesFeedback/index", "pages/casesFeedback/index",
"pages/chatRoom/index", "pages/chatRoom/index",
"pages/chatRoomInfo/index" "pages/chatRoomInfo/index",
"pages/setChatDoctor/index"
] ]
} }
], ],

3
src/app.ts

@ -1,10 +1,11 @@
/* eslint-disable perfectionist/sort-imports */
import component from "@/utils/component"; import component from "@/utils/component";
import relativeTime from "@/utils/dayjs/relativeTime.js"; import relativeTime from "@/utils/dayjs/relativeTime.js";
import page from "@/utils/page"; import page from "@/utils/page";
import { request } from "@/utils/request"; import { request } from "@/utils/request";
import { parseScene } from "./utils/util"; import { parseScene } from "./utils/util";
wx.WebIM = require("@/utils/webIM/WebIM.js").default;
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const licia = require("miniprogram-licia"); const licia = require("miniprogram-licia");

3
src/module1/pages/chatRoom/index.json

@ -2,6 +2,7 @@
"navigationBarTitleText": "聊天室", "navigationBarTitleText": "聊天室",
"navigationStyle": "default", "navigationStyle": "default",
"usingComponents": { "usingComponents": {
"van-icon": "@vant/weapp/icon/index" "van-icon": "@vant/weapp/icon/index",
"van-popup": "@vant/weapp/popup/index"
} }
} }

57
src/module1/pages/chatRoom/index.scss

@ -67,8 +67,7 @@ page {
} }
} }
.c-footer { .c-footer {
margin-top: 16rpx; margin-top: 6rpx;
line-height: 28rpx;
.name { .name {
display: inline-block; display: inline-block;
font-size: 28rpx; font-size: 28rpx;
@ -334,3 +333,57 @@ page {
width: 0; width: 0;
height: 0; height: 0;
} }
.popup1 {
padding: 48rpx 32rpx;
width: 580rpx;
background: linear-gradient(180deg, #e5f5f7 0%, #ffffff 17%);
border-radius: 16rpx 16rpx 16rpx 16rpx;
border: 2rpx solid #ffffff;
.title {
font-size: 36rpx;
color: rgba(20, 21, 21, 1);
line-height: 48rpx;
font-weight: bold;
text-align: center;
}
.scroll {
margin-top: 24rpx;
max-height: 680rpx;
overflow-y: auto;
overflow-x: hidden;
.s-title {
margin-top: 24rpx;
font-size: 28rpx;
color: rgba(20, 21, 21, 1);
line-height: 56rpx;
font-weight: bold;
}
.s-content {
font-size: 28rpx;
color: rgba(133, 133, 133, 1);
line-height: 48rpx;
}
}
.tip {
margin-top: 24rpx;
padding: 16rpx;
border-radius: 10rpx;
text-align: center;
font-size: 24rpx;
color: rgba(255, 125, 0, 1);
line-height: 40rpx;
background-color: rgba(255, 247, 232, 1);
}
.btn {
margin-top: 24rpx;
height: 72rpx;
font-size: 32rpx;
color: rgba(255, 255, 255, 1);
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(90deg, #00b4c5 0%, #54e2b4 100%);
border-radius: 60rpx 60rpx 60rpx 60rpx;
}
}

456
src/module1/pages/chatRoom/index.ts

@ -1,208 +1,270 @@
import dayjs from 'dayjs' import dayjs from "dayjs";
const _app = getApp<IAppOption>() const app = getApp<IAppOption>();
interface IMessageItem { interface IMessageItem {
msgId: string msgId: string;
msgContentType: '1' | '2' | '3' | '4' // 1:文本 4: 语音 contentType: "1" | "2" | "3" | "4" | "5"; // 1:文本 2: 语音 3. 图片 4. 视频 5. 提示信息
msgContent: any content: any;
msgVisitTime: string fromDoctorId: string;
msgFromType: '1' | '2' // 1: 患者 2: 医生 doctorImg: string;
isPlay?: boolean msgVisitTime: string;
welcomeMsg?: { createTime: "";
hotQuestion: Item[] isSelf: 1 | 2;
} isRead: 1 | 2;
msgCreateTime: string // 消息创建时间
msgCreateTimeName?: string // 消息创建时间
showTime?: boolean
} }
interface Item { interface Item {
questionId: string questionId: string;
question: string question: string;
} }
Page({ Page({
data: { data: {
id: "",
show1: false,
fold: true, fold: true,
scrollTop: 0, scrollTop: 0,
scrollIntoView: '', scrollIntoView: "",
doctorDetail: {} as any, doctorDetail: {} as any,
questionActive: 0, questionActive: 0,
questionList: [] as any, questionList: [] as any,
questionActiveList: [] as Item[], questionActiveList: [] as Item[],
roomDoctors: [],
newRoomDoctors: [],
case: {} as any,
chatGroupInfo: {},
chatDoctor: {},
isLoad: false, isLoad: false,
isFinish: false, isFinish: false,
messageList: [ messageList: [
{ {
msgId: '686', msgId: "686",
msgContentType: '2', contentType: "2",
msgContent: '重症肌无力患者复查的频率取决于多种因素', msgContent: "重症肌无力患者复查的频率取决于多种因素",
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '2', msgFromType: "2",
msgCreateTime: '2024-10-10 09:37:40', msgCreateTime: "2024-10-10 09:37:40",
}, },
{ {
msgId: '686', msgId: "686",
msgContentType: '3', contentType: "3",
msgContent: '重症肌无力患者复查的频率取决于多种因素', msgContent: "重症肌无力患者复查的频率取决于多种因素",
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '2', msgFromType: "2",
msgCreateTime: '2024-10-10 09:37:40', msgCreateTime: "2024-10-10 09:37:40",
}, },
{ {
msgId: '686', msgId: "686",
msgContentType: '2', contentType: "2",
msgContent: '重症肌无力患者复查的频率取决于多种因素', msgContent: "重症肌无力患者复查的频率取决于多种因素",
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: '2024-10-10 09:37:40', msgCreateTime: "2024-10-10 09:37:40",
}, },
{ {
msgId: '686', msgId: "686",
msgContentType: '3', contentType: "3",
msgContent: '重症肌无力患者复查的频率取决于多种因素', msgContent: "重症肌无力患者复查的频率取决于多种因素",
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: '2024-10-10 09:37:40', msgCreateTime: "2024-10-10 09:37:40",
}, },
{ {
msgId: '681', msgId: "681",
msgContentType: '1', contentType: "1",
msgContent: '重症肌无力是否有遗传性?', msgContent: "重症肌无力是否有遗传性?",
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: '2024-10-10 09:37:17', msgCreateTime: "2024-10-10 09:37:17",
}, },
{ {
msgId: '681', msgId: "681",
msgContentType: '1', contentType: "1",
msgContent: '重症肌无力是否有遗传性?', msgContent: "重症肌无力是否有遗传性?",
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: '2024-10-10 09:37:17', msgCreateTime: "2024-10-10 09:37:17",
}, },
{ {
msgId: '483', msgId: "483",
msgContentType: '4', contentType: "4",
msgContent: msgContent:
'[{"duration":8,"url":"https://circlehbsaas.oss-cn-beijing.aliyuncs.com/audio/20240907757_tmp_acf4f18c59553a8d2d9f74e173a16328.m4a.mp3"}]', '[{"duration":8,"url":"https://circlehbsaas.oss-cn-beijing.aliyuncs.com/audio/20240907757_tmp_acf4f18c59553a8d2d9f74e173a16328.m4a.mp3"}]',
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '2', msgFromType: "2",
msgCreateTime: '2024-10-08 15:24:19', msgCreateTime: "2024-10-08 15:24:19",
}, },
{ {
msgId: '483', msgId: "483",
msgContentType: '4', contentType: "4",
msgContent: msgContent:
'[{"duration":8,"url":"https://circlehbsaas.oss-cn-beijing.aliyuncs.com/audio/20240907757_tmp_acf4f18c59553a8d2d9f74e173a16328.m4a.mp3"}]', '[{"duration":8,"url":"https://circlehbsaas.oss-cn-beijing.aliyuncs.com/audio/20240907757_tmp_acf4f18c59553a8d2d9f74e173a16328.m4a.mp3"}]',
welcomeMsg: '', welcomeMsg: "",
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: '2024-10-08 15:24:19', msgCreateTime: "2024-10-08 15:24:19",
}, },
], ],
nextMsgId: '', lastMsgId: "",
unReadCount: 0, unReadCount: 0,
firstNotReadMsgId: 0, firstNotReadMsgId: 0,
isVisitAdl: 2, isVisitAdl: 2,
adlMsgId: 0, adlMsgId: 0,
week: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], week: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
timeDay: { 1: '上午', 2: '下午' }, timeDay: { 1: "上午", 2: "下午" },
userInfo: {}, userInfo: {},
}, },
innerAudioContext: null as WechatMiniprogram.InnerAudioContext | null, innerAudioContext: null as WechatMiniprogram.InnerAudioContext | null,
videoContext: null as WechatMiniprogram.VideoContext | null, videoContext: null as WechatMiniprogram.VideoContext | null,
onLoad(options) { onLoad(options) {
this.videoContext = wx.createVideoContext('video') this.setData({
id: options.id,
});
this.videoContext = wx.createVideoContext("video");
app.waitLogin().then(() => {
// this.getAgree();
this.getMessageList();
this.getDetail();
});
}, },
onUnload() { onUnload() {
if (this.innerAudioContext) { if (this.innerAudioContext) {
this.innerAudioContext.stop() this.innerAudioContext.stop();
} }
}, },
getAgree() {
wx.ajax({
method: "GET",
url: "?r=takeda/chat/get-agree",
data: {
roomId: this.data.id,
},
}).then((res) => {
this.setData({
show1: res === 2,
});
});
},
onAgreeClose() {
wx.navigateBack();
},
handleSubmitAgree() {
wx.ajax({
method: "POST",
url: "?r=takeda/chat/agree-room",
data: {
roomId: this.data.id,
},
}).then(() => {
this.setData({
show1: false,
});
});
},
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,
});
});
},
handleRoomDetail() {
wx.navigateTo({
url: `/module1/pages/chatRoomInfo/index?id=${this.data.id}&cid=${this.data.case.caseId}`,
});
},
handleView(index = -1) { handleView(index = -1) {
this.setData({ this.setData({
scrollIntoView: index > -1 ? `view${index}` : `place`, scrollIntoView: index > -1 ? `view${index}` : `place`,
}) });
}, },
getDoctorDetail() { getDoctorDetail() {
wx.ajax({ wx.ajax({
method: 'GET', method: "GET",
url: '?r=zd/message-interact/get-bind-doctor-info', url: "?r=zd/message-interact/get-bind-doctor-info",
data: {}, data: {},
}).then((res) => { }).then((res) => {
this.setData({ this.setData({
doctorDetail: { doctorDetail: {
...res, ...res,
}, },
}) });
}) });
}, },
getQuestionList() { getQuestionList() {
wx.ajax({ wx.ajax({
method: 'GET', method: "GET",
url: '?r=zd/message-interact/get-question-list', url: "?r=zd/message-interact/get-question-list",
data: {}, data: {},
}).then((res) => { }).then((res) => {
this.setData({ this.setData({
questionList: res, questionList: res,
questionActiveList: res[0].questionList, questionActiveList: res[0].questionList,
}) });
}) });
}, },
getMessageList() { getMessageList() {
if (this.data.isLoad || this.data.isFinish) return if (this.data.isLoad || this.data.isFinish) return;
this.setData({ this.setData({
isLoad: true, isLoad: true,
}) });
const nextMsgId = this.data.nextMsgId const lastMsgId = this.data.lastMsgId;
wx.ajax({ wx.ajax({
method: 'GET', method: "GET",
url: '?r=zd/message-interact/patient-get-message-list', url: "?r=takeda/chat/get-message-list",
data: { data: {
nextMsgId, lastMsgId,
roomId: this.data.id,
}, },
}).then((res) => { }).then((res) => {
res.messageList.map((item) => { res.map((item) => {
if (item.msgContentType === '4') { //消息内容类型,1-文本,2-语音,3-图片,4-视频,5-提示信息
item.msgContent = JSON.parse(item.msgContent) if (["2", "3", "4"].includes(item.contentType)) {
} item.msgContent = JSON.parse(item.msgContent);
if (item.msgContentType === '2') {
item.msgVisitTime = JSON.parse(item.msgVisitTime)
}
if (item.msgContentType === '5') {
item.welcomeMsg = JSON.parse(item.welcomeMsg)
} }
return item return item;
}) });
this.setData({ this.setData({
messageList: [...res.messageList.reverse(), ...this.data.messageList], messageList: [...res.messageList.reverse(), ...this.data.messageList],
nextMsgId: res.nextMsgId, lastMsgId: res.lastMsgId,
unReadCount: res.unReadCount, unReadCount: res.unReadCount,
firstNotReadMsgId: res.firstNotReadMsgId, firstNotReadMsgId: res.firstNotReadMsgId,
isVisitAdl: res.isVisitAdl, isVisitAdl: res.isVisitAdl,
adlMsgId: res.adlMsgId, adlMsgId: res.adlMsgId,
isLoad: false, isLoad: false,
isFinish: nextMsgId === res.nextMsgId, isFinish: lastMsgId === res.lastMsgId,
}) });
this.filterCreateTime() this.filterCreateTime();
if (!nextMsgId) { if (!lastMsgId) {
this.handleView() this.handleView();
} }
}) });
}, },
scrolltoupper(e) { scrolltoupper(e) {
// if (e.detail.direction === 'top') { // if (e.detail.direction === 'top') {
@ -210,49 +272,49 @@ Page({
// } // }
}, },
handleHot(e) { handleHot(e) {
const { index, mindex } = e.currentTarget.dataset const { index, mindex } = e.currentTarget.dataset;
const { messageList } = this.data const { messageList } = this.data;
const hotList = messageList[mindex].welcomeMsg?.hotQuestion const hotList = messageList[mindex].welcomeMsg?.hotQuestion;
const hot = hotList?.[index] const hot = hotList?.[index];
this.setData({ this.setData({
messageList: [ messageList: [
...messageList, ...messageList,
{ {
msgId: '', msgId: "",
msgContentType: '1', contentType: "1",
msgContent: hot?.question, msgContent: hot?.question,
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), msgCreateTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
}, },
], ],
}) });
this.handleView() this.handleView();
this.sendQuestion(hot?.questionId) this.sendQuestion(hot?.questionId);
}, },
handleQuestion(e) { handleQuestion(e) {
const { index } = e.currentTarget.dataset const { index } = e.currentTarget.dataset;
const { questionActiveList, messageList } = this.data const { questionActiveList, messageList } = this.data;
const question = questionActiveList[index] const question = questionActiveList[index];
this.setData({ this.setData({
messageList: [ messageList: [
...messageList, ...messageList,
{ {
msgId: '', msgId: "",
msgContentType: '1', contentType: "1",
msgContent: question.question, msgContent: question.question,
msgVisitTime: '', msgVisitTime: "",
msgFromType: '1', msgFromType: "1",
msgCreateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), msgCreateTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
}, },
], ],
}) });
this.sendQuestion(question.questionId) this.sendQuestion(question.questionId);
}, },
sendQuestion(questionId) { sendQuestion(questionId) {
wx.ajax({ wx.ajax({
method: 'POST', method: "POST",
url: '?r=zd/message-interact/send-question-message', url: "?r=zd/message-interact/send-question-message",
data: { data: {
questionId, questionId,
}, },
@ -261,130 +323,130 @@ Page({
messageList: [ messageList: [
...this.data.messageList, ...this.data.messageList,
{ {
msgId: '', msgId: "",
msgContentType: '1', contentType: "1",
msgContent: res, msgContent: res,
msgVisitTime: '', msgVisitTime: "",
msgFromType: '2', msgFromType: "2",
msgCreateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), msgCreateTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
}, },
], ],
}) });
this.filterCreateTime() this.filterCreateTime();
this.handleView() this.handleView();
}) });
}, },
formatTime(date: string) { formatTime(date: string) {
let msgCreateTimeName = '' let msgCreateTimeName = "";
if (dayjs().format('YYYY-MM-DD') === dayjs(date).format('YYYY-MM-DD')) { if (dayjs().format("YYYY-MM-DD") === dayjs(date).format("YYYY-MM-DD")) {
msgCreateTimeName = dayjs(date).format('HH:mm') msgCreateTimeName = dayjs(date).format("HH:mm");
} else if (dayjs().format('YYYY-MM-DD') === dayjs(date).add(1, 'day').format('YYYY-MM-DD')) { } else if (dayjs().format("YYYY-MM-DD") === dayjs(date).add(1, "day").format("YYYY-MM-DD")) {
msgCreateTimeName = `昨天 ${dayjs(date).format('HH:mm')}` msgCreateTimeName = `昨天 ${dayjs(date).format("HH:mm")}`;
} else if (dayjs().diff(date, 'day') < 7) { } else if (dayjs().diff(date, "day") < 7) {
msgCreateTimeName = dayjs(date).format(`dddd HH:mm`) msgCreateTimeName = dayjs(date).format(`dddd HH:mm`);
} else { } else {
msgCreateTimeName = dayjs(date).format('YYYY-MM-DD HH:mm') msgCreateTimeName = dayjs(date).format("YYYY-MM-DD HH:mm");
} }
return msgCreateTimeName return msgCreateTimeName;
}, },
filterCreateTime() { filterCreateTime() {
const gapTime = 5 * 60 * 1000 const gapTime = 5 * 60 * 1000;
const { messageList } = this.data const { messageList } = this.data;
let preTime = 0 let preTime = 0;
messageList.forEach((item, index) => { messageList.forEach((item, index) => {
if (index === 0) { if (index === 0) {
item.showTime = true item.showTime = true;
preTime = dayjs(item.msgCreateTime).valueOf() preTime = dayjs(item.msgCreateTime).valueOf();
item.msgCreateTimeName = this.formatTime(item.msgCreateTime) item.msgCreateTimeName = this.formatTime(item.msgCreateTime);
} else { } else {
const curTime = dayjs(item.msgCreateTime).valueOf() const curTime = dayjs(item.msgCreateTime).valueOf();
if (curTime - preTime > gapTime) { if (curTime - preTime > gapTime) {
item.showTime = true item.showTime = true;
item.msgCreateTimeName = this.formatTime(item.msgCreateTime) item.msgCreateTimeName = this.formatTime(item.msgCreateTime);
preTime = dayjs(item.msgCreateTime).valueOf() preTime = dayjs(item.msgCreateTime).valueOf();
} }
} }
}) });
this.setData({ this.setData({
messageList, messageList,
}) });
}, },
handleQuestionTab(e) { handleQuestionTab(e) {
const { index } = e.currentTarget.dataset const { index } = e.currentTarget.dataset;
this.setData({ this.setData({
questionActive: index, questionActive: index,
questionActiveList: this.data.questionList[index].questionList, questionActiveList: this.data.questionList[index].questionList,
}) });
}, },
handleDoctorDetail() { handleDoctorDetail() {
const { doctorId } = this.data.doctorDetail const { doctorId } = this.data.doctorDetail;
wx.navigateTo({ wx.navigateTo({
url: `/pages/doctorDetail/index?id=${doctorId}`, url: `/pages/doctorDetail/index?id=${doctorId}`,
}) });
}, },
handleRead() { handleRead() {
const { firstNotReadMsgId, messageList } = this.data const { firstNotReadMsgId, messageList } = this.data;
const index = messageList.findIndex((item) => `${item.msgId}` === `${firstNotReadMsgId}`) const index = messageList.findIndex((item) => `${item.msgId}` === `${firstNotReadMsgId}`);
this.handleView(index) this.handleView(index);
this.setData({ this.setData({
unReadCount: 0, unReadCount: 0,
}) });
}, },
handleFooter() { handleFooter() {
this.setData({ this.setData({
fold: !this.data.fold, fold: !this.data.fold,
}) });
if (this.data.fold) { if (this.data.fold) {
setTimeout(() => { setTimeout(() => {
this.handleView() this.handleView();
}, 300) }, 300);
} }
}, },
handleAdl() { handleAdl() {
wx.navigateTo({ wx.navigateTo({
url: '/pages/adl/index', url: "/pages/adl/index",
}) });
}, },
handleAudio(e) { handleAudio(e) {
const { index } = e.currentTarget.dataset const { index } = e.currentTarget.dataset;
const { messageList } = this.data const { messageList } = this.data;
const messageItem = messageList[index] const messageItem = messageList[index];
const { url } = messageItem.msgContent[0] const { url } = messageItem.msgContent[0];
if (this.innerAudioContext) { if (this.innerAudioContext) {
if (messageItem.isPlay) { if (messageItem.isPlay) {
this.innerAudioContext.stop() this.innerAudioContext.stop();
messageItem.isPlay = false messageItem.isPlay = false;
this.setData({ this.setData({
messageList, messageList,
}) });
return return;
} }
this.innerAudioContext.stop() this.innerAudioContext.stop();
this.innerAudioContext.src = url this.innerAudioContext.src = url;
this.innerAudioContext.play() this.innerAudioContext.play();
messageItem.isPlay = true messageItem.isPlay = true;
this.innerAudioContext.onEnded(() => { this.innerAudioContext.onEnded(() => {
messageItem.isPlay = false messageItem.isPlay = false;
this.setData({ this.setData({
messageList, messageList,
}) });
}) });
this.setData({ this.setData({
messageList, messageList,
}) });
} }
}, },
handlePreview(e) { handlePreview(e) {
const { url } = e.currentTarget.dataset const { url } = e.currentTarget.dataset;
wx.previewImage({ wx.previewImage({
urls: [url], urls: [url],
}) });
}, },
handleVideo() { handleVideo() {
if (this.videoContext) { if (this.videoContext) {
this.videoContext.play() this.videoContext.play();
this.videoContext.requestFullScreen({}) this.videoContext.requestFullScreen({});
} }
}, },
}) });

72
src/module1/pages/chatRoom/index.wxml

@ -1,38 +1,25 @@
<view class="page"> <view class="page">
<view class="page-header"> <view class="page-header">
<view class="info"> <view class="info">
<view class="photos"> <view class="photos" bind:tap="handleRoomDetail">
<image <image class="photo" wx:for="{{newRoomDoctors}}" wx:key="doctorId" src="{{item.doctorImg}}"></image>
class="photo" <view class="sealed" wx:if="{{case.caseStatus==='4'}}">已归档</view>
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<image
class="photo"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<image
class="photo"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<image
class="photo"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<view class="sealed">已归档</view>
</view> </view>
<view class="inner"> <view class="inner">
<view class="c-header"> <view class="c-header">
<view class="id">ID:2024020913049204001</view> <view class="id">ID:{{case.caseNo}}</view>
<view class="detail"> <view class="detail">
详情 详情
<van-icon name="arrow" /> <van-icon name="arrow" />
</view> </view>
</view> </view>
<view class="c-footer"> <view class="c-footer">
<view class="name">刘欢1</view> <view class="name">{{case.doctorName}}</view>
<view class="line">|</view> <view class="line">|</view>
<view class="hostipal">广东省人民医院</view> <view class="hostipal">{{case.hospitalName}}</view>
<view class="site">广州市/番禺区</view> <view class="site" wx:if="{{case.cityName}}">
{{case.cityName}}{{case.countyName?'/':''}}{{case.countyName}}
</view>
</view> </view>
</view> </view>
</view> </view>
@ -59,8 +46,8 @@
</view> </view>
<view class="d-container"> <view class="d-container">
<view class="user">李倩 中南大学湘雅医院李倩</view> <view class="user">李倩 中南大学湘雅医院李倩</view>
<view class="message" wx:if="{{message.msgContentType==='1'}}">{{message.msgContent}}</view> <view class="message" wx:if="{{message.contentType==='1'}}">{{message.msgContent}}</view>
<view class="photo" wx:elif="{{message.msgContentType==='2'}}"> <view class="photo" wx:elif="{{message.contentType==='2'}}">
<image <image
class="p-img" class="p-img"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
@ -70,7 +57,7 @@
data-url="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" data-url="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image> ></image>
</view> </view>
<view class="video" wx:elif="{{message.msgContentType==='3'}}" bind:tap="handleVideo"> <view class="video" wx:elif="{{message.contentType==='3'}}" bind:tap="handleVideo">
<image <image
class="v-img" class="v-img"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
@ -83,7 +70,7 @@
</view> </view>
<view <view
class="audio" class="audio"
wx:elif="{{message.msgContentType==='4'}}" wx:elif="{{message.contentType==='4'}}"
bind:tap="handleAudio" bind:tap="handleAudio"
data-index="{{mIndex}}" data-index="{{mIndex}}"
> >
@ -100,10 +87,10 @@
</view> </view>
<view class="patient" wx:if="{{message.msgFromType==='1'}}"> <view class="patient" wx:if="{{message.msgFromType==='1'}}">
<view class="p-container"> <view class="p-container">
<view class="message" wx:if="{{message.msgContentType==='1'}}">{{message.msgContent}}</view> <view class="message" wx:if="{{message.contentType==='1'}}">{{message.msgContent}}</view>
<view <view
class="audio" class="audio"
wx:elif="{{message.msgContentType==='4'}}" wx:elif="{{message.contentType==='4'}}"
bind:tap="handleAudio" bind:tap="handleAudio"
data-index="{{mIndex}}" data-index="{{mIndex}}"
> >
@ -116,7 +103,7 @@
></image> ></image>
<image class="icon" wx:else src="{{imageUrl}}/audio-left.png?t={{Timestamp}}" mode="aspectFit"></image> <image class="icon" wx:else src="{{imageUrl}}/audio-left.png?t={{Timestamp}}" mode="aspectFit"></image>
</view> </view>
<view class="photo" wx:elif="{{message.msgContentType==='2'}}"> <view class="photo" wx:elif="{{message.contentType==='2'}}">
<image <image
class="p-img" class="p-img"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
@ -126,7 +113,7 @@
data-url="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" data-url="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image> ></image>
</view> </view>
<view class="video" wx:elif="{{message.msgContentType==='3'}}" bind:tap="handleVideo"> <view class="video" wx:elif="{{message.contentType==='3'}}" bind:tap="handleVideo">
<image <image
class="v-img" class="v-img"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
@ -154,7 +141,12 @@
<view class="header"> <view class="header">
<image class="icon" src="{{imageUrl}}icon-voice.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon-voice.png?t={{Timestamp}}"></image>
<input class="input" placeholder-class="place-class" type="text" placeholder="请输入要查询的内容" /> <input class="input" placeholder-class="place-class" type="text" placeholder="请输入要查询的内容" />
<image class="icon-add" src="{{imageUrl}}icon-circle-add.png?t={{Timestamp}}" mode="scaleToFill" bind:tap="handleFooter"></image> <image
class="icon-add"
src="{{imageUrl}}icon-circle-add.png?t={{Timestamp}}"
mode="scaleToFill"
bind:tap="handleFooter"
></image>
</view> </view>
<view class="fold-container {{!fold && 'unfold'}}"> <view class="fold-container {{!fold && 'unfold'}}">
<view class="f-item"> <view class="f-item">
@ -173,3 +165,21 @@
id="video" id="video"
src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400" src="http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400"
></video> ></video>
<van-popup show="{{ show1 }}" bind:close="onAgreeClose" closeable round>
<view class="popup1">
<view class="title">用户须知</view>
<view class="scroll">
<view class="s-content">
为了确保患者隐私得到充分保护,我们要求所有使用本小程序的医疗保健专业人士(HCP)遵守以下协议。
</view>
<view class="s-title">一、用户同意</view>
<view class="s-content">
在使用本小程序上传患者档案之前,您必须同意以下条款:隐私保护:我确认我已经阅读并理解了本小程序的隐私政策,并将严格遵守所有相关的隐私保护规定。
信息处理:我保证在上传任何患者档案信息之前,已经彻底去除了所有患者的敏感隐私信息,包括但不限于姓名、地址、身份证号、电话
</view>
</view>
<view class="tip">聊天室自动将此病历讨论医生拉入讨论</view>
<view class="btn" bind:tap="handleSubmitAgree">确定</view>
</view>
</van-popup>

31
src/module1/pages/chatRoomInfo/index.ts

@ -1,6 +1,31 @@
const _app = getApp<IAppOption>(); const app = getApp<IAppOption>();
Page({ Page({
data: {}, data: { id: "", caseId: "", list: [] },
onLoad() {}, onLoad(options) {
this.setData({ id: options.id, caseId: options.cid });
app.waitLogin().then(() => {
this.getDetail();
}); });
},
getDetail() {
wx.ajax({
method: "GET",
url: "?r=takeda/chat/get-room-doctor",
data: {
roomId: this.data.id,
},
}).then((res) => {
this.setData({
list: res,
});
});
},
handleDoctor() {
wx.navigateTo({
url: `/module1/pages/setChatDoctor/index?id=${this.data.id}&cid=${this.data.caseId}`,
});
},
});
export {};

14
src/module1/pages/chatRoomInfo/index.wxml

@ -1,14 +1,10 @@
<view class="page"> <view class="page">
<view class="container"> <view class="container">
<view class="user" wx:for="{{10}}" wx:key="index"> <view class="user" wx:for="{{list}}" wx:key="doctorId">
<doctorAvatar <doctorAvatar class="avatar" src="{{item.doctorImg}}" level="{{item.doctorLevel}}"></doctorAvatar>
class="avatar" <view class="name">{{item.doctorName}}</view>
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567" </view>
level="{{2}}" <view class="add" bind:tap="handleDoctor">
></doctorAvatar>
<view class="name">王鸿军</view>
</view>
<view class="add">
<van-icon name="plus" /> <van-icon name="plus" />
</view> </view>
</view> </view>

3
src/module1/pages/setCaseDoctor/index.json

@ -6,6 +6,7 @@
"doctorAvatar": "/components/doctorAvatar/index", "doctorAvatar": "/components/doctorAvatar/index",
"van-cascader": "@vant/weapp/cascader/index", "van-cascader": "@vant/weapp/cascader/index",
"van-popup": "@vant/weapp/popup/index", "van-popup": "@vant/weapp/popup/index",
"van-dialog": "@vant/weapp/dialog/index" "van-dialog": "@vant/weapp/dialog/index",
"pagination": "/components/pagination/index"
} }
} }

22
src/module1/pages/setCaseDoctor/index.ts

@ -30,6 +30,11 @@ Page({
specialtyId: "", specialtyId: "",
SpecialtyName: "", SpecialtyName: "",
pagination: {
page: 1,
pages: 1,
count: 1,
},
list: [], list: [],
DoctorId: "", DoctorId: "",
@ -124,7 +129,7 @@ Page({
}); });
this.handleSearch(); this.handleSearch();
}, },
getList() { getList(newPage = 1) {
const { search, hospitalId, provinceId, cityId, countyId, specialtyId } = this.data; const { search, hospitalId, provinceId, cityId, countyId, specialtyId } = this.data;
wx.ajax({ wx.ajax({
method: "GET", method: "GET",
@ -136,13 +141,26 @@ Page({
cityId, cityId,
countyId, countyId,
specialtyId, specialtyId,
page: newPage,
}, },
}).then((res) => { }).then((res) => {
const list = res.page === 1 ? res.list : [...this.data.list, ...res.list];
this.setData({ this.setData({
list: res.list, list,
pagination: {
page: res.page,
pages: res.pages,
count: res.count,
},
}); });
}); });
}, },
onReachBottom() {
const { page, pages } = this.data.pagination;
if (pages > page) {
this.getList(page + 1);
}
},
handlePopupDetail(e) { handlePopupDetail(e) {
const { index } = e.currentTarget.dataset; const { index } = e.currentTarget.dataset;
const { list, hospitalClassification } = this.data; const { list, hospitalClassification } = this.data;

5
src/module1/pages/setCaseDoctor/index.wxml

@ -56,7 +56,9 @@
<view class="w-container"> <view class="w-container">
<text class="hostipal">{{item.hospitalName}}</text> <text class="hostipal">{{item.hospitalName}}</text>
<view class="tag">{{item.hospitalClassificationName}}{{item.hospitalLevelName}}</view> <view class="tag">{{item.hospitalClassificationName}}{{item.hospitalLevelName}}</view>
<view class="site" wx:if="{{item.cityName}}">{{item.cityName}}{{item.countyName?'/':''}}{{item.countyName}}</view> <view class="site" wx:if="{{item.cityName}}">
{{item.cityName}}{{item.countyName?'/':''}}{{item.countyName}}
</view>
</view> </view>
<view class="w-footer"> <view class="w-footer">
<image class="wf-label" src="{{imageUrl}}text-specialty.png?t={{Timestamp}}" mode="aspectFit"></image> <image class="wf-label" src="{{imageUrl}}text-specialty.png?t={{Timestamp}}" mode="aspectFit"></image>
@ -67,6 +69,7 @@
</view> </view>
</view> </view>
</view> </view>
<pagination pagination="{{pagination}}"></pagination>
</view> </view>
</radio-group> </radio-group>
</view> </view>

1
src/pages/cases/index.scss

@ -359,6 +359,7 @@ page {
} }
} }
} }
.popup1 { .popup1 {
padding: 0 32rpx 80rpx; padding: 0 32rpx 80rpx;
.title { .title {

2
src/pages/cases/index.ts

@ -212,7 +212,7 @@ Page({
if (show2) { if (show2) {
this.setData({ this.setData({
hospitalId: "", hospitalId: "",
hospitalName: "", hospitalName: "全部",
}); });
this.handleSearch(); this.handleSearch();
} }

5
src/pages/chatRoomList/index.json

@ -3,6 +3,9 @@
"navigationBarTitleText": "聊天室", "navigationBarTitleText": "聊天室",
"usingComponents": { "usingComponents": {
"van-icon": "@vant/weapp/icon/index", "van-icon": "@vant/weapp/icon/index",
"van-popup": "@vant/weapp/popup/index" "van-popup": "@vant/weapp/popup/index",
"pagination": "/components/pagination/index",
"van-cascader": "@vant/weapp/cascader/index",
"van-dialog": "@vant/weapp/dialog/index"
} }
} }

270
src/pages/chatRoomList/index.scss

@ -4,38 +4,11 @@ page {
.page { .page {
padding-bottom: 240rpx; padding-bottom: 240rpx;
.header { .header {
padding: 32rpx 0;
background-color: #fff; background-color: #fff;
border-radius: 0 0 32rpx 32rpx; border-radius: 0 0 32rpx 32rpx;
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
.nav {
padding: 20rpx;
flex: 1;
text-align: center;
font-size: 32rpx;
color: rgba(133, 133, 133, 1);
line-height: 44rpx;
&.active {
position: relative;
color: rgba(0, 180, 197, 1);
&::after {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 48rpx;
height: 8rpx;
border-radius: 8rpx 8rpx 0 0;
content: '';
background-color: rgba(0, 180, 197, 1);
}
}
}
}
.search { .search {
margin: 32rpx 32rpx 0; margin: 0 32rpx 0;
padding: 16rpx 32rpx; padding: 16rpx 32rpx;
display: flex; display: flex;
align-items: center; align-items: center;
@ -56,14 +29,32 @@ page {
} }
} }
.form { .form {
margin: 32rpx 32rpx 0; padding: 32rpx 32rpx 0;
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: 18rpx 28rpx; gap: 18rpx 28rpx;
overflow: hidden;
max-height: 400rpx;
transition: all 0.3s;
&.fold {
max-height: 70rpx;
}
.row { .row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 16rpx; gap: 16rpx;
&.row1 {
padding-left: 20rpx;
grid-area: 2 / 1 / 3 / 3;
background: #f6f6f6;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
&.row2 {
padding-left: 20rpx;
grid-area: 3 / 1 / 4 / 3;
background: #f6f6f6;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
.label { .label {
flex-shrink: 0; flex-shrink: 0;
font-size: 28rpx; font-size: 28rpx;
@ -90,14 +81,28 @@ page {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
} }
} .range {
} flex: 1;
.station {
padding: 32rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; .date {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
.date-content {
flex: 1;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.fold { .fold {
padding: 16rpx 20rpx;
text-align: right;
font-size: 28rpx; font-size: 28rpx;
color: rgba(153, 153, 153, 1); color: rgba(153, 153, 153, 1);
} }
@ -149,7 +154,7 @@ page {
&::before { &::before {
margin-right: 22rpx; margin-right: 22rpx;
display: inline-block; display: inline-block;
content: ''; content: "";
vertical-align: top; vertical-align: top;
width: 10rpx; width: 10rpx;
height: 40rpx; height: 40rpx;
@ -171,6 +176,7 @@ page {
gap: 28rpx; gap: 28rpx;
align-items: flex-start; align-items: flex-start;
.photos { .photos {
position: relative;
padding: 4rpx; padding: 4rpx;
display: grid; display: grid;
grid-template-columns: repeat(2, 36rpx); grid-template-columns: repeat(2, 36rpx);
@ -182,6 +188,15 @@ page {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.no-read{
position: absolute;
top: -9rpx;
right: -9rpx;
width: 18rpx;
height: 18rpx;
border-radius: 50%;
background-color: #ED4F39;
}
} }
.inner { .inner {
.hostipal { .hostipal {
@ -219,6 +234,7 @@ page {
padding-left: 24rpx; padding-left: 24rpx;
flex: 1; flex: 1;
display: flex; display: flex;
justify-content: flex-end;
flex-wrap: wrap; flex-wrap: wrap;
gap: 12rpx; gap: 12rpx;
.tag { .tag {
@ -236,55 +252,179 @@ page {
} }
.popup1 { .popup1 {
padding: 48rpx 32rpx; padding: 0 32rpx 80rpx;
width: 580rpx;
background: linear-gradient(180deg, #e5f5f7 0%, #ffffff 17%);
border-radius: 16rpx 16rpx 16rpx 16rpx;
border: 2rpx solid #ffffff;
.title { .title {
padding: 32rpx;
font-size: 36rpx; font-size: 36rpx;
line-height: 1;
color: rgba(20, 21, 21, 1); color: rgba(20, 21, 21, 1);
line-height: 48rpx;
font-weight: bold;
text-align: center; text-align: center;
} }
.scroll { .scroll {
margin-top: 24rpx; max-height: 50vh;
max-height: 680rpx;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
.s-title { .list {
margin-top: 24rpx; .list-item {
margin-bottom: 24rpx;
padding: 18rpx;
text-align: center;
font-size: 28rpx; font-size: 28rpx;
line-height: 32rpx;
background: #f6f6f6;
border-radius: 16rpx;
border: 2rpx solid #f6f6f6;
&.active {
background: rgba(29, 188, 204, 0.05);
border: 2rpx solid #00b4c5;
color: rgba(29, 188, 204, 1);
}
}
}
}
.submit {
width: 686rpx;
height: 88rpx;
font-size: 32rpx;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(90deg, #00b4c5 0%, #54e2b4 100%);
border-radius: 96rpx 96rpx 96rpx 96rpx;
}
}
.popup2 {
padding: 0 32rpx 80rpx;
.title {
padding: 32rpx;
font-size: 36rpx;
line-height: 1;
color: rgba(20, 21, 21, 1); color: rgba(20, 21, 21, 1);
line-height: 56rpx; text-align: center;
font-weight: bold; }
.search {
padding: 16rpx 32rpx;
display: flex;
align-items: center;
border-radius: 122rpx;
background-color: rgba(246, 246, 246, 1);
.icon {
margin-right: 14rpx;
width: 32rpx;
height: 32rpx;
} }
.s-content { .input {
flex: 1;
font-size: 28rpx; font-size: 28rpx;
color: rgba(133, 133, 133, 1); color: #000;
line-height: 48rpx; }
.place-input {
color: rgba(205, 205, 205, 1);
} }
} }
.tip { .scroll {
margin-top: 24rpx; margin-top: 24rpx;
padding: 16rpx; max-height: 50vh;
border-radius: 10rpx; overflow-y: auto;
text-align: center; overflow-x: hidden;
.list {
.list-item {
margin-bottom: 24rpx;
padding: 32rpx;
border-radius: 16rpx;
border: 2rpx solid rgba(246, 246, 246, 1);
background-color: rgba(246, 246, 246, 1);
.hostipal {
font-size: 32rpx;
color: rgba(20, 21, 21, 1);
line-height: 44rpx;
.tag {
vertical-align: 4rpx;
display: inline-block;
padding: 0 8rpx;
font-size: 24rpx; font-size: 24rpx;
color: rgba(255, 125, 0, 1); line-height: 32rpx;
line-height: 40rpx; color: #fff;
background-color: rgba(255, 247, 232, 1); border-radius: 4rpx;
background-color: rgba(0, 180, 197, 1);
} }
.btn { }
margin-top: 24rpx; .site {
height: 72rpx; margin-top: 16rpx;
font-size: 28rpx;
color: rgba(133, 133, 133, 1);
}
&.active {
background: rgba(29, 188, 204, 0.05);
border: 2rpx solid #00b4c5;
color: rgba(29, 188, 204, 1);
}
}
}
}
}
.popup3 {
padding: 32rpx 30rpx 84rpx;
.title {
display: flex;
justify-content: center;
font-size: 36rpx;
color: rgba(40, 48, 49, 1);
font-weight: bold;
}
.textarea {
padding: 30rpx;
margin-top: 32rpx;
width: 100%;
height: 216rpx;
box-sizing: border-box;
background: #f7f8f9;
border-radius: 24rpx 24rpx 24rpx 24rpx;
border: 2rpx solid #f8f9f9;
font-size: 32rx;
}
.sub-title {
padding: 32rpx 0 16rpx;
font-size: 32rpx; font-size: 32rpx;
color: rgba(255, 255, 255, 1); color: #141515;
}
.tags {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
.tag {
padding: 6rpx 44rpx;
font-size: 32rpx;
color: rgba(133, 133, 133, 1);
line-height: 44rpx;
background-color: #fff;
border: 1px solid #f6f6f6;
border-radius: 8rpx;
background: #f6f6f6;
&.active {
background-color: #fff;
border-color: rgba(1, 180, 197, 1);
color: rgba(1, 180, 197, 1);
}
}
&.tags1 {
.tag {
border-radius: 90rpx;
}
}
}
.submit {
margin-top: 32rpx;
height: 84rpx;
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
align-items: center;
background: linear-gradient(90deg, #00b4c5 0%, #54e2b4 100%); background: linear-gradient(90deg, #00b4c5 0%, #54e2b4 100%);
border-radius: 60rpx 60rpx 60rpx 60rpx; font-size: 36rpx;
color: #fff;
border-radius: 64rpx 64rpx 64rpx 64rpx;
} }
} }

408
src/pages/chatRoomList/index.ts

@ -2,14 +2,78 @@ const app = getApp<IAppOption>();
Page({ Page({
data: { data: {
fold: true, fold: false,
show1: false, show1: false,
show2: false,
show3: false,
show4: false,
show5: false,
showArea: false,
fieldNames: { text: "label", value: "value", children: "children" },
area: [],
caseStatusList: {},
roomTypeList: {},
pagination: {
page: 1,
pages: 1,
count: 1,
},
list: [],
hostilatSearch: "",
hostipalList: [],
hospitalClassification: {},
hospitalLevel: {},
hostipalPagination: {
page: 1,
pages: 1,
count: 1,
},
deptList: [] as any,
labelList: [] as any,
caseStatusName: "全部",
hospitalName: "全部",
deptName: "全部",
provinceName: "",
cityName: "",
countyName: "",
typeName: "全部",
search: "",
caseStatus: [] as any,
hospitalId: [] as any,
createRoomTimeBegin: "",
createRoomTimeEnd: "",
createCaseTimeBegin: "",
createCaseTimeEnd: "",
deptId: [] as any,
labelId: [] as any,
provinceId: "",
cityId: "",
countyId: "",
type: "",
readStatus: "",
userInfo: {},
}, },
onLoad() { onLoad() {
this.getTabBar().setData({ this.getTabBar().setData({
active: 3, active: 3,
}); });
},
onShow() {
app.waitLogin().then(() => { app.waitLogin().then(() => {
this.getBaseInfo();
this.getList();
this.getHospitalsList();
this.getHostipalDict();
this.getDoctorDict();
this.getArea();
app.getUserInfo(this, (userInfo) => { app.getUserInfo(this, (userInfo) => {
this.getTabBar().setData({ this.getTabBar().setData({
userInfo, userInfo,
@ -17,9 +81,347 @@ Page({
}); });
}); });
}, },
handleRoom() { getBaseInfo() {
wx.ajax({
method: "GET",
url: "?r=takeda/chat/get-base-info",
data: {},
}).then((res) => {
this.setData({
caseStatusList: res.caseStatusList,
roomTypeList: res.roomTypeList,
});
});
},
getArea() {
wx.ajax({
method: "GET",
url: "/js/area.json",
isJSON: true,
}).then((res) => {
this.setData({
area: res,
});
});
},
handleNav(e) {
const { nav } = e.currentTarget.dataset;
this.setData({
nav,
isOpen: nav === "1" ? "1" : "",
isHighQuality: nav === "2" ? "1" : "",
});
this.handleSearch();
},
getList(newPage = 1) {
wx.ajax({
method: "POST",
url: "?r=takeda/chat/get-list",
data: {
page: newPage,
search: this.data.search,
caseStatus: this.data.caseStatus,
createRoomTimeBegin: this.data.createRoomTimeBegin,
createRoomTimeEnd: this.data.createRoomTimeEnd,
createCaseTimeBegin: this.data.createCaseTimeBegin,
createCaseTimeEnd: this.data.createCaseTimeEnd,
deptId: this.data.deptId,
labelId: this.data.labelId,
type: this.data.type,
provinceId: this.data.provinceId,
cityId: this.data.cityId,
countyId: this.data.countyId,
hospitalId: this.data.hospitalId,
readStatus: this.data.readStatus,
},
}).then((res) => {
res.list.forEach((item) => {
item.roomDoctors = item.roomDoctors.slice(0, 4);
});
const list = res.page === 1 ? res.list : [...this.data.list, ...res.list];
this.setData({
list,
pagination: {
page: res.page,
pages: res.pages,
count: res.count,
},
});
});
},
onReachBottom() {
const { page, pages } = this.data.pagination;
if (pages > page) {
this.getList(page + 1);
}
},
handleSearch() {
this.getList();
},
handleCaseShow() {
this.setData({
show1: true,
});
},
handleCase(e) {
const { value } = e.currentTarget.dataset;
const { caseStatus, caseStatusList } = this.data;
if (!value) {
this.setData({
caseStatus: [],
caseStatusName: "全部",
});
return;
}
if (caseStatus.includes(value)) {
this.setData({
caseStatus: caseStatus.filter((item) => item !== value),
caseStatusName: caseStatus
.filter((item) => item !== value)
.map((item) => caseStatusList[item])
.join(","),
});
} else {
this.setData({
caseStatus: [...caseStatus, value],
caseStatusName: [...caseStatus, value].map((item) => caseStatusList[item]).join(","),
});
}
},
handleCaseSubmit() {
this.setData({
show1: false,
});
this.handleSearch();
},
handleTypeShow() {
this.setData({
show5: true,
});
},
handleType(e) {
const { value } = e.currentTarget.dataset;
const { type, roomTypeList } = this.data;
if (!value) {
this.setData({
type: "",
typeName: "全部",
});
return;
}
if (value === type) {
this.setData({
type: "",
typeName: "全部",
});
} else {
this.setData({
type: value,
typeName: roomTypeList[value],
});
}
},
handleTypeSubmit() {
this.setData({
show5: false,
});
this.handleSearch();
},
onClose() {
const { show2, showArea } = this.data;
this.setData({
show1: false,
show2: false,
show3: false,
show4: false,
show5: false,
showArea: false,
});
if (show2) {
this.setData({
hospitalId: "",
hospitalName: "全部",
});
this.handleSearch();
}
if (showArea) {
this.setData({
provinceId: "",
cityId: "",
countyId: "",
provinceName: "",
cityName: "",
countyName: "",
});
this.handleSearch();
}
},
handleDetail(e) {
const { params } = e.currentTarget.dataset;
wx.navigateTo({ wx.navigateTo({
url: "/module1/pages/chatRoom/index", url: `/module1/pages/casesDetail/index?id=${params.caseId}`,
});
},
// 医院选择弹窗
handleHostipalShow() {
this.setData({
show2: true,
});
},
getHostipalDict() {
wx.ajax({
method: "GET",
url: "?r=takeda/reg/hospital-dict",
data: {},
}).then((res) => {
this.setData({
hospitalClassification: res.hospitalClassification,
hospitalLevel: res.hospitalLevel,
});
});
},
handleSearchHostipal() {
this.getHospitalsList();
},
getHospitalsList(newPage = 1) {
wx.ajax({
method: "GET",
url: "?r=takeda/reg/hospitals",
data: {
page: newPage,
Search: this.data.hostilatSearch,
},
}).then((res) => {
const hostipalList = res.page === 1 ? res.list : [...this.data.hostipalList, ...res.list];
this.setData({
hostipalList,
hostipalPagination: {
page: res.page,
pages: res.pages,
count: res.count,
},
});
});
},
handleHostipalBottom(e) {
const hostipalPagination = this.data.hostipalPagination;
if (e.detail.direction === "botttom" && hostipalPagination.page < hostipalPagination.pages) {
this.getHospitalsList(Number(hostipalPagination.page) + 1);
}
},
handleHostipal(e) {
const { params } = e.currentTarget.dataset;
this.setData({
show2: false,
hospitalId: this.data.hospitalId.includes(params.HospitalId) ? [] : [params.HospitalId],
hospitalName: this.data.hospitalId.includes(params.HospitalId) ? "全部" : params.Name,
});
this.handleSearch();
},
getDoctorDict() {
wx.ajax({
method: "GET",
url: "?r=takeda/reg/doctor-dict",
data: {},
}).then((res) => {
this.setData({
deptList: res.DoctorSpecialtyLabel,
});
});
},
handleTagShow() {
this.setData({
show3: true,
});
},
handleDept(e) {
const { params } = e.currentTarget.dataset;
const deptId = this.data.deptId;
const newDeptId: any = deptId.includes(params.value)
? deptId.filter((item) => item !== params.value)
: [...deptId, params.value];
const newDeptName = this.data.deptList
.filter((item) => newDeptId.includes(item.value))
.map((item) => item.label)
.join(",");
const labelList = this.data.deptList
.filter((item) => newDeptId.includes(item.value))
.reduce((pre, cur) => {
return [...pre, ...cur.options];
}, []);
this.setData({
deptId: newDeptId,
deptName: newDeptName || "全部",
labelList,
labelId: [],
});
},
handleLabel(e) {
const { params } = e.currentTarget.dataset;
const labelId = this.data.labelId;
const newLabelId = labelId.includes(params.value)
? labelId.filter((item) => item !== params.value)
: [...labelId, params.value];
this.setData({
labelId: newLabelId,
});
},
handleTagSubmit() {
this.setData({
show3: false,
});
this.handleSearch();
},
handleRead(e) {
const { value } = e.currentTarget.dataset;
this.setData({
readStatus: value,
});
this.handleSearch();
},
handleArea() {
this.setData({
showArea: true,
});
},
onFinish(e: any) {
this.setData({
provinceId: e.detail.selectedOptions[0].value,
provinceName: e.detail.selectedOptions[0].label,
cityId: e.detail.selectedOptions[1].value,
cityName: e.detail.selectedOptions[1].label,
countyId: e.detail.selectedOptions[2].value,
countyName: e.detail.selectedOptions[2].label,
showArea: false,
});
this.handleSearch();
},
handleFold() {
this.setData({
fold: !this.data.fold,
});
},
handleCatch() {
return false;
},
handleRoom(e) {
const { params } = e.currentTarget.dataset;
wx.navigateTo({
url: `/module1/pages/chatRoom/index?id=${params.roomId}`,
});
},
handleReadAll() {
wx.ajax({
method: "POST",
url: "?r=takeda/chat/read-history",
data: {},
}).then(() => {
this.handleSearch();
}); });
}, },
}); });

291
src/pages/chatRoomList/index.wxml

@ -1,133 +1,290 @@
<wxs src="/utils/util.wxs" module="tools" />
<view class="page"> <view class="page">
<view class="header"> <view class="header">
<view class="search"> <view class="search">
<image class="icon" src="{{imageUrl}}icon-search.png?t={{Timestamp}}"></image> <image class="icon" src="{{imageUrl}}icon-search.png?t={{Timestamp}}"></image>
<input class="input" placeholder-class="place-input" type="text" placeholder="支持档案编号、医生姓名进行搜索" /> <input
</view> class="input"
<view class="form"> model:value="{{search}}"
confirm-type="search"
bindconfirm="handleSearch"
placeholder-class="place-input"
type="text"
placeholder="支持档案编号、医生姓名进行搜索"
/>
</view>
<view class="form {{fold && 'fold'}}">
<view class="row"> <view class="row">
<view class="label">状态</view> <view class="label">状态</view>
<view class="picker-content"> <view class="picker-content" bind:tap="handleCaseShow">
<view class="content">全全部全部全部全部全部全部全部全部全部全部部</view> <view class="content">{{caseStatusName}}</view>
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</view> </view>
</view> </view>
<view wx:if="{{fold}}" class="fold" bind:tap="handleFold">
展开
<van-icon class="v-icon" name="arrow-down" />
</view>
<view class="row"> <view class="row">
<view class="label">医院</view> <view class="label">医院</view>
<view class="picker-content"> <view class="picker-content" bind:tap="handleHostipalShow">
<view class="content">全全部全部全部全部全部全部全部全部全部全部部</view> <view class="content">{{hospitalName}}</view>
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</view> </view>
</view> </view>
<view class="row"> <view class="row row1">
<view class="label">创建</view> <view class="label">创建病例</view>
<picker class="picker"> <view class="picker">
<view class="picker-content"> <view class="picker-content">
<view class="content">全全部全部全部全部全部全部全部全部全部全部部</view> <view class="range">
<picker
class="date"
end="{{createRoomTimeEnd}}"
model:value="{{createRoomTimeBegin}}"
mode="date"
bind:change="handleSearch"
>
<view class="date-content">{{createRoomTimeBegin || '开始'}}</view>
</picker>
-
<picker
class="date"
start="{{createRoomTimeBegin}}"
model:value="{{createRoomTimeEnd}}"
mode="date"
bind:change="handleSearch"
>
<view class="date-content">{{createRoomTimeEnd || '结束'}}</view>
</picker>
</view>
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</view> </view>
</picker>
</view> </view>
<view class="row"> </view>
<view class="label">更新</view> <view class="row row2">
<picker class="picker"> <view class="label">创建聊天室</view>
<view class="picker">
<view class="picker-content"> <view class="picker-content">
<view class="content">全全部全部全部全部全部全部全部全部全部全部部</view> <view class="range">
<picker
class="date"
end="{{createCaseTimeEnd}}"
model:value="{{createCaseTimeBegin}}"
mode="date"
bind:change="handleSearch"
>
<view class="date-content">{{createCaseTimeBegin || '开始'}}</view>
</picker>
-
<picker
class="date"
start="{{createCaseTimeBegin}}"
model:value="{{createCaseTimeEnd}}"
mode="date"
bind:change="handleSearch"
>
<view class="date-content">{{createCaseTimeEnd || '结束'}}</view>
</picker>
</view>
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</view> </view>
</picker> </view>
</view> </view>
<view class="row"> <view class="row">
<view class="label">标签</view> <view class="label">标签</view>
<view class="picker-content"> <view class="picker-content" bind:tap="handleTagShow">
<view class="content">全全部全部全部全部全部全部全部全部全部全部部</view> <view class="content">{{deptName}}</view>
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</view> </view>
</view> </view>
<view class="row"> <view class="row">
<view class="label">地区</view> <view class="label">类型</view>
<picker class="picker"> <view class="picker-content" bind:tap="handleTypeShow">
<view class="picker-content"> <view class="content">{{typeName}}</view>
<view class="content">全全部全部全部全部全部全部全部全部全部全部部</view>
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</view> </view>
</picker>
</view> </view>
<view class="row">
<view class="label">地区</view>
<view class="picker-content" bind:tap="handleArea">
<view class="content">{{cityName + countyName || '地区'}}</view>
<van-icon name="arrow-down" />
</view> </view>
<view class="station"> </view>
<view class="fold"> <view wx:if="{{!fold}}" class="fold" bind:tap="handleFold">
收起 收起
<van-icon class="v-icon" name="arrow-down" /> <van-icon class="v-icon" name="arrow-up" />
</view> </view>
</view> </view>
</view> </view>
<view class="filter"> <view class="filter">
<view class="wrap"> <view class="wrap">
<view class="btn active">全部</view> <view class="btn {{!readStatus && 'active'}}" bind:tap="handleRead" data-value="">全部</view>
<view class="btn">未读</view> <view class="btn {{readStatus==='1' && 'active'}}" bind:tap="handleRead" data-value="1">未读</view>
<view class="btn">已读</view> <view class="btn {{readStatus==='2' && 'active'}}" bind:tap="handleRead" data-value="2">已读</view>
</view> </view>
<view class="all-read">全部标为已读</view> <view class="all-read" bind:tap="handleReadAll">全部标为已读</view>
</view> </view>
<view class="room-list"> <view class="room-list">
<view class="card" bind:tap="handleRoom"> <view class="card" wx:for="{{list}}" wx:key="msgId" bind:tap="handleRoom" data-params="{{item}}">
<view class="c-header"> <view class="c-header">
<view class="id">ID:2024020913049204001</view> <view class="id">ID:{{item.caseNo}}</view>
<view class="date">10:34</view> <view class="date">{{item.createTime}}</view>
</view> </view>
<view class="c-container"> <view class="c-container">
<view class="photos"> <view class="photos">
<image <image wx:for="{{item.roomDoctors}}" class="photo" wx:key="doctorId" src="{{item.doctorImg}}"></image>
class="photo" <view class="no-read" wx:if="{{item.isRead===2}}"></view>
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<image
class="photo"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<image
class="photo"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
<image
class="photo"
src="https://pic1.zhimg.com/50/v2-dcfbab1219ae4f7a7a6db168bb1580a2_720w.jpg?source=2c26e567"
></image>
</view> </view>
<view class="inner"> <view class="inner">
<view class="hostipal"> <view class="hostipal">
广东省人民医院 {{item.hospitalName}}
<view class="site">广州市/番禺区</view> <view class="site" wx:if="{{item.cityName}}">
{{item.cityName}}{{item.countyName?'/':''}}{{item.countyName}}
</view>
</view> </view>
<view class="content">好的,那我们就按照这种方式来进医院</view> <view class="content">{{item.msgContent}}</view>
</view> </view>
</view> </view>
<view class="c-footer"> <view class="c-footer">
<view class="name">杨梦 副主任医师</view> <view class="name">{{item.doctorName}} {{item.doctorTitleName || item.doctorOtherTitle}}</view>
<view class="tags"> <view class="tags">
<view class="tag">心律失常</view> <view class="tag" wx:for="{{item.caseLabels}}" wx:key="labelId">{{item.labelName}}</view>
<view class="tag">心律失常</view>
<view class="tag">心律失常</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<van-popup show="{{ show1 }}" bind:close="onClose" closeable round> <van-popup show="{{ show1 }}" position="bottom" bind:close="onClose" z-index="10000" round closeable>
<view class="popup1"> <view class="popup1">
<view class="title">用户须知</view> <view class="title">状态</view>
<view class="scroll"> <view class="scroll">
<view class="s-content"> <view class="list">
为了确保患者隐私得到充分保护,我们要求所有使用本小程序的医疗保健专业人士(HCP)遵守以下协议。 <view class="list-item {{!caseStatus.length && 'active'}}" bind:tap="handleCase">全部</view>
<view
class="list-item {{tools.include(index,caseStatus) && 'active'}}"
wx:for="{{caseStatusList}}"
bind:tap="handleCase"
data-value="{{index}}"
wx:key="index"
>
{{item}}
</view> </view>
<view class="s-title">一、用户同意</view>
<view class="s-content">
在使用本小程序上传患者档案之前,您必须同意以下条款:隐私保护:我确认我已经阅读并理解了本小程序的隐私政策,并将严格遵守所有相关的隐私保护规定。
信息处理:我保证在上传任何患者档案信息之前,已经彻底去除了所有患者的敏感隐私信息,包括但不限于姓名、地址、身份证号、电话
</view> </view>
</view> </view>
<view class="tip">聊天室自动将此病历讨论医生拉入讨论</view> <view class="submit" bind:tap="handleCaseSubmit">保存</view>
<view class="btn">确定</view>
</view> </view>
</van-popup> </van-popup>
<van-popup show="{{ show5 }}" position="bottom" bind:close="onClose" z-index="10000" round closeable>
<view class="popup1">
<view class="title">类型</view>
<view class="scroll">
<view class="list">
<view class="list-item {{!type && 'active'}}" bind:tap="handleType">全部</view>
<view
class="list-item {{type === index && 'active'}}"
wx:for="{{roomTypeList}}"
bind:tap="handleType"
data-value="{{index}}"
wx:key="index"
>
{{item}}
</view>
</view>
</view>
<view class="submit" bind:tap="handleTypeSubmit">保存</view>
</view>
</van-popup>
<van-popup show="{{ show2 }}" position="bottom" bind:close="onClose" z-index="10000" round closeable>
<view class="popup2">
<view class="title">选择医院</view>
<view class="search">
<image class="icon" src="{{imageUrl}}icon-search.png?t={{Timestamp}}"></image>
<input
class="input"
model:value="{{hostilatSearch}}"
placeholder-class="place-input"
type="text"
confirm-type="search"
bindconfirm="handleSearchHostipal"
placeholder="搜索医院名称"
/>
</view>
<scroll-view class="scroll" scroll-y="{{true}}" bindscrolltolower="handleHostipalBottom">
<view class="list">
<view
class="list-item {{tools.include(item.HospitalId,hospitalId) && 'active'}}"
wx:for="{{hostipalList}}"
wx:key="HospitalId"
bind:tap="handleHostipal"
data-params="{{item}}"
>
<view class="hostipal">
{{item.Name}}
<view class="tag">
{{hospitalClassification[item.HospitalClassification]}}{{hospitalLevel[item.HospitalLevel]}}
</view>
</view>
<view class="site">
{{item.ProvinceName === item.CityName ? '' : item.ProvinceName}}
{{item.CityName}}{{item.CountyName}}{{item.Address}}
</view>
</view>
<pagination pagination="{{hostipalPagination}}"></pagination>
</view>
</scroll-view>
</view>
</van-popup>
<van-popup
show="{{ show3 }}"
style="--popup-close-icon-color: #283031"
position="bottom"
round
closeable
bind:close="onClose"
z-index="10000"
>
<view class="popup3">
<view class="title">选择标签</view>
<view class="sub-title">所属科室</view>
<view class="tags tags1">
<view
class="tag {{tools.include(item.value,deptId) && 'active'}}"
wx:for="{{deptList}}"
wx:key="value"
bind:tap="handleDept"
data-params="{{item}}"
>
{{item.label}}
</view>
</view>
<view class="sub-title" wx:if="{{labelList.length}}">标签</view>
<view class="tags">
<view
class="tag {{tools.include(item.value,labelId) && 'active'}}"
wx:for="{{labelList}}"
wx:key="value"
bind:tap="handleLabel"
data-params="{{item}}"
>
{{item.label}}
</view>
</view>
<view class="submit" bind:tap="handleTagSubmit">保存</view>
</view>
</van-popup>
<van-popup show="{{ showArea }}" round position="bottom">
<van-cascader
value="{{ cascaderValue }}"
title="请选择所在地区"
options="{{ area }}"
field-names="{{fieldNames}}"
bind:close="onClose"
bind:finish="onFinish"
/>
</van-popup>

2
typings/index.d.ts vendored

@ -25,7 +25,7 @@ interface IAgaxParams extends WechatMiniprogram.RequestOption {
declare namespace WechatMiniprogram { declare namespace WechatMiniprogram {
export interface Wx { export interface Wx {
ajax: (arg0: IAgaxParams) => Promise<any>; ajax: (arg0: IAgaxParams) => Promise<any>;
editImage: any; WebIM;
} }
} }

Loading…
Cancel
Save