feat: track settings changes and enforce Chinese UI copy

This commit is contained in:
chengma
2026-07-06 11:32:02 +08:00
parent 26e59c8cea
commit 19eaa794cf
10 changed files with 430 additions and 19 deletions
+1
View File
@@ -43,6 +43,7 @@
## 5. 代码规范
- 标识符使用英文;UI 文案、注释、文档保持中文,与现有脚本一致。
- 所有用户可见文本必须使用中文:包括弹窗标题/正文/按钮、窗口标题、按钮、菜单、label、placeholder、tooltip、状态栏、空状态、确认框、运行日志、错误提示和成功提示等。不要直接使用 `Save` / `Discard` / `Cancel` 等英文标准按钮露出给用户;如需三选一弹窗,使用自定义中文按钮文案(如“保存”“放弃”“取消”)。URL、配置键、API 字段、模型别名、第三方/Shopee 原始错误可保留原文,但外围必须有中文解释。
- 错误必须处理:CDP 超时、tab 找不到、上传失败、按钮禁用都要给明确提示,不吞错。
- 注释解释“为什么”(尤其 CDP 的坑:代理、Origin、就绪判断、拖拽落点),不复述“做了什么”。
- 复用现有脚本里已验证的 JS 字符串,不重写出不一致的版本。
+1 -1
View File
@@ -129,7 +129,7 @@
| T-528 | ② 计费错误提示 + 余额展示 | T-526, T-527, T-303 | 依据 `docs/cmhub-integration-design.md` v3.2。② AI生成页把 cmhub 计费失败态显式化:通过 `CMHubError.code` 识别 `insufficient_points`,弹明确提示「点数不足,请先充值」并引导去网页端充值,本轮未开始任务可提前中止,不靠中文字符串匹配、不淹没在失败计数里;用 T-526 成功响应事件里的 `points_balance` 刷新②页剩余点数显示,`/balance` 仅作手动刷新/可选批量前预检;`points_cost`/`call_id` 记入脱敏 run_logs。只改② UI、`GenerateWorker` 事件处理/文案及 GUI 单测;不改 AI HTTP 协议、DB schema、Excel、Shopee/CDP 流程 | DONE |
| T-529 | 默认 cmhub 网关并隐藏 AI 后端选择 | T-528, T-527 | 产品收口:后续普通用户只使用 cmhub 网关,不再在⑤设置页暴露「AI 后端」label 与 direct/cmhub 下拉框。方案:`DEFAULT_CONFIG.ai.backend` 改为 `cmhub`;⑤设置页默认直接展示 cmhub 网关配置(Base URL、API Key、生文/生图别名、刷新别名、测试连接/查余额),隐藏 direct 模型选择、模型详情、标题/图片模型角色下拉和「AI 后端」下拉;保存设置固定写 `ai.backend=cmhub`,允许先保存不完整 cmhub 配置,②生成时仍由 `app/ai.py` 对缺 Base URL/Key/别名给出「请去⑤配置 cmhub」错误。direct 代码、`config/ai_models.json` helper 与 direct 单测保留为内部兼容/手工回滚路径,但普通 UI 不提供切换入口。同步 `appconfig`、⑤设置页、②余额默认显示和 GUI/appconfig 单测;不改 AI HTTP 协议、DB schema、Excel、Shopee/CDP 流程 | DONE |
| T-530 | cmhub Base URL 规整 + 404 明确提示 | T-526, T-527 | 现象:手动填入 Base URL 后点「刷新别名」提示 notfound(HTTP 404)。核对确认 cmshopee 请求已达标(`GET /api/v1/models` + Bearer,对齐对接文档 §4.4 与 cmhub `ModelsView` 路由,见 `docs/troubleshooting.md`「cmhub 刷新别名 notfound」与 `docs/cmhub-integration-design.md` v3.4);404 根因是 Base URL 带多余 `/api(/v1)` 路径导致双拼、或所连实例未部署 `/api/v1/models`。方案:保存/请求前规整 Base URL——去掉结尾的 `/`、`/api`、`/api/v1` 等多余路径段,只保留 scheme+host(+port)(`appconfig.cmhub_request_url()` 或保存时统一处理),并在⑤输入框旁给出「只填网关根,如 https://host」提示;`_cmhub_code_for_status` 给 404 一个明确码/中文提示(如「cmhub 接口不存在,请检查 Base URL 或该实例是否已部署 /api/v1/models」),不再透传生涩英文原文。补 `test_appconfig`(Base URL 规整:带 `/api/v1`、带尾斜杠、带路径均归一到根)与 `test_ai`(404 → 明确提示)单测;不改 AI HTTP 协议、DB schema、Excel、Shopee/CDP 流程 | DONE |
| T-531 | ⑤ 设置未保存状态追踪 + 离开确认 | T-530, T-529, T-527 | 现象:在⑤填写 cmhub Base URL/API Key(或改任何设置)后,没有任何"未保存"提示;切换到其它 Tab、关闭窗口都不拦截,输入静默丢失。且「刷新别名/测试连接」用输入框实时文本、不落盘,成功后易误以为已保存。采用**方式 B(显式保存 + 脏状态追踪 + 离开确认)**,不改自动保存(API Key/半份 cmhub 配置不宜自动写盘)。方案:① 脏追踪——⑤ 所有可编辑控件(cmhub Base URL/API Key/别名下拉、模型详情、生成参数、路径端口、Shopee 更新安全等)接 `textChanged`/`currentIndexChanged`/`toggled`/`valueChanged` 置 `self._dirty=True`;「保存设置」成功后清 `False`;`save_app_settings()` 或等价保存入口必须返回成功/失败,失败时保留 dirty 并阻止离开。② 程序化回填保护——加载配置、保存后重载、刷新别名写回下拉、`_populate_app_settings()` / `_populate_cmhub_alias_combos()` 等必须用 `_suspend_dirty` 或 `QSignalBlocker` 避免误置脏;用户手动输入后由刷新/测试触发的 Base URL 规整仍应保持 dirty,提醒其保存。③ 离开拦截——`main_window` 切 Tab 与 `closeEvent` 若发现⑤ `_dirty` 为真,弹三选一「保存 / 放弃 / 取消」:保存则调保存入口且成功后再切/关;放弃必须重新从 `config.json` + `config/cmhub.json` 载入并回填控件,再清 dirty,不能只清标志;取消则留在⑤不切不关。`QTabWidget.currentChanged` 是切换后信号,实现时需维护上一 Tab index,并用 `_reverting_tab_change`/类似 guard 防止 `setCurrentIndex()` 递归触发。④ 视觉提示——「保存设置」旁显示「● 未保存更改」,保存或放弃回填后消失。⑤ 「刷新别名/测试连接」成功后提示语补「别名已拉取,记得点『保存设置』持久化」,**不**顺带偷偷保存 url/key(保持显式保存一致性)。只改 ⑤ 设置页、`main_window` Tab 切换/关闭守卫和 GUI 单测(脏标志置位/清除、切 Tab 保存/放弃/取消/保存失败分支、程序化回填不置脏、放弃会还原输入、currentChanged 回退不递归);不改配置 schema、AI HTTP 协议、DB schema、Excel、Shopee/CDP 流程 | TODO |
| T-531 | ⑤ 设置未保存状态追踪 + 离开确认 | T-530, T-529, T-527 | 现象:在⑤填写 cmhub Base URL/API Key(或改任何设置)后,没有任何"未保存"提示;切换到其它 Tab、关闭窗口都不拦截,输入静默丢失。且「刷新别名/测试连接」用输入框实时文本、不落盘,成功后易误以为已保存。采用**方式 B(显式保存 + 脏状态追踪 + 离开确认)**,不改自动保存(API Key/半份 cmhub 配置不宜自动写盘)。方案:① 脏追踪——⑤ 所有可编辑控件(cmhub Base URL/API Key/别名下拉、模型详情、生成参数、路径端口、Shopee 更新安全等)接 `textChanged`/`currentIndexChanged`/`toggled`/`valueChanged` 置 `self._dirty=True`;「保存设置」成功后清 `False`;`save_app_settings()` 或等价保存入口必须返回成功/失败,失败时保留 dirty 并阻止离开。② 程序化回填保护——加载配置、保存后重载、刷新别名写回下拉、`_populate_app_settings()` / `_populate_cmhub_alias_combos()` 等必须用 `_suspend_dirty` 或 `QSignalBlocker` 避免误置脏;用户手动输入后由刷新/测试触发的 Base URL 规整仍应保持 dirty,提醒其保存。③ 离开拦截——`main_window` 切 Tab 与 `closeEvent` 若发现⑤ `_dirty` 为真,弹三选一「保存 / 放弃 / 取消」:保存则调保存入口且成功后再切/关;放弃必须重新从 `config.json` + `config/cmhub.json` 载入并回填控件,再清 dirty,不能只清标志;取消则留在⑤不切不关。`QTabWidget.currentChanged` 是切换后信号,实现时需维护上一 Tab index,并用 `_reverting_tab_change`/类似 guard 防止 `setCurrentIndex()` 递归触发。④ 视觉提示——「保存设置」旁显示「● 未保存更改」,保存或放弃回填后消失。⑤ 「刷新别名/测试连接」成功后提示语补「别名已拉取,记得点『保存设置』持久化」,**不**顺带偷偷保存 url/key(保持显式保存一致性)。只改 ⑤ 设置页、`main_window` Tab 切换/关闭守卫和 GUI 单测(脏标志置位/清除、切 Tab 保存/放弃/取消/保存失败分支、程序化回填不置脏、放弃会还原输入、currentChanged 回退不递归);不改配置 schema、AI HTTP 协议、DB schema、Excel、Shopee/CDP 流程 | DONE |
## Phase 8 · 工程基础设施后续(`docs/engineering-review.md`)
+2 -2
View File
@@ -381,9 +381,9 @@ T-523 后 GUI 已从旧 `app/gui.py` 拆为 `app/gui/` 包:`__init__.py` 负
⑤ 设置当前要点(T-501):
- `SettingsTab` 使用居中内容区 + 适度左右留白布局,当前留白已从 T-506 初始实现缩短到约 40%;实现上使用最大内容宽度和自适应 margin,避免固定像素导致小屏挤压。各设置组默认响应式 3 列表单:短字段占 1 格,长字段(URL/API Key/路径)跨 2 格或 3 格,窄窗口降为 2 列/1 列。点击「保存设置」成功后,调用 `QMessageBox.information` 弹出“设置已保存”轻量提示框,同时保留状态栏提示。T-531 后 `save_app_settings()` 或包装保存入口应返回 bool:成功写 `config.json` + `config/cmhub.json` 后清 dirty,失败保留 dirty 并让调用方阻止离开。
- `SettingsTab` 使用居中内容区 + 适度左右留白布局,当前留白已从 T-506 初始实现缩短到约 40%;实现上使用最大内容宽度和自适应 margin,避免固定像素导致小屏挤压。各设置组默认响应式 3 列表单:短字段占 1 格,长字段(URL/API Key/路径)跨 2 格或 3 格,窄窗口降为 2 列/1 列。点击「保存设置」成功后,调用 `QMessageBox.information` 弹出“设置已保存”轻量提示框,同时保留状态栏提示。T-531 已完成:`save_app_settings()` 返回 bool,成功写 `config.json` + `config/cmhub.json` 后清 dirty,失败保留 dirty 并让调用方阻止离开。
- `SettingsTab` 的 cmhub 网关配置:Base URL 保存/刷新前规整为网关根;API Key 单独读写 `config/cmhub.json`;别名下拉来自 `fetch_cmhub_models()`,按 `operation_type` 分生文/生图并过滤未计价别名;「测试连接/查余额」调用 cmhub models + balance helper;保存设置固定写 `ai.backend=cmhub`。`refresh_cmhub_models()` / `test_cmhub_connection()` 使用输入框实时值但不得自动保存,成功文案提醒用户保存。`is_dirty()` / `discard_unsaved_changes()` / `_suspend_dirty`(或等价机制)用于 T-531:用户编辑置脏,程序化回填不置脏,放弃时重新加载 `config.json` + `config/cmhub.json` 并回填控件。
- `MainWindow` 在 T-531 后负责⑤设置页离开守卫:切 Tab 与 `closeEvent` 发现 `SettingsTab.is_dirty()` 时弹保存/放弃/取消;保存成功后继续,保存失败或取消时回到⑤。由于 `QTabWidget.currentChanged` 是切换后信号,需维护上一个 index,并用 `_reverting_tab_change` 或等价 guard 防止 `setCurrentIndex()` 递归。
- `MainWindow` 已负责⑤设置页离开守卫:切 Tab 与 `closeEvent` 发现 `SettingsTab.is_dirty()` 时弹保存/放弃/取消;保存成功后继续,保存失败或取消时回到⑤。由于 `QTabWidget.currentChanged` 是切换后信号,需维护上一个 index,并用 `_reverting_tab_change` 或等价 guard 防止 `setCurrentIndex()` 递归。
- 模型详情字段按 3 个组件一组排列:启用、类别、api_type、连接超时等短字段一格;服务商名、模型 ID 视宽度占一格或两格;网址、密钥跨整行或跨 2/3 列。
- 模型数据读写复用 `appconfig.list_ai_models(..., reveal_api_key=True)`、`add_ai_model()`、`update_ai_model()`、`delete_ai_model()`;保存时保留现有 `extra_body` 与 `timeout_seconds`。
- 密钥字段使用 `QLineEdit.Password` 打码显示;首次保存/变更非空 Key 前弹窗提示“本地明文保存”;明文只写入已 gitignore 的 `config/ai_models.json`,不得进入日志/导出。
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -142,12 +142,12 @@
## ⑤ 设置
- 设置页整体布局:内容区居中,左右留白已从 T-506 初始实现缩短到约 40%;实现上用最大内容宽度 + 自适应 margin,而不是写死窗口像素。所有设置组默认响应式 3 列表单:短字段占 1 格,URL/API Key/路径等长字段跨 2 格或 3 格;窄窗口自动降为 2 列/1 列。点击「保存设置」成功后,状态栏显示“设置已保存”,并弹出轻量提示框。T-531 后保存成功还需清除未保存标记;保存失败时保留未保存标记并阻止离开。
- 设置页整体布局:内容区居中,左右留白已从 T-506 初始实现缩短到约 40%;实现上用最大内容宽度 + 自适应 margin,而不是写死窗口像素。所有设置组默认响应式 3 列表单:短字段占 1 格,URL/API Key/路径等长字段跨 2 格或 3 格;窄窗口自动降为 2 列/1 列。点击「保存设置」成功后,状态栏显示“设置已保存”,并弹出轻量提示框。T-531 已完成:保存成功会清除未保存标记;保存失败时保留未保存标记并阻止离开。
- cmhub 网关配置(T-529 后普通用户唯一 AI 入口):⑤设置页不再显示「AI 后端」label 或 direct/cmhub 下拉,直接展示 cmhub 网关 Base URL、API Key、生文别名、生图别名、连接超时、刷新别名、测试连接/查余额;Base URL 输入框旁提示“只填网关根,如 https://host”,保存/刷新前会规整掉 `/api`、`/api/v1` 或其它路径。刷新别名/测试连接使用当前输入框内容发起请求,但不自动保存 URL/API Key,成功文案需提醒“记得点保存设置持久化”。
- API Key 存在 `config/cmhub.json`,本地明文保存;保存/变更时提示;UI 使用密码框打码显示,不进入日志/导出。
- 生文/生图别名来自 `GET /api/v1/models` 动态下拉,过滤未定价别名并展示单价/需原图提示;网关临时不可达时保留已存别名。
- 保存设置固定写 `ai.backend=cmhub`。允许先保存不完整 cmhub 配置,②真正生成时如果缺 Base URL/API Key/别名,会提示去⑤补配置,不静默回退 direct。
- T-531 后,⑤设置页任意可编辑控件变更都进入未保存状态,保存按钮旁显示“● 未保存更改”;切换到其它 Tab 或关闭窗口时弹出保存/放弃/取消。放弃必须重新从本地配置文件回填控件,避免未保存的 URL/API Key 留在界面上;程序化回填、保存后重载和刷新别名填充下拉不得误触发未保存状态。
- T-531 已完成:⑤设置页任意可编辑控件变更都进入未保存状态,保存按钮旁显示“● 未保存更改”;切换到其它 Tab 或关闭窗口时弹出保存/放弃/取消。放弃会重新从本地配置文件回填控件,避免未保存的 URL/API Key 留在界面上;程序化回填、保存后重载和刷新别名填充下拉不会误触发未保存状态。
- direct 模型清单和 `config/ai_models.json` 代码路径保留为内部兼容/手工回滚,不在普通 UI 暴露。
- AI 生成参数:标题并发、图片并发、失败重试、分辨率、返回超时、jpg 质量等短字段按三列排列。
- 分辨率为 `512 / 1k / 2k / 4k`;返回超时只读展示 `resolution_timeouts[resolution]`,不单独编辑。