8.8 KiB
网关台账前端 Mock 演示指南
离线(无 VPN、无后端)一键起完整可演示环境:三个治理页全量可看可玩 + YschTheme 主题五档配色。
一条命令
cd D:\SoftProject\yunhai\open-gateway\front
npm run dev:mock
然后浏览器打开 http://localhost:8131(自动落在「访问台账」页)。
前提:Node 20.19.4(本机 nvm 路径 D:\nvm\nvm\v20.19.4,若 node -v 不对请先 nvm use 20.19.4),front/node_modules 已安装。
dev:mock(scripts/start-mock.mjs,零依赖)做三件事:
- 拉起 YschTheme 本地静态通道:
YschTheme/scripts/dev-serve.mjs把YschTheme/dist/pc挂到http://localhost:9527/static/(主题 CSS/JS 不拷进本仓——应用侧不持主题副本是主题仓硬原则); - 探活
9527/static/manifest.json; - 以
YH_THEME_PROXY_TARGET=http://localhost:9527启动vite --mode mock(8131),vite 的/static代理由此指向本地通道。
全程不触网。Ctrl+C 退出会一并收掉两个子进程;若 9527 被上次残留进程占用且可服务,脚本会直接复用。
切回真后端
装好 VPN 后照旧 npm run dev(走 .env.dev,经 /open-gateway/api 代理到 base 域),与 dev:mock 互不影响、互不覆盖。线上 build(npm run build)不读任何 .env.*,行为与 mock 无关。
每页看什么、玩什么
| 页面 | 看点 / 操作 |
|---|---|
| /ledger 访问台账 | 233 条调用记录,时间倒序。翻页(24 页);target 与 调用方 appKey 精确筛选(试试 notice + 100001 → 共 5 条;callerAppKey 填 anonymous 可筛匿名调用,填了查不到的值=空列表);「查看详情」弹窗;状态码色阶:2xx 绿 / 4xx 琥珀 / 5xx 红;「后端码」恒 -(流式转发不解析业务 code) |
| /routes 路由注册表 | 28 行路由。行内改 visibility(INTERNAL/EXTERNAL)、authMode(SIGNED/ANON)、缓存秒数/范围、qps、启停、备注 → 「保存」→ toast「已保存,注册表加载 N 条路由」;离开页面再进来,值保持(内存态);把缓存秒数改成负数保存 → 后端同款报错 toast(cacheTtlSeconds 非法:-5(须为 ≥0 的整数)) |
| /targets 目标地址 | 7 个生产 ctx。行内改 baseUrl → 保存 → toast「已保存,目标表加载 7 条」;baseUrl 清空保存 → 报错 toast;启停开关 |
| 顶栏 | 「重载注册表」→ toast「已重载:路由 28 条 / 目标 7 条」+「最后更新 HH:mm:ss」;「手动刷新」重建当前页;MOCK 徽标(仅 mock 模式出现) |
| 右上「配色」胶囊 | 五档主题色(原版靛蓝/云海蓝/石墨墨/靛紫/松石绿)+ 侧栏深浅/侧栏跟随/顶部渐变三开关;选择持久化在 localStorage(yh-theme),刷新/重开浏览器保持 |
Mock 数据的存活性:PUT 改动只存在于 vite 进程内存——站内切换页面改动保持;浏览器整页刷新/直达(F5)即重置回静态种子;重启 dev:mock 也重置。台账 ts 以重置时刻为终点向过去铺 6.5 天,所以永远是"近期"。
Mock 数据清单
数据源:src/assets/mock/gatewayApi.ts(种子 + 确定性 LCG,改种子改这里)。
- targets(7):userbase、userclass、yschcms、svc-hall、flow-center、usermsg、notice;
baseUrl = http://{targetCode}-service:8080(照service/docs/sql/03_target.sql语义)。 - routes(28):
- 22 行 =
service/docs/sql/02_init_routes.sql全量种子(全保守档 INTERNAL×SIGNED、cacheTtl 0、qps 0,备注原样照抄); - 6 行治理样本:id23
yschcms /oapi/site/render/**(EXTERNAL×ANON,GLOBAL 缓存 600s,qps 50)、id24svc-hall /oapi/svc/items/**(EXTERNAL×ANON,CALLER 缓存 60s)、id25notice /oapi/notice/public/**(EXTERNAL×ANON,GLOBAL 300s,qps 100)、id26userbase /oapi/user/batchAdd(EXTERNAL×SIGNED,qps 5 熔断)、id27usermsg /oapi/msg/health(INTERNAL×ANON,空备注样本)、id28flow-center /oapi/flow/diagram/**(停用行样本)。 - 四种 visibility×authMode 组合、空备注、停用行、差异化 ttl/qps/remark 全覆盖。
- 22 行 =
- logs(233):appKey 取实测值 100001/100007/100009/100010/100013(约六成行),
"anonymous"约 46 行,callerAppKey=null(未携带 appKey 被网关拒)约 51 行;status 覆盖 200/401/403/404/500(约 125/69/30/3/6);costMs 3~1602ms 快慢兼有;path 为该 target 路由形态(/**或具体 id 段);backendCode 恒 null。
与真实接口的契约对照
统一信封 {code:0, msg:"", data:X};业务非法一律 HTTP 200 + {code:2, msg:"…"}(前端 alova 层弹 msg);分页 data 形状 {total, content, pageIndex, pageSize, totalPages, hasNext}。
| 接口 | 契约 | mock 实现 |
|---|---|---|
GET /api/internal/admin/routes?pageIndex&pageSize |
排序 targetCode,pathPattern;无 keyword 参数 | 一致(localeCompare 排序) |
PUT /api/internal/admin/routes/{id} |
body 只认 7 键:visibility/authMode/cacheTtlSeconds/cacheScope/rateLimitQps/enabled/remark;visibility∈{INTERNAL,EXTERNAL}、authMode∈{SIGNED,ANON}、cacheScope∈{CALLER,GLOBAL};两 int 须 Number 且 ≥0;enabled 须真布尔——传字符串 "true" 一律按 false 落库(后端真实坑,照抄);成功 data={loaded:路由总条数};非法→{code:2,msg:"visibility 非法:XXX(合法 [EXTERNAL, INTERNAL])"} |
全部一致,错误消息格式一字不差 |
GET /api/internal/admin/targets |
同信封分页 | 一致 |
PUT /api/internal/admin/targets/{id} |
body{baseUrl 非空, enabled 真布尔};成功 data={targets:N} |
一致 |
GET /api/internal/admin/logs?pageIndex&pageSize&targetCode&callerAppKey |
pageSize 默认 50 上限 500;筛选精确等值、空串=不过滤;排序 id desc;ts ISO 字符串;backendCode 恒 null |
一致(先过滤再分页) |
POST /api/internal/admin/routes/reload |
无入参 → data={loaded,targets} |
一致(返回内存实时条数:28/7;apps 键 mock 无数据源,前端按 - 渲染) |
GET /api/internal/admin/session |
data={ssoHost,principal},值来自已登录 CAS 会话 |
ssoHost 返空串 → 顶栏「退出」不渲染(同 Notice 的 ssoHost 空态) |
前端请求带 /open-gateway 前缀(serviceHost),mock 中间件按剥前缀后的真实路径匹配。
与真后端的差异(mock 不造假接口)
- 无登录/CAS(后端本就没有,治理面靠 Caddy 白名单);顶栏用户区是静态占位「网关治理」。
- 无 keyword 模糊搜索(routes 接口没有该参数,别造)。
- 无路由/目标的新增与删除(后端只支持行内编辑)。
- 无统计、无时间过滤(M1 范围,后端尚无接口)。
- 无 caller 管理页(appKey 只出现在台账里)。
- 刷新/重启即重置;真实后端当然是持久化的。
主题说明(YschTheme 中央静态通道)
- 接入方式:
index.html头部一段同步 loader(照 Notice 配方,A 类免插件)引/static/js/yh-theme-init.js;host 优先级__APP_CONFIG__.staticHost > baseHost > %VITE_THEME_HOST%(dev 可注入)> 同源 /static/。网关无 env-config,恒走后两档;build 不替换占位符 → 线上走同源通道,零环境值烧入。 - 本地联调:vite
/static代理 →YH_THEME_PROXY_TARGET(dev:mock 指本地 9527;npm run dev时指 base 域——无 VPN 时npm run dev主题 CSS 取不到,页面剩骨架无皮肤,这正是 dev:mock 存在的原因)。 - 档位:五档配色 + 侧栏深浅 + 侧栏跟随 + 顶部渐变,状态存 localStorage(
yh-theme),由/static/js/yh-theme-init.js在首帧前挂<html>档位类(防 FOUC)。 - sync 两件:
src/utils/avatar.ts、src/components/UserAvatar.vue由 YschTheme 下发(consumers.json 已登记 open-gateway 条目)。2026-10-11 对接规范轮裁撤theme.ts+ThemeSwitcher.vue(§3 红线:子应用不做配色切换器),mock 模式配色档位走通道默认档 +/open-gateway/api/appearancemock 端点收敛。
实现备注
- mock 走 vite.config.ts 手写
configureServer中间件(仅--mode mock注册,先于内部代理),而非常规vite-plugin-mock:后者用 esbuild 独立打包 mock 文件,与 vite 配置是两个模块实例,无法实现「整页刷新重置内存态」;且零新依赖(红线:不引运行时新依赖)。 .env.mock仅两行:VITE_SERVICE_HOST=/open-gateway+VITE_IS_MOCK=true(后者驱动顶栏 MOCK 徽标,dev/线上恒不出现)。- 非 mock 模式(
npm run dev/npm run build)行为与改造前一致(唯一例外:布局样式改由主题通道下发,本地layout.css快照已删除)。