--- session_id: 20260613-1 date: 2026-06-13 summary: Mokee Gateway统一登录接入 - 全栈改造 + 多个Bug修复 status: 进行中 - Widget未显示,其他功能正常 --- # Mokee Gateway 统一登录接入改造 系统编码: `nginxServer`,网关: `https://gw.server.zgitm.com`,登录: `https://login.user.zgitm.com` ## 最终改动的文件(汇总) ### 前端 (9 files) | 文件 | 操作 | 说明 | |------|------|------| | `.env.development` | 改 | VITE_GATEWAY_URL / VITE_LOGIN_URL / VITE_SYSTEM_CODE | | `.env.production` | 改 | 同上 | | `index.html` | 改 | 引入 Widget CSS(JS 改在 main.js 动态加载) | | `src/main.js` | 重写 | bootstrap() 鉴权→拉菜单→挂载→加载 Widget | | `src/utils/request.js` | 新增 | 网关 axios 实例,带 Token/X-System-Code,兼容双 code 格式,错误消息提取 | | `src/api/nginxApi.js` | 改 | 换新 request,路径加 /api 前缀 | | `src/router/index.js` | 重写 | 路由守卫,扁平路由注册,导出 menuTree | | `src/layout/MainLayout.vue` | 改 | 侧边栏从 menuTree 渲染(支持目录层级),ICON_MAP 字符串→组件映射,Widget 占位 | | `index.html` | 改 | Widget CSS,已移除静态 JS(改动态加载) | ### 后端 (5 files) | 文件 | 操作 | 说明 | |------|------|------| | `config/CorsConfig.java` | 新增 | allowedOriginPatterns("https://*.zgitm.com","http://localhost:*") + allowCredentials | | `context/UserContext.java` | 新增 | ThreadLocal 工具类(修复 JDK 17 兼容:不用 getOrDefault) | | `filter/UserContextFilter.java` | 新增 | Servlet Filter 提取网关注入的 X-User-Id 等请求头 | | `entity/ForwardingRule.java` | 改 | status 字段加 @TableLogic(value="1", delval="0") | | `entity/DnsZoneConfig.java` | 改 | status 字段加 @TableLogic(value="1", delval="0") | | `config/RestTemplateConfig.java` | **未改** | 保持原样,Spring Boot 直连 Python API | ### 控制器 (3 files) | 文件 | 操作 | 说明 | |------|------|------| | `ForwardingRuleController.java` | 改 | 删除 @CrossOrigin(origins="*"),CORS 统一由 CorsConfig 管 | | `CertificateController.java` | 改 | 同上 | | `DnsController.java` | 改 | 同上 | ### 配置 (1 file) | 文件 | 操作 | 说明 | |------|------|------| | `application.yml` | 改 | **删除全局 logic-delete-field: status**(这是证书重复键Bug的根因) | ### Python API (1 file) | 文件 | 操作 | 说明 | |------|------|------| | `nginx-python-api/app.py` | 改 | 添加 before_request 中间件提取用户请求头到 Flask g(**未部署到服务器**) | ### SQL (1 file) | 文件 | 操作 | 说明 | |------|------|------| | `sql/gateway_init.sql` | 新增 | UUID 变量方式,菜单:Nginx代理管理→三个业务页面,角色:admin/user,管理员:admin_nginxServer | ## 踩过的坑 ### 1. `@CrossOrigin(origins="*")` + `CorsConfig.allowCredentials(true)` 冲突 - 三个 Controller 原来有 `@CrossOrigin(origins="*")`,与全局 CorsConfig 的 `allowCredentials(true)` 合并后产生非法组合 - **修复**:删除三个 Controller 的 `@CrossOrigin`,CORS 统一由 CorsConfig 管理 ### 2. 网关菜单返回字段和前端预期不一致 - 网关实际返回:`{path, name, component, meta:{title,icon}, children}`,`component="Layout"` 表示目录 - 前端最初判断 `menuType`/`menu_name` 等字段,全部对不上 - **修复**:`addDynamicRoutes()` 改为判断 `component==='Layout'`,路由扁平注册到 `/`,侧边栏从 `menuTree` 渲染 ### 3. Widget `process is not defined` - Widget JS 内部引用了 `process.env`,浏览器环境无此全局变量 - **修复**:`main.js` 中加载 Widget 前加 `window.process = { env: {} }` ### 4. 路由嵌套导致菜单不显示 - 最初 `addDynamicRoutes` 把页面路由嵌套在 `/nginx/nginx-forwarding` 下,redirect `/nginx-forwarding` 找不到 - **修复**:页面路由全部扁平注册到 `/`,侧边栏层级单独从 menuTree 渲染 ### 5. 证书列表查询触发 INSERT 重复键 — 全局 logic-delete-field 误伤 - **根因**:`application.yml` 全局 `logic-delete-field: status`,MyBatis-Plus 给所有实体加 `AND status = 1` - `Certificate.status` 是 String "active",`WHERE status = 1` 永远不成立 → selectOne 返回 null → 走 INSERT → 重复键 - `ForwardingRule.status` 和 `DnsZoneConfig.status` 是 Integer 0/1,不受影响 - **修复**:删除全局 logic-delete-field,在 ForwardingRule 和 DnsZoneConfig 的 status 字段加 `@TableLogic(value="1", delval="0")` ### 6. 前端错误消息丢失 - 新 `request.js` 错误拦截器直接透传 axios error,前端拿到 "Request failed with status code 500" - 旧代码从 `error.response.data.message` 提取后端实际消息 - **修复**:错误拦截器追加 `new Error(error.response?.data?.message || error.message || '网络错误')` ### 7. Widget 动态加载时机 - Widget 脚本在 `index.html` 同步加载时 Vue 未渲染,找不到 `#mokee-user-chip` - 移到 `main.js` 的 `app.mount()` 之后动态加载 - **当前状态:Widget 仍未显示,待排查** ## 待解决 - [ ] Widget 用户头像组件不显示(右上角) - [ ] Python API `app.py` 中间件需部署到 10.1.1.160