feat(consignment): 接单模板反推规格字段,打手端大批量选项改下拉
- 新增 consignment-template-spec-service:按「分类 + 子树」解析接单模板商品名, 全部可拆成统一维度且无组合碰撞时生成多字段矩阵,否则整类降级为商品名下拉; 选项只存 ruleKey,取价时实时回查模板,模板停用/删除即无价(missingPricePolicy=block)。 - 匹配引擎:模板驱动配置强制使用 profile specs(不再回退库存旧快照),订单侧按 product_rule_id 反解规格;解析失败按 unknown 处理,不参与自动匹配。 - 管理端:寄卖配置新增「从接单模板生成」,弹窗给出推荐模式(规格字段 / 商品名下拉)、 降级原因与组合→模板价覆盖矩阵。 - 打手端:选项超过 8 个改用带搜索的下拉(地铁逃生 100 个商品),规格网格按字段数 自适应铺满;物品名改用商品名,去掉硬编码「苏尔南」后缀。 - 迁移重编号:合并 main 后寄卖线顺延为 147–151,migrate.ts 保留 legacy→new 幂等映射。 - 同工作区的拼单份额报酬口径、超时重匹配兜底、整单/拼单匹配弹窗调整一并提交。 验证:前端 254/254、后端寄卖相关 41/41、双端 tsc 通过;开发库已实跑 发布→审核入库→自动匹配(模板价 1200 → 匹配报酬 1200)。
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import test from 'node:test'
|
||||
|
||||
/**
|
||||
@@ -24,21 +25,21 @@ function assertTopLevelMount(filePath: string, componentName: string) {
|
||||
|
||||
test('库存面板:手动匹配订单弹窗挂在顶层(按钮点了必须能弹出来)', () => {
|
||||
assertTopLevelMount(
|
||||
new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url)),
|
||||
'ConsignmentManualMatchModal',
|
||||
)
|
||||
})
|
||||
|
||||
test('订单面板:手动指定现货弹窗同样挂在顶层', () => {
|
||||
assertTopLevelMount(
|
||||
new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url)),
|
||||
'ConsignmentManualMatchModal',
|
||||
)
|
||||
})
|
||||
|
||||
test('按钮点击要真的把状态设上,弹窗的 open 由该状态驱动', () => {
|
||||
const source = readFileSync(
|
||||
new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
assert.ok(source.includes('setManualMatchItem(record)'), '行内按钮必须设置待匹配的现货')
|
||||
@@ -47,7 +48,7 @@ test('按钮点击要真的把状态设上,弹窗的 open 由该状态驱动',
|
||||
|
||||
test('手动匹配入口必须按 consignment.fulfill 门控(提交的是履约动作,不能只挂 manage)', () => {
|
||||
const inventoryPanel = readFileSync(
|
||||
new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
// 库存面板:手动匹配订单按钮要与编辑/作废拆开 —— 前者 fulfill(提交打到
|
||||
@@ -64,7 +65,7 @@ test('手动匹配入口必须按 consignment.fulfill 门控(提交的是履
|
||||
)
|
||||
|
||||
const ordersPanel = readFileSync(
|
||||
new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
// 拦截弹窗 footer 的入口同样要门控,无 fulfill 权限的人不该看到能直达 403 的按钮
|
||||
@@ -80,7 +81,7 @@ test('手动匹配入口必须按 consignment.fulfill 门控(提交的是履
|
||||
|
||||
test('手动匹配弹窗:数据过期的 409 要清选择并刷新,走内部现货直接履约', () => {
|
||||
const source = readFileSync(
|
||||
new URL('../src/components/admin/ConsignmentManualMatchModal.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/components/admin/ConsignmentManualMatchModal.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
// 并发占用/规格在打开弹窗后被改 → 清空选择并重新拉列表,不能让运营循环撞同一个错
|
||||
@@ -103,7 +104,7 @@ test('手动匹配弹窗:数据过期的 409 要清选择并刷新,走内部
|
||||
|
||||
test('发布拦截弹窗:只走内部现货履约,文案停在待加好友而不是冷静期', () => {
|
||||
const source = readFileSync(
|
||||
new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/WorkOrdersPanel.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
assert.ok(source.includes('fulfillWorkOrderWithConsignment'), '拦截弹窗必须调用内部现货履约')
|
||||
@@ -119,7 +120,7 @@ test('发布拦截弹窗:只走内部现货履约,文案停在待加好友
|
||||
|
||||
test('寄售仓库库存面板:必须包含「通过审核入库时间」列,且详情弹窗正确展示时间', () => {
|
||||
const source = readFileSync(
|
||||
new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
assert.ok(source.includes("title: '通过审核入库时间'"), '库存表格必须有「通过审核入库时间」列')
|
||||
@@ -136,7 +137,7 @@ test('寄售仓库库存面板:必须包含「通过审核入库时间」列
|
||||
|
||||
test('手动匹配弹窗:候选订单必须展示创建时间,现货展示审核入库时间', () => {
|
||||
const source = readFileSync(
|
||||
new URL('../src/components/admin/ConsignmentManualMatchModal.tsx', import.meta.url).pathname,
|
||||
fileURLToPath(new URL('../src/components/admin/ConsignmentManualMatchModal.tsx', import.meta.url)),
|
||||
'utf8',
|
||||
)
|
||||
assert.ok(
|
||||
|
||||
Reference in New Issue
Block a user