import { HomeServiceAcceptanceType, HomeServiceAdminApplicationType, HomeServiceAssessmentType, HomeServiceApplicationDraftType, HomeServiceCatalogType, HomeServiceCaseType, HomeServiceOverviewCardType, HomeServicePlanType, HomeServiceRectificationType, HomeServiceSettlementType, HomeServiceTaskType, HomeServiceTimelineItemType } from '@/types/home-service.uts' import { confirmServiceOrder, createServiceOrder, getServiceOrderDetail, listConsumerServiceOrders, rejectServiceOrderAcceptance } from '@/services/serviceOrderService.uts' import supa from '@/components/supadb/aksupainstance.uts' import { getServiceOrderStatusText, type ServiceOrderStatus, type ServiceOrderTimelineItemType, type ServiceOrderType } from '@/types/service-order.uts' function plainObject(source: any): any { return JSON.parse(JSON.stringify(source)) as any } function readString(source: any, key: string): string { const value = plainObject(source)[key] if (value == null) { return '' } return typeof value == 'string' ? value : String(value) } function readNumber(source: any, key: string): number { const value = plainObject(source)[key] if (typeof value == 'number') { return value } const parsed = Number(value) return isNaN(parsed) ? 0 : parsed } function readStringArray(source: any, key: string): Array { const value = plainObject(source)[key] if (Array.isArray(value)) { const result = [] as Array for (let i = 0; i < value.length; i++) { result.push(typeof value[i] == 'string' ? value[i] : String(value[i])) } return result } if (typeof value == 'string' && value != '') { try { const parsed = JSON.parse(value) as any if (Array.isArray(parsed)) { const result = [] as Array for (let i = 0; i < parsed.length; i++) { result.push(typeof parsed[i] == 'string' ? parsed[i] : String(parsed[i])) } return result } } catch (error) { return [] as Array } } return [] as Array } function parseCatalogItem(source: any): HomeServiceCatalogType { return { id: readString(source, 'id'), name: readString(source, 'name'), category: readString(source, 'category'), price: readNumber(source, 'price'), durationText: readString(source, 'duration_text'), summary: readString(source, 'summary'), tags: readStringArray(source, 'tags_json'), suitableFor: readString(source, 'suitable_for') } } function createTimeline(title1: string, title2: string, title3: string): Array { return [ { id: 'tl-1', title: title1, time: '2026-05-12 09:00', description: '系统已建立服务申请档案。' }, { id: 'tl-2', title: title2, time: '2026-05-12 11:30', description: '评估员已完成初步核对与上门安排。' }, { id: 'tl-3', title: title3, time: '2026-05-13 08:20', description: '当前环节已进入待执行状态。' } ] } const CASE_STORE: Array = [ { id: 'case-001', caseNo: 'HS202605130001', status: 'pending_dispatch', statusText: '待派单', statusTone: 'warning', serviceName: '基础上门护理', serviceTime: '2026-05-14 09:00-11:00', applicantName: '李晓兰', elderName: '李奶奶', age: 78, phone: '13800138000', address: '梅州市梅江区学海路 18 号 2 栋 602', summary: '老人近期行动困难,需要基础照护与生命体征监测。', currentStep: 3, totalSteps: 8, staffName: '待分配', staffPhone: '待分配', amount: 168, timeline: createTimeline('已提交申请', '待上门评估', '待派单') }, { id: 'case-002', caseNo: 'HS202605130002', status: 'in_service', statusText: '服务中', statusTone: 'primary', serviceName: '慢病健康随访', serviceTime: '2026-05-13 15:00-16:30', applicantName: '张春梅', elderName: '张爷爷', age: 82, phone: '13900139000', address: '梅州市梅县区华侨城康宁路 66 号', summary: '随访血压血糖,核对用药并记录健康建议。', currentStep: 6, totalSteps: 8, staffName: '陈护理', staffPhone: '13688886666', amount: 128, timeline: createTimeline('已提交申请', '已生成服务方案', '服务执行中') } ] const TASK_STORE: Array = [ { id: 'task-001', caseId: 'case-001', caseNo: 'HS202605130001', status: 'pending_visit', statusText: '待上门', statusTone: 'warning', serviceName: '基础上门护理', elderName: '李奶奶', address: '梅州市梅江区学海路 18 号 2 栋 602', appointmentTime: '2026-05-14 09:00', checkInStatus: '未签到', recordSummary: '待填写服务记录', staffName: '黄护理', staffPhone: '13777770001', actionText: '签到开始', timeline: createTimeline('调度已派单', '护理员已接单', '等待上门签到') }, { id: 'task-002', caseId: 'case-002', caseNo: 'HS202605130002', status: 'serving', statusText: '服务中', statusTone: 'primary', serviceName: '慢病健康随访', elderName: '张爷爷', address: '梅州市梅县区华侨城康宁路 66 号', appointmentTime: '2026-05-13 15:00', checkInStatus: '已签到', recordSummary: '已完成血压血糖记录,待补充宣教备注。', staffName: '陈护理', staffPhone: '13688886666', actionText: '完成提交', timeline: createTimeline('调度已派单', '已到岗签到', '服务执行中') } ] const ADMIN_APPLICATIONS: Array = [ { id: 'admin-app-001', caseId: 'case-001', caseNo: 'HS202605130001', status: 'pending_assessment', statusText: '待评估', statusTone: 'warning', elderName: '李奶奶', serviceName: '基础上门护理', preferredTime: '2026-05-14 上午', assessmentResult: '待评估员上门', dispatcherName: '刘调度', staffName: '待分配' }, { id: 'admin-app-002', caseId: 'case-002', caseNo: 'HS202605130002', status: 'pending_acceptance', statusText: '待验收', statusTone: 'success', elderName: '张爷爷', serviceName: '慢病健康随访', preferredTime: '2026-05-13 下午', assessmentResult: '评估通过,按标准随访执行', dispatcherName: '刘调度', staffName: '陈护理' } ] const ADMIN_OVERVIEW: Array = [ { id: 'overview-1', label: '待评估申请', value: '06', tone: 'warning' }, { id: 'overview-2', label: '待派单工单', value: '03', tone: 'primary' }, { id: 'overview-3', label: '服务中任务', value: '08', tone: 'success' }, { id: 'overview-4', label: '待验收任务', value: '04', tone: 'neutral' } ] const ADMIN_ASSESSMENTS: Array = [ { caseId: 'case-001', caseNo: 'HS202605130001', elderName: '李奶奶', serviceName: '基础上门护理', riskLevel: '中风险', careLevel: '护理二级', visitTime: '2026-05-14 09:00', assessmentSummary: '行动缓慢,需重点关注跌倒风险和晨间血压波动。', requirementTags: ['血压监测', '基础照护', '跌倒风险提醒'] }, { caseId: 'case-002', caseNo: 'HS202605130002', elderName: '张爷爷', serviceName: '慢病健康随访', riskLevel: '低风险', careLevel: '随访管理', visitTime: '2026-05-13 15:00', assessmentSummary: '生命体征稳定,重点跟踪慢病用药执行情况。', requirementTags: ['血糖记录', '用药核对', '家属宣教'] } ] const ADMIN_PLANS: Array = [ { caseId: 'case-001', caseNo: 'HS202605130001', elderName: '李奶奶', serviceName: '基础上门护理', planTitle: '基础护理 7 日方案', serviceFrequency: '每周 3 次', serviceCycle: '2026-05-14 至 2026-05-21', executorAdvice: '优先安排熟悉慢病照护的护理员,首次上门同步评估跌倒风险。', billingSummary: '基础护理 ¥168/次,计划总额 ¥504', planSummary: '围绕晨间照护、生命体征监测和风险提醒开展服务。' }, { caseId: 'case-002', caseNo: 'HS202605130002', elderName: '张爷爷', serviceName: '慢病健康随访', planTitle: '慢病随访连续方案', serviceFrequency: '每周 2 次', serviceCycle: '2026-05-13 至 2026-05-27', executorAdvice: '执行人员需同步上传血压血糖记录并完成家属宣教。', billingSummary: '随访服务 ¥128/次,计划总额 ¥512', planSummary: '持续随访血压血糖、用药和饮食管理情况。' } ] const ADMIN_RECTIFICATIONS: Array = [ { caseId: 'case-001', caseNo: 'HS202605130001', elderName: '李奶奶', serviceName: '基础上门护理', issueSummary: '家属要求补充护理动作说明和现场照片留痕。', deadline: '2026-05-14 18:00', ownerName: '黄护理', status: 'pending', statusText: '待整改' }, { caseId: 'case-002', caseNo: 'HS202605130002', elderName: '张爷爷', serviceName: '慢病健康随访', issueSummary: '记录完整,无需整改。', deadline: '2026-05-15 12:00', ownerName: '陈护理', status: 'closed', statusText: '已关闭' } ] const ADMIN_SETTLEMENTS: Array = [ { caseId: 'case-001', caseNo: 'HS202605130001', elderName: '李奶奶', serviceName: '基础上门护理', billingPeriod: '2026-05-14 至 2026-05-21', totalAmount: '¥504', insuranceAmount: '¥300', selfPayAmount: '¥204', archiveStatus: 'pending', archiveStatusText: '待归档' }, { caseId: 'case-002', caseNo: 'HS202605130002', elderName: '张爷爷', serviceName: '慢病健康随访', billingPeriod: '2026-05-13 至 2026-05-27', totalAmount: '¥512', insuranceAmount: '¥256', selfPayAmount: '¥256', archiveStatus: 'pending', archiveStatusText: '待归档' } ] function delay(): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(true) }, 120) }) } function cloneCase(item: HomeServiceCaseType): HomeServiceCaseType { return { ...item, timeline: item.timeline.map((log) => ({ ...log })) } } function cloneTask(item: HomeServiceTaskType): HomeServiceTaskType { return { ...item, timeline: item.timeline.map((log) => ({ ...log })) } } function cloneAssessment(item: HomeServiceAssessmentType): HomeServiceAssessmentType { return { ...item, requirementTags: item.requirementTags.slice(0) } } function clonePlan(item: HomeServicePlanType): HomeServicePlanType { return { ...item } } function cloneRectification(item: HomeServiceRectificationType): HomeServiceRectificationType { return { ...item } } function cloneSettlement(item: HomeServiceSettlementType): HomeServiceSettlementType { return { ...item } } export async function fetchHomeServiceCatalog(): Promise> { const response = await supa .from('hss_service_catalog') .select('id, name, category, price, duration_text, summary, tags_json, suitable_for, sort_no') .eq('status', 1) .is('deleted_at', null) .order('sort_no', { ascending: true }) .execute() if (response.error != null || response.data == null || !Array.isArray(response.data)) { return [] as Array } const result = [] as Array for (let i = 0; i < response.data.length; i++) { result.push(parseCatalogItem(response.data[i])) } return result } export async function fetchConsumerHomeServiceCases(): Promise> { const orders = await listConsumerServiceOrders() const result = [] as Array for (let i = 0; i < orders.length; i++) { result.push(mapOrderToCase(orders[i])) } return result } export async function fetchConsumerHomeServiceCaseDetail(caseId: string): Promise { const detail = await getServiceOrderDetail(caseId) if (detail != null) { return mapOrderToCase(detail) } return null } export async function createHomeServiceApplication(draft: HomeServiceApplicationDraftType): Promise { const catalog = await fetchHomeServiceCatalog() let matchedService: HomeServiceCatalogType | null = null for (let i = 0; i < catalog.length; i++) { if (catalog[i].id == draft.serviceId) { matchedService = catalog[i] break } } if (matchedService != null && draft.serviceAddressSnapshot != null) { const createdOrder = await createServiceOrder({ service: matchedService, address: { addressId: draft.serviceAddressSnapshot.addressId, contactName: draft.serviceAddressSnapshot.contactName, contactPhone: draft.serviceAddressSnapshot.contactPhone, province: '', city: '', district: '', detailAddress: draft.serviceAddressSnapshot.addressDetail, fullAddress: draft.serviceAddressSnapshot.fullAddress, latitude: draft.serviceAddressSnapshot.latitude, longitude: draft.serviceAddressSnapshot.longitude, coordinateType: draft.serviceAddressSnapshot.coordinateType, remark: draft.serviceAddressSnapshot.remark }, recipientName: draft.elderName, recipientPhone: draft.phone, contactName: draft.applicantName, contactPhone: draft.phone, appointmentTime: draft.preferredTime, remark: draft.demandSummary }) if (createdOrder != null) { return mapOrderToCase(createdOrder) } } return null } function getCaseStep(status: ServiceOrderStatus): number { if (status == 'created') return 1 if (status == 'assigned') return 3 if (status == 'accepted') return 4 if (status == 'departed') return 5 if (status == 'arrived' || status == 'in_service') return 6 if (status == 'pending_acceptance') return 7 if (status == 'accepted_by_user' || status == 'reviewed' || status == 'settled') return 8 if (status == 'rejected' || status == 'cancelled' || status == 'exception') return 7 return 2 } function getCaseTone(status: ServiceOrderStatus): string { if (status == 'created' || status == 'assigned' || status == 'pending_acceptance') return 'warning' if (status == 'accepted' || status == 'departed' || status == 'arrived' || status == 'in_service') return 'primary' if (status == 'accepted_by_user' || status == 'reviewed' || status == 'settled') return 'success' if (status == 'exception' || status == 'cancelled' || status == 'rejected') return 'danger' return 'neutral' } function getTimelineDescription(log: ServiceOrderTimelineItemType): string { if (log.remark != '') { return log.remark } if (log.toStatus == 'created') return '平台已接收预约申请,等待后续处理。' if (log.toStatus == 'assigned') return '系统已完成派单,正在通知服务人员。' if (log.toStatus == 'accepted') return '服务人员已接单,正在准备上门。' if (log.toStatus == 'departed') return '服务人员已出发,正在前往服务地点。' if (log.toStatus == 'arrived') return '服务人员已到达服务地点。' if (log.toStatus == 'in_service') return '服务已开始执行,请留意后续进度。' if (log.toStatus == 'completed') return '服务执行已完成,正在整理结果。' if (log.toStatus == 'pending_acceptance') return '服务记录已提交,等待家属验收。' if (log.toStatus == 'accepted_by_user') return '家属已确认本次服务结果。' if (log.toStatus == 'reviewed') return '家属已完成评价反馈。' if (log.toStatus == 'settled') return '本次服务已完成结算归档。' if (log.toStatus == 'cancelled') return '服务单已取消。' if (log.toStatus == 'rejected') return '服务人员未接受该工单。' return '服务过程状态已更新。' } function formatServiceAppointmentText(value: string): string { if (value == '') { return '' } if (value.indexOf('上午') >= 0 || value.indexOf('下午') >= 0 || value.indexOf('晚上') >= 0) { return value } const parsed = Date.parse(value) if (!isNaN(parsed)) { const date = new Date(parsed) let year = date.getFullYear() const currentYear = new Date().getFullYear() if (year < currentYear - 1) { year = currentYear } const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') const hour = String(date.getHours()).padStart(2, '0') const minute = String(date.getMinutes()).padStart(2, '0') return year + '-' + month + '-' + day + ' ' + hour + ':' + minute } const monthDayMatch = value.match(/(\d{2})\/(\d{2})/) const timeMatch = value.match(/(\d{2}:\d{2}(\s*-\s*\d{2}:\d{2})?)/) if (monthDayMatch != null) { const month = monthDayMatch[1] ?? '' const day = monthDayMatch[2] ?? '' const timeText = timeMatch != null ? (timeMatch[1] ?? '') : '' if (month != '' && day != '') { return String(new Date().getFullYear()) + '-' + month + '-' + day + (timeText != '' ? ' ' + timeText.replace(/\s+/g, '') : '') } } return value.replace('T', ' ') } function mapLogsToTimeline(logs: Array): Array { const timeline = [] as Array for (let i = 0; i < logs.length; i++) { timeline.push({ id: logs[i].id, title: getServiceOrderStatusText(logs[i].toStatus), time: logs[i].createdAt, description: getTimelineDescription(logs[i]) }) } return timeline } function mapOrderToCase(order: ServiceOrderType): HomeServiceCaseType { return { id: order.id, caseNo: order.orderNo, status: order.status, statusText: getServiceOrderStatusText(order.status), statusTone: getCaseTone(order.status), serviceName: order.serviceName, serviceTime: formatServiceAppointmentText(order.appointmentTime), applicantName: order.contactName, elderName: order.recipientName, age: 0, phone: order.contactPhone, address: order.addressSnapshot.fullAddress, summary: order.remark, currentStep: getCaseStep(order.status), totalSteps: 8, staffName: order.staffName == '' ? '待分配' : order.staffName, staffPhone: order.staffPhone == '' ? '待分配' : order.staffPhone, amount: order.serviceSnapshot.price, checkinTime: order.executionRecord != null ? order.executionRecord.checkinTime : '', checkinAddress: order.executionRecord != null ? order.executionRecord.checkinAddress : '', serviceStartedAt: order.executionRecord != null ? order.executionRecord.serviceStartedAt : order.serviceStartedAt, serviceFinishedAt: order.executionRecord != null ? order.executionRecord.serviceFinishedAt : order.completedAt, executionSummary: order.executionRecord != null ? (order.executionRecord.summary != '' ? order.executionRecord.summary : order.executionRecord.remark) : '', evidenceCount: order.evidenceFiles.length, serviceAddressSnapshot: null, timeline: mapLogsToTimeline(order.logs) } } export async function fetchWorkerTasks(): Promise> { await delay() return TASK_STORE.map((item) => cloneTask(item)) } export async function fetchWorkerTaskDetail(taskId: string): Promise { await delay() const target = TASK_STORE.find((item) => item.id == taskId) return target == null ? null : cloneTask(target) } export async function advanceWorkerTask(taskId: string): Promise { await delay() const target = TASK_STORE.find((item) => item.id == taskId) if (target == null) { return null } if (target.status == 'pending_visit') { target.status = 'serving' target.statusText = '服务中' target.statusTone = 'primary' target.checkInStatus = '已签到' target.recordSummary = '已完成签到,请按步骤填写服务记录。' target.actionText = '完成提交' target.timeline.unshift({ id: 'tl-' + String(target.timeline.length + 1), title: '已到岗签到', time: '2026-05-13 14:55', description: '护理员已在服务地址完成签到。' }) } else if (target.status == 'serving') { target.status = 'completed' target.statusText = '待验收' target.statusTone = 'success' target.recordSummary = '已提交执行记录与服务凭证,等待家属验收。' target.actionText = '已提交' target.timeline.unshift({ id: 'tl-' + String(target.timeline.length + 1), title: '服务完成待验收', time: '2026-05-13 16:20', description: '服务记录和凭证已经提交。' }) } const relatedCase = CASE_STORE.find((item) => item.id == target.caseId) if (relatedCase != null) { if (target.status == 'serving') { relatedCase.status = 'in_service' relatedCase.statusText = '服务中' relatedCase.statusTone = 'primary' relatedCase.currentStep = 6 relatedCase.staffName = target.staffName relatedCase.staffPhone = target.staffPhone relatedCase.timeline.unshift({ id: 'case-log-' + String(relatedCase.timeline.length + 1), title: '护理员已签到', time: '2026-05-13 14:55', description: '执行端已开始上门服务。' }) } else if (target.status == 'completed') { relatedCase.status = 'pending_acceptance' relatedCase.statusText = '待验收' relatedCase.statusTone = 'success' relatedCase.currentStep = 7 relatedCase.timeline.unshift({ id: 'case-log-' + String(relatedCase.timeline.length + 1), title: '执行完成待验收', time: '2026-05-13 16:20', description: '家属可查看记录并进行验收反馈。' }) } } const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == target.caseId) if (relatedAdmin != null) { if (target.status == 'serving') { relatedAdmin.status = 'in_service' relatedAdmin.statusText = '服务中' relatedAdmin.statusTone = 'primary' relatedAdmin.staffName = target.staffName } else if (target.status == 'completed') { relatedAdmin.status = 'pending_acceptance' relatedAdmin.statusText = '待验收' relatedAdmin.statusTone = 'success' } } return cloneTask(target) } export async function submitWorkerCheckIn(taskId: string, note: string): Promise { await delay() const target = TASK_STORE.find((item) => item.id == taskId) if (target == null) { return null } if (target.status == 'pending_visit') { target.status = 'serving' target.statusText = '服务中' target.statusTone = 'primary' target.checkInStatus = '已签到' target.recordSummary = note == '' ? '已完成签到,请继续填写服务记录。' : note target.actionText = '完成提交' target.timeline.unshift({ id: 'checkin-' + String(target.timeline.length + 1), title: '到岗签到完成', time: '2026-05-13 14:40', description: note == '' ? '护理员已完成签到。' : note }) } const relatedCase = CASE_STORE.find((item) => item.id == target.caseId) if (relatedCase != null) { relatedCase.status = 'in_service' relatedCase.statusText = '服务中' relatedCase.statusTone = 'primary' relatedCase.currentStep = 6 relatedCase.staffName = target.staffName relatedCase.staffPhone = target.staffPhone relatedCase.timeline.unshift({ id: 'case-checkin-' + String(relatedCase.timeline.length + 1), title: '执行人员已到岗', time: '2026-05-13 14:40', description: note == '' ? '已完成签到,开始执行服务。' : note }) } const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == target.caseId) if (relatedAdmin != null) { relatedAdmin.status = 'in_service' relatedAdmin.statusText = '服务中' relatedAdmin.statusTone = 'primary' relatedAdmin.staffName = target.staffName } return cloneTask(target) } export async function submitWorkerServiceRecord(taskId: string, summary: string): Promise { await delay() const target = TASK_STORE.find((item) => item.id == taskId) if (target == null) { return null } target.recordSummary = summary == '' ? target.recordSummary : summary target.timeline.unshift({ id: 'record-' + String(target.timeline.length + 1), title: '服务记录已更新', time: '2026-05-13 15:30', description: summary == '' ? '已保存服务记录。' : summary }) const relatedCase = CASE_STORE.find((item) => item.id == target.caseId) if (relatedCase != null) { relatedCase.summary = summary == '' ? relatedCase.summary : summary relatedCase.timeline.unshift({ id: 'case-record-' + String(relatedCase.timeline.length + 1), title: '执行记录已回传', time: '2026-05-13 15:30', description: summary == '' ? '执行端已保存记录。' : summary }) } return cloneTask(target) } export async function submitWorkerException(taskId: string, exceptionType: string, description: string): Promise { await delay() const target = TASK_STORE.find((item) => item.id == taskId) if (target == null) { return null } target.status = 'exception' target.statusText = '异常上报' target.statusTone = 'warning' target.actionText = '已上报' target.timeline.unshift({ id: 'exception-' + String(target.timeline.length + 1), title: '异常已上报', time: '2026-05-13 15:45', description: exceptionType + ':' + description }) const relatedCase = CASE_STORE.find((item) => item.id == target.caseId) if (relatedCase != null) { relatedCase.status = 'exception' relatedCase.statusText = '异常处理中' relatedCase.statusTone = 'warning' relatedCase.timeline.unshift({ id: 'case-exception-' + String(relatedCase.timeline.length + 1), title: '服务异常待处理', time: '2026-05-13 15:45', description: exceptionType + ':' + description }) } const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == target.caseId) if (relatedAdmin != null) { relatedAdmin.status = 'exception' relatedAdmin.statusText = '异常处理中' relatedAdmin.statusTone = 'warning' } return cloneTask(target) } export async function fetchAdminAssessmentDetail(caseId: string): Promise { await delay() const target = ADMIN_ASSESSMENTS.find((item) => item.caseId == caseId) return target == null ? null : cloneAssessment(target) } export async function submitAdminAssessment(caseId: string, riskLevel: string, careLevel: string, assessmentSummary: string): Promise { await delay() const target = ADMIN_ASSESSMENTS.find((item) => item.caseId == caseId) if (target == null) { return null } target.riskLevel = riskLevel target.careLevel = careLevel target.assessmentSummary = assessmentSummary const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == caseId) if (relatedAdmin != null) { relatedAdmin.status = 'pending_plan' relatedAdmin.statusText = '待方案' relatedAdmin.statusTone = 'primary' relatedAdmin.assessmentResult = careLevel + ' · ' + riskLevel } const relatedCase = CASE_STORE.find((item) => item.id == caseId) if (relatedCase != null) { relatedCase.currentStep = 2 relatedCase.timeline.unshift({ id: 'case-assessment-' + String(relatedCase.timeline.length + 1), title: '上门评估完成', time: '2026-05-13 13:20', description: assessmentSummary }) } return cloneAssessment(target) } export async function fetchAdminServicePlanDetail(caseId: string): Promise { await delay() const target = ADMIN_PLANS.find((item) => item.caseId == caseId) return target == null ? null : clonePlan(target) } export async function submitAdminServicePlan( caseId: string, planTitle: string, serviceFrequency: string, serviceCycle: string, planSummary: string ): Promise { await delay() const target = ADMIN_PLANS.find((item) => item.caseId == caseId) if (target == null) { return null } target.planTitle = planTitle target.serviceFrequency = serviceFrequency target.serviceCycle = serviceCycle target.planSummary = planSummary const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == caseId) if (relatedAdmin != null) { relatedAdmin.status = 'pending_dispatch' relatedAdmin.statusText = '待派单' relatedAdmin.statusTone = 'warning' relatedAdmin.assessmentResult = target.planTitle + ' · ' + target.serviceFrequency } const relatedCase = CASE_STORE.find((item) => item.id == caseId) if (relatedCase != null) { relatedCase.currentStep = 3 relatedCase.status = 'pending_dispatch' relatedCase.statusText = '待派单' relatedCase.statusTone = 'warning' relatedCase.timeline.unshift({ id: 'case-plan-' + String(relatedCase.timeline.length + 1), title: '服务方案已生成', time: '2026-05-13 14:10', description: planSummary }) } return clonePlan(target) } export async function fetchConsumerAcceptanceDetail(caseId: string): Promise { const detail = await getServiceOrderDetail(caseId) if (detail != null) { return { caseId: detail.id, caseNo: detail.orderNo, elderName: detail.recipientName, serviceName: detail.serviceName, acceptanceStatus: detail.status, acceptanceStatusText: getServiceOrderStatusText(detail.status), rating: detail.review != null ? detail.review.rating : 5, feedback: detail.review != null ? detail.review.content : '', tags: detail.review != null ? detail.review.tags : [] as Array } } return null } export async function submitConsumerAcceptance( caseId: string, approved: boolean, rating: number, feedback: string, tags: Array ): Promise { if (approved) { const result = await confirmServiceOrder(caseId, rating, feedback, tags) if (result != null) { return await fetchConsumerAcceptanceDetail(caseId) } return null } const rejected = await rejectServiceOrderAcceptance(caseId, feedback) if (rejected != null) { return await fetchConsumerAcceptanceDetail(caseId) } return null } export async function fetchAdminRectificationDetail(caseId: string): Promise { await delay() const target = ADMIN_RECTIFICATIONS.find((item) => item.caseId == caseId) return target == null ? null : cloneRectification(target) } export async function submitAdminRectification(caseId: string, issueSummary: string): Promise { await delay() const target = ADMIN_RECTIFICATIONS.find((item) => item.caseId == caseId) if (target == null) { return null } target.issueSummary = issueSummary target.status = 'closed' target.statusText = '已关闭' const relatedAdmin = ADMIN_APPLICATIONS.find((item) => item.caseId == caseId) if (relatedAdmin != null) { relatedAdmin.status = 'pending_acceptance' relatedAdmin.statusText = '待复验收' relatedAdmin.statusTone = 'primary' } const relatedCase = CASE_STORE.find((item) => item.id == caseId) if (relatedCase != null) { relatedCase.status = 'pending_acceptance' relatedCase.statusText = '待复验收' relatedCase.statusTone = 'primary' relatedCase.timeline.unshift({ id: 'case-rectification-' + String(relatedCase.timeline.length + 1), title: '整改处理完成', time: '2026-05-13 18:10', description: issueSummary }) } return cloneRectification(target) } export async function fetchAdminSettlementDetail(caseId: string): Promise { await delay() const target = ADMIN_SETTLEMENTS.find((item) => item.caseId == caseId) return target == null ? null : cloneSettlement(target) } export async function submitAdminSettlementArchive(caseId: string): Promise { await delay() const target = ADMIN_SETTLEMENTS.find((item) => item.caseId == caseId) if (target == null) { return null } target.archiveStatus = 'archived' target.archiveStatusText = '已归档' const relatedCase = CASE_STORE.find((item) => item.id == caseId) if (relatedCase != null) { relatedCase.timeline.unshift({ id: 'case-settlement-' + String(relatedCase.timeline.length + 1), title: '结算归档完成', time: '2026-05-13 18:30', description: '结算单和执行材料已完成归档。' }) } return cloneSettlement(target) } export async function fetchAdminHomeServiceApplications(): Promise> { await delay() return ADMIN_APPLICATIONS.map((item) => ({ ...item })) } export async function fetchAdminHomeServiceOverview(): Promise> { await delay() return ADMIN_OVERVIEW.map((item) => ({ ...item })) }