Files
FruitServer/docs/plans/2026-10-17-K13.md

122 lines
4.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-10-17 K13 运行时服务器地址设置(仅 debug)
## 一、目标与边界
解决 debug APK 不带 `--dart-define` 时固定回退到
`http://jiangdeMacBook-Air.local:8081` 的问题。增加仅 debug 可用的运行时地址
覆盖,保存后下次启动生效。
优先级:
```text
SharedPreferencesAsync dev.api_base_url
> --dart-define(API_BASE_URL)
> AppConfig 现有默认地址
```
- 客户端分支:`feature/flutter-k13-dev-server-setting`,基线 `b762289`。
- 文档分支:`docs/k13-dev-server-setting`,FruitServer 基线 `1a5951c`。
- release 不读取 SharedPreferences 覆盖,也不显示设置入口。
- 不做环境列表、远程配置、接口或后端改动。
- 不跑真机。当前有真机 `flutter run` 时,构建使用隔离副本,不终止用户会话。
## 二、运行时解析
新增 `lib/core/config/server_endpoint.dart`:
1. 常量 key:`dev.api_base_url`。
2. `normalize`:
- `trim()`;
- 只接受 `http://` 或 `https://`;
- `Uri.host` 必须非空;
- 去掉末尾所有 `/`。
3. `resolve`:
- 本地值有效时使用本地值;
- 否则使用有效 dart-define;
- 否则使用现有默认值。
4. `load({debug, preferences})`:
- debug=false 时立即返回,不创建/读取 SharedPreferences;
- debug=true 时读取并规范化,合法值写入 `AppConfig` 的运行时覆盖。
5. `save` 与 `clear`:
- save 前规范化,非法值返回 false 且不写;
- clear 删除 key。
`AppConfig` 增加运行时覆盖读写入口和编译期/默认地址 getter;`apiBaseUrl` 优先
返回已加载的运行时值。`main()` 在 `runApp` 前
`await ServerEndpoint.load(debug: kDebugMode)`,确保 `LumaDramaApp` 创建
`ApiClient` 前已加载完成。
## 三、Debug 设置入口
`MineLogic.showLanguage` 增加 `showServerSetting` 参数。我的页设置弹窗中在语言
列表下方增加「服务器地址」行:
- 仅 `MyPage.debugShowSetting == true` 时显示,默认值 `kDebugMode`,测试可注入;
- 副标题显示当前 `AppConfig.apiBaseUrl`;
- 点击打开编辑弹窗,预填当前地址;
- 保存合法地址后关闭编辑弹窗并提示“重启 App 生效”;
- 非法地址在输入框显示校验错误,不保存;
- 提供「恢复默认」,清除本地 key,并提示重启生效;
- release 默认不显示,也不触发本地读取。
新增三语文案:
- `serverAddress`
- `serverAddressHint`
- `saveAddress`
- `restartToApply`
- `restoreDefault`
- `invalidServerAddress`
## 四、测试
新增 `test/config/server_endpoint_test.dart`:
- 本地覆盖 > dart-define > 默认;
- 非法本地值忽略并回落;
- trim、末尾斜杠、http/https;
- `ftp://`、无 scheme、空 host 被拒绝;
- debug=false 不读取覆盖;
- save/clear 对 SharedPreferencesAsync 的行为。
新增/扩展设置弹窗测试:
- debug 注入 true:显示服务器地址行,可打开编辑弹窗;
- 注入 false:不显示入口;
- 非法地址显示错误且不写入。
既有测试只更新必要锚点/新增断言,不删除用例。
## 五、影响文件
- `ReelShort/lib/core/config/server_endpoint.dart`(新增)
- `ReelShort/lib/core/config/app_config.dart`
- `ReelShort/lib/main.dart`
- `ReelShort/lib/pages/mine/mine_view.dart`
- `ReelShort/lib/pages/mine/mine_logic.dart`
- `ReelShort/lib/l10n/app_en.arb`、`app_zh.arb`、`app_id.arb` 与生成文件
- `ReelShort/test/config/server_endpoint_test.dart`(新增)
- 我的设置弹窗测试
- `FruitServer/docs/plans/2026-10-17-K13.md`
- `FruitServer/docs/plans/PROGRESS.md`
- `FruitServer/docs/plans/INBOX.md`
## 六、门禁与 Git
1. 先写运行时解析与入口可见性测试,确认红灯。
2. 实现后跑定向测试。
3. 运行 `dart analyze lib test`、`flutter test`、`flutter build apk --debug`。
4. 当前真机 run 会话不终止;构建在独立副本中进行,原 `build/` 不受影响。
5. 完成后 `merge --no-ff` 回客户端 `develop` 并 push;FruitServer 文档同样
合并推送。作者与提交者统一为
`Zhou Weidong <502333560@qq.com>`。
## 七、风险与待确认
- `AppConfig.apiBaseUrl` 当前是纯 getter;增加运行时静态状态后,测试必须显式
清理,避免用例间污染。
- release 的“完全不读取”由 `ServerEndpoint.load(debug: kDebugMode)` 和主入口
的 debug 参数共同保证;测试使用可注入 debug 参数验证。
- 保存和恢复默认都只在下次启动生效,当前 ApiClient 不在运行中重建。
- 设置入口只在 debug 显示,不修改发布包的信息架构。