|
|
<template>
|
|
|
<view style="padding-bottom: 20rpx;">
|
|
|
<cpn-navbar title="护理详情" :isBack="true"></cpn-navbar>
|
|
|
|
|
|
<view>
|
|
|
<!-- 用户信息 -->
|
|
|
<view class="user-info" v-if="detail.customer">
|
|
|
<view class="top">
|
|
|
<view class="left">
|
|
|
<u-image :src="detail.customer.sex === '男' ? vuex_male_img : vuex_female_img" width="104"
|
|
|
height="104" shape="circle"></u-image>
|
|
|
</view>
|
|
|
<view class="center">
|
|
|
<view class="name">{{detail.customer.name}}</view>
|
|
|
<view class="infos">
|
|
|
<view class="age">{{ageComputed(detail.customer.idcard)}}岁
|
|
|
</view>
|
|
|
<view class="sex">{{detail.customer.sex}}</view>
|
|
|
<view class="organ">机构护理</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="right">
|
|
|
<template v-if="detail.status === 0">
|
|
|
<view class="icon1"></view>
|
|
|
<view>待护理</view>
|
|
|
</template>
|
|
|
<template v-if="detail.status === 1">
|
|
|
<view class="icon3"></view>
|
|
|
<view>护理中</view>
|
|
|
</template>
|
|
|
<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>
|
|
|
<view>委托人:{{detail.customer.contact_name}}</view>
|
|
|
</view>
|
|
|
<view class="address">
|
|
|
<u-icon name="map" width="28" height="28" color="#1479FF"></u-icon>
|
|
|
<view>{{ addressFormat(detail.customer.customer_address) }}</view>
|
|
|
</view>
|
|
|
<view class="phone">
|
|
|
<u-icon name="phone" width="28" height="28" color="#1479FF"></u-icon>
|
|
|
<view>{{detail.customer.phone}}</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="re-location" @click="$u.throttle(refreshLoaction,1000)">
|
|
|
<view class="text">更新定位</view>
|
|
|
<u-image src="/static/detail/distance.png" height="34" width="34"></u-image>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 今日护理 -->
|
|
|
<view class="today-nursing" v-show="detail.status !== 0">
|
|
|
<view class="title">
|
|
|
今日护理
|
|
|
</view>
|
|
|
|
|
|
<view class="line"></view>
|
|
|
<view class="table-title">
|
|
|
<view>护理明细</view>
|
|
|
<view>实际时长</view>
|
|
|
</view>
|
|
|
<view class="content">
|
|
|
<u-checkbox-group :max="(detail.product.demand === 1) ? 1 : 999">
|
|
|
<view class="content-item" v-if="skuList.length > 1" v-for="(item,index) in skuList" :key='item.info.id'>
|
|
|
<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)">
|
|
|
{{item.info.name}}
|
|
|
</u-checkbox>
|
|
|
<view class="input">
|
|
|
<u-input :disabled="detail.status === 2 || !item.isSelect || (detail.product.demand === 1)" 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">
|
|
|
</u-input>
|
|
|
<view style="font-size: 34rpx;">分钟</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
<view class="content-item" v-else v-for="(item,index) in skuList" :key='item.info.id'>
|
|
|
<view style="width: 210rpx;text-align: center;font-weight: bold;color: #333;">{{ item.info.name }}</view>
|
|
|
<view style="width: 220rpx;text-align: center;font-weight: bold;color: #333;">
|
|
|
{{item.info.time_lenth}}分钟
|
|
|
</view>
|
|
|
</view>
|
|
|
</u-checkbox-group>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 打卡 -->
|
|
|
<view class="clock">
|
|
|
<view class="btn" v-if="detail.status === 1 && detail.logs_count < detail.product.process_total"
|
|
|
@click="$u.throttle(clockIn,5000)">
|
|
|
<view class="text1">过程打卡</view>
|
|
|
<view class="text2">({{detail.logs_count + 1}})</view>
|
|
|
</view>
|
|
|
<view class="btn" v-if="detail.status === 0 && flag" @click="$u.throttle(sign,5000)">
|
|
|
<view class="text1">签到</view>
|
|
|
<view class="text2">{{dateFormat(time,'HH:mm:ss')}}</view>
|
|
|
</view>
|
|
|
<view class="btn" v-if="detail.status === 1" @click="$u.throttle(checkSignOut,5000)">
|
|
|
<view class="text1">签退</view>
|
|
|
<view class="text2">{{serviceTime}}</view>
|
|
|
</view>
|
|
|
<view class="btn" v-if="detail.status === 0 && !flag" @click="$u.throttle(refreshLoaction,3000)">
|
|
|
<view class="text1">更新定位</view>
|
|
|
<view class="text2">{{dateFormat(time,'HH:mm:ss')}}</view>
|
|
|
</view>
|
|
|
<view class="btn" v-if="detail.status === 2">
|
|
|
<view class="text1">护理已完成</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 打卡信息 -->
|
|
|
<view class="clock-info" v-if="location.lat && location.lng && location.time">
|
|
|
定位时间:{{dateFormat(location.time,'HH:mm:ss')}} {{location.address}}
|
|
|
</view>
|
|
|
|
|
|
<!-- 打卡记录 -->
|
|
|
<view class="logs" v-if="detail.logs && detail.logs.length > 0">
|
|
|
<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>
|
|
|
<view class="u-order-address">{{item.address}}</view>
|
|
|
<view v-for="(img,tindex) in item.upload_list" :key='tindex' @click="showimg(img)">
|
|
|
<u-image width="100%" v-if='img.upload' height='400rpx' :src="img.upload.url">
|
|
|
</u-image>
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
</u-time-line-item>
|
|
|
</u-time-line>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<u-modal v-model="isShowModal" :show-cancel-button="isSignOutConfirm" :content="tips" @confirm="modalConfirm">
|
|
|
</u-modal>
|
|
|
|
|
|
<imgUpload ref="imgUpload" :isShow.sync="isShowImg" :type="type" @confirm="clock"></imgUpload>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import {
|
|
|
ROOTPATH
|
|
|
} from '@/common/config.js'
|
|
|
import QQMapWX from '@/libs/qqmap-wx-jssdk.js'
|
|
|
import moment from '@/libs/moment.min.js'
|
|
|
import {
|
|
|
getAgeByIdcard
|
|
|
} from '@/common/util.js'
|
|
|
|
|
|
import imgUpload from './components/imgUpload.vue'
|
|
|
export default {
|
|
|
components: {
|
|
|
imgUpload
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
isSubmitConfirm: false,
|
|
|
tips: "",
|
|
|
isSignOutConfirm: false,
|
|
|
isShowModal: false, //是否超过时间确认
|
|
|
type: 0, //打卡类型,1签到 2过程打卡 3签退
|
|
|
isShowImg: false,
|
|
|
id: '',
|
|
|
flag: false, //未开始护理时,是否更新过定位(真为更新过定位)
|
|
|
qqmapsdk: null,
|
|
|
inputStyle: {
|
|
|
fontSize: "34rpx",
|
|
|
color: "#36596A",
|
|
|
width: "140rpx",
|
|
|
background: "#F9F9F9"
|
|
|
},
|
|
|
btnStyle: {
|
|
|
width: '100rpx',
|
|
|
height: '100rpx',
|
|
|
borderRadius: '100%',
|
|
|
background: 'blue'
|
|
|
},
|
|
|
location: {
|
|
|
lng: '',
|
|
|
lat: '',
|
|
|
time: '',
|
|
|
address: ''
|
|
|
},
|
|
|
form: {
|
|
|
schedule_list_id: '',
|
|
|
lat: '',
|
|
|
lng: '',
|
|
|
address: '',
|
|
|
type: '',
|
|
|
upload_list: [],
|
|
|
},
|
|
|
skuList: [],
|
|
|
detail: {},
|
|
|
time: new Date(),
|
|
|
timer: null,
|
|
|
|
|
|
serviceTimer: null,//计时器用来跟新总服务时长
|
|
|
serviceTimeFlag: 0,
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
modalConfirm () {
|
|
|
this.isShowModal = false
|
|
|
|
|
|
|
|
|
if (this.isSignOutConfirm) {
|
|
|
this.signOut()
|
|
|
}
|
|
|
},
|
|
|
|
|
|
showimg(img) {
|
|
|
if (img.upload)
|
|
|
this.$showimg({
|
|
|
imgs: [img.upload.url],
|
|
|
current: 0
|
|
|
})
|
|
|
},
|
|
|
load() {
|
|
|
this.qqmapsdk = new QQMapWX({
|
|
|
key: 'D5EBZ-C3BWP-HZIDG-VO6BE-P2MN5-ESFZO'
|
|
|
});
|
|
|
},
|
|
|
|
|
|
selectPick(e, item) {
|
|
|
if (e.value) {
|
|
|
if (!item.form.time) {
|
|
|
item.form.time = item.info.time_lenth
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
async getDeatil(id) {
|
|
|
let res = await this.$u.api.nurseDetail({
|
|
|
id
|
|
|
})
|
|
|
this.detail = res
|
|
|
this.skuList = []
|
|
|
res.sku.forEach(item => {
|
|
|
if (item.sku_id && item.sku_info) {
|
|
|
this.skuList.push({
|
|
|
info: item.sku_info,
|
|
|
isSelect: (item.time || res.sku.length === 1),
|
|
|
form: {
|
|
|
id: item.id,
|
|
|
time: res.sku.length === 1 ? (item.sku_info.time_lenth) : (item.time || ''),
|
|
|
sku_id: item.sku_id,
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
this.form.schedule_list_id = this.id
|
|
|
if (res.status === 1) {
|
|
|
this.serviceTimer = setInterval(() => {
|
|
|
this.serviceTimeFlag++;
|
|
|
},1000)
|
|
|
}
|
|
|
if (res.status === 3) {
|
|
|
clearInterval(this.serviceTimer)
|
|
|
}
|
|
|
console.log(this.skuList);
|
|
|
},
|
|
|
|
|
|
getMapDistance (location1,location2) {
|
|
|
const [lat1,lng1] = location1;
|
|
|
const [lat2,lng2] = location2;
|
|
|
|
|
|
let radLat1 = lat1*Math.PI / 180.0;
|
|
|
let radLat2 = lat2*Math.PI / 180.0;
|
|
|
let a = radLat1 - radLat2;
|
|
|
let b = lng1*Math.PI / 180.0 - lng2*Math.PI / 180.0;
|
|
|
let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
|
|
|
Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
|
|
|
s = s *6378.137 ;// EARTH_RADIUS;
|
|
|
s = Math.round(s * 10000) / 10000;
|
|
|
|
|
|
s = s * 1000
|
|
|
|
|
|
if (isNaN(s)) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return Math.floor(s/1000 * 100) / 100;
|
|
|
},
|
|
|
|
|
|
//获取当前定位信息
|
|
|
getLoaction() {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
uni.getLocation({
|
|
|
type: 'gcj02',
|
|
|
isHighAccuracy: true
|
|
|
}).then(res => {
|
|
|
console.log(res)
|
|
|
if (res[1]) {
|
|
|
this.location.lat = res[1]?.latitude
|
|
|
this.location.lng = res[1]?.longitude
|
|
|
this.location.time = this.time
|
|
|
this.form.lat = this.location.lat
|
|
|
this.form.lng = this.location.lng
|
|
|
|
|
|
this.qqmapsdk.reverseGeocoder({
|
|
|
location: {
|
|
|
latitude: this.location.lat,
|
|
|
longitude: this.location.lng
|
|
|
},
|
|
|
success: (res) => {
|
|
|
console.log('mapjs',res);
|
|
|
this.location.address = res.result.address + res.result.formatted_addresses.recommend
|
|
|
this.form.address = this.location.address
|
|
|
resolve(res)
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
reject(err)
|
|
|
}
|
|
|
})
|
|
|
} else {
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: '操作频繁,请稍后再试'
|
|
|
})
|
|
|
reject(res)
|
|
|
console.log(res);
|
|
|
}
|
|
|
|
|
|
})
|
|
|
})
|
|
|
},
|
|
|
|
|
|
//更新地址
|
|
|
refreshLoaction() {
|
|
|
this.getLoaction().then(res => {
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: '更新定位成功'
|
|
|
})
|
|
|
this.flag = true
|
|
|
})
|
|
|
},
|
|
|
|
|
|
//图片批量上传
|
|
|
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}`
|
|
|
},
|
|
|
formData: {
|
|
|
is_water: 1,
|
|
|
address: this.form.address,
|
|
|
coordinate: `${this.form.lng},${this.form.lat}`
|
|
|
},
|
|
|
filePath: item,
|
|
|
name: 'file',
|
|
|
success: (res1) => {
|
|
|
resolve(res1)
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
reject(err)
|
|
|
}
|
|
|
})
|
|
|
})
|
|
|
})
|
|
|
|
|
|
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)
|
|
|
// }
|
|
|
|
|
|
},
|
|
|
|
|
|
//打卡
|
|
|
clock(files, type) {
|
|
|
if (this.isSubmitConfirm) {
|
|
|
return
|
|
|
}
|
|
|
if (!this.form.lat || !this.form.lng) {
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: '请重新获取定位信息'
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
let title;
|
|
|
switch (type) {
|
|
|
case 1:
|
|
|
title = '签到成功'
|
|
|
break;
|
|
|
case 2:
|
|
|
title = `第${this.detail.logs_count+1}次打卡成功`
|
|
|
break;
|
|
|
case 3:
|
|
|
title = '签退成功'
|
|
|
break;
|
|
|
default:
|
|
|
title = '操作成功'
|
|
|
}
|
|
|
this.isSubmitConfirm = true
|
|
|
this.uploadImgs(files).then(res => {
|
|
|
this.form.upload_list = res.map(item => {
|
|
|
return {
|
|
|
upload_id: JSON.parse(item.data).id
|
|
|
}
|
|
|
})
|
|
|
this.form.type = type
|
|
|
this.$u.api.processSave(this.form).then(res1 => {
|
|
|
this.isSubmitConfirm = false
|
|
|
uni.showToast({
|
|
|
icon: 'success',
|
|
|
title
|
|
|
})
|
|
|
this.$refs['imgUpload'].clearList()
|
|
|
this.isShowImg = false
|
|
|
this.getDeatil(this.id)
|
|
|
|
|
|
if(res1.tip){
|
|
|
this.tips = "用户服务次数已达到次数、总服务时长未满"
|
|
|
this.isShowModal = true
|
|
|
}
|
|
|
}).catch(err => this.isSubmitConfirm = false)
|
|
|
}).catch(err => this.isSubmitConfirm = false)
|
|
|
},
|
|
|
|
|
|
//保存服务项目
|
|
|
saveSku() {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
let temp1 = this.skuList.filter(item => {
|
|
|
return item.isSelect
|
|
|
})
|
|
|
|
|
|
let temp2 = temp1.map(item => {
|
|
|
return item.form
|
|
|
})
|
|
|
|
|
|
this.$u.api.nurseSave({
|
|
|
id: this.id,
|
|
|
sku_time_list: temp2
|
|
|
}).then(res => {
|
|
|
resolve(res)
|
|
|
}).catch(err => {
|
|
|
reject(err)
|
|
|
})
|
|
|
})
|
|
|
},
|
|
|
|
|
|
//签到
|
|
|
sign() {
|
|
|
this.type = 1
|
|
|
this.isShowImg = true
|
|
|
//this.clock(1)
|
|
|
},
|
|
|
|
|
|
//过程打卡
|
|
|
clockIn() {
|
|
|
//验证是否有选择服务项目并填写
|
|
|
// 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
|
|
|
// }
|
|
|
|
|
|
// this.saveSku().then(res => {
|
|
|
// this.type = 2
|
|
|
// this.isShowImg = true
|
|
|
// }).catch(err => {
|
|
|
// console.log(err);
|
|
|
// uni.showToast({
|
|
|
// icon: 'none',
|
|
|
// title: '请重试'
|
|
|
// })
|
|
|
// })
|
|
|
this.type = 2
|
|
|
this.isShowImg = true
|
|
|
},
|
|
|
|
|
|
//签退前检查
|
|
|
checkSignOut() {
|
|
|
//验证打卡次数是否已满
|
|
|
if (this.detail.logs_count < this.detail.product.process_total) {
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: `请先完成${this.detail.product.process_total}次打卡,再签退。当前完成打卡次数${this.detail.logs_count}`
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
//验证是否有选择服务项目并填写
|
|
|
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
|
|
|
}
|
|
|
//判断时间是否超出
|
|
|
let useTotalTime = 0
|
|
|
for (let i of this.skuList) {
|
|
|
if (i.isSelect && i.form.time) {
|
|
|
useTotalTime += Number(i.form.time)
|
|
|
}
|
|
|
}
|
|
|
let totalTime = this.$moment(new Date()).diff(this.$moment(this.detail.sign_in), 'minutes')
|
|
|
if (useTotalTime <= (totalTime + 10) && useTotalTime > totalTime && this.detail.demand === 2) {
|
|
|
uni.showToast({
|
|
|
icon:'none',
|
|
|
title:'请下次补足时间',
|
|
|
duration:2000
|
|
|
})
|
|
|
} else if (useTotalTime <= totalTime){
|
|
|
} else {
|
|
|
this.tips="当前勾选的时间为"+useTotalTime+"分钟,实际服务时间为"+totalTime+"分钟。系统要求实际服务时间要大于您勾选的时间。";
|
|
|
this.isShowModal = true
|
|
|
return
|
|
|
}
|
|
|
uni.getLocation({
|
|
|
type: 'gcj02',
|
|
|
isHighAccuracy: true
|
|
|
}).then(res => {
|
|
|
if (res[1]) {
|
|
|
//距离
|
|
|
const distance = this.getMapDistance([res[1].latitude,res[1].longitude],this.detail.sign_in_loc.split(","))
|
|
|
console.log('distance',distance)
|
|
|
if (distance && this.detail.product?.product_type?.max_distance && distance > this.detail.product.product_type.max_distance) {
|
|
|
this.isSignOutConfirm = true
|
|
|
this.tips = `当前签退位置距离签到位置超过${this.detail.product.product_type.max_distance}公里,确认要继续签退吗?`
|
|
|
this.isShowModal = true
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
this.signOut()
|
|
|
}
|
|
|
this.isSignOutConfirm = false
|
|
|
})
|
|
|
},
|
|
|
//签退
|
|
|
signOut() {
|
|
|
this.saveSku().then(() => {
|
|
|
this.type = 3
|
|
|
this.isShowImg = true
|
|
|
}).catch(err => {
|
|
|
console.log(err);
|
|
|
uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: '请重试'
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
ageComputed() {
|
|
|
return function(idcard) {
|
|
|
return getAgeByIdcard(idcard)
|
|
|
}
|
|
|
},
|
|
|
addressFormat() {
|
|
|
return function(addresses) {
|
|
|
return addresses.filter(item => {
|
|
|
item.default === 1
|
|
|
})[0]?.address || addresses[0]?.address || '无'
|
|
|
}
|
|
|
},
|
|
|
dateFormat() {
|
|
|
return function(date, fmt = "YYYY-MM-DD") {
|
|
|
if (date) {
|
|
|
return moment(date).format(fmt)
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
serviceTime () {
|
|
|
let flag = this.serviceTimeFlag;
|
|
|
let totalSec = 0;
|
|
|
if (this.detail.sign_out) {
|
|
|
totalSec = moment(this.detail.sign_out).diff(moment(this.detail.sign_in),"seconds")
|
|
|
} else {
|
|
|
totalSec = moment().diff(moment(this.detail.sign_in),"seconds")
|
|
|
}
|
|
|
let sec = totalSec % 60
|
|
|
let min = ((totalSec - sec) / 60) % 60
|
|
|
let hour = (totalSec - sec - (min * 60)) / 60 / 60
|
|
|
|
|
|
return `${hour > 0 ? (hour + '时') : ''}${min > 0 ? (min + '分') : ''}${sec}秒`
|
|
|
},
|
|
|
typeFormat() {
|
|
|
return function(type) {
|
|
|
let map = new Map([
|
|
|
[1, "签到"],
|
|
|
[2, "过程打卡"],
|
|
|
[3, "签退"],
|
|
|
[4, "更新定位"]
|
|
|
])
|
|
|
return map.get(type) || ''
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
onLoad(option) {
|
|
|
this.getDeatil(option.id)
|
|
|
this.id = option.id
|
|
|
|
|
|
},
|
|
|
onShow() {
|
|
|
this.timer = setInterval(() => {
|
|
|
this.time = new Date()
|
|
|
}, 1000)
|
|
|
},
|
|
|
onHide() {
|
|
|
clearInterval(this.timer)
|
|
|
},
|
|
|
mounted() {
|
|
|
this.load()
|
|
|
this.getLoaction()
|
|
|
}
|
|
|
}
|
|
|
</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;
|
|
|
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-weight: 500;
|
|
|
color: #333333;
|
|
|
line-height: 24rpx;
|
|
|
}
|
|
|
|
|
|
.infos {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
padding-top: 20rpx;
|
|
|
|
|
|
.age {
|
|
|
height: 34rpx;
|
|
|
font-size: 24rpx;
|
|
|
font-weight: 500;
|
|
|
color: #A7AFBC;
|
|
|
line-height: 34rpx;
|
|
|
}
|
|
|
|
|
|
.sex {
|
|
|
width: 40rpx;
|
|
|
height: 40rpx;
|
|
|
background: #FDECEC;
|
|
|
opacity: 0.5;
|
|
|
font-size: 28rpx;
|
|
|
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-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;
|
|
|
position: relative;
|
|
|
|
|
|
.bottom-item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
font-size: 28rpx;
|
|
|
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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.re-location {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
position: absolute;
|
|
|
bottom: 36rpx;
|
|
|
right: 20rpx;
|
|
|
|
|
|
.text {
|
|
|
height: 34rpx;
|
|
|
font-size: 24rpx;
|
|
|
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-weight: 500;
|
|
|
color: #333333;
|
|
|
|
|
|
|
|
|
padding: 24rpx 20rpx;
|
|
|
}
|
|
|
|
|
|
.line {
|
|
|
width: 670rpx;
|
|
|
height: 2rpx;
|
|
|
border: 2rpx solid #EEEFF5;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
}
|
|
|
|
|
|
.table-title {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
|
|
|
&>view {
|
|
|
text-align: center;
|
|
|
width: 260rpx;
|
|
|
|
|
|
padding-top: 24rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.content {
|
|
|
|
|
|
padding: 14rpx 20rpx 24rpx 20rpx;
|
|
|
|
|
|
.content-item {
|
|
|
height: 70rpx;
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
.input {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
&>view {
|
|
|
height: 40rpx;
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 500;
|
|
|
color: #36596A;
|
|
|
line-height: 40rpx;
|
|
|
|
|
|
padding-left: 20rpx;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.logs {
|
|
|
@extend .today-nursing;
|
|
|
|
|
|
&-content {
|
|
|
|
|
|
padding: 24rpx 32rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.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-weight: 500;
|
|
|
color: #FFFFFF;
|
|
|
line-height: 46rpx;
|
|
|
}
|
|
|
|
|
|
.text1 {
|
|
|
@extend .text-class;
|
|
|
}
|
|
|
|
|
|
.text2 {
|
|
|
font-size: 30rpx;
|
|
|
@extend .text-class;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.clock-info {
|
|
|
width: 650rpx;
|
|
|
font-size: 28rpx;
|
|
|
font-weight: 500;
|
|
|
color: #36596A;
|
|
|
line-height: 40rpx;
|
|
|
|
|
|
margin: 46rpx auto;
|
|
|
}
|
|
|
|
|
|
.u-order-address {
|
|
|
color: rgb(140, 140, 140);
|
|
|
font-size: 25rpx;
|
|
|
}
|
|
|
|
|
|
::v-deep .u-checkbox__icon-wrap--disabled--checked text {
|
|
|
color: #1d5cba !important;
|
|
|
}
|
|
|
</style>
|