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.

870 lines
18 KiB

<template>
3 years ago
<view style="padding-bottom: 20rpx;">
<cpn-navbar title="护理详情" :isBack="true"></cpn-navbar>
<view>
<!-- 用户信息 -->
3 years ago
<view class="user-info" v-if="detail.customer">
<view class="top">
<view class="left">
3 years ago
<u-image :src="detail.customer.sex === '男' ? vuex_male_img : vuex_female_img" width="104"
height="104" shape="circle"></u-image>
</view>
<view class="center">
3 years ago
<view class="name">{{detail.customer.name}}</view>
<view class="infos">
3 years ago
<view class="age">{{ageComputed(detail.customer.idcard)}}
3 years ago
</view>
<view class="sex">{{detail.customer.sex}}</view>
<view class="organ">机构护理</view>
</view>
</view>
<view class="right">
3 years ago
<template v-if="detail.status === 0">
<view class="icon1"></view>
<view>待护理</view>
</template>
3 years ago
<template v-if="detail.status === 1">
<view class="icon3"></view>
<view>进行中</view>
</template>
3 years ago
<template v-if="detail.status === 2">
<view class="icon2"></view>
<view>已完成</view>
</template>
</view>
</view>
<view class="line"></view>
<view class="bottom">
<view class="client">
<u-icon name="/static/detail/people.png" width="26" height="26"></u-icon>
3 years ago
<view>委托人{{detail.customer.contact_name}}</view>
</view>
<view class="address">
<u-icon name="map" width="28" height="28" color="#1479FF"></u-icon>
3 years ago
<view>{{ addressFormat(detail.customer.customer_address) }}</view>
</view>
<view class="phone">
<u-icon name="phone" width="28" height="28" color="#1479FF"></u-icon>
3 years ago
<view>{{detail.customer.phone}}</view>
</view>
</view>
3 years ago
<view class="re-location" @click="$u.throttle(refreshLoaction,1000)">
3 years ago
<view class="text">更新定位</view>
<u-image src="/static/detail/distance.png" height="34" width="34"></u-image>
</view>
</view>
3 years ago
<!-- 今日护理 -->
3 years ago
<view class="today-nursing" v-show="detail.status !== 0">
3 years ago
<view class="title">
今日护理
</view>
<view class="line"></view>
3 years ago
<view class="table-title">
<view>护理明细</view>
<view>实际时长</view>
</view>
3 years ago
<view class="content">
3 years ago
<view class="content-item" v-for="(item,index) in skuList" :key='item.info.id'>
3 years ago
<u-checkbox class="checkbox" label-size="34" size="36" :disabled="detail.status === 2"
v-model="item.isSelect" shape="square" :name="item.form.name"
@change="selectPick($event,item)">
3 years ago
{{item.info.name}}
3 years ago
</u-checkbox>
3 years ago
<view class="input">
3 years ago
<u-input :disabled="detail.status === 2 || !item.isSelect" v-model="item.form.time"
:custom-style="inputStyle" :placeholder="'需 '+ item.info.time_lenth"
placeholder-style="color:#A7AFBC;font-size:28rpx;" input-align="center"
:clearable="false" type="number" height="46">
3 years ago
</u-input>
3 years ago
<view style="font-size: 34rpx;">分钟</view>
3 years ago
</view>
</view>
</view>
</view>
<!-- 打卡 -->
<view class="clock">
3 years ago
<view class="btn" v-if="detail.status === 1 && detail.logs_count < detail.product.process_total"
3 years ago
@click="$u.throttle(clockIn,5000)">
3 years ago
<view class="text1">过程打卡</view>
3 years ago
<view class="text2">{{detail.logs_count + 1}}</view>
3 years ago
</view>
3 years ago
<view class="btn" v-if="detail.status === 0 && flag" @click="$u.throttle(sign,5000)">
3 years ago
<view class="text1">签到</view>
3 years ago
<view class="text2">{{dateFormat(time,'HH:mm:ss')}}</view>
3 years ago
</view>
3 years ago
<view class="btn" v-if="detail.status === 1" @click="$u.throttle(signOut,5000)">
3 years ago
<view class="text1">签退</view>
3 years ago
<view class="text2">{{dateFormat(time,'HH:mm:ss')}}</view>
3 years ago
</view>
3 years ago
<view class="btn" v-if="detail.status === 0 && !flag" @click="$u.throttle(refreshLoaction,5000)">
3 years ago
<view class="text1">更新定位</view>
3 years ago
<view class="text2">{{dateFormat(time,'HH:mm:ss')}}</view>
3 years ago
</view>
3 years ago
<view class="btn" v-if="detail.status === 2">
<view class="text1">护理已完成</view>
</view>
3 years ago
</view>
<!-- 打卡信息 -->
3 years ago
<view class="clock-info" v-if="location.lat && location.lng && location.time">
3 years ago
定位时间{{dateFormat(location.time,'HH:mm:ss')}} {{location.address}}
3 years ago
</view>
3 years ago
<!-- 打卡记录 -->
3 years ago
<view class="logs" v-if="detail.logs && detail.logs.length > 0">
3 years ago
<view class="title">
打卡记录
</view>
<view class="line"></view>
<view class="logs-content">
<u-time-line>
<u-time-line-item v-for="(item,index) in detail.logs" :key="index">
<template v-slot:content>
<view>
<view class="u-order-desc">{{typeFormat(item.type)}}</view>
<view class="u-order-time">{{item.created_at}}</view>
3 years ago
<view class="u-order-address">{{item.address}}</view>
3 years ago
</view>
</template>
</u-time-line-item>
</u-time-line>
</view>
</view>
</view>
3 years ago
<imgUpload ref="imgUpload" :isShow.sync="isShowImg" :type="type" @confirm="clock"></imgUpload>
</view>
</template>
<script>
3 years ago
import {
ROOTPATH
} from '@/common/config.js'
3 years ago
import QQMapWX from '@/libs/qqmap-wx-jssdk.js'
3 years ago
import moment from '@/libs/moment.min.js'
3 years ago
import {
getAgeByIdcard
} from '@/common/util.js'
3 years ago
3 years ago
import imgUpload from './components/imgUpload.vue'
export default {
3 years ago
components: {
imgUpload
},
data() {
return {
3 years ago
type: 0, //打卡类型,1签到 2过程打卡 3签退
isShowImg: false,
3 years ago
id: '',
flag: false, //未开始护理时,是否更新过定位(真为更新过定位)
3 years ago
qqmapsdk: null,
3 years ago
inputStyle: {
3 years ago
fontSize: "34rpx",
3 years ago
color: "#36596A",
width: "140rpx",
background: "#F9F9F9"
},
3 years ago
btnStyle: {
width: '100rpx',
height: '100rpx',
borderRadius: '100%',
background: 'blue'
},
3 years ago
location: {
lng: '',
lat: '',
time: '',
address: ''
3 years ago
},
form: {
schedule_list_id: '',
lat: '',
lng: '',
address: '',
type: '',
upload_list: [],
},
3 years ago
skuList: [],
3 years ago
detail: {},
time: new Date(),
3 years ago
timer: null,
}
},
methods: {
3 years ago
load() {
this.qqmapsdk = new QQMapWX({
key: 'D5EBZ-C3BWP-HZIDG-VO6BE-P2MN5-ESFZO'
});
},
3 years ago
selectPick(e, item) {
if (e.value) {
if (!item.form.time) {
item.form.time = item.info.time_lenth
}
}
},
3 years ago
async getDeatil(id) {
let res = await this.$u.api.nurseDetail({
id
})
this.detail = res
3 years ago
this.skuList = []
res.sku.forEach(item => {
if (item.sku_id && item.sku_info) {
this.skuList.push({
info: item.sku_info,
isSelect: item.time ? true : false,
form: {
id: item.id,
time: item.time || '',
sku_id: item.sku_id,
}
})
3 years ago
}
})
3 years ago
this.form.schedule_list_id = this.id
3 years ago
console.log(this.skuList);
3 years ago
},
3 years ago
//获取当前定位信息
getLoaction() {
return new Promise((resolve, reject) => {
3 years ago
uni.getLocation({
type:'gcj02',
isHighAccuracy:true
}).then(res => {
3 years ago
if (res[1]) {
this.location.lat = res[1]?.latitude
this.location.lng = res[1]?.longitude
this.location.time = this.time
3 years ago
this.form.lat = this.location.lat
this.form.lng = this.location.lng
3 years ago
3 years ago
this.qqmapsdk.reverseGeocoder({
location: {
latitude: this.location.lat,
longitude: this.location.lng
},
3 years ago
success: (res) => {
this.location.address = res.result.address
3 years ago
this.form.address = this.location.address
3 years ago
resolve(res)
},
fail: (err) => {
reject(err)
3 years ago
}
})
3 years ago
} else {
uni.showToast({
icon: 'none',
title: '操作频繁,请稍后再试'
})
reject(res)
3 years ago
console.log(res);
3 years ago
}
3 years ago
3 years ago
})
})
},
//更新地址
refreshLoaction() {
this.getLoaction().then(res => {
uni.showToast({
icon: 'none',
title: '更新定位成功'
})
3 years ago
this.flag = true
3 years ago
})
},
//图片批量上传
3 years ago
uploadImgs(files) {
let promiseAll = files.map(item => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${ROOTPATH}/api/nurse/upload-file`,
header: {
Authorization: `Bearer ${this.vuex_token}`
},
3 years ago
formData: {
is_water: 1,
address: this.form.address,
coordinate: `${this.form.lng},${this.form.lat}`
},
3 years ago
filePath: item,
name: 'file',
success: (res1) => {
resolve(res1)
},
fail: (err) => {
reject(err)
}
3 years ago
})
})
3 years ago
})
3 years ago
3 years ago
return Promise.all(promiseAll)
// let res = await uni.chooseImage({
// sourceType: ['camera']
// })
// if (res[1]) {
// let promiseAll = res[1].tempFilePaths.map(item => {
// console.log(`${ROOTPATH}/api/nurse/upload-file`);
// return new Promise((resolve, reject) => {
// uni.uploadFile({
// url: `${ROOTPATH}/api/nurse/upload-file`,
// header: {
// Authorization: `Bearer ${this.vuex_token}`
// },
// filePath: item,
// name: 'file',
// success: (res1) => {
// resolve(res1)
// },
// fail: (err) => {
// reject(err)
// }
// })
// })
// })
// return Promise.all(promiseAll)
// } else {
// return Promise.reject(res[0].errMsg)
// }
3 years ago
},
3 years ago
//打卡
3 years ago
clock(files, type) {
3 years ago
let title;
switch (type) {
case 1:
title = '签到成功'
break;
case 2:
title = `${this.detail.logs_count+1}次打卡成功`
break;
case 3:
title = '签退成功'
break;
default:
title = '操作成功'
}
3 years ago
this.uploadImgs(files).then(res => {
3 years ago
this.form.upload_list = res.map(item => {
return {
upload_id: JSON.parse(item.data).id
}
})
3 years ago
this.form.type = type
this.$u.api.processSave(this.form).then(res => {
uni.showToast({
icon: 'success',
title
})
3 years ago
this.$refs['imgUpload'].clearList()
this.isShowImg = false
3 years ago
this.getDeatil(this.id)
}).catch(err => {
uni.showToast({
title: '操作失败,请重试'
})
})
3 years ago
}).catch(err => {
uni.showToast({
icon: 'none',
title: '图片上传失败'
})
3 years ago
})
3 years ago
},
3 years ago
//保存服务项目
saveSku() {
return new Promise((resolve, reject) => {
3 years ago
let temp1 = this.skuList.filter(item => {
3 years ago
return item.isSelect
})
3 years ago
let temp2 = temp1.map(item => {
return item.form
})
3 years ago
this.$u.api.nurseSave({
id: this.id,
3 years ago
sku_time_list: temp2
3 years ago
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
},
//签到
sign() {
3 years ago
this.type = 1
this.isShowImg = true
//this.clock(1)
3 years ago
},
//过程打卡
clockIn() {
//验证是否有选择服务项目并填写
3 years ago
// let flag = false
// for (let i of this.skuList) {
// if (i.isSelect && i.form.time) {
// flag = true
// }
// }
// if (!flag) {
// uni.showToast({
// icon: 'none',
// title: `请选择并填写服务项目与时间`
// })
// return
// }
3 years ago
this.saveSku().then(res => {
3 years ago
this.type = 2
this.isShowImg = true
3 years ago
}).catch(err => {
console.log(err);
uni.showToast({
icon: 'none',
title: '请重试'
})
})
},
//签退
signOut() {
3 years ago
if (this.detail.logs_count < this.detail.product.process_total) {
3 years ago
uni.showToast({
icon: 'none',
3 years ago
title: `请先完成${this.detail.product.process_total}次打卡,再签退。当前完成打卡次数${this.detail.logs_count}`
3 years ago
})
return
}
//验证是否有选择服务项目并填写
let flag = false
for (let i of this.skuList) {
3 years ago
if (i.isSelect && i.form.time) {
3 years ago
flag = true
}
}
if (!flag) {
uni.showToast({
icon: 'none',
title: `请选择并填写服务项目与时间`
})
return
}
3 years ago
//验证服务时间是否都已完成
3 years ago
// let flag2 = 0
// let tempArr = []
// for (let i of this.skuList) {
// if (i.isSelect && (i.form.time >= i.info.time_lenth)) {
// flag2++
// } else {
// tempArr.push(i.info.name)
// }
// }
// if (flag2 < this.skuList.length) {
// uni.showToast({
// icon: 'none',
// title: `${tempArr.toString()}服务时间未满`
// })
// return
// }
3 years ago
this.saveSku().then(() => {
3 years ago
this.type = 3
this.isShowImg = true
3 years ago
}).catch(err => {
console.log(err);
uni.showToast({
icon: 'none',
title: '请重试'
})
})
}
},
computed: {
3 years ago
ageComputed() {
3 years ago
return function(idcard) {
return getAgeByIdcard(idcard)
3 years ago
}
3 years ago
},
addressFormat() {
return function(addresses) {
return addresses.filter(item => {
item.default === 1
})[0]?.address || addresses[0]?.address || '无'
}
3 years ago
},
dateFormat() {
return function(date, fmt = "YYYY-MM-DD") {
if (date) {
return moment(date).format(fmt)
}
}
3 years ago
},
typeFormat() {
return function(type) {
let map = new Map([
[1, "签到"],
[2, "过程打卡"],
[3, "签退"],
[4, "更新定位"]
])
return map.get(type) || ''
}
3 years ago
}
},
3 years ago
onLoad(option) {
this.getDeatil(option.id)
3 years ago
this.id = option.id
3 years ago
3 years ago
},
onShow() {
this.timer = setInterval(() => {
3 years ago
this.time = new Date()
}, 1000)
3 years ago
},
onHide() {
clearInterval(this.timer)
},
mounted() {
this.load()
3 years ago
this.getLoaction()
3 years ago
}
}
</script>
<style scoped lang="scss">
.user-info {
width: 710rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
margin: 40rpx auto 0 auto;
3 years ago
position: relative;
.top {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding-top: 34rpx;
padding-bottom: 30rpx;
.left {
padding-left: 20rpx;
}
.center {
flex: 1;
padding-left: 24rpx;
.name {
height: 48rpx;
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
line-height: 24rpx;
}
.infos {
display: flex;
align-items: center;
padding-top: 20rpx;
.age {
height: 34rpx;
font-size: 24rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #A7AFBC;
line-height: 34rpx;
}
.sex {
width: 40rpx;
height: 40rpx;
background: #FDECEC;
opacity: 0.5;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #36596A;
text-align: center;
line-height: 40rpx;
margin-left: 20rpx;
}
.organ {
width: 140rpx;
height: 40rpx;
background: #F9F9F9;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #36596A;
line-height: 40rpx;
text-align: center;
margin-left: 20rpx;
}
}
}
.right {
display: flex;
align-items: center;
padding-right: 20rpx;
}
}
.line {
width: 670rpx;
height: 2rpx;
border: 2rpx solid #EEEFF5;
margin: 30rpx auto 0 auto;
}
.bottom {
padding: 26rpx 0 34rpx 24rpx;
3 years ago
position: relative;
.bottom-item {
display: flex;
align-items: center;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #36596A;
&>view {
padding-left: 16rpx;
}
}
.client {
@extend .bottom-item;
}
.address {
@extend .bottom-item;
padding-top: 18rpx;
}
.phone {
@extend .bottom-item;
padding-top: 18rpx;
}
}
3 years ago
.re-location {
display: flex;
align-items: center;
position: absolute;
bottom: 36rpx;
right: 20rpx;
.text {
height: 34rpx;
font-size: 24rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #A7AFBC;
line-height: 34rpx;
padding-right: 8rpx;
}
}
}
.today-nursing {
width: 710rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 10rpx 0rpx rgba(219, 218, 218, 0.5);
margin: 20rpx auto 0 auto;
.title {
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #333333;
padding: 24rpx 20rpx;
}
.line {
width: 670rpx;
height: 2rpx;
border: 2rpx solid #EEEFF5;
margin: 0 auto;
}
3 years ago
.table-title {
display: flex;
justify-content: space-between;
&>view {
text-align: center;
width: 260rpx;
padding-top: 24rpx;
}
}
3 years ago
.content {
padding: 14rpx 20rpx 24rpx 20rpx;
.content-item {
height: 70rpx;
display: flex;
justify-content: space-between;
align-items: center;
3 years ago
padding: 24rpx 0;
padding-left: 10rpx;
.checkbox {
flex: 1
}
::v-deep .u-checkbox {
width: 100% !important;
}
::v-deep .u-checkbox__label {
width: 100% !important;
padding-left: 16rpx;
}
3 years ago
.input {
display: flex;
align-items: center;
&>view {
height: 40rpx;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #36596A;
line-height: 40rpx;
padding-left: 20rpx;
}
}
}
}
}
3 years ago
.logs {
@extend .today-nursing;
&-content {
padding: 24rpx 32rpx;
}
}
3 years ago
.clock {
display: flex;
justify-content: space-evenly;
margin-top: 48rpx;
.btn {
width: 190rpx;
height: 190rpx;
background: #1479FF;
border-radius: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
&::before {
content: '';
height: 220rpx;
width: 220rpx;
border-radius: 100%;
background-color: rgba(20, 121, 255, 0.15);
position: absolute;
top: calc(50% - 110rpx);
left: calc(50% - 110rpx);
}
.text-class {
height: 46rpx;
font-size: 32rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #FFFFFF;
line-height: 46rpx;
}
.text1 {
@extend .text-class;
}
.text2 {
@extend .text-class;
}
}
}
.clock-info {
width: 650rpx;
font-size: 28rpx;
font-family: PingFang-SC-Medium, PingFang-SC;
font-weight: 500;
color: #36596A;
line-height: 40rpx;
margin: 46rpx auto;
}
3 years ago
3 years ago
.u-order-address {
color: rgb(140, 140, 140);
font-size: 25rpx;
}
3 years ago
::v-deep .u-checkbox__icon-wrap--disabled--checked text {
3 years ago
color: #1d5cba !important;
3 years ago
}
</style>