diff --git a/admin-frontend-vue/src/pages/tasks/shop-data-api.ts b/admin-frontend-vue/src/pages/tasks/shop-data-api.ts index 78bacd5f..26b9ac09 100644 --- a/admin-frontend-vue/src/pages/tasks/shop-data-api.ts +++ b/admin-frontend-vue/src/pages/tasks/shop-data-api.ts @@ -4,8 +4,10 @@ import { parseShopDataTaskPage, type ShopDataTaskPageResult } from './shop-data- import { toShopDataQuery, type ShopDataFilter } from './shop-data-filter.ts' import { toShopDataZipRequest } from './shop-data-download.ts' import { downloadZipHeaderCounts } from './image-video-download.ts' +import { parseTaskPermissionPayload, toPermissionUserIdsPayload, type TaskPermissionItem } from './task-permission.ts' export const SHOP_DATA_CRAWL_TASKS_ENDPOINT = '/api/admin/shop-data-crawl-tasks' +export const SHOP_DATA_TASK_PERMISSIONS_ENDPOINT = '/api/admin/shop-data-crawl-task-permissions' export async function fetchShopDataTaskList( filter: ShopDataFilter, @@ -32,3 +34,14 @@ export async function requestShopDataZipDownload(resultIds: readonly (number | s const counts = downloadZipHeaderCounts(headers as Record) return { blob: data, fileCount: counts.fileCount, errorCount: counts.errorCount } } + +/** 加载店铺数据任务数据范围授权用户:GET /api/admin/shop-data-crawl-task-permissions。 */ +export async function fetchShopDataTaskPermissionUsers(): Promise { + const { data } = await http.get(SHOP_DATA_TASK_PERMISSIONS_ENDPOINT) + return parseTaskPermissionPayload(data) +} + +/** 保存店铺数据任务数据范围授权:PUT /api/admin/shop-data-crawl-task-permissions { user_ids }。 */ +export async function saveShopDataTaskPermissions(userIds: Iterable): Promise { + await http.put(SHOP_DATA_TASK_PERMISSIONS_ENDPOINT, toPermissionUserIdsPayload(userIds)) +} diff --git a/admin-frontend-vue/tests/task-114.test.ts b/admin-frontend-vue/tests/task-114.test.ts new file mode 100644 index 00000000..b42e4c3d --- /dev/null +++ b/admin-frontend-vue/tests/task-114.test.ts @@ -0,0 +1,62 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readSource } from './helpers.ts' +import { grantedUserIds, parseTaskPermissionPayload, permissionSelectionChanged, toPermissionUserIdsPayload } from '../src/pages/tasks/task-permission.ts' + +const SHOP_DATA_PERM_RESP = { + success: true, + data: [ + { id: 1, username: '张伟', granted: true }, + { id: 2, username: '李四', granted: false }, + { id: 3, username: '王五', granted: true }, + ], +} + +test('test_task_114_shop_data_permission_normal_primary_path', () => { + // 正常主路径:店铺数据权限负载解析并取已授权 id。 + const items = parseTaskPermissionPayload(SHOP_DATA_PERM_RESP) + assert.deepEqual(grantedUserIds(items), [1, 3]) +}) + +test('test_task_114_shop_data_permission_normal_variant_input', () => { + // 正常变体:仅全选/部分授权变更判定。 + const initial = new Set([1, 3]) + assert.equal(permissionSelectionChanged(initial, new Set([1, 3])), false) + assert.equal(permissionSelectionChanged(initial, new Set([1])), true) +}) + +test('test_task_114_shop_data_permission_repeated_is_idempotent', () => { + // 正常重复:保存负载稳定。 + assert.deepEqual(toPermissionUserIdsPayload(new Set([3, 1])), { user_ids: [3, 1] }) +}) + +test('test_task_114_shop_data_permission_boundary_empty_input', () => { + // 边界空值:无授权时的空选择。 + const initial = new Set() + assert.equal(permissionSelectionChanged(initial, new Set()), false) + assert.deepEqual(toPermissionUserIdsPayload(initial), { user_ids: [] }) +}) + +test('test_task_114_shop_data_permission_boundary_single_item', () => { + // 边界单元素:单用户授权变更。 + assert.equal(permissionSelectionChanged(new Set(), new Set([7])), true) +}) + +test('test_task_114_shop_data_permission_boundary_limit_or_missing_field', () => { + // 边界上限/缺字段:仅新增未授权用户时判定为已变更。 + assert.equal(permissionSelectionChanged(new Set([1]), new Set([1, 4])), true) +}) + +test('test_task_114_shop_data_permission_invalid_input_rejected', () => { + // 异常输入:success=false 抛后端 message。 + assert.throws(() => parseTaskPermissionPayload({ success: false, message: '仅超级管理员可配置' }), /仅超级管理员/) +}) + +test('test_task_114_shop_data_permission_dependency_failure_returns_actionable_message', () => { + // 依赖失败/加载走 adapter:GET|PUT /api/admin/shop-data-crawl-task-permissions。 + const api = readSource('src/pages/tasks/shop-data-api.ts') + assert.match(api, /\/api\/admin\/shop-data-crawl-task-permissions/) + assert.match(api, /fetchShopDataTaskPermissionUsers/) + assert.match(api, /saveShopDataTaskPermissions/) + assert.match(api, /http\.put/) +})