feat(consignment): 支持复制寄卖模板配置与一二级分类折叠展示

This commit is contained in:
2026-11-09 16:00:09 +08:00
parent 6867431a72
commit 89a3d23874
10 changed files with 969 additions and 38 deletions
@@ -0,0 +1,58 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import { buildConsignmentCategoryGroups } from '../src/utils/consignment-category-tree.ts'
type Item = { id: number; parentId: number | null; parentName?: string; name: string }
function build(items: Item[]) {
return buildConsignmentCategoryGroups({
items,
getCategoryId: (item) => item.id,
getParentId: (item) => item.parentId,
getParentName: (item) => item.parentName,
getFallbackName: (item) => item.name,
})
}
test('分类树:一级在前、其二级紧随其后', () => {
const groups = build([
{ id: 1, parentId: null, name: '苏尔南手枪' },
{ id: 2, parentId: null, name: '密钥' },
{ id: 11, parentId: 1, parentName: '苏尔南手枪', name: '暗潮' },
{ id: 12, parentId: 1, parentName: '苏尔南手枪', name: '怒嚎' },
])
assert.deepEqual(
groups.map((group) => group.groupName),
['苏尔南手枪', '密钥'],
)
assert.deepEqual(
groups[0]?.children.map((child) => child.name),
['暗潮', '怒嚎'],
)
assert.equal(groups[1]?.root?.name, '密钥')
})
test('分类树:只有二级配置时创建一个无 root 的分组', () => {
const groups = build([
{ id: 11, parentId: 1, parentName: '苏尔南手枪', name: '暗潮' },
{ id: 12, parentId: 1, parentName: '苏尔南手枪', name: '怒嚎' },
])
assert.equal(groups.length, 1)
assert.equal(groups[0]?.groupName, '苏尔南手枪')
assert.equal(groups[0]?.root, null)
assert.deepEqual(
groups[0]?.children.map((child) => child.name),
['暗潮', '怒嚎'],
)
})
test('分类树:没有下级的一级保持为单节点', () => {
const groups = build([{ id: 2, parentId: null, name: '密钥' }])
assert.equal(groups.length, 1)
assert.equal(groups[0]?.root?.name, '密钥')
assert.deepEqual(groups[0]?.children, [])
})
@@ -47,7 +47,7 @@ test('寄卖配置面板:必须覆盖保证金/服务费/数量限制/匹配/
test('打手端:寄卖页必须按已发布配置动态生成 tab,并支持改价', () => {
const page = read('../src/pages/worker/WorkerConsignmentPage.tsx')
assert.ok(page.includes('fetchWorkerConsignmentProfiles'), '必须拉取已发布寄卖配置')
assert.ok(page.includes('consignmentProfiles.map'), '必须按配置生成 tab')
assert.ok(page.includes('profileTreeData'), '必须按配置生成 tab/分类树')
assert.ok(page.includes('修改售价'), '在售寄卖必须提供改价入口')
assert.ok(page.includes('updateWorkerConsignmentPrice'), '改价必须调用专用接口')
assert.ok(page.includes('priceDropSuggestion'), '必须展示降价建议')
@@ -135,3 +135,41 @@ test('寄卖配置:保证金支持按数量(规格),弹窗内配置选
assert.ok(panel.includes('specPricesYuan'), '选项价格必须写回配置')
assert.ok(panel.includes('填充全部选项'), '弹窗必须支持批量填充选项价格')
})
test('寄卖配置:规格字段与联系方式区块提供复制模板配置入口', () => {
const panel = read('../src/pages/admin/panels/ConsignmentConfigPanel.tsx')
assert.ok(panel.includes('复制模板配置'), '两个区块都要有复制模板配置按钮')
assert.ok(panel.includes("setCopyTemplateMode('specs')"), '规格字段入口必须打开规格复制')
assert.ok(panel.includes("setCopyTemplateMode('intake')"), '联系方式入口必须打开凭据复制')
assert.ok(panel.includes('ConsignmentTemplateCopyModal'), '必须挂载复制模板弹窗')
const modal = read('../src/components/admin/ConsignmentTemplateCopyModal.tsx')
assert.ok(modal.includes('已发布版本'), '复制来源必须支持已发布版本')
assert.ok(modal.includes('当前草稿'), '复制来源必须支持当前草稿')
assert.ok(modal.includes('publishedConfig'), '已发布版本必须读取发布快照配置')
assert.ok(modal.includes('不影响价格、保证金、服务费、匹配和超时设置'), '复制只替换当前区块')
assert.ok(modal.includes('ruleKey'), '模板驱动规格必须提示 ruleKey 仍指向来源模板')
assert.ok(modal.includes('TreeSelect'), '来源选择必须使用折叠树')
assert.ok(modal.includes('treeDefaultExpandAll={false}'), '来源树默认必须折叠')
assert.ok(modal.includes('treeTitleRender'), '来源树必须自定义层级标题')
})
test('打手端:寄卖分类按一二级层级展示', () => {
const page = read('../src/pages/worker/WorkerConsignmentPage.tsx')
assert.ok(page.includes('categoryParentName'), '必须使用父分类名称')
assert.ok(page.includes('orderWorkerProfiles'), '必须按一级/二级排序')
assert.ok(page.includes('profileTreeData'), '必须构建一级/二级树')
assert.ok(page.includes('TreeSelect'), '必须使用可折叠的 TreeSelect')
assert.ok(page.includes('treeDefaultExpandAll={false}'), '默认必须折叠')
assert.ok(page.includes('treeTitleRender'), '必须自定义层级标题')
assert.ok(page.includes('二级'), '二级分类必须有层级标签')
})
test('寄售仓库:寄卖分类筛选按一二级层级展示', () => {
const panel = read('../src/pages/admin/panels/ConsignmentInventoryPanel.tsx')
assert.ok(panel.includes('categoryTreeData'), '必须构建一级/二级树')
assert.ok(panel.includes('TreeSelect'), '必须使用可折叠的 TreeSelect')
assert.ok(panel.includes('treeDefaultExpandAll={false}'), '默认必须折叠')
assert.ok(panel.includes('treeTitleRender'), '必须自定义层级标题')
assert.ok(panel.includes('继承'), '继承型二级分类必须有继承标记')
})