This commit is contained in:
2023-10-24 10:05:03 +08:00
parent 3082c4554b
commit 2646df0a48
9 changed files with 994 additions and 0 deletions

38
api/homepage/index.js Normal file
View File

@ -0,0 +1,38 @@
import request from "../request.js"
// 查询工单列表
export function getList(data) {
return request({
url: `/nurseApp/orders/getList`,
method: 'GET',
data: data
})
}
//修改订单状态
export function updateStatus(data) {
return request({
url: `/nurseApp/orders/updateStatus`,
method: 'post',
data: data
})
}
//拒单接口
export function closeHealthConsultationOrder(data) {
return request({
url: `/nurseApp/weChatPayment/closeHealthConsultationOrder`,
method: 'post',
data: data
})
}
//消息列表
export function consultationInfolist(data) {
return request({
url: `/nurseApplet/consultationInfo/list`,
method: 'get',
data: data
})
}

9
api/taskDetails/index.js Normal file
View File

@ -0,0 +1,9 @@
import request from "../request.js"
// 工单详情
export function consultationInfo(id) {
return request({
url: `/nurseApplet/consultationInfo/${id}`,
method: 'GET',
})
}

View File

@ -0,0 +1,755 @@
<template>
<view class="content">
<!-- <view class="title">
<image src="../../static/huijiantou.png" @click="back"></image>
{{currentItem.senderName}}
</view> -->
<!-- 聊天渲染列表 -->
<!-- scroll-y scroll-into-view="placeholder" scroll-top="500" scroll-with-animation -->
<scroll-view scroll-y="true" :scroll-top='scrollTop' id="demo"
:style="'height:calc(100vh - '+ inputboxtop +'px)'" scroll-with-animation="true">
<view style="height: 85vh; padding-top: 200rpx;" @tap='touchend'>
<view class="snedItem" v-for="(item, index) in newsList" :key="index">
<view class="ifSend" v-if="item.senderName == userName">
<view class="sendBox" v-if="item.messageType=='1'">{{item.content}}</view>
<image v-if="item.messageType=='2'" :src="baseurl+item.content" class="snedItemimage" />
<image class="head" src="@/static/headsculpture.png"></image>
</view>
<view class="doctorSend" v-else>
<image class="head" src="@/static/docHead.png"></image>
<view class="">
<text>{{item.senderName}}</text>
<view class="sendBox" v-if="item.content">{{item.content}}</view>
</view>
</view>
<video v-if="item.video" :src="item.video"></video>
</view>
<!-- <view class="placeholder" id="placeholder" v-if="showFunBtn"></view> -->
</view>
</scroll-view>
<!-- 底部输入 -->
<view class="input-box" :class="{ 'input-box-mpInputMargin': mpInputMargin }">
<view class="input-box-flex">
<!--弹出常用 -->
<!-- <image class="icon_img" :src="require('@/static/ico/often.png')" @tap="oftenx"></image> -->
<!-- 输入框 -->
<view class="input-box-flex-grow"> <input type="text" class="contenxxt" id="input"
v-model="formData.content" :hold-keyboard="true" :confirm-type="'send'" :confirm-hold="true"
placeholder-style="color:#DDDDDD;" :cursor-spacing="10" @confirm='sendconfirm' /> </view>
<!-- 选择表情包 -->
<!-- <image class=" icon_btn_add" :src="require('@/static/ico/emoji.png')" @tap="exprec"></image> -->
<!-- 发送消息按钮 -->
<image class=" icon_btn_add" :src="require('@/static/ico/send.png')" @tap="sendout"
v-if="formData.content!==''" mode=""></image>
<!-- <text class="send-out iconfont icon-fasong" ></text> -->
<!-- 弹出拍照-->
<!-- @tap="switchFun" -->
<uni-icons type="plus" size="33" class="icon_btn_add" v-else @tap='goshowFunBtn'></uni-icons>
<!-- <image :src="require('@/static/ico/more.png')" v-else @tap='goshowFunBtn'></image> -->
</view>
<!-- 弹出拍照-->
<view class="fun-box" :class="{'show-fun-box':showFunBtn}">
<u-grid :col="4" hover-class="contentType2-hover-class" :border="false">
<u-grid-item v-for="(item, index) in funList" @tap.stop="tapGrid(index)" :index="index" :key="index"
bg-color="#f3f3f3">
<u-icon :name="item.icon" :size="52"></u-icon>
<uni-icons style="opacity: 0.7;width: 52rpx;height: 52rpx; " v-if="index==2"
:type="index==2?'folder-add-filled':''" size="26"></uni-icons>
<view class="grid-text">{{ item.title }}</view>
</u-grid-item>
</u-grid>
</view>
<!-- 弹出表情 -->
<view class="fun-box2" :class="{'show-fun-box':showExpre}">
<view class="emoji-box emoji-move-in">
<scroll-view scroll-y="true" style="height:200px">
<view class="list">
<text v-for="(item,index) in emojisList" :key="index" @tap.stop="expre(item)"
class="touch-active">{{item}}</text>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
sendMessage,
getChatRecord,
markRead
} from '@/api/pagesC/seekadvicefrom/seekadvicefrom.js';
import baseurl from '@/api/baseurl.js'
export default {
data() {
return {
baseurl: '',
title: '',
SOCKETURL: 'ws://8.131.93.145:54088/webSocket/',
socketOpen: false,
sendInfo: {},
currentItem: '',
userName: '',
mpInputMargin: true, //
//
formData: {
content: "",
limit: 15,
index: 1,
},
timeout: 180000,
timeoutObj: null,
newsList: [],
showFunBtn: false, //
showOften: false, //
showExpre: false, //
//
funList: [{
icon: "photo-fill",
title: "照片",
uploadType: ["album"]
},
{
icon: "camera-fill",
title: "拍摄",
uploadType: ["camera"]
},
{
icon: "",
title: "文件",
},
],
emojisList: [
'😄', '😃', '😀', '😊', '😉', '😍', '😘', '😚', '😗',
'😙', '😜', '😝', '😛', '😳', '😁', '😔', '😌', '😒',
'😞', '😣', '😢', '😂', '😭', '😪', '😥', '😰', '😅',
'😓', '😩', '😫', '😨', '😱', '😠', '😡', '😤', '😖',
'👦', '👧', '👨', '👩', '👴', '👵', '👱', '👼', '👸',
'👀', '👍', '👎', '👌', '👊', '✊', '✌', '👉', '👏',
'💗', '💛', '💙', '💜', '💚', '❤', '💔', '💓', '💕',
'🌟', '💢', '🏃', '🙅', '💁', '🙋', '💼', '💬', '💭',
], //
//
oftenTermList: [{
id: 0,
title: "你好,很高兴",
},
{
id: 0,
title: "在吗",
},
],
scrollTop: 999999,
inputboxtop: undefined,
};
},
onReady() { //
uni.setNavigationBarTitle({
title: this.title,
});
},
onLoad(options) {
this.baseurl = baseurl;
// uni.closeSocket()
this.currentItem = JSON.parse(options.item)
this.title = this.currentItem.doctorName //
this.userName = this.currentItem.patientName
this.SOCKETURL = this.SOCKETURL + this.currentItem.patientId
this.getPageHistory()
this.scoket()
},
mounted() {
// wx.pageScrollTo({
// scrollTop: 9999999
// })
},
methods: {
getPageHistory() {
let obj = {
consultationId: this.currentItem.id,
senderId: this.currentItem.patientId,
recipientId: this.currentItem.doctorId,
}
getChatRecord(obj).then(res => {
res.data.forEach(e => {
if (e.readStatus == 0) {
this.Read()
}
})
this.newsList = res.data
setTimeout(() => {
let query = uni.createSelectorQuery().in(this);
//iddemo
query.select('.input-box').boundingClientRect(data => {
this.inputboxtop = data.height //
this.scrollTop = this.scrollTop + 1;
}).exec();
}, 100)
})
},
Read() {
let markReadData = {
consultationId: this.currentItem.id,
recipientId: this.currentItem.doctorId,
}
markRead(markReadData)
},
//
sendconfirm(value) {
this.sendout();
},
touchend() {
this.showFunBtn = false; //
this.showExpre = false; //
this.showOften = false; //
uni.hideKeyboard();
setTimeout(() => {
let query = uni.createSelectorQuery().in(this);
//iddemo
query.select('.input-box').boundingClientRect(data => {
this.inputboxtop = data.height //
this.scrollTop = this.scrollTop + 1;
}).exec();
}, 200)
},
goshowFunBtn() {
this.showFunBtn = !this.showFunBtn; //
uni.hideKeyboard();
setTimeout(() => {
let query = uni.createSelectorQuery().in(this);
//iddemo
query.select('.input-box').boundingClientRect(data => {
console.log(data)
this.inputboxtop = data.height //
setTimeout(() => {
this.scrollTop = this.scrollTop + 1;
}, 200)
}).exec();
}, 300)
},
sendout() {
const that = this
if (this.socketOpen == false) {
return
}
this.newsList.push({
senderName: this.userName,
content: this.formData.content
})
let obj = {
consultationId: that.currentItem.id,
senderId: that.currentItem.patientId,
senderName: that.currentItem.patientName,
recipientId: that.currentItem.doctorId,
recipientName: that.currentItem.doctorName,
messageType: 1,
sendTime: new Date(),
content: this.formData.content
}
sendMessage(obj).then(res => {
that.formData.content = '' //
setTimeout(() => {
that.scrollTop = that.scrollTop + 1;
}, 100)
if (res.code != 200) {
}
})
// try {
// const that = this
// let message = this.formData.content
// uni.sendSocketMessage({
// data: message,
// success(res) {
// let obj = {
// consultationId: that.currentItem.id,
// senderId: that.currentItem.patientId,
// senderName: that.currentItem.patientName,
// recipientId: that.currentItem.doctorId,
// recipientName: that.currentItem.doctorName,
// messageType: 1,
// sendTime: new Date(),
// // messageType: (0 1 2 3 4 5 6 )
// content: message
// }
// sendMessage(obj).then(res => {
// setTimeout(() => {
// that.scrollTop = that.scrollTop + 1;
// }, 100)
// })
// }
// })
// } catch (e) {
// console.log(e, '线')
// // uni.closeSocket();
// }
},
//
oftenc(e) {
this.formData.content = e.title;
},
//
expre(e) {
this.formData.content = !this.formData.content ? e : this.formData.content + e;
},
//
// switchFun() {
// this.showOften = false; //
// this.showExpre = false; //
// this.showFunBtn = !this.showFunBtn; //
// uni.hideKeyboard();
// setTimeout(() => {
// let query = uni.createSelectorQuery().in(this);
// //iddemo
// query.select('.input-box').boundingClientRect(data => {
// this.inputboxtop = data.height //
// }).exec();
// this.scrollTop = this.scrollTop + 1;
// }, 200)
// },
//
// oftenx() {
// this.showFunBtn = false; //
// this.showExpre = false; //
// this.showOften = !this.showOften; //
// uni.hideKeyboard();
// setTimeout(() => {
// let query = uni.createSelectorQuery().in(this);
// //iddemo
// query.select('.input-box').boundingClientRect(data => {
// this.inputboxtop = data.height //
// }).exec();
// this.scrollTop = this.scrollTop + 1;
// }, 100)
// },
//
// exprec() {
// this.showFunBtn = false; //
// this.showOften = false; //
// this.showExpre = !this.showExpre; //
// uni.hideKeyboard();
// setTimeout(() => {
// let query = uni.createSelectorQuery().in(this);
// //iddemo
// query.select('.input-box').boundingClientRect(data => {
// this.inputboxtop = data.height //
// }).exec();
// this.scrollTop = this.scrollTop + 1;
// }, 100)
// },
//
tapGrid(index) {
if (index == 0) {
this.chooseImage(["album"]);
} else if (index == 1) {
this.chooseImage(["camera"]);
} else if (index == 2) {
uni.chooseMessageFile({
count: 6, //100
extension: ['.zip', '.doc'],
success: function(res) {
console.log(res)
// console.log(JSON.stringify(res.tempFilePaths));
}
});
}
},
//
chooseImage(sourceType) {
var that = this
if (this.socketOpen == false) {
return
}
uni.chooseImage({
sourceType,
sizeType: ["compressed"],
success: (res) => {
that.showFunBtn = false;
setTimeout(() => {
let query = uni.createSelectorQuery().in(this);
//iddemo
query.select('.input-box').boundingClientRect(data => {
console.log(data)
this.inputboxtop = data.height //
setTimeout(() => {
this.scrollTop = this.scrollTop + 1;
}, 200)
}).exec();
}, 300)
res.tempFilePaths.forEach(e => {
that.newsList.push({
imgurl: e,
senderName: that.userName,
})
uni.uploadFile({
url: baseurl +
'/nurseApplet/consultationInfo/uploadConsultationFile',
filePath: e,
name: 'file',
timeout: 5000,
success(resp) {
console.log(resp)
var fileurls = JSON.parse(resp.data)
let obj = {
consultationId: that.currentItem.id,
senderId: that.currentItem.patientId,
senderName: that.currentItem.patientName,
recipientId: that.currentItem.doctorId,
recipientName: that.currentItem.doctorName,
messageType: 2,
sendTime: new Date(),
content: fileurls.fileUrl
}
sendMessage(obj).then(respp => {
console.log(respp)
})
}
})
})
},
});
},
//
touchstart() {
uni.hideKeyboard();
setTimeout(() => {
let query = uni.createSelectorQuery().in(this);
//iddemo
query.select('.input-box').boundingClientRect(data => {
this.inputboxtop = data.height //
this.scrollTop = this.scrollTop + 1;
}).exec();
}, 200)
},
scoket() {
const that = this
this.socketOpen = false
try {
uni.connectSocket({
url: that.SOCKETURL
})
uni.onSocketOpen(res => {
console.log('webScoket连接已打开', res);
that.socketOpen = true
that.reset()
})
uni.onSocketError(err => {
console.log('webScoket连接打开失败', err);
if (err && err.code != 1000) {
setTimeout(() => {
that.socketOpen = true
uni.connectSocket({
url: that.SOCKETURL
})
}, 3 * 1000)
}
})
uni.onSocketClose(err => {
console.log('webScoket连接关闭', err);
if (err && err.code !== 1000) {
setTimeout(() => {
that.socketOpen = true
uni.connectSocket({
url: that.SOCKETURL
})
}, 3 * 1000)
}
})
uni.onSocketMessage(res => {
console.log("webScoket监听收到的信息", res);
that.newsList.push({
senderName: that.currentItem.patientName,
content: JSON.parse(res.data).message
})
that.Read()
})
} catch (e) {
console.log(e);
}
},
//
reset() {
let that = this
clearInterval(that.timeoutObj);
that.timeoutObj = setInterval(() => {
uni.sendSocketMessage({
data: 'ping',
success(res) {
console.log('正在发送心跳');
},
fail(err) {
console.log('心跳发送失败,重新连接...');
that.socketOpen = true
uni.connectSocket({
url: that.SOCKETURL
})
}
})
}, that.timeout)
},
back() {
uni.navigateBack({
delta: 1
})
}
},
onUnload() {
clearInterval(this.timeoutObj);
if (this.socketOpen == true) {
uni.closeSocket();
}
}
};
</script>
<style lang="scss" scoped>
page {
background-color: #f3f3f3;
}
#demo {
transition: all 0.3s ease;
}
.content {
.input-box {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
box-sizing: content-box;
z-index: 999;
background-color: #f3f3f3;
/* #ifdef APP-PLUS */
margin-bottom: 0rpx;
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
/* #endif */
/* #ifdef MP-WEIXIN */
padding-bottom: 0rpx;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
.input-box-flex {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
padding: 20rpx;
box-sizing: border-box;
image {
width: 63rpx;
height: 63rpx;
}
.icon_img {
margin-right: 20rpx;
}
.icon_btn_add {
margin-left: 20rpx;
}
// .send-out {
// font-size: 65rpx;
// margin-left: 15rpx;
// color: #16c694;
// width: 100rpx;
// height: 100rpx;
// }
.input-box-flex-grow {
flex: 1;
}
.contenxxt {
box-sizing: border-box;
background-color: #fff;
height: 80rpx;
padding: 0 20rpx;
border-radius: 12rpx;
font-size: 28rpx;
caret-color: $uni-color-success;
}
}
.fun-box {
opacity: 0;
height: 0;
transition: all 0.3s ease;
transform: translateY(100%);
.grid-text {
padding-top: 10rpx;
color: $uni-text-color-grey;
}
}
.fun-box1 {
opacity: 0;
transition: all 0.1s ease-in-out;
height: 0;
.often-super {
padding: 30rpx;
height: 240rpx;
background-color: #f3f3f3;
width: auto;
.flex-row {
padding: 10rpx 0;
border-bottom: 1rpx #e8e8e8 solid;
.often-text-size {
color: #5a5a5a;
font-size: 26rpx;
margin-top: 6rpx;
margin-bottom: 6rpx;
}
}
}
}
.fun-box2 {
opacity: 0;
transition: all 0.1s ease-in-out;
height: 0;
.emoji-box {
position: relative;
height: 200rpx;
padding: 5rpx 0;
box-sizing: border-box;
margin-bottom: -200rpx;
background-color: #f3f3f3;
.list {
display: flex;
flex-wrap: wrap;
padding: 0 0 0 14rpx;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.touch-active {
width: 65rpx;
height: 60rpx;
text-align: center;
border-radius: 3rpx;
line-height: 60rpx;
font-size: 38rpx;
}
}
}
.emoji-move-in {
-webkit-animation: emoji-move-in 0.3s forwards;
animation: emoji-move-in 0.3s forwards;
}
}
.show-fun-box {
opacity: 1;
height: 300rpx;
transition: all 0.3s ease;
transform: translateY(0%) !important;
}
}
.input-box-mpInputMargin {
/* #ifdef MP-WEIXIN */
padding-bottom: 0rpx;
/* #endif */
}
}
.snedItem {
padding: 0rpx 30rpx 40rpx 30rpx;
.snedItemimage {
width: 200rpx;
height: 200rpx;
border-radius: 3rpx;
}
}
.ifSend {
display: flex;
justify-content: flex-end;
.head {
width: 80rpx;
height: 80rpx;
margin-left: 20rpx;
}
.sendBox {
background-color: #55d0df7d;
padding: 18rpx 20rpx;
border-radius: 0 0 10rpx 10rpx;
font-size: 34rpx;
flex: none;
max-width: 550rpx;
word-break: break-all;
}
}
.doctorSend {
display: flex;
justify-content: flex-start;
align-items: center;
.head {
width: 90rpx;
height: 90rpx;
margin-right: 20rpx;
}
text {
color: #b2b2b2;
font-size: 24rpx;
}
.sendBox {
background-color: #d7d7d77d;
padding: 18rpx 20rpx;
border-radius: 0 0 10rpx 10rpx;
font-size: 34rpx;
flex: none;
max-width: 550rpx;
word-break: break-all;
}
}
.placeholder {
height: 200rpx;
transition: all 0.3s ease;
transform: translateY(0%) !important;
}
.title {
font-size: 20px;
text-align: center;
height: 80rpx;
border-bottom: 1rpx solid #f6f6f6;
padding-top: 100rpx;
position: fixed;
width: 100%;
background: white;
z-index: 10;
image {
width: 20rpx;
height: 30rpx;
transform: rotate(180deg);
position: absolute;
left: 40rpx;
bottom: 38rpx;
}
}
</style>

