Files
medical-mall/services/deliveryService.uts
2026-06-12 13:03:13 +08:00

467 lines
15 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
acceptDeliveryOrderById,
arriveOrderById,
checkinOrderById,
finishServiceById,
getDeliveryDashboardByStaffId,
getDeliveryOrderDetailById,
getDeliveryOrdersByStaffId,
getDeliveryProfileByUserId,
loginDelivery as loginDeliveryApi,
saveServiceProgressById,
startDepartById,
startServiceById
} from '@/api/delivery.uts'
import {
getOrderDetail as getDirectServiceOrderDetail,
getOrdersByTab as getDirectOrdersByTab
} from '@/services/serviceOrderService.uts'
import {
getDeliveryInfo,
getUserInfo,
requireDeliveryAuth,
setDeliveryInfo
} from '@/utils/deliveryAuth.uts'
import { getCurrentAkUserId as readCurrentAkUserId } from '@/utils/akUserMapping.uts'
import type {
DeliveryAbnormalReportType,
DeliveryCheckinPayloadType,
DeliveryDashboardType,
DeliveryExceptionPayloadType,
DeliveryFinishPayloadType,
DeliveryInfoType,
DeliveryLocationType,
DeliveryLoginPayloadType,
DeliveryLoginResultType,
DeliveryMessageType,
DeliveryOrderQueryType,
DeliveryOrderStatus,
DeliveryOrderType,
DeliveryProgressPayloadType,
DeliveryRecordType,
DeliveryServiceRecordType
} from '@/types/delivery.uts'
function nowText(): string {
return new Date().toISOString().replace('T', ' ').substring(0, 19)
}
function emptyDashboard(): DeliveryDashboardType {
return {
pendingAssignmentCount: 0,
pendingAcceptCount: 0,
todayOrderCount: 0,
pendingDepartCount: 0,
servingCount: 0,
completedCount: 0,
exceptionCount: 0,
expectedIncome: 0,
onlineStatus: 'resting',
nextOrder: null,
recentOrders: [] as Array<DeliveryOrderType>
} as DeliveryDashboardType
}
async function getCurrentStaffIdOrEmpty(): Promise<string> {
const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
if (!authResult.ok || authResult.deliveryInfo == null) {
return ''
}
return authResult.deliveryInfo.id
}
function hasOrderCoreInfo(order: DeliveryOrderType | null): boolean {
if (order == null) {
return false
}
return order.serviceName != '' || order.elderName != '' || order.address != '' || order.contactName != ''
}
function filterOrdersWithCoreInfo(orders: Array<DeliveryOrderType>): Array<DeliveryOrderType> {
const result = [] as Array<DeliveryOrderType>
for (let i = 0; i < orders.length; i++) {
if (hasOrderCoreInfo(orders[i])) {
result.push(orders[i])
}
}
return result
}
function shouldFallbackOrders(orders: Array<DeliveryOrderType>): boolean {
if (orders.length == 0) {
return false
}
for (let i = 0; i < orders.length; i++) {
if (hasOrderCoreInfo(orders[i])) {
return false
}
}
return true
}
function mapOrderToRecord(order: DeliveryOrderType): DeliveryRecordType {
const isAccepted = order.status == 'completed' || order.status == 'pending_acceptance' || order.status == 'settled' || order.status == 'archived'
return {
id: order.id,
orderId: order.id,
orderNo: order.orderNo,
serviceName: order.serviceName,
elderName: order.fullElderName != '' ? order.fullElderName : order.elderName,
elderNameMasked: order.elderNameMasked != '' ? order.elderNameMasked : order.elderName,
status: order.status,
statusText: order.statusText,
appointmentStartTime: order.appointmentStartTime,
appointmentTime: order.appointmentTime,
actualStartTime: order.actualStartTime,
actualEndTime: order.actualEndTime != '' ? order.actualEndTime : order.finishTime,
staffIncome: order.staffIncome,
settlementStatus: order.settlementStatus != '' ? order.settlementStatus : '待结算',
acceptanceStatus: order.status,
exceptionDesc: order.exceptionDesc,
ratingText: isAccepted ? '已验收' : (order.status == 'pending_acceptance' ? '待验收' : '待补充'),
hasServiceRecord: order.serviceRecord != null
} as DeliveryRecordType
}
export async function loginDelivery(payload: DeliveryLoginPayloadType): Promise<DeliveryLoginResultType> {
return await loginDeliveryApi(payload)
}
export async function getDeliveryProfile(): Promise<DeliveryInfoType | null> {
const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
if (!authResult.ok) {
return null
}
return authResult.deliveryInfo
}
export async function getDeliveryByUserId(userId: string): Promise<DeliveryInfoType | null> {
return await getDeliveryProfileByUserId(userId)
}
export async function getCurrentDeliverer(): Promise<DeliveryInfoType | null> {
return await getDeliveryProfile()
}
export async function checkDeliveryAccountByUserId(userId: string): Promise<DeliveryInfoType | null> {
return await getDeliveryProfileByUserId(userId)
}
export async function checkDeliveryAuth(): Promise<boolean> {
const result = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
return result.ok
}
async function getCurrentStaffId(): Promise<string> {
// 旧 delivery RPCdashboard / order_list需要 ml_delivery_staff.id513449ca...
const deliveryInfo = getDeliveryInfo()
if (deliveryInfo != null && deliveryInfo.id != null && String(deliveryInfo.id) != '') {
console.warn('[deliveryService] getCurrentStaffId: 使用 deliveryStaffId =', String(deliveryInfo.id))
return String(deliveryInfo.id)
}
console.error('[deliveryService] getCurrentStaffId: 未获取到 deliveryStaffId')
return ''
}
function createEmptyLocation(): DeliveryLocationType {
return {
latitude: 0,
longitude: 0,
address: '',
time: new Date().toISOString().replace('T', ' ').substring(0, 19)
}
}
export async function getDeliveryDashboard(): Promise<DeliveryDashboardType> {
const staffId = await getCurrentStaffId()
if (staffId != '') {
return await getDeliveryDashboardByStaffId(staffId)
}
// staffId 为空时返回空 dashboard
console.error('[deliveryService] getDeliveryDashboard: staffId 为空,返回空数据')
return emptyDashboard()
}
export async function getDeliveryOrders(params: DeliveryOrderQueryType): Promise<Array<DeliveryOrderType>> {
const staffId = await getCurrentStaffId()
if (staffId != '') {
return await getDeliveryOrdersByStaffId(staffId, params)
}
// staffId 为空时返回空列表
console.error('[deliveryService] getDeliveryOrders: staffId 为空,返回空列表')
return [] as Array<DeliveryOrderType>
}
export async function getDeliveryOrderDetail(id: string): Promise<DeliveryOrderType | null> {
return await getDeliveryOrderDetailById(id)
}
export async function acceptDeliveryOrder(id: string): Promise<DeliveryOrderType | null> {
return await acceptDeliveryOrderById(id)
}
export async function rejectDeliveryOrder(id: string, reason: string): Promise<DeliveryOrderType | null> {
return rejectCareOrder(id, reason)
}
export async function startDepart(id: string, location: DeliveryLocationType): Promise<DeliveryOrderType | null> {
return await startDepartById(id, location)
}
export async function arriveOrder(id: string, location: DeliveryLocationType): Promise<DeliveryOrderType | null> {
return await arriveOrderById(id, location)
}
export async function checkinOrder(id: string, payload: DeliveryCheckinPayloadType): Promise<DeliveryOrderType | null> {
return await checkinOrderById(id, payload)
}
export async function startService(id: string): Promise<DeliveryOrderType | null> {
return await startServiceById(id)
}
export async function saveServiceProgress(id: string, payload: DeliveryProgressPayloadType): Promise<DeliveryOrderType | null> {
return await saveServiceProgressById(id, payload)
}
export async function uploadEvidence(id: string, phase: string, files: Array<string>): Promise<Array<any>> {
return files.map((item, index) => ({
id: id + '-evidence-' + String(index + 1),
orderId: id,
phase,
fileType: 'image',
name: 'mock-image-' + String(index + 1),
url: '',
localPath: item,
status: 'success',
progress: 100,
retryable: false,
createdAt: new Date().toISOString().replace('T', ' ').substring(0, 19)
})) as Array<any>
}
export async function retryUploadEvidence(id: string, evidenceId: string): Promise<any | null> {
return {
id: evidenceId,
orderId: id,
phase: 'service',
fileType: 'image',
name: 'mock-retry',
url: '',
localPath: '',
status: 'success',
progress: 100,
retryable: false,
createdAt: new Date().toISOString().replace('T', ' ').substring(0, 19)
} as any
}
export async function submitException(id: string, payload: DeliveryExceptionPayloadType): Promise<DeliveryOrderType | null> {
return submitCareAbnormalReport(id, payload)
}
export async function finishService(id: string, payload: DeliveryFinishPayloadType | null = null): Promise<DeliveryOrderType | null> {
const finishPayload = payload != null ? payload : {
serviceSummary: '',
signatureName: '',
confirmByFamily: false
} as DeliveryFinishPayloadType
return await finishServiceById(id, finishPayload)
}
export async function getDeliveryRecords(): Promise<Array<DeliveryRecordType>> {
return getCareRecords()
}
export async function getDeliveryMessages(): Promise<Array<DeliveryMessageType>> {
return [
{
id: 'delivery-msg-01',
title: '今日待服务提醒',
content: '请优先处理上午 9:00 的上门助浴订单。',
type: 'workbench',
createdAt: new Date().toISOString().replace('T', ' ').substring(0, 19),
read: false,
orderId: 'mock-care-001'
} as DeliveryMessageType
]
}
export async function updateDeliveryOnlineStatus(status: string): Promise<DeliveryInfoType | null> {
if (status == 'online' || status == 'resting' || status == 'busy') {
return updateDeliveryCareOnlineStatus(status)
}
return getDeliveryCareProfile()
}
export async function getDeliveryDashboardStats(): Promise<DeliveryDashboardType> {
return await getDeliveryDashboard()
}
export async function getPendingServiceOrders(): Promise<Array<DeliveryOrderType>> {
const orders = await getDeliveryOrders({ tab: 'pending', keyword: '' } as DeliveryOrderQueryType)
const validOrders = filterOrdersWithCoreInfo(orders)
if (validOrders.length > 0) {
return validOrders
}
if (shouldFallbackOrders(orders)) {
console.warn('[deliveryService] pending orders missing core info, fallback to direct query')
const fallbackOrders = await getDirectOrdersByTab('pending')
if (fallbackOrders.length > 0) {
return fallbackOrders
}
}
return orders
}
export async function getTodayServiceOrders(): Promise<Array<DeliveryOrderType>> {
const orders = await getDeliveryOrders({ tab: 'today', keyword: '' } as DeliveryOrderQueryType)
const validOrders = filterOrdersWithCoreInfo(orders)
if (validOrders.length > 0) {
return validOrders
}
if (shouldFallbackOrders(orders)) {
console.warn('[deliveryService] today orders missing core info, fallback to direct query')
const fallbackOrders = await getDirectOrdersByTab('today')
if (fallbackOrders.length > 0) {
return fallbackOrders
}
}
return orders
}
export async function getHistoryServiceOrders(): Promise<Array<DeliveryOrderType>> {
const orders = await getDeliveryOrders({ tab: 'history', keyword: '' } as DeliveryOrderQueryType)
const validOrders = filterOrdersWithCoreInfo(orders)
if (validOrders.length > 0) {
return validOrders
}
if (shouldFallbackOrders(orders)) {
console.warn('[deliveryService] history orders missing core info, fallback to direct query')
const fallbackOrders = await getDirectOrdersByTab('history')
if (fallbackOrders.length > 0) {
return fallbackOrders
}
}
return orders
}
export async function getServiceOrderDetail(orderId: string): Promise<DeliveryOrderType | null> {
const order = await getDeliveryOrderDetailById(orderId)
if (!hasOrderCoreInfo(order)) {
console.warn('[deliveryService] order detail missing core info, fallback to direct query:', orderId)
const fallbackOrder = await getDirectServiceOrderDetail(orderId)
if (hasOrderCoreInfo(fallbackOrder)) {
return fallbackOrder
}
}
return order
}
export async function acceptServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
// 居家服务订单必须调用 rpc_homecare_accept_assignment_v2
// 不再调用 acceptDeliveryOrder / rpc_delivery_accept_order
const akUserId = await resolveCurrentAkUserIdForDelivery()
console.warn('[HOMECARE ACCEPT] acceptServiceOrder: orderId=', orderId, ' akUserId=', akUserId)
if (akUserId == '') {
uni.showToast({ title: '未获取到业务用户 ID请重新登录', icon: 'none' })
return null
}
// 调用居家服务接单 RPC
const { acceptHomecareAssignmentV2 } = await import('@/api/delivery.uts')
const result = await acceptHomecareAssignmentV2(orderId, akUserId)
console.warn('[HOMECARE ACCEPT] rpc_homecare_accept_assignment_v2 result:', result)
// 刷新订单列表
await loadData()
return null
}
/**
* 获取当前业务用户 ID从 akUserMapping 或缓存)
*/
async function resolveCurrentAkUserIdForDelivery(): Promise<string> {
try {
const id = await readCurrentAkUserId()
if (id != null && id != '') {
console.warn('[deliveryService] resolveCurrentAkUserIdForDelivery: from akUserMapping =', id)
return id
}
} catch (e) {
console.warn('[deliveryService] readCurrentAkUserId failed:', e)
}
try {
const cached = uni.getStorageSync('ak_user_id')
if (cached != null && String(cached) != '') {
console.warn('[deliveryService] resolveCurrentAkUserIdForDelivery: from storage ak_user_id =', String(cached))
return String(cached)
}
} catch (e) {}
try {
const currentAkUser = uni.getStorageSync('current_ak_user')
if (currentAkUser != null && String(currentAkUser) != '') {
const obj = JSON.parse(String(currentAkUser)) as any
if (obj != null && obj.id != null && String(obj.id) != '') {
console.warn('[deliveryService] resolveCurrentAkUserIdForDelivery: from current_ak_user.id =', String(obj.id))
return String(obj.id)
}
}
} catch (e) {}
return ''
}
export async function rejectServiceOrder(orderId: string, reason: string): Promise<DeliveryOrderType | null> {
return rejectCareOrder(orderId, reason)
}
export async function markDeparted(orderId: string): Promise<DeliveryOrderType | null> {
return await startDepartById(orderId, createEmptyLocation())
}
export async function markArrived(orderId: string): Promise<DeliveryOrderType | null> {
return await arriveOrderById(orderId, createEmptyLocation())
}
export async function checkInServiceOrder(orderId: string, note: string, location: DeliveryLocationType | null = null): Promise<DeliveryOrderType | null> {
if (location == null) {
return null
}
return await checkinOrderById(orderId, {
location,
note,
photos: [] as Array<string>,
checkinMode: 'gps'
})
}
export async function startServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
return await startServiceById(orderId)
}
export async function submitServiceRecord(orderId: string, record: DeliveryServiceRecordType): Promise<DeliveryOrderType | null> {
return await saveRealServiceRecord(orderId, record)
}
export async function completeServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
return await finishService(orderId)
}
export async function submitAbnormalReport(orderId: string, report: DeliveryExceptionPayloadType): Promise<DeliveryOrderType | null> {
return submitCareAbnormalReport(orderId, report)
}
export async function updateOrderStatus(orderId: string, nextStatus: DeliveryOrderStatus, extraRemark: string = ''): Promise<DeliveryOrderType | null> {
return updateCareOrderStatus(orderId, nextStatus, extraRemark)
}
export async function getAbnormalReport(orderId: string): Promise<DeliveryAbnormalReportType | null> {
const order = getCareOrderDetail(orderId)
return order != null ? order.abnormalReport : null
}