From a36dda7cccd9a875ee706d9cbc1544ab0eb85ff4 Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Wed, 8 Jul 2026 11:15:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(F006-W17.4.6):=20UserFormDialog=20=E5=85=B3?= =?UTF-8?q?=E8=81=94=E4=BC=81=E4=B8=9A=E4=B8=8B=E6=8B=89=E6=94=B9=E4=BB=8E?= =?UTF-8?q?=20user/user/page=20=E8=81=9A=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户反馈: 关联企业的下拉框是空的 排查: 1. nginx-vue.conf 加 /enterprise/ location (W17.4.5) ✅ 2. gateway.json 加 enterprise 路由 + 推 nacos ✅ 3. 但 gateway 启动时 bootstrap.yml 没订阅 gateway.json dataId (bootstrap.yml 只订阅 datasource.yaml + common.yaml + gateway-server.yaml/-dev.yaml) gateway.json 仅供运维手工管理, 实际不参与路由 4. /enterprise/list 在 user-server 也 404 (jar 是旧版本, ApiEnterpriseController @RequestMapping 路径未生效) 修法: 前端从 /user/user/page 拉用户列表聚合 (enterpriseId, enterpriseName) 去重 - 端点 100% 可用 (已在 W11 验收过 2284 用户) - 字段 enterpriseId + enterpriseName 已在 user 表 - 聚合 Map 去重, 按 id 排序 - 弹窗打开时拉一次缓存, 后续复用 nginx /enterprise/ location + gateway.json 路由保留: future-proof, 等后端 jar 重打包后会自动生效 前端聚合方式短期可行, 但仅用于下拉选项场景; 如要真正查询某企业的所有用户等场景, 仍需后端打 jar 暴露 /enterprise/page --- src/modules/user/UserFormDialog.vue | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/modules/user/UserFormDialog.vue b/src/modules/user/UserFormDialog.vue index ab0d9fe..39dcfb7 100644 --- a/src/modules/user/UserFormDialog.vue +++ b/src/modules/user/UserFormDialog.vue @@ -108,19 +108,30 @@ function resetForm() { /** * 加载企业下拉选项 (弹窗打开时拉一次, 后续复用) - * 后端: GET /enterprise/list 返 EnterpriseFeignDTO 列表 [{id, enterpriseName, ...}] - * 兜底: 后端失败时给空数组, UI 仍可用 (只是下拉是空的) + * + * 实现: 从 /user/user/page 用户列表聚合 (enterpriseId, enterpriseName) 去重 + * 原因: gateway.json 当前没配 /enterprise/** 路由, /enterprise/list 返 404; + * 而 user-server jar 内 ApiEnterpriseController 也没正确暴露路径 + * (推测 jar 是旧版本编译, controller 路径没生效) + * 替代: 用户表里有 enterpriseId + enterpriseName 字段, 直接聚合即可 + * 兜底: 后端失败时给空数组 */ async function loadEnterprises() { if (enterpriseOptions.value.length > 0) return enterpriseLoading.value = true try { - const data: any = await httpGet('/enterprise/list') - const arr = Array.isArray(data) ? data : (data?.list || []) - enterpriseOptions.value = arr.map((it: any) => ({ - id: Number(it.id ?? it.enterpriseId ?? 0), - name: it.enterpriseName || it.name || `企业 #${it.id}` - })).filter((it: EnterpriseOpt) => it.id > 0) + const data: any = await httpGet('/user/user/page', { page: 1, limit: 10000 }) + const arr = Array.isArray(data?.list) ? data.list : (Array.isArray(data) ? data : []) + const seen = new Map() + for (const u of arr) { + const eid = Number(u.enterpriseId ?? 0) + if (eid > 0 && !seen.has(eid)) { + seen.set(eid, u.enterpriseName || `企业 #${eid}`) + } + } + enterpriseOptions.value = Array.from(seen.entries()) + .map(([id, name]) => ({ id, name })) + .sort((a, b) => a.id - b.id) } catch { enterpriseOptions.value = [] } finally {