import type { DeliveryAbnormalReportType, DeliveryDashboardType, DeliveryExceptionPayloadType, DeliveryInfoType, DeliveryLocationType, DeliveryOnlineStatus, DeliveryOrderStatus, DeliveryOrderType, DeliveryRecordType, DeliveryServiceItemType, DeliveryServiceRecordType, DeliveryStatusLogType, DeliveryTimelineItemType } from '@/types/delivery.uts' const PROFILE_KEY = 'delivery_care_profile' const ORDER_KEY = 'delivery_care_orders' function nowText(): string { return new Date().toISOString().replace('T', ' ').substring(0, 19) } function cloneProfile(profile: DeliveryInfoType): DeliveryInfoType { return JSON.parse(JSON.stringify(profile)) as DeliveryInfoType } function cloneOrder(order: DeliveryOrderType): DeliveryOrderType { return JSON.parse(JSON.stringify(order)) as DeliveryOrderType } function cloneOrders(orders: Array): Array { return JSON.parse(JSON.stringify(orders)) as Array } function createStatusText(status: DeliveryOrderStatus): string { if (status == 'pending_assignment' || status == 'pending_accept') return '待接单' if (status == 'accepted') return '已接单' if (status == 'waiting_departure') return '待出发' if (status == 'departed' || status == 'on_the_way') return '已出发' if (status == 'arrived') return '已到达' if (status == 'checked_in') return '已签到' if (status == 'in_service' || status == 'serving') return '服务中' if (status == 'pending_confirm' || status == 'pending_acceptance' || status == 'pending_submit') return '待确认' if (status == 'completed') return '已完成' if (status == 'rejected') return '已拒单' if (status == 'cancelled') return '已取消' if (status == 'abnormal' || status == 'exception_pending') return '异常上报' if (status == 'terminated') return '服务终止' return '已归档' } function createStatusTone(status: DeliveryOrderStatus): string { if (status == 'pending_assignment' || status == 'pending_accept' || status == 'pending_confirm' || status == 'pending_acceptance' || status == 'pending_submit') return 'warning' if (status == 'completed') return 'success' if (status == 'rejected' || status == 'cancelled' || status == 'terminated') return 'neutral' if (status == 'abnormal' || status == 'exception_pending') return 'danger' return 'primary' } function createStatusLog(orderId: string, fromStatus: DeliveryOrderStatus, toStatus: DeliveryOrderStatus, remark: string): DeliveryStatusLogType { return { id: orderId + '-log-' + nowText().replace(/[-: ]/g, ''), orderId, fromStatus, toStatus, operatorRole: 'service_staff', operatorId: 'mock-staff-001', remark, createdAt: nowText() } as DeliveryStatusLogType } function createTimeline(title: string, description: string): DeliveryTimelineItemType { return { id: 'timeline-' + nowText().replace(/[-: ]/g, ''), title, time: nowText(), description } as DeliveryTimelineItemType } function createServiceItems(orderId: string): Array { return [ { id: orderId + '-item-1', name: '生命体征监测', required: true, completed: false, incompleteReason: '', remark: '', updatedAt: '' } as DeliveryServiceItemType, { id: orderId + '-item-2', name: '基础照护服务', required: true, completed: false, incompleteReason: '', remark: '', updatedAt: '' } as DeliveryServiceItemType, { id: orderId + '-item-3', name: '家属沟通与宣教', required: false, completed: false, incompleteReason: '', remark: '', updatedAt: '' } as DeliveryServiceItemType ] } function createProfile(): DeliveryInfoType { return { id: 'mock-staff-001', userId: 'mock-delivery-user-001', staffNo: 'CARE-202605-001', name: '陈护理', phone: '13600001111', role: 'care_worker', status: 'active', organizationId: 'org-care-001', organizationName: '梅江区居家康护中心', certificates: [] as Array, certificateStatus: 'valid', certificateExpireAt: '2027-12-31', onlineStatus: 'online', serviceArea: '梅江区 / 梅县区', skills: ['上门助浴', '康复陪护', '慢病随访', '居家照护'], avatarUrl: '', todayAccepted: 2, todayServing: 1, todayCompleted: 1, usesMock: true } as DeliveryInfoType } function createOrder( orderId: string, serviceName: string, serviceType: string, status: DeliveryOrderStatus, appointmentTime: string, duration: number, price: number, staffIncome: number, elderName: string, elderGender: string, elderAge: number, elderPhone: string, contactName: string, contactPhone: string, contactRelation: string, address: string, addressDetail: string, distance: string, riskTags: Array, healthTags: Array, needFamilyPresent: boolean, needMaterials: boolean, remark: string ): DeliveryOrderType { const statusText = createStatusText(status) const items = createServiceItems(orderId) return { id: orderId, orderNo: 'CARE-' + orderId.toUpperCase(), serviceType, serviceName, serviceCategory: serviceType, serviceItems: items, serviceContentOptions: ['基础护理', '生命体征监测', '安全巡视', '家属沟通'], elderId: 'elder-' + orderId, elderName, elderNameMasked: elderName.substring(0, 1) + '**', elderGender, elderAge, elderPhone, elderPhoneMasked: elderPhone.substring(0, 3) + '****' + elderPhone.substring(elderPhone.length - 4), fullElderName: elderName, fullPhone: elderPhone, contactName, contactPhone, contactRelation, addressSummary: address, address, addressDetail, fullAddress: address + ' ' + addressDetail, latitude: 24.2898, longitude: 116.1179, appointmentTime, appointmentStartTime: appointmentTime, appointmentEndTime: appointmentTime, duration, estimatedDuration: duration, price, staffIncome, distance, actualStartTime: '', actualEndTime: '', status, statusText, statusTone: createStatusTone(status), riskTags, healthTags, careLevel: '护理二级', needFamilyPresent, needMaterials, remark, merchantId: 'merchant-care-001', merchantName: '梅江区居家康护中心', deliveryStaffId: 'mock-staff-001', deliveryStaffName: '陈护理', acceptTime: '', rejectTime: '', departTime: '', arriveTime: '', checkinTime: '', startServiceTime: '', finishTime: '', cancelReason: '', exceptionType: '', exceptionDesc: '', evidenceList: [] as Array, signatureUrl: '', signatureName: '', satisfactionStatus: '待确认', settlementStatus: '待结算', archiveStatus: '未归档', createdAt: nowText(), updatedAt: nowText(), notices: ['请提前 15 分钟电话联系', '如遇突发异常先上报再处置'], timeline: [createTimeline('订单已生成', '平台已生成上门服务订单')], statusLog: [createStatusLog(orderId, status, status, '初始化 mock 订单')], serviceSummary: '', progressNote: '', distanceKm: distance, allowCheckinRadiusMeters: 120, lastLocation: null, trackPoints: [] as Array, serviceRecord: null, abnormalReport: null } as DeliveryOrderType } function createDefaultOrders(): Array { const orders = [ createOrder('mock-care-001', '上门助浴', '生活照护', 'pending_assignment', '2026-05-20 09:00', 90, 199, 128, '李秀珍', '女', 79, '13800131024', '李晓兰', '13900139000', '女儿', '梅江区江南路 18 号', '2 栋 602 室', '2.4km', ['高龄', '行动不便'], ['高血压'], true, true, '请准备防滑垫和浴后保暖衣物'), createOrder('mock-care-002', '康复陪护', '康复护理', 'pending_assignment', '2026-05-20 10:30', 120, 260, 160, '张志坤', '男', 83, '13700132233', '张春梅', '13600136666', '女儿', '梅县区新城锦绣花园 5 栋', '1403 室', '5.8km', ['需家属在场'], ['术后恢复'], true, true, '需携带弹力带与康复手册'), createOrder('mock-care-003', '陪诊服务', '陪诊陪护', 'accepted', '2026-05-20 13:00', 180, 320, 220, '黄玉英', '女', 76, '13500135566', '黄晓娟', '13500130088', '女儿', '梅江区学海路康养公寓 A 座', '907 室', '1.1km', ['高龄'], ['糖尿病'], false, false, '就诊前需先核对病历资料'), createOrder('mock-care-004', '慢病随访', '健康管理', 'departed', '2026-05-20 14:30', 60, 168, 108, '陈国辉', '男', 81, '13900133301', '陈丽芳', '13800136660', '妻子', '梅县区扶老社区 11 栋', '203 室', '3.6km', ['行动不便'], ['高血压', '冠心病'], false, true, '重点测量血压并复核药盒'), createOrder('mock-care-005', '居家照护', '长期照护', 'in_service', '2026-05-20 15:00', 120, 288, 190, '王月兰', '女', 87, '13400137744', '王秀玲', '13600139922', '女儿', '梅江区东汇城旁康颐楼 3 单元', '1204 室', '4.2km', ['失能', '需家属在场'], ['血糖异常'], true, true, '服务中注意翻身护理与进食观察'), createOrder('mock-care-006', '上门护理', '护理服务', 'completed', '2026-05-19 16:00', 90, 230, 150, '刘建华', '男', 72, '13300136655', '刘敏', '13300998877', '儿子', '梅江区和顺苑 9 栋', '401 室', '6.0km', ['术后恢复'], ['低蛋白'], false, false, '完成换药与术后宣教') ] orders[2].acceptTime = '2026-05-20 11:40:00' orders[2].timeline.unshift(createTimeline('已接单', '服务人员已确认接单')) orders[2].statusLog.unshift(createStatusLog(orders[2].id, 'pending_assignment', 'accepted', '手动接单')) orders[3].acceptTime = '2026-05-20 12:00:00' orders[3].departTime = '2026-05-20 13:58:00' orders[3].timeline.unshift(createTimeline('已出发', '服务人员已从机构出发')) orders[3].statusLog.unshift(createStatusLog(orders[3].id, 'accepted', 'departed', '已出发')) orders[4].acceptTime = '2026-05-20 13:00:00' orders[4].departTime = '2026-05-20 14:00:00' orders[4].arriveTime = '2026-05-20 14:40:00' orders[4].checkinTime = '2026-05-20 14:45:00' orders[4].startServiceTime = '2026-05-20 14:50:00' orders[4].actualStartTime = '2026-05-20 14:50:00' orders[4].serviceItems[0].completed = true orders[4].serviceItems[0].remark = '血压 132/82,心率 76 次/分' orders[4].serviceItems[0].updatedAt = '2026-05-20 15:10:00' orders[4].timeline.unshift(createTimeline('开始服务', '已进入服务执行阶段')) orders[4].statusLog.unshift(createStatusLog(orders[4].id, 'checked_in', 'in_service', '开始服务')) orders[5].acceptTime = '2026-05-19 14:30:00' orders[5].departTime = '2026-05-19 15:10:00' orders[5].arriveTime = '2026-05-19 15:48:00' orders[5].checkinTime = '2026-05-19 15:52:00' orders[5].startServiceTime = '2026-05-19 15:55:00' orders[5].finishTime = '2026-05-19 17:18:00' orders[5].actualStartTime = '2026-05-19 15:55:00' orders[5].actualEndTime = '2026-05-19 17:18:00' orders[5].serviceSummary = '已完成换药、伤口巡视和家属宣教。' orders[5].serviceRecord = { id: 'record-' + orders[5].id, orderId: orders[5].id, startTime: '2026-05-19 15:55:00', endTime: '2026-05-19 17:18:00', actualDurationMinutes: 83, serviceItems: orders[5].serviceItems, serviceContent: ['换药护理', '伤口观察', '家属宣教'], processNote: '服务过程平稳,老人配合良好。', elderStatus: '精神状态稳定,伤口恢复良好。', healthMetrics: { bloodPressure: '126/80', heartRate: '74', bloodSugar: '', bloodOxygen: '98' }, materialsUsed: '无菌敷料 2 片,棉签 4 支', abnormalNote: '', photos: ['mock-photo-1'], staffRemark: '建议继续保持每日换药。', familyConfirmation: { method: 'sms_code', code: '652318', signatureName: '刘敏', signatureUrl: '', confirmedAt: '2026-05-19 17:20:00' }, createdAt: '2026-05-19 17:18:00', updatedAt: '2026-05-19 17:18:00' } as DeliveryServiceRecordType return orders } function readProfileStore(): DeliveryInfoType { const cached = uni.getStorageSync(PROFILE_KEY) as DeliveryInfoType | null if (cached != null && cached.id != null && cached.id != '') { return cloneProfile(cached) } const created = createProfile() uni.setStorageSync(PROFILE_KEY, cloneProfile(created)) return created } function writeProfileStore(profile: DeliveryInfoType): DeliveryInfoType { uni.setStorageSync(PROFILE_KEY, cloneProfile(profile)) return profile } function readOrderStore(): Array { const cached = uni.getStorageSync(ORDER_KEY) as Array | null if (cached != null && cached.length > 0) { return cloneOrders(cached) } const created = createDefaultOrders() uni.setStorageSync(ORDER_KEY, cloneOrders(created)) return created } function writeOrderStore(orders: Array): Array { uni.setStorageSync(ORDER_KEY, cloneOrders(orders)) return orders } function sortOrdersByAppointment(orders: Array): Array { return orders.sort((left, right) => left.appointmentTime.localeCompare(right.appointmentTime)) } function isPendingStatus(status: DeliveryOrderStatus): boolean { return status == 'pending_assignment' || status == 'pending_accept' } function isHistoryStatus(status: DeliveryOrderStatus): boolean { return status == 'completed' || status == 'rejected' || status == 'cancelled' || status == 'abnormal' || status == 'terminated' || status == 'archived' } function isTodayStatus(status: DeliveryOrderStatus): boolean { return !isPendingStatus(status) && !isHistoryStatus(status) } function refreshOrderMeta(order: DeliveryOrderType): void { order.statusText = createStatusText(order.status) order.statusTone = createStatusTone(order.status) order.updatedAt = nowText() order.distanceKm = order.distance order.fullAddress = order.address + ' ' + order.addressDetail order.fullElderName = order.elderName order.fullPhone = order.elderPhone order.elderNameMasked = order.elderName.substring(0, 1) + '**' order.elderPhoneMasked = order.elderPhone.substring(0, 3) + '****' + order.elderPhone.substring(order.elderPhone.length - 4) order.timeline.unshift(createTimeline(order.statusText, '订单状态已更新为' + order.statusText)) } function findOrderIndex(orders: Array, orderId: string): number { for (let i = 0; i < orders.length; i++) { if (orders[i].id == orderId) { return i } } return -1 } export function getDeliveryCareProfile(): DeliveryInfoType { return readProfileStore() } export function updateDeliveryCareOnlineStatus(status: DeliveryOnlineStatus): DeliveryInfoType { const profile = readProfileStore() profile.onlineStatus = status return cloneProfile(writeProfileStore(profile)) } export function getDeliveryCareDashboard(): DeliveryDashboardType { const profile = readProfileStore() const orders = sortOrdersByAppointment(readOrderStore()) let pendingCount = 0 let todayCount = 0 let pendingDepartCount = 0 let servingCount = 0 let completedCount = 0 let exceptionCount = 0 let expectedIncome = 0 let nextOrder: DeliveryOrderType | null = null const recentOrders: Array = [] for (let i = 0; i < orders.length; i++) { const item = orders[i] if (isPendingStatus(item.status)) { pendingCount += 1 } if (isTodayStatus(item.status) || item.status == 'completed') { todayCount += 1 } if (item.status == 'accepted' || item.status == 'waiting_departure') { pendingDepartCount += 1 } if (item.status == 'in_service' || item.status == 'serving') { servingCount += 1 } if (item.status == 'completed') { completedCount += 1 } if (item.status == 'abnormal' || item.status == 'exception_pending') { exceptionCount += 1 } if (!isHistoryStatus(item.status) && item.status != 'rejected' && item.status != 'cancelled') { expectedIncome += item.staffIncome } if (nextOrder == null && !isHistoryStatus(item.status)) { nextOrder = cloneOrder(item) } if (recentOrders.length < 4) { recentOrders.push(cloneOrder(item)) } } profile.todayAccepted = pendingDepartCount profile.todayServing = servingCount profile.todayCompleted = completedCount writeProfileStore(profile) return { pendingAssignmentCount: pendingCount, pendingAcceptCount: pendingCount, todayOrderCount: todayCount, pendingDepartCount, servingCount, completedCount, exceptionCount, expectedIncome, onlineStatus: profile.onlineStatus, nextOrder, recentOrders } as DeliveryDashboardType } export function getPendingCareOrders(): Array { const orders = sortOrdersByAppointment(readOrderStore()) const result: Array = [] for (let i = 0; i < orders.length; i++) { if (isPendingStatus(orders[i].status)) { result.push(cloneOrder(orders[i])) } } return result } export function getTodayCareOrders(): Array { const orders = sortOrdersByAppointment(readOrderStore()) const result: Array = [] for (let i = 0; i < orders.length; i++) { if (isTodayStatus(orders[i].status)) { result.push(cloneOrder(orders[i])) } } return result } export function getHistoryCareOrders(): Array { const orders = sortOrdersByAppointment(readOrderStore()) const result: Array = [] for (let i = 0; i < orders.length; i++) { if (isHistoryStatus(orders[i].status)) { result.push(cloneOrder(orders[i])) } } return result } export function getCareOrderDetail(orderId: string): DeliveryOrderType | null { const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index < 0) { return null } return cloneOrder(orders[index]) } export function updateCareOrderStatus(orderId: string, nextStatus: DeliveryOrderStatus, remark: string): DeliveryOrderType | null { const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index < 0) { return null } const target = orders[index] const fromStatus = target.status target.status = nextStatus if (nextStatus == 'accepted') { target.acceptTime = nowText() } if (nextStatus == 'rejected') { target.rejectTime = nowText() } if (nextStatus == 'departed') { target.departTime = nowText() } if (nextStatus == 'arrived') { target.arriveTime = nowText() } if (nextStatus == 'checked_in') { target.checkinTime = nowText() } if (nextStatus == 'in_service') { target.startServiceTime = nowText() target.actualStartTime = target.startServiceTime != null ? target.startServiceTime : nowText() } if (nextStatus == 'completed') { target.finishTime = nowText() target.actualEndTime = target.finishTime } target.statusLog.unshift(createStatusLog(orderId, fromStatus, nextStatus, remark)) refreshOrderMeta(target) writeOrderStore(orders) return cloneOrder(target) } export function acceptCareOrder(orderId: string): DeliveryOrderType | null { return updateCareOrderStatus(orderId, 'accepted', '接单成功') } export function rejectCareOrder(orderId: string, reason: string): DeliveryOrderType | null { const order = updateCareOrderStatus(orderId, 'rejected', reason) if (order != null) { const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index >= 0) { orders[index].cancelReason = reason writeOrderStore(orders) return cloneOrder(orders[index]) } } return order } export function markCareOrderDeparted(orderId: string): DeliveryOrderType | null { return updateCareOrderStatus(orderId, 'departed', '服务人员已出发') } export function markCareOrderArrived(orderId: string): DeliveryOrderType | null { return updateCareOrderStatus(orderId, 'arrived', '服务人员已到达') } export function checkInCareOrder(orderId: string, location: DeliveryLocationType | null, note: string): DeliveryOrderType | null { const order = updateCareOrderStatus(orderId, 'checked_in', note != '' ? note : '到达签到') if (order == null) { return null } const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index >= 0) { orders[index].lastLocation = location writeOrderStore(orders) return cloneOrder(orders[index]) } return order } export function startCareService(orderId: string): DeliveryOrderType | null { return updateCareOrderStatus(orderId, 'in_service', '开始服务') } export function submitCareServiceRecord(orderId: string, record: DeliveryServiceRecordType): DeliveryOrderType | null { const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index < 0) { return null } orders[index].serviceRecord = cloneOrder({ ...orders[index], serviceRecord: record } as DeliveryOrderType).serviceRecord orders[index].serviceSummary = record.processNote orders[index].progressNote = record.staffRemark orders[index].serviceItems = record.serviceItems orders[index].status = 'pending_confirm' orders[index].statusLog.unshift(createStatusLog(orderId, 'in_service', 'pending_confirm', '已提交服务记录')) refreshOrderMeta(orders[index]) writeOrderStore(orders) return cloneOrder(orders[index]) } export function completeCareOrder(orderId: string): DeliveryOrderType | null { const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index < 0) { return null } if (orders[index].serviceRecord == null) { return null } orders[index].statusLog.unshift(createStatusLog(orderId, orders[index].status, 'completed', '完成服务')) orders[index].status = 'completed' orders[index].finishTime = nowText() orders[index].actualEndTime = orders[index].finishTime refreshOrderMeta(orders[index]) writeOrderStore(orders) return cloneOrder(orders[index]) } export function submitCareAbnormalReport(orderId: string, payload: DeliveryExceptionPayloadType): DeliveryOrderType | null { const orders = readOrderStore() const index = findOrderIndex(orders, orderId) if (index < 0) { return null } orders[index].abnormalReport = { id: 'abnormal-' + orderId, orderId, type: payload.exceptionType, description: payload.description, occurredAt: payload.occurredAt != null ? payload.occurredAt : nowText(), locationText: payload.locationText != null ? payload.locationText : '当前位置 mock', images: payload.images, needPlatformIntervention: payload.needPlatformIntervention === true, requestCancelOrder: payload.requestCancelOrder === true, requestReschedule: payload.requestReschedule === true, createdAt: nowText() } as DeliveryAbnormalReportType orders[index].exceptionType = payload.exceptionType orders[index].exceptionDesc = payload.description orders[index].statusLog.unshift(createStatusLog(orderId, orders[index].status, 'abnormal', '提交异常上报')) orders[index].status = 'abnormal' refreshOrderMeta(orders[index]) writeOrderStore(orders) return cloneOrder(orders[index]) } export function getCareRecords(): Array { const orders = readOrderStore() const result: Array = [] for (let i = 0; i < orders.length; i++) { const item = orders[i] if (item.serviceRecord != null || item.status == 'completed') { result.push({ id: 'record-list-' + item.id, orderId: item.id, orderNo: item.orderNo, serviceName: item.serviceName, elderName: item.elderName, elderNameMasked: item.elderNameMasked, status: item.status, statusText: item.statusText, appointmentStartTime: item.appointmentStartTime, appointmentTime: item.appointmentTime, actualStartTime: item.actualStartTime, actualEndTime: item.actualEndTime, staffIncome: item.staffIncome, settlementStatus: item.settlementStatus, acceptanceStatus: item.satisfactionStatus, exceptionDesc: item.exceptionDesc, ratingText: item.satisfactionStatus, hasServiceRecord: item.serviceRecord != null } as DeliveryRecordType) } } return result } export function resetCareOrderStore(): void { uni.removeStorageSync(ORDER_KEY) uni.removeStorageSync(PROFILE_KEY) }