align(去重汇总): 页顶数据权限分组汇总卡(超管全部分组·N个/组员chips组长·组员/未加入分组)、导出改流式下载+等待遮罩(正在生成导出文件/已等待N秒)、分组空值显示未分组(对齐 admin.js renderDedupeGroupSummary/showDedupeTotalDataExportWait)

This commit is contained in:
2026-09-05 23:21:50 +08:00
parent 603822a6c1
commit 0387dc4918
4 changed files with 255 additions and 37 deletions
@@ -2,7 +2,7 @@
import { http } from '@/api/http'
import { unwrap } from '@/api/envelope'
import { normalizeAsinPageParams, toAsinPageQuery, type AsinListParams } from './asin-filter'
import { parseDedupeTotalPage, type DedupeTotalPageResult } from './dedupe-total-model'
import { parseDedupeTotalPage, parseDedupeGroupOptionList, type DedupeGroupOption, type DedupeTotalPageResult } from './dedupe-total-model'
export const DEDUPE_TOTAL_ENDPOINT = '/api/admin/dedupe-total-data'
/** 数据权限分组选项源(与店铺/去重共用同一分组集)。 */
@@ -14,10 +14,7 @@ export async function fetchDedupeTotalList(params: Partial<AsinListParams> = {})
return parseDedupeTotalPage(data)
}
export interface DedupeGroupOption {
id: number
name: string
}
export { type DedupeGroupOption }
/** 编辑单行去重总数据(ASIN 值 + 分组):PUT /dedupe-total-data/{id}。 */
export async function updateDedupeTotal(id: number, dataValue: string, groupId: number): Promise<void> {
@@ -34,30 +31,8 @@ export async function deleteDedupeTotal(id: number): Promise<void> {
unwrap<unknown>(data)
}
/** 加载数据权限分组选项:GET /shop-manage-groups → {id,name}[]。 */
/** 加载数据权限分组选项:GET /shop-manages/groups → {id,name,leaderUserId}[]。 */
export async function fetchDedupeTotalGroups(): Promise<DedupeGroupOption[]> {
const { data } = await http.get<unknown>(DEDUPE_GROUPS_ENDPOINT)
return parseDedupeGroupOptionList(data)
}
/** 归一化分组选项负载(信封 items 或裸数组),缺 id 行丢弃。 */
export function parseDedupeGroupOptionList(payload: unknown): DedupeGroupOption[] {
const core = unwrap<unknown>(payload)
const rawList = Array.isArray(core)
? core
: core && typeof core === 'object'
? (core as Record<string, unknown>).items
: []
if (!Array.isArray(rawList)) return []
const options: DedupeGroupOption[] = []
for (const raw of rawList) {
if (!raw || typeof raw !== 'object') continue
const record = raw as Record<string, unknown>
const id = typeof record.id === 'number' ? Math.floor(record.id) : Number(record.group_id)
if (!Number.isFinite(id) || id <= 0) continue
const nameRaw = record.group_name ?? record.name
const name = typeof nameRaw === 'string' ? nameRaw.trim() : ''
options.push({ id, name: name || `分组${id}` })
}
return options
}