From a1336fe9b7a2b5c7aea0029412f7839e099af3ac Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Tue, 7 Jul 2026 17:14:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(F006-W17.3.9):=20UserListView=20stats=20?= =?UTF-8?q?=E4=B8=8E=20tab=20=E8=A7=A3=E8=80=A6=20(=E8=B7=A8=20tab=20?= =?UTF-8?q?=E5=85=A8=E9=87=8F=E8=AE=A1=E6=95=B0=E4=B8=80=E8=87=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户反馈: 切 tab 时"正常/已禁用"两个统计数会变化 (全部 10/0, 正常 10/0, 已禁用 0/1) 期望: stats 是全量统计, 切 tab 不应变化 根因: enabledStats 是在 load() 内"基于当前页 10 条结果"累加, 切 tab 后数据不同, stats 跟着变 修法: - 拆 load() → loadList() + loadStats() - buildSearchParams(): 排除 enabled (tab) 的搜索参数 (userId/nickName/mobile/isEnterprise/enterpriseName) - loadStats(): 并发拉 enabled=0/1 的 page=1&limit=1, 用 resp.total 当 stats (后端只 count 不返列表, 开销可忽略) - onTabChange: 只调 loadList(), stats 不重算 - onSearch/onReset/onPageChange/onLimitChange/toggleEnabled: 调 load() (并发刷 list + stats) 效果: 三个 tab 看到的正常/已禁用计数一致 (因为跟 tab 解耦, 只跟搜索条件关联) --- src/modules/user/UserListView.vue | 52 ++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/modules/user/UserListView.vue b/src/modules/user/UserListView.vue index 8680112..532741b 100644 --- a/src/modules/user/UserListView.vue +++ b/src/modules/user/UserListView.vue @@ -91,15 +91,24 @@ function fmtDate(ts: number | null | undefined) { return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` } -async function load() { +/** + * 构建除 enabled (tab) 外的搜索参数 (用于 stats 查询) + * stats 必须与 tab 解耦, 只反映当前搜索条件下的全量计数 + */ +function buildSearchParams() { + const params: any = {} + if (query.userId) params.id = query.userId + if (query.nickName) params.nickName = query.nickName + if (query.mobile) params.mobile = query.mobile + if (query.enterpriseName) params.enterpriseName = query.enterpriseName + if (query.isEnterprise !== '') params.isEnterprise = Number(query.isEnterprise) + return params +} + +async function loadList() { loading.value = true try { - const params: any = { page: query.page, limit: query.limit } - if (query.userId) params.id = query.userId - if (query.nickName) params.nickName = query.nickName - if (query.mobile) params.mobile = query.mobile - if (query.enterpriseName) params.enterpriseName = query.enterpriseName - if (query.isEnterprise !== '') params.isEnterprise = Number(query.isEnterprise) + const params: any = { page: query.page, limit: query.limit, ...buildSearchParams() } if (query.enabled !== '') params.enabled = Number(query.enabled) const resp: any = await httpGet('/user/user/page', params) if (resp && Array.isArray(resp.list)) { @@ -118,9 +127,6 @@ async function load() { raw: it })) total.value = Number(resp.total || 0) - // 统计 (后端 enabled 语义: 0=正常 1=禁用) - enabledStats.normal = list.value.filter(u => u.enabled === 0).length - enabledStats.disabled = list.value.filter(u => u.enabled === 1).length } else { list.value = [] total.value = 0 @@ -134,6 +140,30 @@ async function load() { } } +/** + * 加载 stats (normal/disabled 全量计数) + * 与 tab 无关, 只跟搜索条件 (userId/nickName/mobile/isEnterprise/enterpriseName) 关联 + * 通过 limit=1 + page=1 拿到 total (后端只 count 不返列表, 开销可忽略) + */ +async function loadStats() { + try { + const baseParams = buildSearchParams() + const [respNormal, respDisabled] = await Promise.all([ + httpGet('/user/user/page', { ...baseParams, enabled: 0, page: 1, limit: 1 }), + httpGet('/user/user/page', { ...baseParams, enabled: 1, page: 1, limit: 1 }) + ]) + enabledStats.normal = Number(respNormal?.total ?? 0) + enabledStats.disabled = Number(respDisabled?.total ?? 0) + } catch { + enabledStats.normal = 0 + enabledStats.disabled = 0 + } +} + +async function load() { + await Promise.all([loadList(), loadStats()]) +} + const tabItems = computed(() => [ { key: 'all', label: '全部', count: total.value }, { key: 'normal', label: '正常', count: enabledStats.normal }, @@ -146,7 +176,7 @@ function onTabChange(key: string) { else if (key === 'normal') query.enabled = '0' else if (key === 'disabled') query.enabled = '1' query.page = 1 - load() + loadList() // 切 tab 只重载列表, stats 已与 tab 解耦 } function onPageChange(p: number) { query.page = p; load() }