Files
pruchase_jhw/src/tasks/surugaya_trade_monitor.py
T
2026-06-11 12:33:51 +08:00

107 lines
4.3 KiB
Python

import json
import time
from typing import Any
from loguru import logger
from parsers.surugaya import SurugayaOrderDetailParser
from src.tasks.base import BasePurchaseTask
from task_queue.redis_manager import get_redis_client
class SurugayaTradeMonitorTask(BasePurchaseTask):
"""
骏河屋交易订单获取任务。
入参约定:
- topic: surugaya_trade_monitor
- payload.trade_list: 交易单号列表
"""
async def execute(self) -> dict[str, Any]:
self.report_event = "surugaya_trade_monitor"
self.is_report = False
redis_client = None
trade_code = ""
try:
logger.debug(f"[任务 {self.task_id}] 骏河屋交易订单获取工作流已启动。")
if not self.page:
raise ValueError("页面对象未初始化,无法执行交易订单获取任务。")
payload = self.message.get("payload", {})
trade_code = payload.get("trade_code", "")
if not trade_code:
err_msg = f"无法解析交易单号 '{trade_code}'"
logger.error(err_msg)
raise ValueError(err_msg)
page = self.page
await page.goto(f"https://www.suruga-ya.jp/pcmypage/action_sell_search/detail?trade_code={trade_code}",
wait_until="domcontentloaded", timeout=30000)
order_detail_model = await SurugayaOrderDetailParser.parse_page(page)
order_detail = order_detail_model.model_dump(mode="json") if order_detail_model else None
logger.info(f"[任务 {self.task_id}] 骏河屋交易订单获取工作流执行成功,订单详情:{order_detail}")
# 写入hash表
if not order_detail:
raise Exception(f"交易单号 '{trade_code}' 未解析到订单详情。")
new_trade_status = order_detail_model.status.trade_status or ""
trade_number = order_detail_model.summary.trade_number or None
redis_client = get_redis_client()
# 更新hash表
hash_key = self.get_hash_key()
delay_zset_key = self.get_delay_zset_key()
requeue_member = json.dumps({"trade_code": trade_code}, ensure_ascii=False)
# 获取上次保存的订单状态
old_trade_status = None
existing_order_detail = await redis_client.hget(hash_key, trade_code)
if existing_order_detail:
old_trade_status = json.loads(existing_order_detail)["status"]["trade_status"]
if old_trade_status and old_trade_status != new_trade_status:
logger.info(f"[任务 {self.task_id}] 订单状态发生改变,需要上报。")
self.is_report = True
await redis_client.hset(
hash_key,
trade_code,
json.dumps(order_detail, ensure_ascii=False),
)
logger.info(
f"[任务 {self.task_id}] 已将订单详情写入 Redis Hash '{hash_key}',field='{trade_code}'"
)
enqueue = True # 是否需要再次入队
if trade_number is not None:
logger.warning(
f"[任务 {self.task_id}] 订单物流单号已获取到 '{trade_number}',放弃再次入队。"
)
enqueue = False
elif new_trade_status == "発送済み" or new_trade_status == "取引終了":
logger.warning(f"[任务 {self.task_id}] 订单状态为 '{new_trade_status}',放弃再次入队。")
enqueue = False
# 任务再次入队
if enqueue:
next_score = int(time.time()) + self.get_delay_interval_seconds()
await redis_client.zadd(delay_zset_key, {requeue_member: next_score})
logger.info(
f"[任务 {self.task_id}] 延时任务已重新入队,key='{delay_zset_key}',score={next_score}"
)
return {
"trade_code": trade_code,
"order_detail": order_detail,
}
except Exception as e:
self.is_report = False
logger.error(f"[任务 {self.task_id}] 骏河屋交易订单获取工作流执行失败,错误信息:{e}")
raise e