6.4 KiB
6.4 KiB
id, title, phase, deps, status, created
| id | title | phase | deps | status | created | |
|---|---|---|---|---|---|---|
| T-638 | 商品套图卖点输入自动保存与自适应高度 | 7 |
|
TODO | 2026-07-16 |
问题 / 背景
⑥「商品套图」的「商品卖点与要求」输入框当前存在两个体验问题:
textChanged只把文本更新到当前SuiteTaskState.prompt,不会立即写入 SQLite。只有修改生成设置、开始生成等后续动作碰巧调用_persist_state()时才会保存;用户仅修改文本后直接关闭任务、关闭软件,内容可能丢失。- 输入框当前固定在约
96~112px高度,内容较多时依赖内部竖向滚动条。左侧配置区已经由外层suiteConfigScroll统一滚动,继续保留输入框内部滚动会形成嵌套滚动,运营用户不容易判断是否还有未看到的内容。
本任务把卖点文本改为可靠的防抖自动保存,并让输入框根据完整文本高度自然向下展开。
方案
1. 卖点文本使用 500ms 防抖自动保存
修改 app/gui/tabs/product_suite.py:
prompt_edit.textChanged后继续立即更新当前SuiteTaskState.prompt,同时启动约500ms的单次防抖保存。- 连续输入只在最后一次变更稳定后写入 SQLite,避免每个字符都触发数据库更新。
- 防抖任务必须绑定触发变更的
state.key或等价稳定标识;定时器触发时不得直接读取届时的_displayed_state,避免用户快速切换商品任务后把文本写入错误项目。 - 仅当该状态已有
project_id时调用既有image_studio.update_project_prompt()或等价统一持久化入口。 - 尚未创建项目时只保存在当前任务内存,不因输入一个字符自动创建临时项目,避免产生大量空草稿;后续添加图片、绑定商品或开始生成并创建项目时,必须把当前文本一并写入。
- 程序化加载项目文本期间继续受
_loading或信号阻断保护,不得把回填动作识别成用户修改。 - 保存成功保持安静,不连续弹窗或刷状态栏;保存失败通过现有中文 danger 状态提示,并保留内存文本供用户继续操作。
- 可记录每个任务最近一次成功保存的文本,内容未变化时不重复写库。
2. 离开关键路径前同步补保存
防抖保存之外,下列操作前同步刷新控件状态并尝试保存已有项目,作为关闭窗口和快速切换时的兜底:
- 切换套图任务;
- 关闭套图任务;
- 关闭程序;
- 开始生成;
- AI 帮写结果写回后;
- 创建或绑定项目完成后。
若有尚未触发的防抖计时,先停止该计时,再保存对应任务,避免之后重复写入或保存错对象。历史生成 job 的 prompt 快照语义不变。
3. 输入框关闭内部滚动并自然增高
- 关闭「商品卖点与要求」输入框的横向和纵向滚动条。
- 保留约
96px的空内容最低高度,删除当前112px最大高度限制。 - 根据文本换行后的文档实际高度动态调整控件高度,保证全部内容可见;不能只隐藏滚动条而保留固定高度。
- 文本增加时向下撑开,删除文本时允许缩回最低高度。
- 输入框宽度、窗口尺寸、字体或 Windows DPI 变化导致换行变化时重新计算高度。
- 动态高度计算应包含 frame、contents margin 和少量安全余量,避免最后一行被裁切;高度未变化时不要反复设置几何尺寸。
- 页面过长时继续由已有外层
suiteConfigScroll承担滚动,不增加新的嵌套滚动区域。
实现可在 app/gui/tabs/product_suite.py 内增加仅供本页使用的自适应 QPlainTextEdit 子类,或放入现有 GUI widgets 模块复用;不为了单一控件引入复杂抽象。
4. 文档同步
- 更新
docs/routes.md中⑥「商品套图」说明:商品卖点会自动保存,输入框随内容自然增高并由外层配置区统一滚动。 - 如果持久化调用边界有调整,在本任务执行记录中写明,不修改 SQLite schema。
验收要点
- 已打开正式项目或临时草稿时,修改卖点内容并停止输入约
500ms后,SQLitedraft_prompt自动更新。 - 连续快速输入只保存最终稳定内容,不按每个字符重复写库。
- 修改后立即切换到另一套图任务,原任务内容保存到原项目,不会串写到新任务。
- 修改后立即关闭任务或关闭程序,再次打开项目仍能看到修改后的内容。
- 尚未创建项目时输入内容不会自动新增临时项目;后续添加图片或开始生成创建项目后,当前内容正确保存。
- AI 帮写结果写回输入框后同样自动保存,不需要额外点击按钮。
- 空内容时输入框高度不低于约
96px;输入多行内容后完整向下展开,不显示内部横向或纵向滚动条。 - 删除多行内容后输入框能缩回;窗口变窄导致换行增加时高度重新计算,最后一行不被裁切。
- 长内容由
suiteConfigScroll统一滚动,下方套图结构配置仍可访问,页面不存在嵌套滚动。 - 自动保存失败时显示中文错误提示,内存中的编辑内容不被清空。
- 不影响 T-637 提示词设置弹窗、模板渲染、AI 帮写、生成任务 prompt 快照和历史重试。
测试
tests/test_product_suite_gui.py覆盖:- 已有项目防抖自动保存及最终文本;
- 快速切换任务不会串写;
- 关闭前同步保存;
- 无项目输入不自动创建草稿,项目建立后保存;
- AI 帮写写回后的保存路径;
- 输入框内部滚动条关闭;
- 空文本、多行文本、删除文本和宽度变化时的动态高度。
- 运行:
py -3.10 -m unittest tests.test_product_suite_gui
py -3.10 -m unittest discover -s tests
py -3.10 -m ruff check app tests main.py
py -3.10 -m compileall app main.py
git diff --check
边界(不改什么)
- 不修改 SQLite schema、项目表字段或历史数据迁移。
- 不在用户刚输入文本时自动创建临时项目。
- 不增加显式「保存卖点」按钮,不为每次成功保存弹窗。
- 不修改 T-637 的全局套图提示词模板文件、占位符、校验器或预览弹窗。
- 不修改 cmhub 提交、轮询、下载、计费、并发或超时。
- 不修改 CDP、蝦皮主图拉取、①导入采集、②AI生成、③更新蝦皮、④账号管理或⑤设置。