修复更新资料未修改接单价格

This commit is contained in:
yml2213
2026-08-19 18:42:34 +08:00
parent ab6387759e
commit 1bea34367b
3 changed files with 91 additions and 24 deletions
@@ -1473,16 +1473,6 @@ export async function submitAdminWorkOrderMaterial(
errorCode: 'work_order_material_status_invalid',
})
}
if (
workOrder.sharing_enabled === true &&
Number(workOrder.active_share_quantity || 0) > 0 &&
payload.rewardAmount !== undefined
) {
throw createHttpError('拼单订单的份额奖励已锁定,不能在更新资料时修改价格', {
statusCode: 409,
errorCode: 'work_order_material_reward_sharing_invalid',
})
}
const fields = resolveRequirementFields(workOrder)
const submittedFields = normalizeSubmittedFields(payload.fields || payload.material || payload)
@@ -1491,12 +1481,13 @@ export async function submitAdminWorkOrderMaterial(
)
const now = nowIso()
const screenshots = normalizeUploadedFiles(payload.screenshots || payload.files)
const rewardAmount =
workOrder.sharing_enabled === true &&
Number(workOrder.active_share_quantity || 0) > 0 &&
payload.rewardAmount !== undefined
? normalizeAmountFen(payload.rewardAmount, workOrder.reward_amount)
: workOrder.reward_amount
const hasActiveShares = Number(workOrder.active_share_quantity || 0) > 0
const rewardAmount = resolveAdminMaterialRewardAmount({
currentRewardAmount: Number(workOrder.reward_amount || 0),
requestedRewardAmount: payload.rewardAmount,
sharingEnabled: workOrder.sharing_enabled === true,
activeShareQuantity: Number(workOrder.active_share_quantity || 0),
})
const material = {
...safeParseJson(workOrder.material_json),
collect: {
@@ -1507,7 +1498,6 @@ export async function submitAdminWorkOrderMaterial(
source: 'admin',
},
}
const hasActiveShares = Number(workOrder.active_share_quantity || 0) > 0
const nextStatus =
hasActiveShares || workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
? workOrder.status
@@ -1530,7 +1520,12 @@ export async function submitAdminWorkOrderMaterial(
: 'material_completed',
fromStatus: workOrder.status,
toStatus: nextStatus,
payloadJson: JSON.stringify({ fields: submittedFields, complete, rewardAmount }),
payloadJson: JSON.stringify({
fields: submittedFields,
complete,
previousRewardAmount: Number(workOrder.reward_amount || 0),
rewardAmount,
}),
now,
})
if (nextStatus !== WORK_ORDER_STATUS.PENDING_MATERIAL) {
@@ -1543,6 +1538,23 @@ export async function submitAdminWorkOrderMaterial(
return { order: mapWorkOrderAdmin(updated || workOrder), complete }
}
/** 更新资料时仅普通接单可改价;已有参与者的拼单必须保留份额价格快照。 */
export function resolveAdminMaterialRewardAmount(input: {
currentRewardAmount: number
requestedRewardAmount: unknown
sharingEnabled: boolean
activeShareQuantity: number
}): number {
if (input.requestedRewardAmount === undefined) return input.currentRewardAmount
if (input.sharingEnabled && input.activeShareQuantity > 0) {
throw createHttpError('拼单订单的份额奖励已锁定,不能在更新资料时修改价格', {
statusCode: 409,
errorCode: 'work_order_material_reward_sharing_invalid',
})
}
return normalizeAmountFen(input.requestedRewardAmount, input.currentRewardAmount)
}
export async function createAdminMockWorkOrder(payload: JsonObject = {}) {
const defaults = await ensureWorkerPlatformDefaults()
const now = nowIso()
@@ -24,6 +24,7 @@ import {
mapWorkOrderAdmin,
maskWorkerLeaderboardDisplayName,
resolveCollectSubmitTargetWorkOrder,
resolveAdminMaterialRewardAmount,
resolveMatchingProductRuleDecision,
resolveWorkerPermissions,
resolveSkuNameQuantity,
@@ -741,6 +742,50 @@ test('拼单份额撤单只允许未验收份额并让母工单回到大厅状
assert.equal(resolveWorkOrderShareCancellationStatus('open', 'cancelled'), null)
})
test('后台更新资料时普通接单可以修改接单价格', () => {
assert.equal(
resolveAdminMaterialRewardAmount({
currentRewardAmount: 1280,
requestedRewardAmount: 15.5,
sharingEnabled: false,
activeShareQuantity: 0,
}),
1550,
)
})
test('后台更新资料未提交价格时保留原接单价格', () => {
assert.equal(
resolveAdminMaterialRewardAmount({
currentRewardAmount: 1280,
requestedRewardAmount: undefined,
sharingEnabled: false,
activeShareQuantity: 0,
}),
1280,
)
})
test('后台更新资料禁止修改已有参与者的拼单价格', () => {
assert.throws(
() =>
resolveAdminMaterialRewardAmount({
currentRewardAmount: 3840,
requestedRewardAmount: 15.5,
sharingEnabled: true,
activeShareQuantity: 3,
}),
(error: unknown) =>
Boolean(
error &&
typeof error === 'object' &&
(error as { statusCode?: number }).statusCode === 409 &&
(error as { errorCode?: string }).errorCode ===
'work_order_material_reward_sharing_invalid',
),
)
})
test('resolveCollectSubmitTargetWorkOrder returns the only pending work order when no id is provided', () => {
const workOrder = buildWorkOrderRow()
const selected = resolveCollectSubmitTargetWorkOrder('ORDER-001', [workOrder], '')