Skip to content

fix(paths): 跟随 ZCode 的 dataBaseDir,修复改过数据目录后账号切换不生效 - #18

Merged
pjpv merged 1 commit into
pjpv:mainfrom
codeyy2023:fix/follow-zcode-databasedir
Sep 25, 2026
Merged

pjpv merged 1 commit into
pjpv:mainfrom
codeyy2023:fix/follow-zcode-databasedir

Conversation

@codeyy2023

Copy link
Copy Markdown
Contributor

关联

现象

Z·SWITCH 提示切换成功、界面把目标账号标为「使用中」,但打开 ZCode 仍是旧账号。两个界面对同一个账号状态给出不同答案。

根因

ZCode 的数据根由 ~/.zcode/v2/setting.json 的 dataBaseDir 决定,账号登录态文件会跟着搬到新目录:

// 从官方 app.asar 提取
getDataBaseDir()      = setting.json.dataBaseDir || env.ZCODE_DATA_BASE_DIR || homedir()
getZCodeDataRootDir() = <dataBaseDir>/.zcode
getAppConfigDir()     = <dataBaseDir>/.zcode/v2
getCredentialsFile()  = <getAppConfigDir()>/credentials.json    // 唯一路径,没有 home 回退

setting.json 自身是 bootstrap 文件,恒留在 ~/.zcode/v2/;credentials.json / config.json / telemetry-state.json / coding-plan-cache.json / provider_config.json / 日志 / tasks db 全在 <dataBaseDir>/.zcode/v2/ 下。

而 store.rs:66-70 把这几个路径全部硬编码在 home 下,仓库里没有任何地方读取 dataBaseDir —— 用户改过数据目录后,zcode-switch 改的是一份 ZCode 根本不读的僵尸副本。

改动

src-tauri/src/store.rs

  • Paths 新增 data_root: PathBuf;
  • 新增 resolve_data_root() / bootstrap_data_base_dir() / abs_env_path(),优先级与 ZCode 完全同序:
    ZCODE_SWITCH_DATA_ROOT(本工具自己的逃生开关)> setting.json.dataBaseDir > env.ZCODE_DATA_BASE_DIR > home;
  • live_file / live_config / live_telemetry / live_plan_cache 改为走 zcode_dir() = <data_root>/.zcode/v2/;
  • home 保持不变 —— 它同时是 enc:v1 的解密密钥基准(zcrypto::default_secret)和 .zcode-switch 账号库的所在位置,绝不能跟着搬;
  • live_setting() 保持 home 根 —— setting.json 是 bootstrap 文件,ZCode 永远从 homedir()/.zcode/v2/ 读它,改动它反而会把 family-domain 对齐写错地方;
  • atomic_write() 补上父目录 create_dir_all —— write_live_config / write_live_device_mid 原先假定目录已存在,在「已激活」早退分支上会失败(数据根是新建目录时窗口更明显)。

src-tauri/src/quota.rs

  • device_mid() 读的 telemetry-state.json 改走数据根(原先读的也是僵尸副本,会导致 deviceMid 取错值)。

为什么不采用「把 home 指到 dataBaseDir」的绕过写法

ZCODE_SWITCH_HOME 指向数据目录看似等价,实测会坏掉:home 也是 enc:v1 的解密密钥基准,改完之后所有密文字段都解不开,account_identity / find_same_login / already_active 判定全部失效,甚至可能重新触发 v1.5.0 修过的「Auto xx 重复账号」。所以必须改代码而不是改环境变量。

验证(Windows / ZCode 装在非默认目录 / 数据目录改为 F:\zcode)

  1. --cli state 的 live_identity 由「home 根里的旧账号」变为与 ZCode 界面一致的账号,store_dir 仍在 ~/.zcode-switch(账号库没有搬家)。
  2. 往返切换测试:切到账号 A → 解密 F:\zcode\.zcode\v2\credentials.json 的 oauth:bigmodel:user_info 得账号 A;切回账号 B → 得账号 B。
  3. 整个过程中 C:\Users\<user>\.zcode\v2\credentials.json 的 SHA256 完全没变(时间戳也未更新)—— 证明补丁后只动真正的文件、不再写僵尸副本。
  4. 切换后存档的 is_active 恢复正常,「使用中」标记与 ZCode 一致。

兼容性与风险

  • setting.json 不存在、或 dataBaseDir 缺失/为空/相对路径、或等于 home 时,data_root == home,行为与旧版逐字节一致(不做「目录是否存在」的猜测,取到就用,避免再次出现静默分叉)。
  • 首次升级后:数据根里的 credentials.json 是 ZCode 自己写过的版本,与账号存档不逐字节相同,因此界面一开始不会给任何账号打「使用中」,但 live_identity 会正确显示;下一次切换会走既有的 sync_live_back_to_source(哈希 + 身份双匹配)把存档对齐,不会再产生重复账号。
  • Paths::detect() 每次调用会多读一次 setting.json(微秒级,无网络)。
  • 新增 ZCODE_SWITCH_DATA_ROOT 逃生开关,便于排查/测试;不影响既有变量语义。

测试说明

仓库在 11496a8 之后不再附带单元测试,本次为手工验证(步骤见上)。

另附一条源码编译的注意事项:手工构建必须带 --features tauri/custom-protocol,否则 tauri/build.rs 的 let dev = !custom_protocol; 会把它当成 dev 模式,窗口去连 http://127.0.0.1:5173 并显示 ERR_CONNECTION_REFUSED(官方 release 走 tauri-action 不受影响):

npm ci && npm run build
cd src-tauri && cargo build --release --features tauri/custom-protocol

用户在 ZCode 里改过「数据目录」之后,账号登录态文件会跟着搬到
<dataBaseDir>/.zcode/v2/ 下;而 live_file / live_config / live_telemetry /
live_plan_cache 仍硬编码在 home 根,于是切换只改到一份 ZCode 根本不读的
僵尸副本:界面提示切换成功、ZCode 里仍是旧账号。

- Paths 新增 data_root,优先级与 ZCode 完全同序:
  ZCODE_SWITCH_DATA_ROOT > setting.json.dataBaseDir > ZCODE_DATA_BASE_DIR > home
- live_file / live_config / live_telemetry / live_plan_cache 改走 <data_root>/.zcode/v2/
- home 保持不变(enc:v1 解密密钥基准 + .zcode-switch 账号库位置)
- live_setting() 保持 home 根(setting.json 是 bootstrap 文件,恒在该处)
- quota::device_mid() 读的 telemetry-state.json 一并改走数据根
- atomic_write() 补上父目录 create_dir_all

Refs pjpv#6
@pjpv

pjpv commented Sep 25, 2026

Copy link
Copy Markdown
Owner

感谢,分析很扎实,已对照核实无误。会合入下个版本,届时在此说明。

@pjpv
pjpv merged commit f342256 into pjpv:main Sep 25, 2026
@pjpv

pjpv commented Sep 25, 2026

Copy link
Copy Markdown
Owner

已在 v1.7.0-beta.1 合入,感谢贡献!合入时把相关路径判定也一并做了跟随适配。

方便的话,欢迎在你的环境(自定义数据目录)验证这版的行为是否符合预期。另外 macOS / Linux 目前仅通过 CI 编译、未经真机测试,这两个平台的反馈同样欢迎。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants