拆分资料收集服务
This commit is contained in:
@@ -12,6 +12,7 @@ export * from './worker-profile-service.js'
|
|||||||
export * from './worker-hall-service.js'
|
export * from './worker-hall-service.js'
|
||||||
export * from './worker-order-timeout-service.js'
|
export * from './worker-order-timeout-service.js'
|
||||||
export * from './worker-order-realtime-service.js'
|
export * from './worker-order-realtime-service.js'
|
||||||
|
export * from './worker-collect-service.js'
|
||||||
export * from './worker-platform-defaults.js'
|
export * from './worker-platform-defaults.js'
|
||||||
export * from './work-order-timeout-policy.js'
|
export * from './work-order-timeout-policy.js'
|
||||||
export * from './after-sales-service.js'
|
export * from './after-sales-service.js'
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
import { WORK_ORDER_STATUS } from '../../domain/work-order-status.js'
|
||||||
|
import {
|
||||||
|
createWorkOrderEvent,
|
||||||
|
listPendingMaterialWorkOrdersByPlatformOrderId,
|
||||||
|
updateWorkOrder,
|
||||||
|
type WorkOrderRow,
|
||||||
|
} from '../../repositories/worker-platform/index.js'
|
||||||
|
import type { JsonObject } from '../../types/json.js'
|
||||||
|
import { createHttpError } from '../../utils/http.js'
|
||||||
|
import { nowIso } from '../../utils/time.js'
|
||||||
|
import { safeParseJson } from '../admin/admin-query-utils.js'
|
||||||
|
import { publishWorkOrderRealtimeChange } from '../realtime/realtime-event-service.js'
|
||||||
|
import {
|
||||||
|
mapCollectLookupOrder,
|
||||||
|
mapWorkOrderPublic,
|
||||||
|
normalizeOptionalId,
|
||||||
|
normalizeSubmittedFields,
|
||||||
|
normalizeUploadedFiles,
|
||||||
|
resolveRequirementFields,
|
||||||
|
} from './mappers.js'
|
||||||
|
|
||||||
|
export async function collectLookupWorkOrder(payload: JsonObject = {}) {
|
||||||
|
const orderNo = String(payload.orderNo || payload.platformOrderId || '').trim()
|
||||||
|
if (!orderNo) {
|
||||||
|
throw createHttpError('请填写订单号', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'collect_order_no_required',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const workOrders = await listPendingMaterialWorkOrdersByPlatformOrderId(orderNo)
|
||||||
|
if (workOrders.length === 0) {
|
||||||
|
throw createHttpError('未找到待完善订单,请确认订单号是否正确', {
|
||||||
|
statusCode: 404,
|
||||||
|
errorCode: 'collect_order_not_found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const [primaryOrder] = workOrders
|
||||||
|
if (!primaryOrder) {
|
||||||
|
throw createHttpError('未找到待完善订单,请确认订单号是否正确', {
|
||||||
|
statusCode: 404,
|
||||||
|
errorCode: 'collect_order_not_found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
order: mapWorkOrderPublic(primaryOrder),
|
||||||
|
fields: resolveRequirementFields(primaryOrder),
|
||||||
|
orders: workOrders.map(mapCollectLookupOrder),
|
||||||
|
pendingCount: workOrders.length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function collectSubmitWorkOrder(payload: JsonObject = {}) {
|
||||||
|
const orderNo = String(payload.orderNo || payload.platformOrderId || '').trim()
|
||||||
|
if (!orderNo) {
|
||||||
|
throw createHttpError('请填写订单号', {
|
||||||
|
statusCode: 400,
|
||||||
|
errorCode: 'collect_order_no_required',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const workOrders = await listPendingMaterialWorkOrdersByPlatformOrderId(orderNo)
|
||||||
|
if (workOrders.length === 0) {
|
||||||
|
throw createHttpError('未找到待完善订单,请确认订单号是否正确', {
|
||||||
|
statusCode: 404,
|
||||||
|
errorCode: 'collect_order_not_found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const workOrder = resolveCollectSubmitTargetWorkOrder(
|
||||||
|
orderNo,
|
||||||
|
workOrders,
|
||||||
|
payload.workOrderId || payload.work_order_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
const fields = resolveRequirementFields(workOrder)
|
||||||
|
const submittedFields = normalizeSubmittedFields(payload.fields || payload.material || payload)
|
||||||
|
const complete = fields.every(
|
||||||
|
(field) => !field.required || String(submittedFields[field.key] || '').trim(),
|
||||||
|
)
|
||||||
|
const now = nowIso()
|
||||||
|
const screenshots = normalizeUploadedFiles(payload.screenshots || payload.files)
|
||||||
|
const material = {
|
||||||
|
...safeParseJson(workOrder.material_json),
|
||||||
|
collect: {
|
||||||
|
fields: submittedFields,
|
||||||
|
screenshots,
|
||||||
|
submittedAt: now,
|
||||||
|
complete,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const nextStatus = complete ? WORK_ORDER_STATUS.UNASSIGNED : WORK_ORDER_STATUS.PENDING_MATERIAL
|
||||||
|
const updated = await updateWorkOrder(workOrder.id, {
|
||||||
|
status: nextStatus,
|
||||||
|
material_json: material,
|
||||||
|
updated_at: now,
|
||||||
|
})
|
||||||
|
await createWorkOrderEvent({
|
||||||
|
workOrderId: workOrder.id,
|
||||||
|
actorType: 'collect',
|
||||||
|
actorId: orderNo,
|
||||||
|
eventType: 'material_submitted',
|
||||||
|
fromStatus: workOrder.status,
|
||||||
|
toStatus: nextStatus,
|
||||||
|
payloadJson: JSON.stringify({ fields: submittedFields, complete }),
|
||||||
|
now,
|
||||||
|
})
|
||||||
|
publishWorkOrderRealtimeChange({ workOrderId: Number(workOrder.id) })
|
||||||
|
return {
|
||||||
|
order: mapWorkOrderPublic(updated || workOrder),
|
||||||
|
complete,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveCollectSubmitTargetWorkOrder(
|
||||||
|
orderNo: string,
|
||||||
|
workOrders: WorkOrderRow[],
|
||||||
|
requestedWorkOrderId: unknown,
|
||||||
|
): WorkOrderRow {
|
||||||
|
const workOrderId = normalizeOptionalId(requestedWorkOrderId)
|
||||||
|
if (workOrderId) {
|
||||||
|
const matched = workOrders.find((item) => Number(item.id) === workOrderId)
|
||||||
|
if (matched) return matched
|
||||||
|
throw createHttpError('待完善订单不存在或已更新,请刷新后重试', {
|
||||||
|
statusCode: 404,
|
||||||
|
errorCode: 'collect_work_order_not_found',
|
||||||
|
context: { orderNo, workOrderId },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (workOrders.length === 1) {
|
||||||
|
const [singleWorkOrder] = workOrders
|
||||||
|
if (singleWorkOrder) return singleWorkOrder
|
||||||
|
}
|
||||||
|
throw createHttpError('该订单存在多个待完善商品,请逐个提交资料', {
|
||||||
|
statusCode: 409,
|
||||||
|
errorCode: 'collect_work_order_required',
|
||||||
|
context: { orderNo, pendingCount: workOrders.length },
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -26,7 +26,6 @@ import {
|
|||||||
revokeWorkerSession,
|
revokeWorkerSession,
|
||||||
touchWorkerSession,
|
touchWorkerSession,
|
||||||
joinWorkOrderShare,
|
joinWorkOrderShare,
|
||||||
listPendingMaterialWorkOrdersByPlatformOrderId,
|
|
||||||
listWorkerCancelRequests,
|
listWorkerCancelRequests,
|
||||||
listWorkerOrderFeedbacks,
|
listWorkerOrderFeedbacks,
|
||||||
listWorkerSharesByWorker,
|
listWorkerSharesByWorker,
|
||||||
@@ -73,9 +72,7 @@ import {
|
|||||||
} from '../realtime/realtime-event-service.js'
|
} from '../realtime/realtime-event-service.js'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
mapCollectLookupOrder,
|
|
||||||
mapWorkOrderForWorker,
|
mapWorkOrderForWorker,
|
||||||
mapWorkOrderPublic,
|
|
||||||
mapWorkOrderEvents,
|
mapWorkOrderEvents,
|
||||||
mapWorkOrderShare,
|
mapWorkOrderShare,
|
||||||
mapWorkerCancelRequest,
|
mapWorkerCancelRequest,
|
||||||
@@ -85,10 +82,8 @@ import {
|
|||||||
normalizePositiveInteger,
|
normalizePositiveInteger,
|
||||||
normalizeStatuses,
|
normalizeStatuses,
|
||||||
normalizeStringArray,
|
normalizeStringArray,
|
||||||
normalizeSubmittedFields,
|
|
||||||
normalizeUploadedFiles,
|
normalizeUploadedFiles,
|
||||||
resolveFreezeDepositAmount,
|
resolveFreezeDepositAmount,
|
||||||
resolveRequirementFields,
|
|
||||||
resolveWorkerPermissions,
|
resolveWorkerPermissions,
|
||||||
canWorkerAutoAcceptWholeOrder,
|
canWorkerAutoAcceptWholeOrder,
|
||||||
throwGrabWorkOrderFailure,
|
throwGrabWorkOrderFailure,
|
||||||
@@ -1371,129 +1366,8 @@ async function saveWorkerSharingAcceptanceDraft(
|
|||||||
return { share: share ? mapWorkOrderShare(share) : mapWorkOrderShare(sharingShare) }
|
return { share: share ? mapWorkOrderShare(share) : mapWorkOrderShare(sharingShare) }
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function collectLookupWorkOrder(payload: JsonObject = {}) {
|
export {
|
||||||
const orderNo = String(payload.orderNo || payload.platformOrderId || '').trim()
|
collectLookupWorkOrder,
|
||||||
if (!orderNo) {
|
collectSubmitWorkOrder,
|
||||||
throw createHttpError('请填写订单号', {
|
resolveCollectSubmitTargetWorkOrder,
|
||||||
statusCode: 400,
|
} from './worker-collect-service.js'
|
||||||
errorCode: 'collect_order_no_required',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const workOrders = await listPendingMaterialWorkOrdersByPlatformOrderId(orderNo)
|
|
||||||
if (workOrders.length === 0) {
|
|
||||||
throw createHttpError('未找到待完善订单,请确认订单号是否正确', {
|
|
||||||
statusCode: 404,
|
|
||||||
errorCode: 'collect_order_not_found',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const [primaryOrder] = workOrders
|
|
||||||
if (!primaryOrder) {
|
|
||||||
throw createHttpError('未找到待完善订单,请确认订单号是否正确', {
|
|
||||||
statusCode: 404,
|
|
||||||
errorCode: 'collect_order_not_found',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
order: mapWorkOrderPublic(primaryOrder),
|
|
||||||
fields: resolveRequirementFields(primaryOrder),
|
|
||||||
orders: workOrders.map(mapCollectLookupOrder),
|
|
||||||
pendingCount: workOrders.length,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function collectSubmitWorkOrder(payload: JsonObject = {}) {
|
|
||||||
const orderNo = String(payload.orderNo || payload.platformOrderId || '').trim()
|
|
||||||
if (!orderNo) {
|
|
||||||
throw createHttpError('请填写订单号', {
|
|
||||||
statusCode: 400,
|
|
||||||
errorCode: 'collect_order_no_required',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const workOrders = await listPendingMaterialWorkOrdersByPlatformOrderId(orderNo)
|
|
||||||
if (workOrders.length === 0) {
|
|
||||||
throw createHttpError('未找到待完善订单,请确认订单号是否正确', {
|
|
||||||
statusCode: 404,
|
|
||||||
errorCode: 'collect_order_not_found',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const workOrder = resolveCollectSubmitTargetWorkOrder(
|
|
||||||
orderNo,
|
|
||||||
workOrders,
|
|
||||||
payload.workOrderId || payload.work_order_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
const fields = resolveRequirementFields(workOrder)
|
|
||||||
const submittedFields = normalizeSubmittedFields(payload.fields || payload.material || payload)
|
|
||||||
const complete = fields.every(
|
|
||||||
(field) => !field.required || String(submittedFields[field.key] || '').trim(),
|
|
||||||
)
|
|
||||||
const now = nowIso()
|
|
||||||
const screenshots = normalizeUploadedFiles(payload.screenshots || payload.files)
|
|
||||||
const material = {
|
|
||||||
...safeParseJson(workOrder.material_json),
|
|
||||||
collect: {
|
|
||||||
fields: submittedFields,
|
|
||||||
screenshots,
|
|
||||||
submittedAt: now,
|
|
||||||
complete,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
const nextStatus = complete ? WORK_ORDER_STATUS.UNASSIGNED : WORK_ORDER_STATUS.PENDING_MATERIAL
|
|
||||||
const updated = await updateWorkOrder(workOrder.id, {
|
|
||||||
status: nextStatus,
|
|
||||||
material_json: material,
|
|
||||||
updated_at: now,
|
|
||||||
})
|
|
||||||
await createWorkOrderEvent({
|
|
||||||
workOrderId: workOrder.id,
|
|
||||||
actorType: 'collect',
|
|
||||||
actorId: orderNo,
|
|
||||||
eventType: 'material_submitted',
|
|
||||||
fromStatus: workOrder.status,
|
|
||||||
toStatus: nextStatus,
|
|
||||||
payloadJson: JSON.stringify({ fields: submittedFields, complete }),
|
|
||||||
now,
|
|
||||||
})
|
|
||||||
publishWorkOrderRealtimeChange({
|
|
||||||
workOrderId: Number(workOrder.id),
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
order: mapWorkOrderPublic(updated || workOrder),
|
|
||||||
complete,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveCollectSubmitTargetWorkOrder(
|
|
||||||
orderNo: string,
|
|
||||||
workOrders: WorkOrderRow[],
|
|
||||||
requestedWorkOrderId: unknown,
|
|
||||||
): WorkOrderRow {
|
|
||||||
const workOrderId = normalizeOptionalId(requestedWorkOrderId)
|
|
||||||
if (workOrderId) {
|
|
||||||
const matched = workOrders.find((item) => Number(item.id) === workOrderId)
|
|
||||||
if (matched) {
|
|
||||||
return matched
|
|
||||||
}
|
|
||||||
throw createHttpError('待完善订单不存在或已更新,请刷新后重试', {
|
|
||||||
statusCode: 404,
|
|
||||||
errorCode: 'collect_work_order_not_found',
|
|
||||||
context: { orderNo, workOrderId },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (workOrders.length === 1) {
|
|
||||||
const [singleWorkOrder] = workOrders
|
|
||||||
if (singleWorkOrder) {
|
|
||||||
return singleWorkOrder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw createHttpError('该订单存在多个待完善商品,请逐个提交资料', {
|
|
||||||
statusCode: 409,
|
|
||||||
errorCode: 'collect_work_order_required',
|
|
||||||
context: {
|
|
||||||
orderNo,
|
|
||||||
pendingCount: workOrders.length,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user