perf(admin): 优化管理端页面切换性能与包体积

- 阶段 A: 增加 KeepAlive 缓存高频列表页,改用 onActivated 进行后台静默刷新,优化 tab 切换与 HomeEntry 闪屏

- 阶段 B: beforeEach 守卫在 TTL 内走同步快速路径,api 请求拦截器缓存 token 避免重复解析 JWT

- 阶段 C: 引入 unplugin 插件启用 Element Plus 组件按需加载,清理 App.vue 中 960+ 行冗余暗色主题 CSS

- i18n 拆包: 将三语文案包提取为独立懒加载 chunks,主包体积从 209KB 减少至 99KB (降低 53%)
This commit is contained in:
2026-06-18 15:30:27 +08:00
parent 4244c9e10b
commit 5baac41ce8
26 changed files with 549 additions and 603 deletions

161
AGENTS.md
View File

@@ -1,25 +1,31 @@
# AGENTS.md
> 给 AI 编程助手Cursor 等)看的项目速查手册,浓缩开发约定与易错点。
> 人类日常开发请优先看 `README.md` 与 `docs/`。
> 人类日常开发请优先看 `README.md` 与 `docs/`。
如果你是AI请每次读了这个文件就在已有的次数上+1
当前被读次数: 1
## 目录
| 章节 | 何时查 |
|------|--------|
| [运行环境与仓库结构](#运行环境与仓库结构) | 不确定 monorepo 各 app 分工 |
| [本地启动](#本地启动) | 起 dev、数据库、端口 |
| [常用命令](#常用命令) | build / test / 打镜像 |
| [API 领域结构](#api-领域结构) | 业务代码该放哪个 domain |
| [API 约定](#api-约定) | 鉴权、钱包、迁移、赔率快照 |
| [前端约定](#前端约定) | 改 .vue/.ts、权限、dist |
| [i18n 改文案流程](#i18n-改文案流程) | 三语文案改哪几个文件 |
| [主题分支](#主题分支player-多皮肤) | theme-2/3/4 与 main 同步禁忌 |
| [演示账号](#演示账号开发-seed) | 本地登录测试号 |
| [文档索引](#文档索引) | 详细说明在 `docs/` 哪篇 |
| [测试与冒烟](#测试与冒烟) | Jest、UAT、smoke-tests |
| [部署注意](#部署注意) | 生产 compose、seed、打包 |
| [AI 改代码时请避免](#ai-改代码时请避免) | 常见踩坑清单 |
| 章节 | 何时查 |
| ------------------------- | ----------------------- |
| [运行环境与仓库结构](#运行环境与仓库结构) | 不确定 monorepo 各 app 分工 |
| [本地启动](#本地启动) | 起 dev、数据库、端口 |
| [常用命令](#常用命令) | build / test / 打镜像 |
| [API 领域结构](#api-领域结构) | 业务代码该放哪个 domain |
| [API 约定](#api-约定) | 鉴权、钱包、迁移、赔率快照 |
| [前端约定](#前端约定) | 改 .vue/.ts、权限、dist |
| [i18n 改文案流程](#i18n-改文案流程) | 三语文案改哪几个文件 |
| [主题分支](#主题分支player-多皮肤) | theme-2/3/4 与 main 同步禁忌 |
| [演示账号](#演示账号开发-seed) | 本地登录测试号 |
| [文档索引](#文档索引) | 详细说明在 `docs/` 哪篇 |
| [测试与冒烟](#测试与冒烟) | Jest、UAT、smoke-tests |
| [部署注意](#部署注意) | 生产 compose、seed、打包 |
| [AI 改代码时请避免](#ai-改代码时请避免) | 常见踩坑清单 |
> **AI 会读吗?** Cursor 等工具会在对话开始时把 `AGENTS.md` 注入上下文;当前约 200 行,一般能整篇读入。文件继续变长时,索引有助于人和 AI 快速定位章节;细节仍以 `docs/` 为准,此处只写约定与指针。
@@ -56,17 +62,19 @@
业务规则放在 `apps/api/src/domains/*`,应用层只做编排:
| 领域 | 路径 | 职责 |
|------|------|------|
| identity | `domains/identity/` | 登录、用户、员工、RBAC |
| agent | `domains/agent/` | 代理网络、授信 |
| ledger | `domains/ledger/` | 钱包、账变 |
| catalog | `domains/catalog/` | 赛事 |
| odds | `domains/odds/` | 盘口 |
| betting | `domains/betting/` | 注单 |
| settlement | `domains/settlement/` | 结算 |
| operations | `domains/operations/` | 返水、内容、审计等 |
| player-messages / presence | 各子模块 | 站内信、在线状态 |
| 领域 | 路径 | 职责 |
| -------------------------- | --------------------- | ------------- |
| identity | `domains/identity/` | 登录、用户、员工、RBAC |
| agent | `domains/agent/` | 代理网络、授信 |
| ledger | `domains/ledger/` | 钱包、账变 |
| catalog | `domains/catalog/` | 赛事 |
| odds | `domains/odds/` | 盘口 |
| betting | `domains/betting/` | 注单 |
| settlement | `domains/settlement/` | 结算 |
| operations | `domains/operations/` | 返水、内容、审计等 |
| player-messages / presence | 各子模块 | 站内信、在线状态 |
门户控制器:`applications/{player,admin,agent}/`
@@ -82,7 +90,7 @@
## 前端约定
-`apps/player/src``apps/admin/src` 下的 **`.ts` / `.vue`**`src` 下虽有 `.js` 旁文件,但 `index.html` 入口是 `/src/main.ts`Vite 优先解析 TS。
-`apps/player/src``apps/admin/src` 下的 `**.ts` / `.vue`**`src` 下虽有 `.js` 旁文件,但 `index.html` 入口是 `/src/main.ts`Vite 优先解析 TS。
- 管理端同一应用服务 `ADMIN``AGENT` 账号;路由/菜单权限在 `router/index.ts``stores/auth.ts`;员工可见菜单字段 `visibleMenus`
- 管理端权限常量:`apps/admin/src/constants/permissions.ts``AdminPerm`)。
- 玩家端移动优先;性能验收见 `docs/player-mobile-performance.md`
@@ -95,13 +103,15 @@
### 玩家端(`apps/player`
| 项 | 说明 |
|----|------|
| 文案文件 | `apps/player/src/i18n/zh-CN.ts``en-US.ts``ms-MY.ts` |
| 结构 | **嵌套对象**(如 `bet.place_bet``nav.home` |
| 组件用法 | `useI18n()``t('bet.odds_changed')` |
| 语言切换 | `useAppLocale().setLocale()`;按需 `ensurePlayerLocale` 懒加载对应 ts 文件 |
| 存储 key | `localStorage.locale`登录用户会 `POST /player/language` 同步后端 |
| 项 | 说明 |
| ------ | ---------------------------------------------------------------- |
| 文案文件 | `apps/player/src/i18n/zh-CN.ts``en-US.ts``ms-MY.ts` |
| 结构 | **嵌套对象**(如 `bet.place_bet``nav.home` |
| 组件用法 | `useI18n()``t('bet.odds_changed')` |
| 语言切换 | `useAppLocale().setLocale()`按需 `ensurePlayerLocale` 懒加载对应 ts 文件 |
| 存储 key | `localStorage.locale`;登录用户会 `POST /player/language` 同步后端 |
**改文案步骤:**
@@ -113,22 +123,24 @@
### 管理端(`apps/admin`
| 项 | 说明 |
|----|------|
| 核心入口 | `apps/admin/src/i18n/admin-messages.ts`(三语扁平 `Record<string, string>` |
| 列表/弹窗大段文案 | `admin-pages.ts`(中/英)、`admin-pages-ms.ts`(马来)→ 通过 spread 并入 `admin-messages` |
| 表单校验 key | `form-validation.ts``err.*` 等,用 `resolveFormError` 展示) |
| 组件用法 | `useAdminLocale().t('nav.bets')``t('key', { n: 1 })` 占位符 `{n}` |
| 语言切换 | `useAdminLocale().setLocale()` `preloadAdminLocale` + `localStorage.admin_locale` |
| 动态拆包 | `bundles/{zh-CN,en-US,ms-MY}.ts` + `locale-loader.ts`(当前主包仍含三语全文,拆包未完全落地) |
| 项 | 说明 |
| --------- | ----------------------------------------------------------------------------------- |
| 核心入口 | `apps/admin/src/i18n/admin-messages.ts`(三语扁平 `Record<string, string>` |
| 列表/弹窗大段文案 | `admin-pages.ts`(中/英)、`admin-pages-ms.ts`(马来)→ 通过 spread 并入 `admin-messages` |
| 表单校验 key | `form-validation.ts``err.`* 等,用 `resolveFormError` 展示) |
| 组件用法 | `useAdminLocale().t('nav.bets')` `t('key', { n: 1 })` 占位符 `{n}` |
| 语言切换 | `useAdminLocale().setLocale()``preloadAdminLocale` + `localStorage.admin_locale` |
| 动态拆包 | `bundles/{zh-CN,en-US,ms-MY}.ts` + `locale-loader.ts`(当前主包仍含三语全文,拆包未完全落地) |
**改文案步骤:**
1. 确定 key 命名:导航 `nav.*`、通用 `common.*`、页面 `user.*` / `match.*` / `deposit.*` 等,与现有前缀保持一致。
1. 确定 key 命名:导航 `nav.`*、通用 `common.*`、页面 `user.*` / `match.*` / `deposit.*` 等,与现有前缀保持一致。
2.`admin-messages.ts` 的 **zh / en / ms 三个对象**里各加同名 key核心短文案
3. 若属于某列表页/弹窗长文案,优先加到 `admin-pages.ts`(中/英)与 `admin-pages-ms.ts`(马来)的对应 export它们会 spread 进 `admin-messages`
4. 表单校验错误throw `FormValidationError('err.xxx')` 并在三语里定义 `err.xxx`
5. 本地 `pnpm dev:admin`,右上角切换语言验证;改 `admin-pages*` 后若未刷新,重启 dev 一次。
5. 本地 `pnpm dev:admin`,右上角切换语言验证;改 `admin-pages`* 后若未刷新,重启 dev 一次。
6. Admin 与 Player **文案独立**,改玩家端不要只改 admin 文件(反之亦然)。
### 常见错误
@@ -145,42 +157,48 @@
## 主题分支player 多皮肤)
| 分支 | 风格 | 注意 |
|------|------|------|
| `main` | 暗金主题 | 生产默认发版分支 |
| 分支 | 风格 | 注意 |
| --------- | ----------- | ------------------------------------------------------------------- |
| `main` | 暗金主题 | 生产默认发版分支 |
| `theme-2` | Pinnacle 蓝白 | 玩家 UI 与 main 分叉,**禁止** `git checkout main -- apps/player/...` 整文件覆盖 |
| `theme-3` | 统一移动端视觉 | 同 theme-2 |
| `theme-4` | 海军蓝暗色极简 | 含悬浮客服等独有组件 |
| `theme-3` | 统一移动端视觉 | 同 theme-2 |
| `theme-4` | 海军蓝暗色极简 | 含悬浮客服等独有组件 |
同步功能到 theme 分支API/Admin/迁移可整目录 checkoutPlayer 只做逻辑合并 + 保留各分支 `styles.css` 与主题资源。发版前在目标分支打包镜像。
## 演示账号(开发 seed
| 角色 | 用户名 | 密码 |
|------|--------|------|
| 超级管理员 | admin | Admin@123 |
| 一级代理 | agent1 | Agent@123 |
| 级代理 | agent2 | Agent@123 |
| 玩家 | player1 | Player@123 |
| 角色 | 用户名 | 密码 |
| ----- | ------- | ---------- |
| 超级管理员 | admin | Admin@123 |
| 级代理 | agent1 | Agent@123 |
| 二级代理 | agent2 | Agent@123 |
| 玩家 | player1 | Player@123 |
生产 seed 仅创建 admin + WC2026 样例数据,不含代理/玩家演示号。详见 `docs/默认数据说明.md`
## 文档索引
| 文档 | 用途 |
|------|------|
| `docs/项目启动指南.md` | 本地开发、排错、端口 |
| `docs/Docker部署指南.md` | 生产部署、备份、回滚、发版流程 |
| `docs/docker/镜像构建与导出.md` | 本地打镜像 tar |
| `docs/默认数据说明.md` | seed 数据、WC2026、48 强 |
| `docs/投注玩法说明.md` | 玩法与判赢规则 |
| `docs/结算与返水金额规则.md` | 派彩/返水金额公式 |
| `docs/settlement-and-fund-flow-analysis.md` | 结算操作流程 |
| `docs/手动充值功能说明.md` | 充值审核流程 |
| `docs/短信调试与日志说明.md` | 创蓝短信排错 |
| `docs/UAT_CHECKLIST.md` | 上线前回归清单 |
| `docs/player-mobile-performance.md` | 玩家端性能验收 |
| `docs/admin-page-switch-performance.md` | 管理端切页优化任务 |
| 文档 | 用途 |
| ------------------------------------------- | ------------------- |
| `docs/项目启动指南.md` | 本地开发、排错、端口 |
| `docs/Docker部署指南.md` | 生产部署、备份、回滚、发版流程 |
| `docs/docker/镜像构建与导出.md` | 本地打镜像 tar |
| `docs/默认数据说明.md` | seed 数据、WC2026、48 强 |
| `docs/投注玩法说明.md` | 玩法与判赢规则 |
| `docs/结算与返水金额规则.md` | 派彩/返水金额公式 |
| `docs/settlement-and-fund-flow-analysis.md` | 结算操作流程 |
| `docs/手动充值功能说明.md` | 充值审核流程 |
| `docs/短信调试与日志说明.md` | 创蓝短信排错 |
| `docs/UAT_CHECKLIST.md` | 上线前回归清单 |
| `docs/player-mobile-performance.md` | 玩家端性能验收 |
| `docs/admin-page-switch-performance.md` | 管理端切页优化任务 |
## 测试与冒烟
@@ -202,5 +220,6 @@
- 不要 `git merge main` 进 theme 分支做 player 同步(会把 main 暗金样式大量带入)。
- 不要直接改数据库余额修结算;走结算/钱包服务。
- 不要提交 `.env``.env.docker`、镜像 tar、`apps/*/dist/`
- 改 player 主题相关文件时,先确认当前分支是 `main` 还是 `theme-*`,避免用错 CSS 变量(如 theme-2 无 `--gold`)。
- 改 player 主题相关文件时,先确认当前分支是 `main` 还是 `theme-`*,避免用错 CSS 变量(如 theme-2 无 `--gold`)。
- 管理端改列表页性能时,参考 `docs/admin-page-switch-performance.md` 任务清单,优先 KeepAlive + 缓存而非盲目减 API 字段。