feat(gui): optimize product status filter defaults
This commit is contained in:
@@ -99,6 +99,9 @@ class ApplyTab(QWidget):
|
||||
self.product_status_filter.setObjectName("applyProductStatusFilter")
|
||||
for label, value in product_status.PRODUCT_STATUS_FILTER_ITEMS:
|
||||
self.product_status_filter.addItem(label, value)
|
||||
self.product_status_filter.setCurrentIndex(
|
||||
self.product_status_filter.findData(product_status.STATUS_NORMAL)
|
||||
)
|
||||
self.refresh_button = QPushButton("刷新")
|
||||
|
||||
filter_layout = QHBoxLayout()
|
||||
|
||||
@@ -1150,6 +1150,9 @@ class GenerateTab(QWidget):
|
||||
self.product_status_filter.setObjectName("generateProductStatusFilter")
|
||||
for label, value in product_status.PRODUCT_STATUS_FILTER_ITEMS:
|
||||
self.product_status_filter.addItem(label, value)
|
||||
self.product_status_filter.setCurrentIndex(
|
||||
self.product_status_filter.findData(product_status.STATUS_NORMAL)
|
||||
)
|
||||
self.refresh_button = QPushButton("刷新")
|
||||
self.open_image_dir_button = QPushButton("打开图片文件夹")
|
||||
self.open_image_dir_button.setObjectName("openImageDirButton")
|
||||
|
||||
@@ -543,6 +543,7 @@ T-523 后 GUI 已从旧 `app/gui.py` 拆为 `app/gui/` 包:`__init__.py` 负
|
||||
- 封面提示词模板下拉读取 `data/prompts/cover/*.txt`;支持新建、保存、另存为、重命名、删除。删除由 GUI 二次确认,删空后下拉显示内存态“默认”,不会自动建文件。
|
||||
- 「插入标题」在封面提示词光标处插入 `{新标题}`;「预览」使用当前选中任务(无选择则用第一条)调用 `prompts.render_prompt()` 并弹窗展示。
|
||||
- 筛选栏包含:批次、店铺、商品ID、状态、刷新。批次来自 `db.list_batches()`;店铺来自当前任务别名并优先显示匹配账号名;商品ID输入框按包含匹配 `item_id`,清空表示全部;状态支持全部/待生成/已生成/失败/略过/已更新。
|
||||
- ②商品状态筛选初始为「架上商品」;③商品状态筛选初始也为「架上商品」。①保持初始「全部商品状态」,避免待检测的新导入记录被隐藏。用户主动选择任一商品状态后,刷新或调整批次、店铺、商品ID、处理/生成/更新状态时继续保留该筛选值。商品状态筛选只缩小当前列表,不能绕过①采集范围确认、②生成范围确认或③状态/内容预检。
|
||||
- 任务列表使用 `QTableView + GenerateTaskTableModel`,列为:店铺、商品ID、旧标题、新标题、状态。`stage=collected` 显示“待生成”,`stage=generated` 显示“已生成”,`status=failed/skipped/running` 优先显示对应状态;已生成、未提交线上、非运行中的「新标题」列可双击编辑,调用 `db.update_generated_title()` 写回本地并清空 `last_error`。
|
||||
- 双击「新标题」列进入本地编辑;双击其他列弹窗展示旧封面与新封面路径对应图片;图片不存在时显示空态/路径提示,只做查看,不做审核。
|
||||
- 底部「开始生成」只处理当前筛选结果里可补齐的任务;批次/店铺/商品ID/状态筛选共同决定当前筛选结果;②「生成内容」下拉支持只生成标题、只生成封面、生成标题和封面。只生成封面时不调用生文,任务有新标题则使用新标题,否则使用已采集旧标题作为封面prompt回退;新旧标题都为空才不纳入。候选存在时由 `product_status.build_generation_plan()` 统计正常/未上架/审核中/未知并冻结指纹,弹出与①共用的 `ProductStatusScopeDialog`:默认按钮为“生成架上商品”(`normal_only`,仅将检测结果为正常的商品交给 AI),扩展按钮为“生成全部商品”(`all`,还会处理未上架、审核中和状态未知商品,可能额外消耗点数),后者使用警示橙色的扩大范围样式;历史未采集状态按未知处理,默认不入队。取消或指纹变化时不创建 Worker;无异常候选时 `all` 禁用。`GenerateWorker` 接收最终精确任务列表,并在 `normal_only` 下再次排除非正常任务后才调用 `ai.generate_batch()`。点击「开始生成」时先清空 `GenerateTab` 可见日志文本并写入本轮开始摘要,后续只追加本轮日志;运行日志 options/summary 记录范围、状态计数、范围排除数和计划指纹。cmhub 模式开始摘要显示“图片并发 X,cmhub实际生图并发 Y,下载并发 Y”,其中 `Y=min(X,5)`。
|
||||
|
||||
+3
-3
@@ -73,7 +73,7 @@
|
||||
- 导入:openpyxl 解析**输入列**(账号名/别名/商品id)入 SQLite。
|
||||
- **导入汇总栏**(导入后即时刷新,跑采集前的校验关口):显示 文件数、解析行数(原始数据量)、有效/无效行、匹配账号行数(按账号细分)、未匹配行数。未匹配/无效数字标红可点,点击在列表筛出便于定位纠错。
|
||||
- 采集:点击后先从专用范围选择框选择范围,默认「采集架上商品」(即检测结果为正常),「采集全部商品」为警示橙色描边而非删除红色,包含未上架、审核中和状态未知商品;三个选项纵向全宽显示,常见 Windows 缩放下不截断。随后为本轮匹配账号确保 Chrome 就绪(已开复用、未开启动),再检测登录;明确未登录账号的任务整组略过并汇总提示。`NO_SESSION_COOKIE`、登录检测超时或 CDP 短暂异常会重试,连续不确定时不批量略过,继续打开商品页由真实页面结果决定成功/失败。登录账号用对应 Chrome 只读打开商品页,先检测并保存商品状态;默认范围下只有正常商品才读旧标题、下载旧封面到 `data/images/<batch_id>/<slug>/<task_id>_<item_id>_old.jpg`,未上架、审核中和状态未知商品按范围略过且不覆盖已有内容。选择全部范围时四类商品均继续采集。采集不主动把商品页切到前台;程序自动新建商品页 tab 时尽量后台创建,采集结束后自动关闭;若复用用户原本打开的 tab,则不关闭。采集结束不关闭账号 Chrome,用户可自行关闭。
|
||||
- ①任务表显示账号、别名、商品 ID、阶段和商品状态。商品状态筛选位于「处理状态」筛选左侧,选项为全部商品状态、架上商品、未上架、审核中、状态未知、待检测;它与批次、店铺、商品 ID 和处理状态叠加。空状态在①显示为「待检测」,显式 `unknown` 显示为「状态未知」;历史默认的架上商品可在 tooltip 查看“未实时检测”备注。商品状态只影响列表可见范围,不改变采集、生成或更新的安全规则。
|
||||
- ①任务表显示账号、别名、商品 ID、阶段和商品状态。商品状态筛选位于「处理状态」筛选左侧,选项为全部商品状态、架上商品、未上架、审核中、状态未知、待检测;新打开①默认「全部商品状态」,确保新导入的待检测记录可见。它与批次、店铺、商品 ID 和处理状态叠加。空状态在①显示为「待检测」,显式 `unknown` 显示为「状态未知」;历史默认的架上商品可在 tooltip 查看“未实时检测”备注。商品状态只影响列表可见范围,不改变采集、生成或更新的安全规则。
|
||||
- 商品状态功能于 `2026-07-18T16:34:37` 上线。更早创建的活动历史批次中,空状态在启动数据库时自动按「架上商品」写为 `normal`,备注「历史批次默认按架上商品处理(未实时检测)」且不写检测时间;同一范围内仅把由已知促销编辑提示误写的 `unknown` 修正为 `normal`,保留原检测时间并写明历史修正。其他真实保存的未上架、审核中、状态未知,以及上线时点及之后的空状态均不覆盖;不打开 Chrome、不访问详情页。①不提供「重新检测商品状态」入口。
|
||||
- 若商品 ID 已失效、无权限或店铺不匹配,Shopee 可能只弹出短暂错误 toast;采集失败时界面日志应显示捕获到的 toast 文案,并把 toast HTML/URL 写入本地诊断日志,避免用户手动抢复制。只有明确捕获商品失效/商品不存在/无权限类 toast 时,①列表“阶段”列显示“商品失效”;其他商品页打开失败仍显示“失败”。如果失败发生在 `open_product()` 内部,本轮自动新建的商品 tab 必须关闭,复用用户已有 tab 不关闭。
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
- **标题提示词**:模板下拉(读 `data/prompts/title/*.txt`)+「新建 / 保存模板 / 模板操作(另存为、重命名、删除)」+ 多行输入 + 下方工具条「插入旧标题」(插 `{旧标题}`)/「保存标题提示词」(写 `data/title_prompt.txt`)。启动时自动加载 `title_prompt.txt` 回显,不自动用模板覆盖工作文本;用户选择模板时才把模板内容载入输入框。若标题提示词包含 `{旧标题}`,生成前替换为当前任务旧标题且不重复追加旧标题块;不包含时保持旧行为自动追加旧标题。
|
||||
- **封面提示词**:模板控件压缩到一行(读 `data/prompts/cover/*.txt`,新建/保存模板/另存为/重命名/删除)+ 多行输入 + 下方工具条「插入标题」(插 `{新标题}`)/「预览」(变量替换后查看)。
|
||||
- 变量:标题提示词本阶段只支持 `{旧标题}`;封面提示词支持 `{旧标题}`/`{新标题}`/`{商品id}`/`{店铺}`,生成前按任务替换。
|
||||
- 右上:按导入批次 / 店铺 / 商品ID / 商品状态 / 生成状态筛选任务;商品状态位于生成状态左侧,选项与①一致,按原始快照区分架上商品、未上架、审核中、状态未知和待检测;生成状态继续表示待生成、已生成、失败、略过、已更新。商品状态筛选只缩小当前列表,商品ID输入框按包含匹配 `item_id`,清空表示全部。
|
||||
- 右上:按导入批次 / 店铺 / 商品ID / 商品状态 / 生成状态筛选任务;商品状态位于生成状态左侧,选项与①一致,按原始快照区分架上商品、未上架、审核中、状态未知和待检测;新打开②默认「架上商品」。生成状态继续表示待生成、已生成、失败、略过、已更新。商品状态筛选只缩小当前列表,商品ID输入框按包含匹配 `item_id`,清空表示全部;用户主动改选商品状态后,刷新或切换其他筛选条件保留该选择。
|
||||
- 筛选行提供「打开图片文件夹」按钮,用于只读打开本地图片目录:选中某行时打开该商品所在账号图片文件夹(优先打开已有新/旧封面文件的真实父目录,缺失时回退到规范账号目录);未选行且选择具体批次时打开该批次图片文件夹;未选行且为全部批次时打开图片根目录。目录不存在只中文提示,不自动创建目录,不修改任务状态。
|
||||
- 右下:任务列表(店铺名、商品id、旧标题、新标题、标题状态、图片状态)+ AI生成运行日志;标题/图片状态由 `new_title`、`new_cover_path`、`stage/status` 和失败步骤推导,帮助用户区分“标题未生成 / 图片未生成 / 标题成功但图片失败”。商品ID列按原等分宽度约 50% 显示;标题状态和图片状态列在 T-554 基础上再缩到约 33%,缩出的宽度平均给旧标题和新标题。已生成、未提交线上、非运行中的任务可双击「新标题」列本地微调,写回 `tasks.new_title`,清空 `last_error` 并回到可更新;双击其他列弹窗展示旧封面、新封面和历史候选图。
|
||||
- 底部**单个「开始生成」+「停止」**,并增加「生成内容」下拉:默认只生成标题,可选只生成封面或生成标题和封面;只生成封面不调用生文,有新标题时优先使用,没有时用已采集旧标题作为封面prompt参考,新旧标题都为空才不纳入。开始前先从真实候选重新分组商品状态,弹出与①共用的纵向范围确认框:默认「生成架上商品」(即仅检测结果为正常的商品),「生成全部商品」为警示橙色描边,还会处理未上架、审核中、状态未知商品,可能额外消耗点数;未上架、审核中、状态未知默认不入队、不请求 AI、不消耗点数,用户明确选择全部范围才可入队。商品状态功能上线前的历史空状态会启动时迁移为默认正常;上线后仍为空的记录按未知处理。范围确认不跨轮记忆,取消或候选在确认期间变化均不启动生成;无异常候选时该警示选项禁用。标题/图片两条进度条右侧分别显示同宽用时标签(`生标题用时 N 秒` / `生图用时 N 秒`),运行中每秒递增,完成/停止后冻结;原图片进度条右侧的失败数和 cmhub 余额不再占用该位置。cmhub 模式会把用户设置的图片并发内部限制到最大 5,并用同样最大 5 的独立下载线程池拉取 `image_url`,不新增用户可见下载并发配置;运行日志显示用户设置并发和实际并发。下拉状态持久化到 `config.json` 的 `ai.generate_mode`,并继续写回旧兼容 `ai.generate_cover`。
|
||||
@@ -130,7 +130,7 @@
|
||||
└───────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- 顶部**按批次 / 店铺 / 商品ID / 商品状态 / 更新状态筛选**(与①②一致);商品状态位于更新状态左侧,选项与①一致,按原始快照区分架上商品、未上架、审核中、状态未知和待检测;更新状态继续表示已生成、失败、已更新、略过和全部状态。商品ID输入框按包含匹配 `item_id`,清空表示全部;「开始更新」作用于**当前筛选结果**,是一道范围控制。
|
||||
- 顶部**按批次 / 店铺 / 商品ID / 商品状态 / 更新状态筛选**(与①②一致);商品状态位于更新状态左侧,选项与①一致,按原始快照区分架上商品、未上架、审核中、状态未知和待检测;新打开③默认「架上商品」,用户主动改选后刷新或切换其他筛选条件保留该选择。更新状态继续表示已生成、失败、已更新、略过和全部状态。商品ID输入框按包含匹配 `item_id`,清空表示全部;「开始更新」作用于**当前筛选结果**,是一道范围控制。
|
||||
- 店铺筛选:建议**逐店铺更新**(每店铺需先启动其 Chrome 并登录)。
|
||||
- 状态筛选:`已生成` 只跑未更新的;`失败` 用于**失败重试**;`已更新成功/略过` 仅查看。
|
||||
- 「更新内容」下拉支持只更新标题、只更新封面、更新标题和封面;点击「检查本轮更新」或「开始更新」前统一用状态优先的预检计划:仅 `product_status=normal` 可进入标题/封面完整性检查,`unlisted`、`reviewing`、`unknown` 及上线后历史 NULL 一律排除,不传给 `ApplyWorker`。商品状态功能上线前的活动历史批次空状态已在数据库初始化时默认迁移为 `normal`,可进入既有内容完整性检查;该默认值会标注为未实时检测,但不要求用户额外打开商品页。状态异常和缺失内容记录都在确认框、状态栏和本轮日志列出分类、数量与示例商品ID;全部被排除时按真实原因中文弹窗阻断,不打开 Chrome、不改任务状态。用户确认后重新计算计划指纹,任务状态、更新时间、新标题或新封面变化则中止并要求重新开始。
|
||||
|
||||
+10
-8
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: T-676
|
||||
title: 三个工作流商品状态筛选默认值优化
|
||||
status: TODO
|
||||
status: DONE
|
||||
phase: 7
|
||||
deps: [T-669, T-671, T-672]
|
||||
created: 2026-07-20
|
||||
@@ -25,12 +25,12 @@ created: 2026-07-20
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] 新打开①时商品状态筛选为「全部商品状态」,待检测的新导入行可见;采集范围确认默认策略不变。
|
||||
- [ ] 新打开②和③时商品状态筛选为「架上商品」,列表仅展示原始状态为 `normal` 的记录。
|
||||
- [ ] ②③主动改选全部、未上架、审核中、状态未知或待检测后,刷新或切换其他筛选条件不会无故重置为架上商品。
|
||||
- [ ] ②默认架上商品时开始生成、③默认架上商品时检查/开始更新,只以当前筛选结果构建候选;异常商品即使用户手动筛出,仍不能绕过既有范围确认、状态预检和内容预检。
|
||||
- [ ] 不修改 SQLite schema、历史商品状态迁移、Chrome/CDP、AI 调用、Excel 回写或线上更新逻辑。
|
||||
- [ ] `tests/test_gui.py` 覆盖三个页面的新建默认值、待检测可见性、用户选择保留及②③安全边界不回归。
|
||||
- [x] 新打开①时商品状态筛选为「全部商品状态」,待检测的新导入行可见;采集范围确认默认策略不变。
|
||||
- [x] 新打开②和③时商品状态筛选为「架上商品」,列表仅展示原始状态为 `normal` 的记录。
|
||||
- [x] ②③主动改选全部、未上架、审核中、状态未知或待检测后,刷新或切换其他筛选条件不会无故重置为架上商品。
|
||||
- [x] ②默认架上商品时开始生成、③默认架上商品时检查/开始更新,只以当前筛选结果构建候选;异常商品即使用户手动筛出,仍不能绕过既有范围确认、状态预检和内容预检。
|
||||
- [x] 不修改 SQLite schema、历史商品状态迁移、Chrome/CDP、AI 调用、Excel 回写或线上更新逻辑。
|
||||
- [x] `tests/test_gui.py` 覆盖三个页面的新建默认值、待检测可见性、用户选择保留及②③安全边界不回归。
|
||||
|
||||
## 测试与文档
|
||||
|
||||
@@ -53,4 +53,6 @@ git diff --check
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 待实现。
|
||||
- 2026-07-20:② `GenerateTab`、③ `ApplyTab` 初始化商品状态下拉为 `normal`;①保持原有 `all` 默认值。刷新任务列表不会重置用户主动选择的商品状态。
|
||||
- 2026-07-20:补充 GUI 覆盖:①待检测行初始可见;②③初始仅显示架上商品;②③切换到异常状态后刷新仍保留选择;②③原有生成范围确认、更新状态/内容预检继续生效。依赖旧“默认全部”展示前提的历史用例显式选择“全部商品状态”。
|
||||
- 验证通过:`py -3.10 -m unittest discover -s tests -p "test_gui.py"`(209 项)、`py -3.10 -m unittest discover -s tests`(633 项)、`py -3.10 -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check`。
|
||||
|
||||
+80
-1
@@ -3579,6 +3579,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
)
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.resize(1000, 600)
|
||||
tab.show()
|
||||
QApplication.processEvents()
|
||||
@@ -3645,6 +3648,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
selection = tab.task_table.selectionModel()
|
||||
selection.select(tab.model.index(0, 0), QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
||||
selection.select(tab.model.index(1, 0), QItemSelectionModel.Select | QItemSelectionModel.Rows)
|
||||
@@ -3687,6 +3693,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.task_table.selectRow(0)
|
||||
tab.task_table.setCurrentIndex(tab.model.index(0, 0))
|
||||
|
||||
@@ -3780,6 +3789,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
)
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.task_table.selectRow(0)
|
||||
tab.task_table.setCurrentIndex(tab.model.index(0, 0))
|
||||
|
||||
@@ -4061,6 +4073,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
db.set_generated(task.id, "已有标题", None, path=cfg["db_path"])
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
|
||||
tab.status_filter.setCurrentIndex(tab.status_filter.findData("to_generate"))
|
||||
self.assertEqual(0, tab.model.rowCount())
|
||||
@@ -4137,6 +4152,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
title_templates_dir=title_templates_dir,
|
||||
)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
|
||||
self.assertEqual("标题启动回显", tab.title_prompt_edit.toPlainText())
|
||||
self.assertEqual("选择模板", tab.title_template_combo.currentText())
|
||||
@@ -4244,6 +4262,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
title_templates_dir=os.path.join(temp_dir, "prompts", "title"),
|
||||
)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.cover_prompt_edit.setPlainText("新:{新标题};旧:{旧标题}")
|
||||
tab.task_table.selectRow(0)
|
||||
|
||||
@@ -5257,6 +5278,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
statuses = []
|
||||
tab = GenerateTab(config=cfg, status_callback=statuses.append)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
index = tab.model.index(0, 3)
|
||||
|
||||
self.assertTrue(bool(tab.model.flags(index) & gui.Qt.ItemIsEditable))
|
||||
@@ -5299,6 +5323,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
statuses = []
|
||||
tab = GenerateTab(config=cfg, status_callback=statuses.append)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.task_table.selectRow(0)
|
||||
|
||||
message_box, boxes = self.make_fake_message_box("重置全部")
|
||||
@@ -5365,6 +5392,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
statuses = []
|
||||
tab = GenerateTab(config=cfg, status_callback=statuses.append)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.task_table.clearSelection()
|
||||
|
||||
message_box, boxes = self.make_fake_message_box("重置标题")
|
||||
@@ -5420,6 +5450,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
db.set_applied(tasks[0].id, True, path=cfg["db_path"])
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
selection = tab.task_table.selectionModel()
|
||||
for row in [0, 1]:
|
||||
selection.select(
|
||||
@@ -6389,6 +6422,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
)
|
||||
tab = GenerateTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
FakeGenerateWorker.instances.clear()
|
||||
fake_thread = FakeThread()
|
||||
|
||||
@@ -6593,6 +6629,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
statuses = []
|
||||
tab = GenerateTab(config=cfg, status_callback=statuses.append)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
|
||||
self.assertEqual("采集失败", tab.model.index(0, 4).data())
|
||||
tab.start_generate()
|
||||
@@ -6729,6 +6768,12 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
for index in range(tab.product_status_filter.count())
|
||||
],
|
||||
)
|
||||
self.assertEqual("normal", tab.product_status_filter.currentData())
|
||||
self.assertEqual(1, tab.model.rowCount())
|
||||
self.assertEqual("51100639510", tab.model.index(0, 1).data())
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
label_texts = [label.text() for label in tab.findChildren(QLabel)]
|
||||
self.assertIn("商品状态", label_texts)
|
||||
self.assertIn("更新状态", label_texts)
|
||||
@@ -6763,6 +6808,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(1, tab.model.rowCount())
|
||||
self.assertEqual("51100639511", tab.model.index(0, 1).data())
|
||||
tab.refresh_tasks()
|
||||
self.assertEqual("unlisted", tab.product_status_filter.currentData())
|
||||
self.assertEqual(1, tab.model.rowCount())
|
||||
with mock.patch("app.gui.QMessageBox.warning") as warning, mock.patch(
|
||||
"app.gui.run_worker"
|
||||
) as run_worker:
|
||||
@@ -6842,6 +6890,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
statuses = []
|
||||
tab = ApplyTab(config=cfg, status_callback=statuses.append)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.status_filter.setCurrentIndex(tab.status_filter.findData("applied"))
|
||||
tab.task_table.selectRow(0)
|
||||
|
||||
@@ -7254,6 +7305,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
states = []
|
||||
tab = ApplyTab(config=cfg, status_callback=states.append)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
|
||||
with mock.patch("app.gui.QMessageBox.warning") as warning, mock.patch(
|
||||
"app.gui.QMessageBox.question"
|
||||
@@ -7310,6 +7364,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
db.set_generated(tasks[2].id, None, "new.jpg", path=cfg["db_path"])
|
||||
tab = ApplyTab(config=cfg)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
thread = FakeThread()
|
||||
|
||||
with mock.patch("app.gui.QMessageBox.question", return_value=gui.QMessageBox.Yes) as question, mock.patch(
|
||||
@@ -8169,6 +8226,12 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
for index in range(tab.product_status_filter.count())
|
||||
],
|
||||
)
|
||||
self.assertEqual("normal", tab.product_status_filter.currentData())
|
||||
self.assertEqual(1, tab.model.rowCount())
|
||||
self.assertEqual("51100639510", tab.model.index(0, 1).data())
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
self.assertEqual(4, tab.model.rowCount())
|
||||
self.assertEqual("主店", tab.model.index(0, 0).data())
|
||||
self.assertEqual("51100639510", tab.model.index(0, 1).data())
|
||||
@@ -8199,6 +8262,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
tab.product_status_filter.findData("unlisted")
|
||||
)
|
||||
self.assertEqual(1, tab.model.rowCount())
|
||||
tab.refresh_tasks()
|
||||
self.assertEqual("unlisted", tab.product_status_filter.currentData())
|
||||
self.assertEqual(1, tab.model.rowCount())
|
||||
unlisted_plan = product_status.build_generation_plan(
|
||||
tab._generation_candidates("title"),
|
||||
"title",
|
||||
@@ -8527,6 +8593,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
for index in range(tab.product_status_filter.count())
|
||||
],
|
||||
)
|
||||
self.assertEqual("all", tab.product_status_filter.currentData())
|
||||
self.assertEqual(5, tab.model.rowCount())
|
||||
self.assertEqual("待检测", tab.model.index(0, 4).data())
|
||||
self.assertEqual("架上商品", tab.model.index(1, 4).data())
|
||||
@@ -9072,6 +9139,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
refresh_workflow_callback=lambda: refresh_calls.append(True),
|
||||
)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.resize(1000, 600)
|
||||
tab.show()
|
||||
QApplication.processEvents()
|
||||
@@ -9162,6 +9232,9 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
refresh_workflow_callback=lambda: refresh_calls.append(True),
|
||||
)
|
||||
self.addCleanup(tab.close)
|
||||
tab.product_status_filter.setCurrentIndex(
|
||||
tab.product_status_filter.findData("all")
|
||||
)
|
||||
tab.status_filter.setCurrentIndex(tab.status_filter.findData("all"))
|
||||
tab.resize(1000, 600)
|
||||
tab.show()
|
||||
@@ -9245,7 +9318,13 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
path=cfg["db_path"],
|
||||
)
|
||||
task = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])[0]
|
||||
db.set_collected(task.id, "旧标题", "old.jpg", path=cfg["db_path"])
|
||||
db.set_collected(
|
||||
task.id,
|
||||
"旧标题",
|
||||
"old.jpg",
|
||||
product_status_value="normal",
|
||||
path=cfg["db_path"],
|
||||
)
|
||||
db.set_generated(task.id, "新标题", "new.jpg", path=cfg["db_path"])
|
||||
statuses = []
|
||||
tab = ApplyTab(config=cfg, status_callback=statuses.append)
|
||||
|
||||
Reference in New Issue
Block a user