Files
open-gateway-front/MOCK.md

8.6 KiB
Raw Permalink Blame History

网关台账前端 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,零依赖)做三件事:

  1. 拉起 YschTheme 本地静态通道:YschTheme/scripts/dev-serve.mjs 把 YschTheme/dist/pc 挂到 http://localhost:9527/static/(主题 CSS/JS 不拷进本仓——应用侧不持主题副本是主题仓硬原则);
  2. 探活 9527/static/manifest.json;
  3. 以 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)、id24 svc-hall /oapi/svc/items/**(EXTERNAL×ANON,CALLER 缓存 60s)、id25 notice /oapi/notice/public/**(EXTERNAL×ANON,GLOBAL 300s,qps 100)、id26 userbase /oapi/user/batchAdd(EXTERNAL×SIGNED,qps 5 熔断)、id27 usermsg /oapi/msg/health(INTERNAL×ANON,空备注样本)、id28 flow-center /oapi/flow/diagram/**(停用行样本)。
    • 四种 visibility×authMode 组合、空备注、停用行、差异化 ttl/qps/remark 全覆盖。
  • 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/routes/refresh 无入参 → data={loaded,targets} 一致(返回内存实时条数:28/7)

前端请求带 /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/theme.ts、src/components/ThemeSwitcher.vue、src/utils/avatar.ts、src/components/UserAvatar.vue 由 YschTheme 下发(consumers.json 已登记 open-gateway 条目)。⚠️ theme.ts 顶部有本仓加的 // @ts-nocheck(上游为松类型产物)——下次 npm run sync 覆盖后需补回该行,否则 npm run typecheck 报错。

实现备注

  • 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 快照已删除)。