fix: update patrol delete progress handling
This commit is contained in:
@@ -1792,6 +1792,10 @@ class PatrolDeleteTask:
|
||||
f"国家 {country_name} 处理结束,success={country_result['success']},"
|
||||
f"deleted={country_result['deletedCount']},reopenRequired={requires_browser_reset}"
|
||||
)
|
||||
self._post_progress_result_safely(
|
||||
task_id=task_id,
|
||||
shop_name=shop_name,
|
||||
)
|
||||
|
||||
if driver is not None:
|
||||
self.log(f"店铺 {shop_name} 国家处理完成,正在关闭店铺")
|
||||
@@ -1822,6 +1826,22 @@ class PatrolDeleteTask:
|
||||
del runing_shop[shop_name]
|
||||
self.log(f"店铺 {shop_name} 已从执行列表中移除")
|
||||
|
||||
def _post_progress_result_safely(
|
||||
self,
|
||||
task_id: int,
|
||||
shop_name: str,
|
||||
) -> None:
|
||||
"""Submit a heartbeat-only payload so Java does not append duplicate result rows."""
|
||||
try:
|
||||
self.post_result(
|
||||
task_id=task_id,
|
||||
shop_name=shop_name,
|
||||
shop_done=False,
|
||||
heartbeat_only=True,
|
||||
)
|
||||
except Exception as exc:
|
||||
self.log(f"店铺 {shop_name} 中间结果回传失败,继续执行: {str(exc)}", "WARNING")
|
||||
|
||||
def open_shop(self, max_retries: int, company_name: str, shop_name: str, iskill: bool = False) -> Optional[InventoryManage]:
|
||||
error_info = ""
|
||||
driver: Optional[InventoryManage] = None
|
||||
@@ -1996,6 +2016,8 @@ class PatrolDeleteTask:
|
||||
"type": "completeDraft",
|
||||
"status": PatrolDeleteTask._string_result_field(item.get("tag")),
|
||||
"quantity": quantity,
|
||||
"deleteQuantity": "",
|
||||
"processStatus": "",
|
||||
}
|
||||
)
|
||||
self.log(f"trace_id={trace_id} 国家 {country_name} 补全草稿读取完成: rows={rows}")
|
||||
@@ -2032,6 +2054,7 @@ class PatrolDeleteTask:
|
||||
"status": status,
|
||||
"quantity": InventoryManage._normalize_quantity_text(item.get("quantity")),
|
||||
"deleteQuantity": str(deleted_count),
|
||||
"processStatus": "已完成" if deleted_count > 0 else "",
|
||||
}
|
||||
)
|
||||
section = {"country": country_name, "rows": rows} if rows else None
|
||||
@@ -2116,6 +2139,7 @@ class PatrolDeleteTask:
|
||||
cart_ratios: Optional[List[Dict[str, Any]]] = None,
|
||||
error: str = "",
|
||||
shop_done: bool = False,
|
||||
heartbeat_only: bool = False,
|
||||
):
|
||||
"""回传巡店删除结果到 Java API。"""
|
||||
from config import DELETE_BRAND_API_BASE
|
||||
@@ -2130,6 +2154,8 @@ class PatrolDeleteTask:
|
||||
}
|
||||
if error:
|
||||
shop_payload["error"] = error
|
||||
elif heartbeat_only:
|
||||
shop_payload["heartbeatOnly"] = True
|
||||
else:
|
||||
shop_payload["countrySections"] = self._normalize_country_sections_for_result(country_sections)
|
||||
shop_payload["cartRatios"] = self._normalize_cart_ratios_for_result(cart_ratios)
|
||||
@@ -2217,9 +2243,12 @@ class PatrolDeleteTask:
|
||||
rows = []
|
||||
for row in section.get("rows") or []:
|
||||
if cls._is_complete_draft_result_row(row):
|
||||
delete_quantity = cls._string_result_field(row.get("deleteQuantity"))
|
||||
normalized_row = {
|
||||
"status": cls._complete_draft_result_status(row),
|
||||
"quantity": cls._string_result_field(row.get("quantity")),
|
||||
"deleteQuantity": cls._string_result_field(row.get("deleteQuantity")),
|
||||
"deleteQuantity": delete_quantity,
|
||||
"processStatus": cls._complete_draft_process_status(row, delete_quantity),
|
||||
}
|
||||
else:
|
||||
normalized_row = {
|
||||
@@ -2255,6 +2284,19 @@ class PatrolDeleteTask:
|
||||
row_type = str(row.get("type") or row.get("kind") or row.get("_kind") or "").strip()
|
||||
return status in {"补全草稿", "商品信息草稿"} or tag == "补全草稿" or row_type == "completeDraft"
|
||||
|
||||
@staticmethod
|
||||
def _complete_draft_result_status(row: Dict[str, Any]) -> str:
|
||||
status = PatrolDeleteTask._string_result_field(row.get("status") or row.get("tag")).strip()
|
||||
return status or "商品信息草稿"
|
||||
|
||||
@staticmethod
|
||||
def _complete_draft_process_status(row: Dict[str, Any], delete_quantity: str) -> str:
|
||||
process_status = PatrolDeleteTask._string_result_field(row.get("processStatus")).strip()
|
||||
if process_status:
|
||||
return process_status
|
||||
match = re.search(r"\d+", str(delete_quantity or ""))
|
||||
return "已完成" if match and int(match.group(0)) > 0 else ""
|
||||
|
||||
@classmethod
|
||||
def _replace_complete_draft_rows(
|
||||
cls,
|
||||
|
||||
@@ -27,9 +27,9 @@ def _resolve_asset_filename(filename):
|
||||
"""Resolve hashed Vite assets without maintaining hardcoded alias tables."""
|
||||
safe_name = os.path.basename(filename)
|
||||
asset_dirs = [
|
||||
ASSETS_DIR,
|
||||
os.path.abspath(os.path.join(BASE_DIR, 'new_web_source', 'assets')),
|
||||
os.path.abspath(os.path.join(BASE_DIR, '..', 'new_web_source', 'assets')),
|
||||
ASSETS_DIR,
|
||||
]
|
||||
for asset_dir in asset_dirs:
|
||||
exact_path = os.path.join(asset_dir, safe_name)
|
||||
@@ -153,9 +153,9 @@ def serve_assets(filename):
|
||||
"""提供 static 目录及子目录下的静态文件访问。"""
|
||||
filename = _resolve_asset_filename(filename)
|
||||
candidate_dirs = [
|
||||
os.path.abspath(ASSETS_DIR),
|
||||
os.path.abspath(os.path.join(BASE_DIR, 'new_web_source', 'assets')),
|
||||
os.path.abspath(os.path.join(BASE_DIR, '..', 'new_web_source', 'assets')),
|
||||
os.path.abspath(ASSETS_DIR),
|
||||
]
|
||||
for static_abs in candidate_dirs:
|
||||
filepath = os.path.normpath(os.path.join(static_abs, filename))
|
||||
|
||||
@@ -7,13 +7,13 @@ import json
|
||||
import sys
|
||||
import shutil
|
||||
import os
|
||||
from amazon.main import TaskMonitor
|
||||
os.makedirs(cache_path,exist_ok=True)
|
||||
if not debug:
|
||||
today = datetime.datetime.now().strftime("%Y_%m_%d")
|
||||
sys.stdout = open(os.path.join(cache_path,f'{today}.log'), 'a',buffering=1,encoding='utf-8')
|
||||
sys.stderr = sys.stdout
|
||||
|
||||
from amazon.main import TaskMonitor
|
||||
import webview
|
||||
import threading
|
||||
import time
|
||||
|
||||
@@ -105,7 +105,7 @@ def test_patrol_delete_task_post_result_retries_business_failure(monkeypatch):
|
||||
assert len(calls) == 3
|
||||
|
||||
|
||||
def test_normalize_country_sections_omits_status_fields_for_complete_draft_rows():
|
||||
def test_normalize_country_sections_keeps_status_fields_for_complete_draft_rows():
|
||||
rows = PatrolDeleteTask._normalize_country_sections_for_result(
|
||||
[
|
||||
{
|
||||
@@ -132,7 +132,7 @@ def test_normalize_country_sections_omits_status_fields_for_complete_draft_rows(
|
||||
{
|
||||
"country": "意大利",
|
||||
"rows": [
|
||||
{"quantity": "12", "deleteQuantity": "3"},
|
||||
{"status": "商品信息草稿", "quantity": "12", "deleteQuantity": "3", "processStatus": "已完成"},
|
||||
{"status": "缺少的信息", "quantity": "1", "deleteQuantity": "1", "processStatus": "已完成"},
|
||||
],
|
||||
}
|
||||
@@ -150,8 +150,8 @@ def test_replace_complete_draft_rows_uses_quick_view_rows():
|
||||
complete_draft_section = {
|
||||
"country": "西班牙",
|
||||
"rows": [
|
||||
{"type": "completeDraft", "quantity": "1", "deleteQuantity": "1"},
|
||||
{"type": "completeDraft", "quantity": "0", "deleteQuantity": "0"},
|
||||
{"type": "completeDraft", "quantity": "1", "deleteQuantity": "1", "processStatus": "已完成"},
|
||||
{"type": "completeDraft", "quantity": "0", "deleteQuantity": "0", "processStatus": ""},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -161,8 +161,8 @@ def test_replace_complete_draft_rows_uses_quick_view_rows():
|
||||
"country": "西班牙",
|
||||
"rows": [
|
||||
{"status": "全部", "quantity": "6230", "deleteQuantity": "0", "processStatus": "无可删商品"},
|
||||
{"type": "completeDraft", "quantity": "1", "deleteQuantity": "1"},
|
||||
{"type": "completeDraft", "quantity": "0", "deleteQuantity": "0"},
|
||||
{"type": "completeDraft", "quantity": "1", "deleteQuantity": "1", "processStatus": "已完成"},
|
||||
{"type": "completeDraft", "quantity": "0", "deleteQuantity": "0", "processStatus": ""},
|
||||
],
|
||||
}
|
||||
assert PatrolDeleteTask._normalize_country_sections_for_result([merged]) == [
|
||||
@@ -170,8 +170,8 @@ def test_replace_complete_draft_rows_uses_quick_view_rows():
|
||||
"country": "西班牙",
|
||||
"rows": [
|
||||
{"status": "全部", "quantity": "6230", "deleteQuantity": "0", "processStatus": "无可删商品"},
|
||||
{"quantity": "1", "deleteQuantity": "1"},
|
||||
{"quantity": "0", "deleteQuantity": "0"},
|
||||
{"status": "商品信息草稿", "quantity": "1", "deleteQuantity": "1", "processStatus": "已完成"},
|
||||
{"status": "商品信息草稿", "quantity": "0", "deleteQuantity": "0", "processStatus": ""},
|
||||
],
|
||||
}
|
||||
]
|
||||
@@ -261,6 +261,18 @@ def test_patrol_delete_task_process_task_aggregates_country_results(monkeypatch)
|
||||
assert runing_task[1]["deleted_listings_count"] == 2
|
||||
assert "郭亚芳" not in runing_shop
|
||||
assert calls == [
|
||||
{
|
||||
"task_id": 1,
|
||||
"shop_name": "郭亚芳",
|
||||
"shop_done": False,
|
||||
"heartbeat_only": True,
|
||||
},
|
||||
{
|
||||
"task_id": 1,
|
||||
"shop_name": "郭亚芳",
|
||||
"shop_done": False,
|
||||
"heartbeat_only": True,
|
||||
},
|
||||
{
|
||||
"task_id": 1,
|
||||
"shop_name": "郭亚芳",
|
||||
@@ -377,16 +389,28 @@ def test_delete_complete_draft_country_section_reports_delete_quantity(monkeypat
|
||||
assert result["countrySection"] == {
|
||||
"country": "德国",
|
||||
"rows": [
|
||||
{"type": "completeDraft", "status": "未提交的草稿", "quantity": "0", "deleteQuantity": "3"},
|
||||
{"type": "completeDraft", "status": "已提交:提供缺少的信息", "quantity": "2", "deleteQuantity": "0"},
|
||||
{
|
||||
"type": "completeDraft",
|
||||
"status": "未提交的草稿",
|
||||
"quantity": "0",
|
||||
"deleteQuantity": "3",
|
||||
"processStatus": "已完成",
|
||||
},
|
||||
{
|
||||
"type": "completeDraft",
|
||||
"status": "已提交:提供缺少的信息",
|
||||
"quantity": "2",
|
||||
"deleteQuantity": "0",
|
||||
"processStatus": "",
|
||||
},
|
||||
],
|
||||
}
|
||||
assert PatrolDeleteTask._normalize_country_sections_for_result([result["countrySection"]]) == [
|
||||
{
|
||||
"country": "德国",
|
||||
"rows": [
|
||||
{"quantity": "0", "deleteQuantity": "3"},
|
||||
{"quantity": "2", "deleteQuantity": "0"},
|
||||
{"status": "未提交的草稿", "quantity": "0", "deleteQuantity": "3", "processStatus": "已完成"},
|
||||
{"status": "已提交:提供缺少的信息", "quantity": "2", "deleteQuantity": "0", "processStatus": ""},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user