⚠️ 这篇已失效,仅作历史记录保留

本文写于 2026-08-10,依据的是 gameboxclient旧代码基线。 当前代码库已被整体替换:文中反复出现的 /workspace(游戏资源库)、 /option(游戏发布栈)、src/views/Workspace/src/views/UI/ 在新代码中均已不存在, 所有 file:line 引用都无法再定位。

请改读重建后的课程首页, 或直接看新的架构图接手文档

Reference · 逐课增量建设中

故障分诊表

拿到报障 → 判归属层 → 找第一检查点。每条都能追到 file:line

这张表的状态

你 mission 里点名要「照着分诊表定位线上问题」。这张表原本不存在 ——课程每讲完一层,就往这里追加该层的判定条件和第一检查点,第 7 课再拿真实问题跑一遍。

已建:接口环境层(课 01)、定位层与路由权限(课 02)。 待建:主进程 / IPC 层(课 03)、渲染层(课 04)、 外部工具层(课 04–05)、打包安装层(课 06)。

第一步:固定现场(任何一层都先做这个)

脱敏后再外发。.envGameENV 里含 SVN / Jenkins / OSS / COS 的账号密码和 token,日志和截图里不能出现这些值,也不要出现带敏感 查询参数的完整 URL。只记键名和「有没有值」。

第二步:判归属层

现象 归属层 第一检查点 状态
请求打去了错误的域名或 pCode;404 / 401;「测试环境的数据出现在正式环境」 接口环境层 见下方 §接口环境层 ✅ 课 01
页面不更新、按钮点了没反应、数据对但没渲染 渲染层 待建(课 04)
界面提示「成功」,但结果没发生 / 资源没变 副作用层 见下方 §定位层,先分清「请求」还是「副作用」 ✅ 课 02
某个人看不到某个按钮 / 进不去某个页面 路由权限层 见下方 §定位层 ✅ 课 02
窗口、菜单、自动更新异常;文档小窗口行为怪 主进程 / IPC 层 待建(课 03)
SVN / Jenkins / Python / 解压 / TiledMap 报错 外部工具层 待建(课 04–05)。本机已知:内置 svnpython3 无可执行位,系统 svn 未安装 部分
只在安装包里出现,开发模式正常 打包安装层 待建(课 06)。关键词 DIST_EXTEND / app.asar.unpacked / asarUnpack

定位层 建于课 02

在判断「是谁坏了」之前,先回答「它在哪」。走完通常不到 15 分钟, 而且不需要读懂任何一个函数的内部逻辑。完整讲解见 课 02

① 界面文字 ├─ A 菜单/页面标题 ─→ rg src/locales/zh-CN.ts 拿 key ─→ 路由表 ─→ 组件 │ ★ 路由名和目录名不对应,查 路由定位速查卡 ├─ B 按钮/提示(多数属于这类)─→ rg "那句中文" src 一步命中组件 └─ C 全局弹窗(GM、个人信息)─→ 不经路由,看 src/App.vue ▼ ② 读组件的 import 块 ─→ 这个页面碰了哪几层 ▼ ③ 进 src/api/** ─→ 分流:请求 or 本地副作用

第 ③ 步的分流是本层的核心判断。 src/api/**不是只有 HTTP 请求,看 import 块第一行就能分:

已知实例:资源库里「替换」一个目录型资源, 当目标目录已存在时会直接 svnDelete + svnCommitsrc/api/workspace/index.ts:763,770-772),不经过发布栈。 提交的只有删除,新内容留在本地(该函数里没有 svnAdd 或第二次提交)。 而且 await Promise.all( 被注释掉了(src/api/workspace/index.ts:759-760), 所以「更新成功」弹窗出现时,实际工作可能一步都没做完。

权限问题也在这一层解决。generateRoutes() 零过滤(src/store/modules/permission.ts:36-56), 所有登录用户的路由表完全一样,去路由表里找权限是白费时间。 按现象分:

现象 去哪找
能进页面,看不到某个按钮,或 看得见但点不动 定位到该组件,搜这一串:userInfoPrivilegeuser_typev-ifv-show:disabled、TSX 的 &&。 实例:src/views/Option/Option.vue:227:disabled)、src/views/UI/UIManager/TabsPane.vue:137(TSX &&)、src/views/Workspace/index.vue:107(进页面即拦下)。 这些只控制界面可见性,不是访问授权
整个页面进不去,提示「无权限」 src/permission.ts 的守卫:uiView()/ui:81-97)、docView() 管文档窗口分流(:40-79
没登录就被踢走 白名单只有 ['/login']src/permission.ts:23), 开发模式下多一条 /onboarding/day1src/permission.ts:24
点一下跳了两次 / 停在奇怪的页面 守卫里 next() 被多次调用(src/permission.ts:99-140docViewuiView 各自也在调)

接口环境层 建于课 01

触发条件:失败请求的 url 里含 1000y。不含则本层不适用, 去调用处找写死的地址。

① Console: sessionStorage.currentRouter 值是什么?在 ROUTE_CONFIG_MAP 里吗?(service.ts:31-64,共 8 条) 不在 → 落默认分支 VITE_API_PCODE / VITE_API_PATH 注意 GM 弹窗会把它改成 '/GM'(GlobalEventListener.vue:187,202) 关闭时会改成 ''(同文件 :184) ② 实际用的 pCode 含 "_dev" 吗? 是 → 被硬编码劫持到 common-gm-460qntest(service.ts:88-89) 这条优先级最高,压过一切 ③ 命中映射表时读 sessionStorage,没命中时读 Pinia 内存 Application → Session Storage → GameENV → 对应 pathKey/pcodeKey 有值吗? (service.ts:92-94) ④ 值是空的 → 回头查 envOption.ts:39-56 后端下发的 gameConfig 给了什么?pcode / gm_url / gm_url_dev
结论 典型根因
currentRouter 不在映射表里 新页面加了路由,但没往 ROUTE_CONFIG_MAP 里加对应条目
currentRouter'/GM' 但你在别的页面 GM 弹窗关闭后没被复位
pCode 含 _dev 用户选了「测试版」。这个下拉的实现就是给 pCode 拼 _dev 后缀(src/views/GM/GameNotice/index.vue:110-115, 文案见 src/locales/zh-CN.ts:214-215),随后被 service.ts:88-89 的硬编码测试域名接管
切了「正式版 / 测试版」但请求没跟着变 13 个页面有这个开关,其中 10 个是直接写 sessionStorage、绕过 Pinia 的。 若某处改成了写 Pinia 而读的一方仍读 sessionStorage(或反之),切换就会失效
操作成功但作用在了错误的对象上(没有任何报错) baseURL 或 pCode 算错。这类故障不会自己暴露, 只能靠 Network 面板比对实际域名与请求体里的 pCode
GameENV 里 pathKey 为空 后端 gameConfig 没下发该字段,且 .env 里也没有兜底值
刚改完配置立刻发请求就错,重试一次就对 ⚠️ 持久化时序窗口:watch 默认 flush: 'pre' 是异步的 (GameEvn.ts:44-86),sessionStorage 还没写就被读了

第三步:从入口向副作用追

用户动作 → template 事件 → script 方法 → store / API / IPC / Node 工具 → 网络、文件、子进程或主进程副作用 → 状态写回与 UI 更新

不要漫无目的读目录。用 路由定位速查 的流程从界面文字反查入口。

第四步:最小修复与回归