Files
wxapp_escort/pages/escort/recorddetail.js
2026-06-04 09:14:50 +08:00

397 lines
12 KiB
JavaScript

const API = require('../../utils/api.js')
const STATUS_MAP = {
pending: { text: '待确认', color: '#F59E0B', bg: '#FEF3C7', gradient: 'linear-gradient(135deg, #F59E0B 0%, #D97706 100%)', icon: 'time', desc: '您的订单已提交,等待确认中' },
confirmed: { text: '已确认', color: '#3B82F6', bg: '#DBEAFE', gradient: 'linear-gradient(135deg, #3B82F6 0%, #2563EB 100%)', icon: 'check-circle', desc: '订单已确认,陪诊员将准时为您服务' },
in_progress: { text: '进行中', color: '#8B5CF6', bg: '#EDE9FE', gradient: 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)', icon: 'play-circle', desc: '陪诊服务正在进行中' },
completed: { text: '已完成', color: '#10B981', bg: '#D1FAE5', gradient: 'linear-gradient(135deg, #10B981 0%, #059669 100%)', icon: 'check-circle-filled', desc: '陪诊服务已完成,感谢您的使用' },
cancelled: { text: '已取消', color: '#6B7280', bg: '#F3F4F6', gradient: 'linear-gradient(135deg, #9CA3AF 0%, #6B7280 100%)', icon: 'close-circle', desc: '该订单已取消' }
}
const PAYMENT_STATUS_MAP = {
unpaid: { text: '未支付', color: '#F59E0B', bg: '#FEF3C7' },
partial: { text: '部分支付', color: '#F59E0B', bg: '#FEF3C7' },
paid: { text: '已支付', color: '#10B981', bg: '#D1FAE5' },
refunded: { text: '已退款', color: '#6B7280', bg: '#F3F4F6' }
}
const SEX_MAP = {
male: '男',
female: '女'
}
const ATTENDANT_SEX_MAP = {
none: '不限',
male: '男',
female: '女'
}
Page({
data: {
recordId: '',
record: {},
loading: true,
editing: false,
editPatientNote: '',
editingPatient: false,
editPatient: {},
showCancelPopup: false,
cancelReason: '',
cancelReasons: [
'临时有事,无法前往',
'病情好转,无需陪诊',
'医院停诊/改期',
'陪诊员无法到达',
'其他原因'
]
},
onLoad(options) {
const id = options.id
if (!id) {
wx.showToast({ title: '参数错误', icon: 'none' })
setTimeout(() => wx.navigateBack(), 1500)
return
}
this.setData({ recordId: id })
this.loadRecord(id)
},
onShow() {
if (this.data.recordId) {
this.loadRecord(this.data.recordId)
}
},
onPullDownRefresh() {
if (this.data.recordId) {
this.loadRecord(this.data.recordId).finally(() => {
wx.stopPullDownRefresh()
})
}
},
loadRecord(id) {
this.setData({ loading: true })
return API.escort.getRecordById(id)
.then((res) => {
if (res.code === 0 && res.data) {
const record = this.formatRecord(res.data.record)
this.setData({ record })
} else {
wx.showToast({ title: res.msg || '加载失败', icon: 'none' })
}
})
.catch(() => {
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
.finally(() => {
this.setData({ loading: false })
})
},
formatRecord(item) {
const statusInfo = STATUS_MAP[item.status] || STATUS_MAP.pending
const paymentInfo = PAYMENT_STATUS_MAP[item.payment?.status] || PAYMENT_STATUS_MAP.unpaid
return {
_id: item._id,
patientName: item.patient?.name || '',
patientSexText: SEX_MAP[item.patient?.sex] || '',
patientAge: item.patient?.age || 0,
patientWeight: item.patient?.weight || 0,
patientHeight: item.patient?.height || 0,
patientMobile: item.patient?.mobile || '',
patientIdnumber: item.patient?.idnumber || '',
hospitalProvince: item.hospital?.province || '',
hospitalName: item.hospital?.name || '',
hospitalAddress: item.hospital?.address || '',
hospitalDepartment: item.hospital?.department || '',
hospitalDoctor: item.hospital?.doctor || '',
medicalRecordNo: item.hospital?.medicalRecordNo || '',
scheduleDate: item.schedule?.date ? this.formatDate(item.schedule.date) : '',
scheduleStartTime: item.schedule?.startTime || '',
scheduleEndTime: item.schedule?.endTime || '',
scheduleDuration: item.schedule?.duration || 0,
escortServiceName: item.escort?.serviceName || '',
attendantName: item.attendant?.name || '',
attendantSexText: ATTENDANT_SEX_MAP[item.escort?.sexRequirement] || '',
totalFee: (item.payment?.totalFee || 0).toFixed(2),
paidFee: (item.payment?.paidFee || 0).toFixed(2),
paymentStatus: item.payment?.status || 'unpaid',
paymentStatusText: paymentInfo.text,
paymentStatusColor: paymentInfo.color,
paymentStatusBg: paymentInfo.bg,
patientNote: item.notes?.patientNote || '',
escortNote: item.notes?.escortNote || '',
medicalSummary: item.notes?.medicalSummary || '',
status: item.status,
statusText: statusInfo.text,
statusColor: statusInfo.color,
statusBg: statusInfo.bg,
statusGradient: statusInfo.gradient,
statusIcon: statusInfo.icon,
statusDesc: statusInfo.desc,
createTime: item.meta?.createtime ? this.formatDateTime(item.meta.createtime) : '',
updateTime: item.meta?.updatetime ? this.formatDateTime(item.meta.updatetime) : ''
}
},
formatDate(dateStr) {
const d = new Date(dateStr)
const year = d.getFullYear()
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
},
formatDateTime(dateStr) {
const d = new Date(dateStr)
const year = d.getFullYear()
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
const hour = String(d.getHours()).padStart(2, '0')
const minute = String(d.getMinutes()).padStart(2, '0')
return `${year}-${month}-${day} ${hour}:${minute}`
},
onCallPatient() {
const mobile = this.data.record.patientMobile
if (!mobile || mobile === '--') return
wx.makePhoneCall({ phoneNumber: mobile })
},
onCallService() {
wx.makePhoneCall({ phoneNumber: '18618162956' })
},
onEditPatientNote() {
this.setData({
editing: true,
editPatientNote: this.data.record.patientNote || ''
})
},
onPatientNoteInput(e) {
this.setData({ editPatientNote: e.detail.value })
},
onCancelEdit() {
this.setData({ editing: false })
},
onSavePatientNote() {
const note = this.data.editPatientNote.trim()
wx.showLoading({ title: '保存中...' })
API.escort.updateRecord(this.data.recordId, {
'notes.patientNote': note
})
.then((res) => {
wx.hideLoading()
if (res.code === 0) {
wx.showToast({ title: '保存成功', icon: 'success' })
this.setData({
editing: false,
'record.patientNote': note
})
} else {
wx.showToast({ title: res.msg || '保存失败', icon: 'none' })
}
})
.catch(() => {
wx.hideLoading()
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
},
onEditPatientInfo() {
const record = this.data.record
this.setData({
editingPatient: true,
editPatient: {
name: record.patientName || '',
sex: record.patientSexText === '男' ? 'male' : record.patientSexText === '女' ? 'female' : '',
age: record.patientAge ? String(record.patientAge) : '',
weight: record.patientWeight ? String(record.patientWeight) : '',
height: record.patientHeight ? String(record.patientHeight) : '',
mobile: record.patientMobile || '',
idnumber: record.patientIdnumber || ''
}
})
},
onPatientInfoInput(e) {
const field = e.currentTarget.dataset.field
const value = e.detail.value
this.setData({
[`editPatient.${field}`]: value
})
},
onPatientSexChange(e) {
const value = e.currentTarget.dataset.value
this.setData({
'editPatient.sex': value
})
},
onCancelEditPatientInfo() {
this.setData({ editingPatient: false })
},
onSavePatientInfo() {
const patient = this.data.editPatient
if (!patient.name.trim()) {
wx.showToast({ title: '请输入姓名', icon: 'none' })
return
}
if (!patient.mobile.trim()) {
wx.showToast({ title: '请输入联系电话', icon: 'none' })
return
}
wx.showLoading({ title: '保存中...' })
API.escort.updateRecord(this.data.recordId, {
'patient.name': patient.name.trim(),
'patient.sex': patient.sex,
'patient.age': parseInt(patient.age) || 0,
'patient.weight': parseFloat(patient.weight) || 0,
'patient.height': parseFloat(patient.height) || 0,
'patient.mobile': patient.mobile.trim(),
'patient.idnumber': patient.idnumber.trim()
})
.then((res) => {
wx.hideLoading()
if (res.code === 0) {
wx.showToast({ title: '保存成功', icon: 'success' })
this.setData({ editingPatient: false })
this.loadRecord(this.data.recordId)
} else {
wx.showToast({ title: res.msg || '保存失败', icon: 'none' })
}
})
.catch(() => {
wx.hideLoading()
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
},
onCancelOrder() {
this.setData({
showCancelPopup: true,
cancelReason: ''
})
},
onCloseCancelPopup() {
this.setData({ showCancelPopup: false })
},
onSelectCancelReason(e) {
this.setData({ cancelReason: e.currentTarget.dataset.reason })
},
onConfirmCancel() {
if (!this.data.cancelReason) {
wx.showToast({ title: '请选择取消原因', icon: 'none' })
return
}
wx.showLoading({ title: '处理中...' })
API.escort.updateStatus(this.data.recordId, {
status: 'cancelled',
reason: this.data.cancelReason
})
.then((res) => {
wx.hideLoading()
if (res.code === 0) {
wx.showToast({ title: '订单已取消', icon: 'success' })
this.setData({ showCancelPopup: false })
this.loadRecord(this.data.recordId)
} else {
wx.showToast({ title: res.msg || '操作失败', icon: 'none' })
}
})
.catch(() => {
wx.hideLoading()
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
},
onPayOrder() {
wx.showToast({ title: '支付功能开发中', icon: 'none' })
},
onConfirmComplete() {
wx.showModal({
title: '确认完成',
content: '确认陪诊服务已完成?',
confirmColor: '#6B8E7B',
success: (res) => {
if (res.confirm) {
wx.showLoading({ title: '处理中...' })
API.escort.updateStatus(this.data.recordId, {
status: 'completed'
})
.then((res) => {
wx.hideLoading()
if (res.code === 0) {
wx.showToast({ title: '已确认完成', icon: 'success' })
this.loadRecord(this.data.recordId)
} else {
wx.showToast({ title: res.msg || '操作失败', icon: 'none' })
}
})
.catch(() => {
wx.hideLoading()
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
}
}
})
},
onDeleteOrder() {
wx.showModal({
title: '删除订单',
content: '确定要删除该订单吗?删除后不可恢复。',
confirmColor: '#EF4444',
success: (res) => {
if (res.confirm) {
wx.showLoading({ title: '删除中...' })
API.escort.deleteRecord(this.data.recordId)
.then((res) => {
wx.hideLoading()
if (res.code === 0) {
wx.showToast({ title: '删除成功', icon: 'success' })
setTimeout(() => {
wx.navigateBack()
}, 1500)
} else {
wx.showToast({ title: res.msg || '删除失败', icon: 'none' })
}
})
.catch(() => {
wx.hideLoading()
wx.showToast({ title: '网络请求失败', icon: 'none' })
})
}
}
})
},
onRebook() {
const serviceId = this.data.record.escortServiceName
wx.navigateTo({
url: `/pages/escort/itemlist`
})
},
onShareAppMessage() {
return {
title: '暖橙陪诊 - 专业陪诊服务',
path: '/pages/home/index'
}
}
})