View File

@ -0,0 +1,163 @@
<template>
<view class="app" v-if="list">
<view class="top">
<view class="title">
患者信息
</view>
<view class="text">
姓名{{list.patientName}}
</view>
<view class="text">
性别{{list.sex}}
</view>
<view class="text">
身份证号{{list.cardNo}}
</view>
<view class="text">
手机号码{{list.phone}}
</view>
<view class="text">
家庭住址{{list.address}}
</view>
</view>
<view class="center top">
<view class="title">
预约时间
</view>
<view class="time">
{{list.appointmentDate}}{{' '+list.appointmentStartTime+'-'+list.appointmentEndTime}}
</view>
</view>
<view class="bottom top">
<view class="title">
咨询内容
</view>
<view class="text-area">
{{list.problemStatement}}
</view>
</view>
<view class="fileimage top">
<view class="title">
检查单/患处照片
</view>
<view class="images" v-for='(item,index) in fileUrls'>
<image :src="item" mode="" @click.stop='previewImage(index)'></image>
</view>
</view>
</view>
</template>
<script>
import baseurl from '@/api/baseurl.js'
import {
consultationInfo
} from '@/api/taskDetails/index.js'
import {
getSex
} from '@/utils/conversion.js'
export default {
data() {
return {
list: null,
baseurl: null,
fileUrls: [],
};
},
onLoad(options) {
this.baseurl = baseurl
this.info(options.id)
},
methods: {
previewImage(index) {
uni.previewImage({
urls: this.fileUrls,
current: index,
indicator: "default",
loop: true
})
},
info(id) {
consultationInfo(id).then(res => {
res.data.fileUrls.forEach(e => {
e = this.baseurl + e
this.fileUrls.push(e)
})
res.data.sex = getSex(res.data.cardNo)
this.list = res.data
})
}
}
}
</script>
<style lang="scss">
.app {
.fileimage {
.images {
width: 90%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
image {
width: 100%;
}
}
}
.bottom {
.text-area {
width: 90%;
margin: 30rpx auto;
font-weight: 500;
word-break: break-all;
}
}
.center {
.time {
width: 90%;
margin: 0 auto;
height: 80rpx;
line-height: 80rpx;
background: #F7F9F8;
margin-top: 20rpx;
border-radius: 14rpx;
font-size: 28rpx;
font-weight: 500;
color: #333333;
padding-left: 20rpx;
}
}
.title {
width: 90%;
height: 80rpx;
line-height: 80rpx;
margin: 0 auto;
font-size: 28rpx;
font-weight: 500;
color: #333333;
border-bottom: 2rpx solid #E6E6E6;
}
.top {
width: 94%;
margin: 0 auto;
background-color: #fff;
border-radius: 10rpx;
margin-top: 20rpx;
padding-bottom: 20rpx;
.text {
font-size: 24rpx;
font-weight: 500;
color: #333333;
line-height: 60rpx;
width: 90%;
margin: 0 auto;
}
}
}
</style>

BIN
static/homepages.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/jinbi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/my.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/mys.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

29
utils/conversion.js Normal file
View File

@ -0,0 +1,29 @@
export function getSex(idCard) {
if (idCard.length === 15) {
return ['女', '男'][idCard.substr(14, 1) % 2]
} else if (idCard.length === 18) {
return ['女', '男'][idCard.substr(16, 1) % 2]
}
return ''
}
export function getBirthday(idCard) {
var birthday = "";
if (idCard != null && idCard != "") {
if (idCard.length == 15) {
birthday = "19" + idCard.substr(6, 6);
} else if (idCard.length == 18) {
birthday = idCard.substr(6, 8);
}
birthday = birthday.replace(/(.{4})(.{2})/, "$1-$2-");
}
return birthday;
};
// 出生日期转年龄
export function getAgeFun(value) {
var birthdays = new Date(value.replace(/-/g, "/")); //value 是传入的值
var time = new Date(); //当前时间
var age = time.getFullYear() - birthdays.getFullYear() - (time.getMonth() < birthdays.getMonth() || (time.getMonth() == birthdays.getMonth() &&
time.getDate() < birthdays.getDate()) ? 1 : 0);
return age;
}