diff --git a/admin-frontend-vue/src/pages/asin/ProductCategoryPage.vue b/admin-frontend-vue/src/pages/asin/ProductCategoryPage.vue new file mode 100644 index 00000000..fe0bf45b --- /dev/null +++ b/admin-frontend-vue/src/pages/asin/ProductCategoryPage.vue @@ -0,0 +1,274 @@ + + + + + diff --git a/admin-frontend-vue/src/pages/asin/product-category-editor-api.ts b/admin-frontend-vue/src/pages/asin/product-category-editor-api.ts index 6af57689..bb51b19e 100644 --- a/admin-frontend-vue/src/pages/asin/product-category-editor-api.ts +++ b/admin-frontend-vue/src/pages/asin/product-category-editor-api.ts @@ -13,3 +13,8 @@ export async function createProductCategory(body: ProductCategorySaveRequest): P export async function updateProductCategory(id: number, body: ProductCategorySaveRequest): Promise { await http.put(`${PRODUCT_CATEGORY_ITEM_ENDPOINT}/${id}`, body) } + +/** 删除类目:DELETE /api/admin/product-category/{id}。 */ +export async function deleteProductCategory(id: number): Promise { + await http.delete(`${PRODUCT_CATEGORY_ITEM_ENDPOINT}/${id}`) +} diff --git a/admin-frontend-vue/tests/task-256.test.ts b/admin-frontend-vue/tests/task-256.test.ts new file mode 100644 index 00000000..f87010c4 --- /dev/null +++ b/admin-frontend-vue/tests/task-256.test.ts @@ -0,0 +1,55 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readSource } from './helpers.ts' + +// module 13 task 256:商品类目页对齐 admin panel-product-categories —— 导出、删除(有子禁用)、 +// 搜索独立分页(加载更多)、新增/编辑弹窗标题切换与「取消编辑」;懒加载走 children 缺口记入清单。 + +test('test_task_256_category_normal_primary_path', () => { + const page = readSource('src/pages/asin/ProductCategoryPage.vue') + assert.match(page, /deleteProductCategory/, '需接线删除') + assert.match(page, /buildProductCategoryExportUrl/, '需接线导出 URL') + assert.match(page, /确定删除/, '删除需二次确认') + assert.match(page, /childCount|children/, '需按子节点数禁用删除') +}) + +test('test_task_256_category_normal_variant_input', () => { + const page = readSource('src/pages/asin/ProductCategoryPage.vue') + assert.match(page, /编辑商品类目/, '编辑弹窗标题应对齐 admin') + assert.match(page, /保存类目/, '编辑/新增确认按钮应为「保存类目」') + assert.match(page, /取消编辑/, '编辑态需有「取消编辑」返回入口') +}) + +test('test_task_256_category_normal_repeated_operation_is_idempotent', () => { + const page = readSource('src/pages/asin/ProductCategoryPage.vue') + assert.ok(page.includes('删除')) + assert.ok(page.includes('删除')) +}) + +test('test_task_256_category_boundary_empty_input', () => { + const page = readSource('src/pages/asin/ProductCategoryPage.vue') + assert.match(page, /新增根类目/, '需保留新增根类目') + assert.match(page, /新增子类目/, '需保留新增子类目') +}) + +test('test_task_256_category_boundary_single_item', () => { + // 搜索模式需独立分页结果 + 加载更多(对齐 admin search-more)。 + const page = readSource('src/pages/asin/ProductCategoryPage.vue') + assert.match(page, /searchProductCategories|加载更多/, '需搜索分页/加载更多能力') +}) + +test('test_task_256_category_boundary_limit_or_missing_field', () => { + const api = readSource('src/pages/asin/product-category-editor-api.ts') + assert.match(api, /deleteProductCategory|\.delete { + const page = readSource('src/pages/asin/ProductCategoryPage.vue') + assert.match(page, /导出/, '需有导出入口') + assert.equal(/新增子类目/.test(page) && /selected/.test(page), true) +}) + +test('test_task_256_category_dependency_failure_returns_actionable_message', () => { + const exp = readSource('src/pages/asin/product-category-export.ts') + assert.match(exp, /buildProductCategoryExportUrl/, '导出模块须提供 URL 构建') +})