完善多店铺开启多窗口、外观进度条等

This commit is contained in:
super
2026-05-01 21:09:54 +08:00
parent 4419c5bacd
commit e1cca219b8
41 changed files with 964 additions and 17737 deletions

View File

@@ -234,12 +234,14 @@ class InventoryManage(AmamzonBase):
country: str,
max_delete_operations: Optional[int] = None,
trace_id: str = "",
delete_conditions: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
"""循环删除非白名单分类商品,直到当前国家没有可删项。"""
trace_id = trace_id or _new_trace_id("del")
logger.info(
f"trace_id={trace_id} 开始批量删除非白名单商品: "
f"shop={shop_name}, country={country}, max_delete_operations={max_delete_operations}"
f"shop={shop_name}, country={country}, max_delete_operations={max_delete_operations}, "
f"delete_conditions={self._format_delete_conditions(delete_conditions)}"
)
all_results: List[Dict[str, Any]] = []
delete_counts: Dict[str, int] = {}
@@ -249,7 +251,10 @@ class InventoryManage(AmamzonBase):
stop_reason = "no-candidates"
latest_status_rows = self._read_listing_status_rows_for_delete(shop_name, country, trace_id=trace_id)
latest_delete_candidates = self._build_deletable_status_rows(latest_status_rows)
latest_delete_candidates = self._build_deletable_status_rows(
latest_status_rows,
delete_conditions=delete_conditions,
)
if not latest_delete_candidates:
logger.info(f"trace_id={trace_id} 未找到可删除商品分类: shop={shop_name}, country={country}")
final_status_rows = latest_status_rows
@@ -783,7 +788,12 @@ class InventoryManage(AmamzonBase):
]
@classmethod
def _build_deletable_status_rows(cls, rows: Iterable[Dict[str, Any]]) -> List[Dict[str, Any]]:
def _build_deletable_status_rows(
cls,
rows: Iterable[Dict[str, Any]],
delete_conditions: Optional[List[Dict[str, Any]]] = None,
) -> List[Dict[str, Any]]:
condition_texts = cls._normalize_delete_condition_texts(delete_conditions)
candidates = []
for row in rows:
status = cls._normalize_option_text(row.get("status") or "")
@@ -795,6 +805,8 @@ class InventoryManage(AmamzonBase):
canonical_status = cls._canonical_listing_status(status)
if not quantity_text or quantity <= 0 or canonical_status in LISTING_STATUS_DELETE_WHITELIST:
continue
if condition_texts and not cls._matches_delete_conditions(status, condition_texts):
continue
candidates.append(
{
@@ -805,6 +817,39 @@ class InventoryManage(AmamzonBase):
)
return candidates
@classmethod
def _normalize_delete_condition_texts(
cls,
delete_conditions: Optional[List[Dict[str, Any]]],
) -> List[str]:
texts = []
for condition in delete_conditions or []:
if isinstance(condition, dict):
raw_text = condition.get("conditionText") or condition.get("condition_text") or condition.get("text")
else:
raw_text = condition
text = cls._normalize_option_text(str(raw_text or "")).lower()
if text:
texts.append(text)
return list(dict.fromkeys(texts))
@classmethod
def _matches_delete_conditions(cls, status: str, condition_texts: List[str]) -> bool:
normalized_status = cls._normalize_option_text(status).lower()
canonical_status = cls._canonical_listing_status(status).lower()
return any(
condition in normalized_status
or condition in canonical_status
or normalized_status in condition
or canonical_status in condition
for condition in condition_texts
)
@classmethod
def _format_delete_conditions(cls, delete_conditions: Optional[List[Dict[str, Any]]]) -> str:
texts = cls._normalize_delete_condition_texts(delete_conditions)
return ", ".join(texts) if texts else "default"
@staticmethod
def _format_deletable_candidates(candidates: Iterable[Dict[str, Any]]) -> str:
summary = []
@@ -1299,6 +1344,7 @@ class PatrolDeleteTask:
items = data.get("items", [])
country_sections = data.get("country_sections", [])
cart_ratios = data.get("cart_ratios", [])
delete_conditions = data.get("delete_conditions") or data.get("deleteConditions") or []
if not task_id:
self.log("任务ID为空跳过", "WARNING")
@@ -1321,10 +1367,14 @@ class PatrolDeleteTask:
"failed_count": 0,
"failed_countries": 0,
"deleted_listings_count": 0,
"delete_conditions": delete_conditions,
"stop_requested": False,
}
self.log(f"开始处理巡店删除任务 {task_id},共 {len(items)} 个店铺,{total_countries} 个国家")
self.log(
f"开始处理巡店删除任务 {task_id},共 {len(items)} 个店铺,{total_countries} 个国家,"
f"删除条件 {len(delete_conditions)}"
)
for index, shop_item in enumerate(items, 1):
if runing_task[task_id].get("stop_requested", False):
self.log(f"检测到任务 {task_id} 的暂停请求,停止处理", "WARNING")
@@ -1333,7 +1383,7 @@ class PatrolDeleteTask:
shop_name = shop_item.get("shopName", "未知店铺")
self.log(f"[{index}/{len(items)}] 开始处理店铺: {shop_name}")
self.process_shop(task_id, shop_item, country_sections, cart_ratios)
self.process_shop(task_id, shop_item, country_sections, cart_ratios, delete_conditions)
runing_task[task_id]["processed_shops"] += 1
if runing_task[task_id].get("stop_requested", False):
@@ -1359,6 +1409,7 @@ class PatrolDeleteTask:
shop_item: Dict[str, Any],
country_sections: List[Dict[str, Any]],
cart_ratios: List[Dict[str, Any]],
delete_conditions: Optional[List[Dict[str, Any]]] = None,
):
"""处理单个店铺。"""
from config import runing_shop, runing_task
@@ -1412,6 +1463,7 @@ class PatrolDeleteTask:
task_id=task_id,
shop_name=shop_name,
country_name=country_name,
delete_conditions=delete_conditions,
)
country_results.append(country_result)
aggregated_sections[country_name] = country_result["countrySection"]
@@ -1522,6 +1574,7 @@ class PatrolDeleteTask:
task_id: int,
shop_name: str,
country_name: str,
delete_conditions: Optional[List[Dict[str, Any]]] = None,
) -> Dict[str, Any]:
from config import runing_task
@@ -1543,6 +1596,7 @@ class PatrolDeleteTask:
shop_name,
country_name,
trace_id=trace_id,
delete_conditions=delete_conditions,
)
latest_status_rows = delete_result.get("statusRows") or []
self.log(