fix(worker): 用户付款金额未变化时不再写审计日志

This commit is contained in:
2026-11-01 16:15:47 +08:00
parent c46d9083a8
commit d135a34e35
3 changed files with 77 additions and 10 deletions
@@ -31,6 +31,7 @@ import {
updateAdminWorkOrderPaymentAmount,
updateAdminWorkOrderSharing,
} from '../../../services/worker-platform/index.js'
import { buildWorkOrderPaymentAmountAuditData } from '../../../services/worker-platform/work-order-payment-amount.js'
import {
createJsonHandler,
requireAdminPermission,
@@ -251,20 +252,14 @@ router.put(
errorMessage: '修改用户付款金额失败',
scope: '[admin/worker-platform/orders/:workOrderId/payment-amount]',
audit: (req, data) => {
const result = (data || {}) as {
previousAmountFen?: number | null
amountFen?: number
reason?: string
}
// 金额未变化时服务层不会写工单事件,这里也不留下一条“已更新”的审计记录。
const auditData = buildWorkOrderPaymentAmountAuditData(data)
if (!auditData) return null
return {
action: 'work_order_payment_amount_updated',
targetType: 'work_order',
targetId: String(req.params.workOrderId || ''),
data: {
previousAmountFen: result.previousAmountFen ?? null,
amountFen: result.amountFen ?? null,
reason: result.reason || '',
},
data: auditData,
}
},
},
@@ -2,6 +2,7 @@ import assert from 'node:assert/strict'
import test from 'node:test'
import {
buildWorkOrderPaymentAmountAuditData,
mergeUserPaymentAmountIntoMaterial,
normalizeUserPaymentAmountFen,
resolveDisplayedUserPaymentAmountFen,
@@ -87,3 +88,38 @@ test('mergeUserPaymentAmountIntoMaterial:兼容 JSON 字符串与异常结构'
source: { orderAmountFen: 1234 },
})
})
test('buildWorkOrderPaymentAmountAuditData:未变化不写审计,变化时保留原值', () => {
assert.equal(
buildWorkOrderPaymentAmountAuditData({
unchanged: true,
previousAmountFen: 1000,
amountFen: 1000,
reason: '',
}),
null,
'未变化提交不能留下「已更新」审计',
)
assert.deepEqual(
buildWorkOrderPaymentAmountAuditData({
unchanged: false,
previousAmountFen: 1000,
amountFen: 1234,
reason: ' 修正 ',
}),
{ previousAmountFen: 1000, amountFen: 1234, reason: '修正' },
)
assert.deepEqual(
buildWorkOrderPaymentAmountAuditData({
unchanged: false,
previousAmountFen: null,
amountFen: 1234,
}),
{ previousAmountFen: null, amountFen: 1234, reason: '' },
'原标题金额缺失时保留 null,不能误写成 0',
)
assert.equal(buildWorkOrderPaymentAmountAuditData(null), null)
})
@@ -78,3 +78,39 @@ export function mergeUserPaymentAmountIntoMaterial(
}
return { ...material, source: nextSource }
}
export type WorkOrderPaymentAmountAuditData = {
previousAmountFen: number | null
amountFen: number | null
reason: string
}
function toAmountFenOrNull(value: unknown): number | null {
if (value === null || value === undefined || value === '') return null
const parsed = Number(value)
return Number.isFinite(parsed) ? parsed : null
}
/**
* 后台审计载荷:金额未变化时不写「已更新」审计。
*
* 前端已拦截未变化提交,但接口仍可能被直接调用或重放;此时服务层不会写
* payment_amount_updated 工单事件,审计也不能留下一条原金额等于新金额的修改记录。
*/
export function buildWorkOrderPaymentAmountAuditData(
data: unknown,
): WorkOrderPaymentAmountAuditData | null {
if (!data || typeof data !== 'object' || Array.isArray(data)) return null
const result = data as {
previousAmountFen?: unknown
amountFen?: unknown
reason?: unknown
unchanged?: unknown
}
if (result.unchanged === true) return null
return {
previousAmountFen: toAmountFenOrNull(result.previousAmountFen),
amountFen: toAmountFenOrNull(result.amountFen),
reason: String(result.reason || '').trim(),
}
}