From 0315a3a93d407418da7fe74ed5f7029e8c20c037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Sun, 6 Sep 2026 01:48:57 +0800 Subject: [PATCH] =?UTF-8?q?task-273(=E9=AA=8C=E6=94=B6=E5=8F=8D=E9=A6=88):?= =?UTF-8?q?=20=E5=BA=97=E9=93=BA=E6=95=B0=E6=8D=AE=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=AE=AB=E6=A0=BC=E6=8E=92(=E4=B8=80=E8=A1=8C3=E4=B8=AA/?= =?UTF-8?q?=E4=B8=80=E9=A1=B59=E5=BC=A0+=E5=8D=A1=E7=89=87=E5=88=86?= =?UTF-8?q?=E9=A1=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/tasks/ShopDataTasksPage.vue | 26 +++++++++++-- .../tests/align-shop-data-cards.test.ts | 4 +- .../tests/align-shop-data-grid.test.ts | 39 +++++++++++++++++++ admin-frontend-vue/tests/task-266.test.ts | 2 +- 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 admin-frontend-vue/tests/align-shop-data-grid.test.ts diff --git a/admin-frontend-vue/src/pages/tasks/ShopDataTasksPage.vue b/admin-frontend-vue/src/pages/tasks/ShopDataTasksPage.vue index 3db6c573..5bcbbb1b 100644 --- a/admin-frontend-vue/src/pages/tasks/ShopDataTasksPage.vue +++ b/admin-frontend-vue/src/pages/tasks/ShopDataTasksPage.vue @@ -30,6 +30,9 @@ const groups = ref([]) const totalShops = ref(0) const page = ref(1) const pageSize = 20 +// 卡片宫格分页:一行 3 个、一页 9 张卡片(在店铺分页的结果文件内翻页)。 +const cardPage = ref(1) +const cardPageSize = 9 const filter = reactive({ ...createShopDataFilter(), dateRange: [] }) const selection = ref>(new Set()) @@ -90,8 +93,15 @@ function reset() { } const allResultRows = computed(() => groups.value.flatMap((group) => group.results)) +const pagedResultRows = computed(() => + allResultRows.value.slice((cardPage.value - 1) * cardPageSize, cardPage.value * cardPageSize), +) const selectionCount = computed(() => countShopDataSelection(selection.value)) +function changeCardPage(p: number) { + cardPage.value = p +} + function resultFileCount(): number { return groups.value.reduce((sum, group) => sum + group.results.length, 0) } @@ -274,12 +284,12 @@ onMounted(load) :total="totalShops" :page-size="pageSize" :current-page="page" - @current-change="(p: number) => { page = p; selection = new Set(); load() }" + @current-change="(p: number) => { page = p; cardPage = 1; selection = new Set(); load() }" />
-
+
{{ row.shopName || '-' }}
@@ -335,6 +345,16 @@ onMounted(load)
+ @@ -366,7 +386,7 @@ onMounted(load) .f-item.wide { width: 340px; } .f-item.btn-row { flex-direction: row; align-items: flex-end; gap: 8px; width: auto; } .shop-summary-row { display: flex; justify-content: space-between; align-items: center; color: var(--el-text-color-secondary); font-size: 13px; } -.shop-card-grid { display: flex; flex-direction: column; gap: 14px; } +.shop-card-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; } .shop-card { border: 1px solid var(--el-border-color); border-radius: 12px; background: #fff; box-shadow: 0 1px 2px rgba(39, 67, 94, 0.04), 0 14px 30px -24px rgba(39, 67, 94, 0.28); overflow: hidden; } .shop-card-head { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--el-border-color-lighter); } .shop-name { font-weight: 600; color: var(--el-text-color-primary); } diff --git a/admin-frontend-vue/tests/align-shop-data-cards.test.ts b/admin-frontend-vue/tests/align-shop-data-cards.test.ts index df597009..bdb6568e 100644 --- a/admin-frontend-vue/tests/align-shop-data-cards.test.ts +++ b/admin-frontend-vue/tests/align-shop-data-cards.test.ts @@ -6,8 +6,8 @@ import { readSource } from './helpers.ts' test('align_shop_data_cards_per_task', () => { const page = readSource('src/pages/tasks/ShopDataTasksPage.vue') - // 每任务一张卡:以 resultRow 迭代渲染卡片,不再按店铺聚合。 - assert.match(page, /v-for="row in allResultRows"/, '逐任务卡片渲染') + // 每任务一张卡:以 resultRow 迭代渲染卡片(宫格分页后绑定 pagedResultRows),不再按店铺聚合。 + assert.match(page, /v-for="row in pagedResultRows"/, '逐任务卡片渲染') assert.doesNotMatch(page, /v-for="group in groups"/, '去掉按店铺聚合卡片') // 卡片结构:店铺名头 + 任务号/状态 + 分组/最新/国家/文件 信息行 + 下载文件/删除。 assert.match(page, /任务 {{ row\.taskNo \|\| row\.resultId }}|任务 {{ row\.taskNo/, '卡片含任务号') diff --git a/admin-frontend-vue/tests/align-shop-data-grid.test.ts b/admin-frontend-vue/tests/align-shop-data-grid.test.ts new file mode 100644 index 00000000..3aa15775 --- /dev/null +++ b/admin-frontend-vue/tests/align-shop-data-grid.test.ts @@ -0,0 +1,39 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readSource } from './helpers.ts' + +// 验收反馈:店铺数据记录卡片用宫格排(一行 3 个、一页 9 张卡片)+ 分页组件翻页。 + +const PAGE = 'src/pages/tasks/ShopDataTasksPage.vue' + +test('align_shop_data_grid_normal_primary_path', () => { + const src = readSource(PAGE) + assert.match(src, /grid-template-columns:\s*repeat\(3,\s*1fr\)/, '卡片容器应为 3 列宫格') +}) + +test('align_shop_data_grid_normal_variant_input', () => { + const src = readSource(PAGE) + assert.match(src, /cardPageSize\s*=\s*9|pageSize\s*=\s*9/, '卡片分页每页 9 张') + assert.match(src, /cardPage\b/, '应有卡片页状态') + assert.match(src, /pagedResultRows|cardPageRows/, '卡片应绑定按 9 张切片的数据') +}) + +test('align_shop_data_grid_boundary_empty_input', () => { + // 卡片区下方有翻页组件(prev/next),与店铺分页并存。 + const src = readSource(PAGE) + const count = (src.match(/el-pagination/g) || []).length + assert.ok(count >= 2, '页面应含店铺分页 + 卡片分页两处 el-pagination') + assert.match(src, /layout="prev, pager, next"/, '卡片分页含上一页/下一页') +}) + +test('align_shop_data_grid_boundary_single_item', () => { + // 卡片渲染绑定分页后的数组而非全量。 + const src = readSource(PAGE) + assert.match(src, /v-for="row in pagedResultRows"/, '卡片 v-for 使用分页后数组') +}) + +test('align_shop_data_grid_repeated_operation_is_idempotent', () => { + // 切店铺页时卡片页重置为第一页,避免空页。 + const src = readSource(PAGE) + assert.match(src, /cardPage\s*(?:\.value)?\s*=\s*1/, '切页需重置卡片页到 1') +}) diff --git a/admin-frontend-vue/tests/task-266.test.ts b/admin-frontend-vue/tests/task-266.test.ts index ab3b0089..ae400b85 100644 --- a/admin-frontend-vue/tests/task-266.test.ts +++ b/admin-frontend-vue/tests/task-266.test.ts @@ -10,7 +10,7 @@ test('test_task_266_view_normal_primary_path', () => { // 视图已改为「每条任务一张卡」(对齐 admin.js renderShopDataRecordTable)。 const page = readSource('src/pages/tasks/ShopDataTasksPage.vue') assert.match(page, /shop-card-grid/, '需任务卡片网格') - assert.match(page, /v-for="row in allResultRows"/, '逐任务渲染卡片') + assert.match(page, /v-for="row in pagedResultRows"/, '逐任务渲染卡片') assert.match(page, /shop-card-task-no/, '卡片含任务号') assert.match(page, /暂无符合条件的店铺数据任务/, '空态文案') })