后端批次已提供判定/差异/强制留痕与双向读取接口,这里补界面,让客服真的能用上。 - 新增共享弹窗 ConsignmentManualMatchModal:订单侧(匹配弹窗「手动指定现货匹配」)与 库存侧(寄售仓库行内「手动匹配订单」)共用同一套交互与落地逻辑,避免两套 UI 漂移 - 交互:搜索 → 选中(精确/非精确/规格冲突三档标签 + 字段级差异说明)→ 选交付方式 (内部现货履约 / 指派供货打手)→ 非精确需勾选确认、冲突需勾选「确认规格不一致」并必填原因 → 落地;并在落地前提示"现货立刻被占用、点错需撤销寄售履约" - 判定规则收敛成纯函数 consignment-manual-match.ts(需不需要确认/填原因、能否提交、 关键词过滤、标签文案)并加 4 例单测 - 服务与类型补齐:fetchWorkOrderConsignmentMatchOptions / fetchInventoryMatchableOrders, fulfill/assign 入参增加 allowSpecMismatch 与 matchNote - 凭证核销失败的提示沿用既有规则(核销失败不能报成功) 验证:前端 typecheck/lint/format/44 例测试/build 全过;两个新接口未登录访问均 401 (路由已挂载、权限位生效)。
62 lines
2.4 KiB
TypeScript
62 lines
2.4 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
canSubmitManualMatch,
|
|
describeManualMatchType,
|
|
filterManualMatchOptions,
|
|
resolveManualMatchRequirement,
|
|
} from '../src/utils/consignment-manual-match.ts'
|
|
|
|
test('精确匹配不需要任何确认,直接可提交', () => {
|
|
assert.deepEqual(resolveManualMatchRequirement('exact'), {
|
|
needsPartialConfirm: false,
|
|
needsMismatchConfirm: false,
|
|
needsNote: false,
|
|
})
|
|
assert.equal(canSubmitManualMatch({ matchType: 'exact' }), true)
|
|
})
|
|
|
|
test('非精确匹配必须勾选确认,但不用写原因', () => {
|
|
assert.equal(resolveManualMatchRequirement('partial').needsNote, false)
|
|
assert.equal(canSubmitManualMatch({ matchType: 'partial' }), false)
|
|
assert.equal(canSubmitManualMatch({ matchType: 'partial', confirmedPartial: true }), true)
|
|
})
|
|
|
|
test('规格冲突必须勾选确认**并且**填原因', () => {
|
|
assert.equal(resolveManualMatchRequirement('conflict').needsNote, true)
|
|
assert.equal(canSubmitManualMatch({ matchType: 'conflict', confirmedMismatch: true }), false)
|
|
assert.equal(
|
|
canSubmitManualMatch({ matchType: 'conflict', confirmedMismatch: true, matchNote: ' ' }),
|
|
false,
|
|
)
|
|
assert.equal(
|
|
canSubmitManualMatch({
|
|
matchType: 'conflict',
|
|
confirmedMismatch: true,
|
|
matchNote: '订单规格录错,已与买家确认',
|
|
}),
|
|
true,
|
|
)
|
|
})
|
|
|
|
test('匹配状态文案与色调:绿/橙/红三档,冲突要一眼看出来', () => {
|
|
assert.equal(describeManualMatchType('exact').tone, 'ok')
|
|
assert.equal(describeManualMatchType('partial').tone, 'warning')
|
|
assert.equal(describeManualMatchType('conflict').tone, 'danger')
|
|
assert.equal(describeManualMatchType('conflict').label, '规格冲突')
|
|
})
|
|
|
|
test('关键词过滤:现货能按寄卖单号/物品名搜到,大小写与空格无关', () => {
|
|
const list = [
|
|
{ submissionNo: 'SUB26091711256110', itemName: '苹果微信暗潮2钻' },
|
|
{ submissionNo: 'SUB26091519501248', itemName: '安卓QQ苍龙4钻' },
|
|
]
|
|
const pick = (item: (typeof list)[number]) => [item.submissionNo, item.itemName]
|
|
|
|
assert.equal(filterManualMatchOptions(list, '', pick).length, 2)
|
|
assert.equal(filterManualMatchOptions(list, ' sub260917 ', pick).length, 1)
|
|
assert.equal(filterManualMatchOptions(list, '苍龙', pick).length, 1)
|
|
assert.equal(filterManualMatchOptions(list, '不存在', pick).length, 0)
|
|
})
|