- 新增 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)。
57 lines
2.9 KiB
TypeScript
57 lines
2.9 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import { fileURLToPath } from 'node:url'
|
|
import test from 'node:test'
|
|
|
|
/**
|
|
* 寄卖规格口径(2026-09 定案):
|
|
* - 操作后台全量:系统 苹果/安卓/通用,区服 微信区/QQ区/互通;
|
|
* - 打手端发布按物品类型展示:苏尔南 = 系统二选一(苹果/安卓,不给通用),
|
|
* 区服固定「互通」且默认选中(互通 = QQ/微信都能收);
|
|
* - 「互通」是区服通配值(互通现货匹配微信/QQ 订单,反之亦然),
|
|
* 订单文案里的「通用/全区/不限」由后端归一化成通配别名。
|
|
*/
|
|
|
|
test('后台全量选项:系统含通用,区服含互通', () => {
|
|
const source = readFileSync(
|
|
fileURLToPath(new URL('../src/utils/consignment-spec.ts', import.meta.url)),
|
|
'utf8',
|
|
)
|
|
assert.ok(source.includes("{ label: '通用', value: '通用' }"), '系统全量选项必须含「通用」')
|
|
assert.ok(source.includes("value: '互通'"), '区服选项必须包含「互通」')
|
|
})
|
|
|
|
test('苏尔南默认配置:取消代码内置字段,由合并迁移 147 提供五个单选字段', () => {
|
|
const utils = readFileSync(
|
|
fileURLToPath(new URL('../src/utils/consignment-spec.ts', import.meta.url)),
|
|
'utf8',
|
|
)
|
|
assert.ok(!utils.includes('SURNAN_PUBLISH_SYSTEM_OPTIONS'), '前端不再写死苏尔南发布选项')
|
|
assert.ok(!utils.includes('DEFAULT_SPEC_FIELDS'), '前端不再内置默认 5 个字段')
|
|
assert.ok(utils.includes('SPEC_FIELD_TYPE_OPTIONS'), '字段类型选项必须集中维护')
|
|
})
|
|
|
|
test('打手端发布表单:按寄卖配置动态渲规格,不再回退内置字段', () => {
|
|
const source = readFileSync(
|
|
fileURLToPath(new URL('../src/pages/worker/WorkerConsignmentPage.tsx', import.meta.url)),
|
|
'utf8',
|
|
)
|
|
assert.ok(source.includes('selectedSpecs.map'), '规格字段必须来自配置动态渲染')
|
|
assert.ok(source.includes('config.specs'), '必须读取寄卖配置的 specs')
|
|
assert.ok(!source.includes('DEFAULT_SPEC_FIELDS'), '空配置不能回退内置 5 项')
|
|
assert.ok(source.includes('fetchWorkerConsignmentPricePreview'), '价格必须走动态预览接口')
|
|
assert.ok(source.includes('buildSpecItemName'), '物品名必须按名称模板生成')
|
|
assert.ok(!source.includes('[...CONSIGNMENT_'), '发布端不直接引用后台全量选项')
|
|
})
|
|
|
|
test('客服端两个表单(提报审核 / 库存编辑)用后台全量选项,不再自由填写', () => {
|
|
for (const file of ['ConsignmentSubmissionsPanel.tsx', 'ConsignmentInventoryPanel.tsx']) {
|
|
const source = readFileSync(
|
|
fileURLToPath(new URL(`../src/pages/admin/panels/${file}`, import.meta.url)),
|
|
'utf8',
|
|
)
|
|
assert.ok(source.includes('CONSIGNMENT_SYSTEM_OPTIONS'), `${file} 应引用全量系统选项`)
|
|
assert.ok(source.includes('CONSIGNMENT_ZONE_OPTIONS'), `${file} 应引用全量区服选项`)
|
|
}
|
|
})
|