Project Map · Structure

这个仓库里什么在哪

九万八千行代码,但你日常真正会碰的只有其中三块。先认路,再干活。

基线:2026-08-12 的 gameboxclient 工作区快照。 行数是当时统计的,用来判断「这块有多重」,不必精确对上。

先说人话:三十秒版本

仓库根目录下真正重要的只有四个地方:

electron/ —— 桌面外壳。开窗口、管更新、跟操作系统打交道。15 个文件,很小。

src/ —— 界面和业务。你 90% 的时间在这里。约 9.8 万行。

extend/ —— 外挂的第三方工具:SVN 客户端、Python 打包脚本、7-Zip、 地图编辑器、便携版 nginx 和 node。不是代码,是二进制,随安装包一起分发。

tools/ —— 给开发自己用的小脚本和 Excel 样表,跟运行时无关。

src/ 里面,真正的主战场是三个目录src/views/GameEditor/(各类配置编辑页,4.2 万行)、 src/store/config/(每张配置表的字段定义)、 src/components/PropEditor/(把字段定义渲染成表单的通用引擎)。 这三个是一套东西的三个面,理解了它们就理解了这个工具的一大半。

完整目录树

点标题展开。带标记的地方要特别留意: 主战场 日常改动集中区 · 别碰 有坑或已废弃 · 孤立 不在路由里、疑似停用 · 外部 二进制或外部工具。

我要改 X,该去哪

这张表是本页最该收藏的部分。左边是需求的原话,右边是实际要动的文件。

需求听起来像 真正要改的地方 注意
物品表加一个字段 src/store/config/Item.ts 加字段定义 页面组件不用动,PropEditor 会自己渲染
某个字段的下拉选项要加一项 对应 src/store/config/*.ts 里该字段的 options 选项若来自另一张表,去 views/GameEditor/*/module.ts
字段要换个控件(比如改成开关) 同上,改字段的 editor / type 可选控件全在 components/PropEditor/Components/
某个字段要显示在另一个标签页 src/views/GameEditor/<模块>/view.ts 的 Groups 只有部分模块有 view.ts,其余直接写在页面里
新增一个编辑页 / 菜单项 src/router/index.ts 加路由 + src/locales/zh-CN.tsrouter.future.* 标题 菜单靠 meta.showMenu 控制,图标用 iconify 名
接口地址要改 / 换服务器 src/utils/extend/envOption.ts 不是 .env。多数地址由 /user/info 下发,前端只是接收
请求要加一个统一的头 / 参数 src/config/axios/service.ts 的请求拦截器 别改成 serviceold.ts
要读写本地文件 / 调系统命令 src/utils/extend/ 加一个模块 渲染层能直接 require('fs'),但新代码建议走 IPC
要加一个主进程能力(开窗口、读注册表…) electron/main/handler/channel.tsipcMain.handle 渲染侧用 ipcRenderer.invoke
发布流程要加一种任务 src/api/task/index.ts 的卡片列表 + utils/extend/jenkins/config.ts 的 JOB_TYPES 先想清楚是 SVN 型还是 Jenkins 型,两条路径完全不同
登录后要多做一件事 src/api/login/index.tsloginSuccess() 注意它同时被 ReLogin 页调用,改动影响启动链
改按钮文案 / 菜单名 src/locales/zh-CN.ts 有不少页面把中文直接写死在模板里,先全局搜一下原文案
改样式 页面内的 <style lang="less" scoped>,或 WindiCSS 的原子类 两套并存:Element Plus 主题、WindiCSS 原子类、以及 src/styles/
要加一张新的配置表 src/store/config/ 新增 schema + store/modules/table.tstableConfigMap 与几个表名数组 表名和文件名不一致时必须在 tableConfigMap 里登记映射

找不到入口时的通用办法

从界面文案倒推。在应用里看到「刷新时间」这个标签, 就全局搜这四个字。搜到的多半是某个 src/store/config/*.ts 里的 summary 字段,从那里往上就能定位到表和模块。

搜不到就搜路由名:地址栏 hash 里是 #/game/npc_edit, 去 src/router/index.tsnpc_edit, 直接看到它的 component 指向哪个文件。

已知坑:动手前先知道这几件事

❌ 别学

Python 工具链的解释器路径当前是断的。 src/utils/extend/python.ts:34-41 按平台去找 extend/Python/Win/3.11/python.exeextend/Python/Mac/3.8/bin/python3, 但当前 extend/Python/根本没有 Win/ 和 Mac/ 这两个目录 —— 只有 move/ luaTrans/ Script/ mapMask/ transPlist/,里面是 16 个 .exe

影响:地图转换、动画转换、lua 读写、nginx 初始化这几条链路, 在任何平台上都会因为找不到解释器而失败。

这是本仓库目前最该问清楚的一件事:这些 exe 是不是已经打包成独立 可执行文件、不再需要 python 解释器了?如果是,python.ts 里那段 command 拼接就是死代码。问到答案前不要自己乱改。

❌ 别学

smallWindow 一个变量当两样东西用。 electron/main/helpers/window.ts 里,smallWindow 本来存的是 Excel 小窗的 BrowserWindow 实例(71 行), 但 setSharedData(data)(103 行)会把它整个覆写成任意数据, getSharedData()(106 行)再读回来。

后果:一旦调过 setSharedDatagetSmallWindow() 拿到的就不再是窗口对象了。 跨窗口传数据和窗口引用管理必须拆成两个变量。

❌ 别学

小窗的 setWindowOpenHandler 解构了不存在的字段。 helpers/window.ts:91 写的是 ({ docUrl }) => shell.openExternal(docUrl), 但这个回调的入参对象里字段名是 url,不是 docUrl —— 同一个文件 48 行的主窗口就写对了。

后果:在 Excel 小窗里点任何外链,传给 shell.openExternal 的都是 undefined规范做法Electron · setWindowOpenHandler,参数是 { url, frameName, features, ... }