fix(worker): 整单指派拼单订单无法验收
- 前端:拼单订单整单指派给本人时放行验收 - 后端:整单指派清掉 sharing_enabled;已有有效份额则拒绝
This commit is contained in:
@@ -143,6 +143,7 @@ export async function assignWorkOrderToWorker(input: {
|
||||
order: WorkOrderRow | null
|
||||
failureReason:
|
||||
| 'work_order_not_assignable'
|
||||
| 'work_order_has_shares'
|
||||
| 'worker_active_order_limit'
|
||||
| 'worker_deposit_insufficient'
|
||||
| null
|
||||
@@ -167,6 +168,19 @@ export async function assignWorkOrderToWorker(input: {
|
||||
}
|
||||
const fromStatus = workOrder.status
|
||||
|
||||
// 已有拼单份额的订单不能按整单指派:否则会出现“整单接单人 + 其他人的份额”混在一起。
|
||||
const shareCountResult = await client.query<{ total: number }>(
|
||||
`
|
||||
SELECT COUNT(*)::int AS total
|
||||
FROM work_order_shares
|
||||
WHERE work_order_id = $1 AND status <> 'cancelled'
|
||||
`,
|
||||
[input.workOrderId],
|
||||
)
|
||||
if (Number(shareCountResult.rows[0]?.total || 0) > 0) {
|
||||
return { order: null, failureReason: 'work_order_has_shares' }
|
||||
}
|
||||
|
||||
await ensureWorkerWalletWithClient(client, input.workerId, input.now)
|
||||
const wallet = await getWorkerWalletWithClient(client, input.workerId)
|
||||
const activeOrderCount = await countWorkerActiveOrdersWithClient(client, input.workerId)
|
||||
@@ -193,6 +207,9 @@ export async function assignWorkOrderToWorker(input: {
|
||||
friend_added_at = NULL,
|
||||
gift_available_at = NULL,
|
||||
${CLEAR_DELIVERY_RESIDUE_SQL},
|
||||
-- 管理端/寄卖履约都是整单指派,不会创建 work_order_shares;
|
||||
-- 必须同时清掉拼单标记,避免出现“已开拼单但没有份额”的脏状态。
|
||||
sharing_enabled = false,
|
||||
updated_at = $2
|
||||
WHERE id = $4
|
||||
`,
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
countWorkerActiveOrders,
|
||||
createWorkOrderEvent,
|
||||
getWorkerUserById,
|
||||
listWorkOrderShares,
|
||||
} from '../../repositories/worker-platform/index.js'
|
||||
import type { JsonObject } from '../../types/json.js'
|
||||
import { createHttpError } from '../../utils/http.js'
|
||||
@@ -64,6 +65,18 @@ export async function assignAdminWorkOrderToWorker(
|
||||
})
|
||||
}
|
||||
|
||||
// 已有拼单份额的订单不能再按整单指派;放在核销电子凭证之前,
|
||||
// 避免“凭证已核销但指派失败”的副作用。
|
||||
const activeShares = (await listWorkOrderShares(workOrder.id)).filter(
|
||||
(share) => share.status !== 'cancelled',
|
||||
)
|
||||
if (activeShares.length > 0) {
|
||||
throw createHttpError('该订单已有拼单份额,不能按整单指派;请使用拼单管理', {
|
||||
statusCode: 409,
|
||||
errorCode: 'work_order_has_shares',
|
||||
})
|
||||
}
|
||||
|
||||
const voucherConsume = await consumeIndustryVouchersBeforeWorkOrderAssign(workOrder)
|
||||
if (!voucherConsume.ok) {
|
||||
const failedAt = nowIso()
|
||||
@@ -112,6 +125,15 @@ export async function assignAdminWorkOrderToWorker(
|
||||
{ statusCode: 409, errorCode: 'worker_deposit_insufficient' },
|
||||
)
|
||||
}
|
||||
if (failureReason === 'work_order_has_shares') {
|
||||
throw createHttpError(
|
||||
resolveAssignFailureMessage(
|
||||
voucherConsume.voucherCount,
|
||||
'该订单已有拼单份额,不能按整单指派;请使用拼单管理',
|
||||
),
|
||||
{ statusCode: 409, errorCode: 'work_order_has_shares' },
|
||||
)
|
||||
}
|
||||
if (!updated) {
|
||||
throw createHttpError(
|
||||
resolveAssignFailureMessage(voucherConsume.voucherCount, '指派失败,订单状态可能已变化'),
|
||||
|
||||
Reference in New Issue
Block a user