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

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

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

Reference · 打印出来贴在手边

运行时配置与接口环境

GameBox 客户端。源课:课 01

一句话

运行时真值不在 .env,在 Pinia useGameEvn().ENV 和 sessionStorage GameENV 这两份副本里;service.tscurrentRouter 决定读哪一份。

四层链路

.env / .env.dev / .env.test / .env.pro │ 构建期替换(vite --mode) ▼ import.meta.env │ electron/main/processHandler.ts:6-9 ▼ 主进程 process.env (+ DIST_ELECTRON / DIST_EXTEND / DIST / PUBLIC) │ src/utils/extend/electron.ts:1-4 @electron/remote ▼ ENV │ 登录 → src/api/login/index.ts:11 → initEnv() │ src/utils/extend/envOption.ts:39-89 后端配置覆盖 ▼ Pinia useGameEvn().ENV ★真值 │ src/store/modules/GameEvn.ts:44-86 watch deep → 持久化 ▼ sessionStorage['GameENV'] ★真值副本

代码索引

要找什么 去哪
store 定义、getEnvKey/setEnvKey/clean src/store/modules/GameEvn.ts:8-38
组件外用法 useGameEvnWithOut src/store/modules/GameEvn.ts:40-42
持久化 watch src/store/modules/GameEvn.ts:44-86
createPinia()setupStore src/store/index.ts:4-10
后端配置覆盖(GM / SVN / Jenkins) src/utils/extend/envOption.ts:39-69
Jenkins job 名里 channel 字面量替换 src/utils/extend/envOption.ts:72-89
登录后触发 initEnv src/api/login/index.ts:11
App 启动时 gameEnv.init(process.env) src/App.vue:24
路由 → pCode/path 映射表 src/config/axios/service.ts:31-64
pCode 取值分叉 src/config/axios/service.ts:73-82
baseURL 取值分叉 src/config/axios/service.ts:85-95
sessionStorage 读写封装 src/hooks/web/useStorage.ts:7-46
主进程注入 env electron/main/processHandler.ts:6-15

ROUTE_CONFIG_MAP 全表

src/config/axios/service.ts:31-64不在这张表里的路由一律落到默认分支VITE_API_PCODE / VITE_API_PATH)。

currentRouter pcodeKey pathKey
/GM VITE_API_GM_PCODE VITE_API_GM_PATH
/gameNotice VITE_API_GAMENOTICE_PCODE VITE_API_GAMENOTICE_PATH
/sectConfig VITE_API_SECTCONFIG_PCODE VITE_API_SECTCONFIG_PATH
/loginNotice VITE_API_LOGINNOTICE_PCODE VITE_API_PATH
/regionTagConfig VITE_API_LOGINNOTICE_PCODE VITE_API_PATH
/script VITE_API_SCRIPT_PCODE VITE_API_PATH
/newscript VITE_API_SCRIPT_PCODE VITE_API_PATH
/gateway VITE_API_GATEWAY_PCODE VITE_API_GATEWAY_PATH

注意 /regionTagConfig 复用了 VITE_API_LOGINNOTICE_PCODE/script/newscript 的 pathKey 也不是各自的 *_SCRIPT_PATH。 这些看起来像笔误,但改之前必须先确认业务预期——线上可能正靠它工作。

currentRouter 写入点

位置 写入
src/layout/TagsView.vue:71 切标签 → 该标签 path
src/App.vue:63-66 初始化 → 当前标签 path
src/layout/GlobalEventListener.vue:184 ''(空串)
src/layout/GlobalEventListener.vue:187, 202 '/GM'(虚拟值,地址栏不变)
src/layout/GlobalEventListener.vue:189 传入的 route

「接口打错服务」四步分诊

① url 里含 1000y 吗? 否 → 这套动态切换根本不生效,去查调用处写死的地址 ② Console: sessionStorage.currentRouter 值是什么?在上面那张表里吗? 不在 → 落默认分支 VITE_API_PCODE / VITE_API_PATH ③ pCode 含 "_dev" 吗? 是 → 被硬编码劫持到 common-gm-460qntest(service.ts:88-89) 这条优先级最高,压过一切 ④ Application → Session Storage → GameENV 对应 pathKey / pcodeKey 是空的吗? 空 → 回头查 envOption.ts:49-56,后端 gameConfig 给了什么

Pinia 语法速查(本项目用到的全部)

// 定义(Options 式,本项目全部是这种)
export const useXxx = defineStore('id', {
  state: () => ({ foo: 1 }),        // 必须是函数
  getters: { double: (s) => s.foo * 2 },
  actions: { set(v) { this.foo = v } }  // this === store
})

// 组件内
const s = useXxx()
s.foo            // 直接读,不用 .value
s.set(2)         // 直接调 action
s.$patch({ foo: 3 })
s.$subscribe((mutation, state) => {})  // 官方推荐的持久化钩子

// 组件外(api / config / utils 里必须用这个)
import { store } from '@/store'
export const useXxxWithOut = () => useXxx(store)

禁忌

不要 改用
直读 import.meta.env 取 SVN / Jenkins / GM / pCode / COS 配置 gameEnv.getEnvKey('VITE_XXX')
新增直读 getStorage('GameENV')[key] 的地方 同上,统一走 store
src/config/axios/serviceold.ts(遗留死代码) src/config/axios/service.ts
照着 electron/preload/index.tswindow.extendApi 写 ——它从未被加载vite.config.ts:62,72 的 preload 构建块整段被注释, electron/main/index.ts:47-51webPreferences 里也没有 preload src/utils/extend/electron.ts(经 @electron/remote
把配置值、token、SVN 密码打进 console.log 只打键名和是否存在

import.meta.env.DEVVITE_BASEPATHVITE_APP_TITLE 这类构建期常量不在禁忌之列——它们本来就不会被登录配置覆盖。