import assert from 'node:assert/strict' import test from 'node:test' import { canManuallyMatchConsignmentOrder, 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) }) test('待指派/待补资料/大厅待抢的订单均能手动指定现货(与后端前置校验同口径)', async () => { const { isManuallyMatchableOrderStatus } = await import('../src/utils/consignment-manual-match.ts') assert.equal(isManuallyMatchableOrderStatus('unassigned'), true) assert.equal(isManuallyMatchableOrderStatus('pending_material'), true) assert.equal(isManuallyMatchableOrderStatus('open'), true) for (const status of ['in_progress', 'pending_acceptance', 'accepted', 'cancelled', 'disputed']) { assert.equal(isManuallyMatchableOrderStatus(status), false, `${status} 不该给手动匹配入口`) } }) test('寄卖只做整单:已有打手参与的拼单工单不给「手动匹配寄卖」入口', () => { // 状态允许但已有人拼单 → 不给入口(后端也会返回 work_order_sharing_not_consignable) assert.equal( canManuallyMatchConsignmentOrder({ status: 'open', sharingProgress: { joinedQuantity: 2 } }), false, '有份额被认领的拼单工单不能走寄卖现货履约', ) assert.equal( canManuallyMatchConsignmentOrder({ status: 'open', sharingWorkers: [{ workerId: 7 }] }), false, '拼单参与者列表非空同样说明已有人参与', ) // 开了拼单但还没人参与(整单照样能履约)→ 仍然给入口 assert.equal( canManuallyMatchConsignmentOrder({ status: 'open', sharingProgress: { joinedQuantity: 0 }, sharingWorkers: [], }), true, ) // 普通整单 assert.equal(canManuallyMatchConsignmentOrder({ status: 'unassigned' }), true) assert.equal(canManuallyMatchConsignmentOrder({ status: 'pending_material' }), true) // 状态本身不允许的仍然不给 for (const status of ['in_progress', 'pending_acceptance', 'accepted', 'cancelled']) { assert.equal( canManuallyMatchConsignmentOrder({ status, sharingProgress: { joinedQuantity: 0 } }), false, `${status} 本就不该给入口`, ) } })