feat(collect): choose product status scope
This commit is contained in:
+60
-3
@@ -8,6 +8,7 @@ from ...collect_skip import (
|
||||
format_skip_reason_summary,
|
||||
normalize_skip_reason_counts,
|
||||
)
|
||||
from ... import product_status
|
||||
from ..models import TaskTableModel
|
||||
from ..widgets import *
|
||||
from ..workers import CollectWorker as _RealCollectWorker, WriteBackWorker as _RealWriteBackWorker
|
||||
@@ -28,6 +29,7 @@ COLLECT_ACTIVITY_STEP_LABELS = {
|
||||
"prepare_task": "准备采集",
|
||||
"open_product": "打开商品页",
|
||||
"wait_ready": "等待商品页加载",
|
||||
"read_product_status": "读取商品状态",
|
||||
"read_title": "读取标题",
|
||||
"read_cover": "读取封面",
|
||||
"download_cover": "下载封面",
|
||||
@@ -718,11 +720,16 @@ class CollectTab(QWidget):
|
||||
if not tasks:
|
||||
self._set_status("没有可采集任务")
|
||||
return
|
||||
collect_scope = self._choose_collect_scope()
|
||||
if collect_scope is None:
|
||||
self._set_status("已取消采集")
|
||||
return
|
||||
worker = CollectWorker(
|
||||
tasks,
|
||||
db_path=self.db_path,
|
||||
config=self.config,
|
||||
diagnostic_log_dir=diagnostics.DEFAULT_LOG_DIR,
|
||||
collect_scope=collect_scope,
|
||||
)
|
||||
activity_signal = getattr(worker, "activity", None)
|
||||
if activity_signal is not None:
|
||||
@@ -742,6 +749,32 @@ class CollectTab(QWidget):
|
||||
self._start_collect_activity()
|
||||
thread.start()
|
||||
|
||||
def _choose_collect_scope(self):
|
||||
box = QMessageBox(self)
|
||||
box.setIcon(QMessageBox.Question)
|
||||
box.setWindowTitle("选择采集范围")
|
||||
box.setText("请选择本轮要采集的商品范围。")
|
||||
box.setInformativeText(
|
||||
"程序会逐个打开商品详情页检测状态并保存结果。"
|
||||
"采集所有状态商品包含未上架、审核中和状态未知商品,"
|
||||
"可能增加采集时间,但本步骤不消耗 AI 点数。"
|
||||
)
|
||||
normal_button = box.addButton("只采集状态正常的商品", QMessageBox.AcceptRole)
|
||||
normal_button.setObjectName("collectNormalOnlyButton")
|
||||
all_button = box.addButton("采集所有状态的商品", QMessageBox.DestructiveRole)
|
||||
all_button.setObjectName("collectAllStatusesButton")
|
||||
all_button.setStyleSheet("color: #cf222e; font-weight: 600;")
|
||||
cancel_button = box.addButton("取消", QMessageBox.RejectRole)
|
||||
cancel_button.setObjectName("collectScopeCancelButton")
|
||||
box.setDefaultButton(normal_button)
|
||||
box.setEscapeButton(cancel_button)
|
||||
box.exec()
|
||||
if box.clickedButton() is normal_button:
|
||||
return product_status.COLLECT_SCOPE_NORMAL_ONLY
|
||||
if box.clickedButton() is all_button:
|
||||
return product_status.COLLECT_SCOPE_ALL
|
||||
return None
|
||||
|
||||
def stop_collect(self, checked=False):
|
||||
if self.collect_worker is not None:
|
||||
self.collect_worker.cancel()
|
||||
@@ -870,6 +903,17 @@ class CollectTab(QWidget):
|
||||
skipped=payload.get("skipped", 0),
|
||||
failed=payload.get("failed", 0),
|
||||
)
|
||||
status_counts = payload.get("product_status_counts") or {}
|
||||
status_skipped = int(payload.get("status_scope_skipped", 0) or 0)
|
||||
if status_counts:
|
||||
message += ";状态正常{normal},未上架{unlisted},审核中{reviewing},状态未知{unknown}".format(
|
||||
normal=status_counts.get("normal", 0),
|
||||
unlisted=status_counts.get("unlisted", 0),
|
||||
reviewing=status_counts.get("reviewing", 0),
|
||||
unknown=status_counts.get("unknown", 0),
|
||||
)
|
||||
if status_skipped:
|
||||
message += f";按范围略过{status_skipped}"
|
||||
self._show_collect_account_summary(payload, message)
|
||||
if payload.get("collected", 0) > 0:
|
||||
batch_id = self._active_batch_id()
|
||||
@@ -917,14 +961,25 @@ class CollectTab(QWidget):
|
||||
reused = payload.get("reused_accounts") or []
|
||||
login_required = payload.get("login_required_accounts") or []
|
||||
skipped = max(0, int(payload.get("skipped", 0) or 0))
|
||||
status_scope_skipped = int(payload.get("status_scope_skipped", 0) or 0)
|
||||
account_skipped = max(0, skipped - status_scope_skipped)
|
||||
skip_counts = normalize_skip_reason_counts(
|
||||
payload.get("skip_reason_counts"),
|
||||
skipped_total=skipped,
|
||||
skipped_total=account_skipped,
|
||||
)
|
||||
if not launched and not reused and not login_required and skipped == 0:
|
||||
if (
|
||||
not launched
|
||||
and not reused
|
||||
and not login_required
|
||||
and account_skipped == 0
|
||||
and status_scope_skipped == 0
|
||||
):
|
||||
return
|
||||
lines = [message]
|
||||
skip_summary = format_skip_reason_summary(skip_counts, skipped_total=skipped)
|
||||
skip_summary = format_skip_reason_summary(
|
||||
skip_counts,
|
||||
skipped_total=account_skipped,
|
||||
)
|
||||
if skip_summary:
|
||||
lines.append(skip_summary)
|
||||
if skip_counts[ALIAS_UNMATCHED] > 0:
|
||||
@@ -941,6 +996,8 @@ class CollectTab(QWidget):
|
||||
)
|
||||
if skip_counts[LOGIN_REQUIRED] > 0:
|
||||
lines.append("请到账号管理完成对应账号登录后,再重新采集略过任务。")
|
||||
if status_scope_skipped:
|
||||
lines.append(f"本轮按范围略过{status_scope_skipped}个非正常状态商品,未下载标题和封面。")
|
||||
if launched or reused or login_required:
|
||||
lines.append("采集结束后不会自动关闭账号 Chrome,请按需自行关闭。")
|
||||
text = "\n".join(lines)
|
||||
|
||||
Reference in New Issue
Block a user