预校验、签到流程跑通

This commit is contained in:
2026-06-16 11:32:53 +08:00
parent 72d29d4b68
commit 6b11144366
13 changed files with 3900 additions and 6067 deletions

View File

@@ -1,5 +1,6 @@
import {
import {
acceptDeliveryOrderById,
acceptHomecareAssignmentV2,
arriveOrderById,
checkinOrderById,
finishServiceById,
@@ -33,6 +34,7 @@ import type {
DeliveryLocationType,
DeliveryLoginPayloadType,
DeliveryLoginResultType,
DeliveryActionResultType,
DeliveryMessageType,
DeliveryOrderQueryType,
DeliveryOrderStatus,
@@ -99,6 +101,80 @@ function shouldFallbackOrders(orders: Array<DeliveryOrderType>): boolean {
return true
}
function getOrderCanonicalKey(order: DeliveryOrderType): string {
const orderNo = String(order.orderNo).trim().toLowerCase()
if (orderNo != '') {
return orderNo
}
const sourceOrderId = String(order.sourceOrderId).trim().toLowerCase()
if (sourceOrderId != '') {
return sourceOrderId
}
const legacyServiceOrderId = String(order.legacyServiceOrderId).trim().toLowerCase()
if (legacyServiceOrderId != '') {
return legacyServiceOrderId
}
return String(order.id).trim().toLowerCase()
}
function isActiveHomecareStatus(status: string): boolean {
const s = String(status).trim().toLowerCase()
return s == 'assigned' ||
s == 'accepted' ||
s == 'departed' ||
s == 'arrived' ||
s == 'in_service' ||
s == 'serving' ||
s == 'service_started' ||
s == 'completed'
}
function buildActiveOrderKeys(orders: Array<DeliveryOrderType>): Array<string> {
const keys = [] as Array<string>
for (let i = 0; i < orders.length; i++) {
const order = orders[i]
if (!isActiveHomecareStatus(String(order.status))) {
continue
}
const key = getOrderCanonicalKey(order)
if (key == '') {
continue
}
let exists = false
for (let j = 0; j < keys.length; j++) {
if (keys[j] == key) {
exists = true
break
}
}
if (!exists) {
keys.push(key)
}
}
return keys
}
function filterPendingOrdersAgainstActiveKeys(orders: Array<DeliveryOrderType>, activeKeys: Array<string>): Array<DeliveryOrderType> {
if (orders.length == 0 || activeKeys.length == 0) {
return orders
}
const result = [] as Array<DeliveryOrderType>
for (let i = 0; i < orders.length; i++) {
const key = getOrderCanonicalKey(orders[i])
let duplicated = false
for (let j = 0; j < activeKeys.length; j++) {
if (activeKeys[j] == key) {
duplicated = true
break
}
}
if (!duplicated) {
result.push(orders[i])
}
}
return result
}
function mapOrderToRecord(order: DeliveryOrderType): DeliveryRecordType {
const isAccepted = order.status == 'completed' || order.status == 'pending_acceptance' || order.status == 'settled' || order.status == 'archived'
return {
@@ -130,7 +206,6 @@ export async function loginDelivery(payload: DeliveryLoginPayloadType): Promise<
export async function getDeliveryProfile(): Promise<DeliveryInfoType | null> {
const authResult = await requireDeliveryAuth({ redirectOnFail: false, toastOnFail: false })
if (!authResult.ok) {
return null
}
return authResult.deliveryInfo
}
@@ -153,14 +228,28 @@ export async function checkDeliveryAuth(): Promise<boolean> {
}
async function getCurrentStaffId(): Promise<string> {
// 旧 delivery RPCdashboard / order_list需要 ml_delivery_staff.id513449ca...
console.log('[DELIVERY_SERVICE_TRACE][getCurrentStaffId][START]', {
hasDeliveryInfo: getDeliveryInfo() != null
})
// delivery RPC (dashboard / order_list) 需要使用 ml_delivery_staff.id
const deliveryInfo = getDeliveryInfo()
if (deliveryInfo != null && deliveryInfo.id != null && String(deliveryInfo.id) != '') {
console.warn('[deliveryService] getCurrentStaffId: 使用 deliveryStaffId =', String(deliveryInfo.id))
return String(deliveryInfo.id)
const resolvedId = String(deliveryInfo.id)
console.log('[DELIVERY_SERVICE_TRACE][getCurrentStaffId][RESOLVED]', {
source: 'deliveryStaffId',
resolvedId: resolvedId
})
return resolvedId
}
console.error('[deliveryService] getCurrentStaffId: 未获取到 deliveryStaffId')
console.error('[DELIVERY_SERVICE_TRACE][getCurrentStaffId][ERROR]', {
errorMessage: 'deliveryStaffId not available',
errorStack: '',
params: {
hasDeliveryInfo: deliveryInfo != null
}
})
return ''
}
@@ -174,27 +263,91 @@ function createEmptyLocation(): DeliveryLocationType {
}
export async function getDeliveryDashboard(): Promise<DeliveryDashboardType> {
console.log('[DELIVERY_SERVICE_TRACE][getDeliveryDashboard][START]', {})
const staffId = await getCurrentStaffId()
if (staffId != '') {
return await getDeliveryDashboardByStaffId(staffId)
try {
const result = await getDeliveryDashboardByStaffId(staffId)
console.log('[DELIVERY_SERVICE_TRACE][getDeliveryDashboard][SUCCESS]', {
result: result
})
return result
} catch (e) {
console.error('[DELIVERY_SERVICE_TRACE][getDeliveryDashboard][ERROR]', {
errorMessage: e != null ? String(e.message ?? e) : '',
errorStack: e != null ? String(e.stack ?? '') : '',
params: {
staffId: staffId
}
})
return emptyDashboard()
}
}
// staffId 为空时返回空 dashboard
console.error('[deliveryService] getDeliveryDashboard: staffId 为空,返回空数据')
console.error('[DELIVERY_SERVICE_TRACE][getDeliveryDashboard][ERROR]', {
errorMessage: 'staffId is empty',
errorStack: '',
params: {}
})
return emptyDashboard()
}
export async function getDeliveryOrders(params: DeliveryOrderQueryType): Promise<Array<DeliveryOrderType>> {
console.log('[DELIVERY_SERVICE_TRACE][getDeliveryOrders][START]', {
params: params
})
const staffId = await getCurrentStaffId()
if (staffId != '') {
return await getDeliveryOrdersByStaffId(staffId, params)
try {
const result = await getDeliveryOrdersByStaffId(staffId, params)
console.log('[DELIVERY_SERVICE_TRACE][getDeliveryOrders][SUCCESS]', {
count: result.length,
result: result
})
return result
} catch (e) {
console.error('[DELIVERY_SERVICE_TRACE][getDeliveryOrders][ERROR]', {
errorMessage: e != null ? String(e.message ?? e) : '',
errorStack: e != null ? String(e.stack ?? '') : '',
params: {
staffId: staffId,
query: params
}
})
return [] as Array<DeliveryOrderType>
}
}
// staffId 为空时返回空列表
console.error('[deliveryService] getDeliveryOrders: staffId 为空,返回空列表')
console.error('[DELIVERY_SERVICE_TRACE][getDeliveryOrders][ERROR]', {
errorMessage: 'staffId is empty',
errorStack: '',
params: {
query: params
}
})
return [] as Array<DeliveryOrderType>
}
export async function getDeliveryOrderDetail(id: string): Promise<DeliveryOrderType | null> {
return await getDeliveryOrderDetailById(id)
console.log('[DELIVERY_SERVICE_TRACE][getDeliveryOrderDetail][START]', {
id: id
})
try {
const result = await getDeliveryOrderDetailById(id)
console.log('[DELIVERY_SERVICE_TRACE][getDeliveryOrderDetail][SUCCESS]', {
id: id,
hasResult: result != null,
result: result
})
return result
} catch (e) {
console.error('[DELIVERY_SERVICE_TRACE][getDeliveryOrderDetail][ERROR]', {
errorMessage: e != null ? String(e.message ?? e) : '',
errorStack: e != null ? String(e.stack ?? '') : '',
params: {
id: id
}
})
return null
}
}
export async function acceptDeliveryOrder(id: string): Promise<DeliveryOrderType | null> {
@@ -301,18 +454,36 @@ export async function getDeliveryDashboardStats(): Promise<DeliveryDashboardType
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
let pendingOrders = filterOrdersWithCoreInfo(orders)
if (pendingOrders.length == 0) {
pendingOrders = orders
}
let todayOrders = await getDeliveryOrders({ tab: 'today', keyword: '' } as DeliveryOrderQueryType)
let validTodayOrders = filterOrdersWithCoreInfo(todayOrders)
if (validTodayOrders.length == 0) {
validTodayOrders = todayOrders
}
if (shouldFallbackOrders(todayOrders)) {
const fallbackTodayOrders = await getDirectOrdersByTab('today')
if (fallbackTodayOrders.length > 0) {
validTodayOrders = fallbackTodayOrders
}
}
const activeKeys = buildActiveOrderKeys(validTodayOrders)
const filteredPendingOrders = filterPendingOrdersAgainstActiveKeys(pendingOrders, activeKeys)
if (filteredPendingOrders.length > 0 || pendingOrders.length == 0) {
return filteredPendingOrders
}
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 filterPendingOrdersAgainstActiveKeys(fallbackOrders, activeKeys)
}
}
return orders
return filteredPendingOrders
}
export async function getTodayServiceOrders(): Promise<Array<DeliveryOrderType>> {
@@ -359,29 +530,37 @@ export async function getServiceOrderDetail(orderId: string): Promise<DeliveryOr
return order
}
export async function acceptServiceOrder(orderId: string): Promise<DeliveryOrderType | null> {
// 居家服务订单必须调用 rpc_homecare_accept_assignment_v2
// 不再调用 acceptDeliveryOrder / rpc_delivery_accept_order
export async function acceptServiceOrder(orderId: string): Promise<DeliveryActionResultType> {
const akUserId = await resolveCurrentAkUserIdForDelivery()
console.warn('[HOMECARE ACCEPT] acceptServiceOrder: orderId=', orderId, ' akUserId=', akUserId)
if (akUserId == '') {
uni.showToast({ title: '未获取到业务用户 ID请重新登录', icon: 'none' })
return null
return {
ok: false,
message: '未获取到业务用户 ID请重新登录',
order: null
} as DeliveryActionResultType
}
// 调用居家服务接单 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
if (result == null) {
return {
ok: false,
message: '接单失败,请稍后重试',
order: null
} as DeliveryActionResultType
}
const ok = result.getBoolean('ok') ?? false
const message = result.getString('message') ?? ''
return {
ok,
message,
order: null
} as DeliveryActionResultType
}
/**
* 获取当前业务用户 ID akUserMapping 或缓存)
* 鑾峰彇褰撳墠涓氬姟鐢ㄦ埛 ID锛堜粠 akUserMapping 鎴栫紦瀛橈級
*/
async function resolveCurrentAkUserIdForDelivery(): Promise<string> {
try {