# -*- coding: utf-8 -*- """订单ETL任务""" import json from .base_task import BaseTask from loaders.facts.order import OrderLoader from models.parsers import TypeParser class OrdersTask(BaseTask): """订单数据ETL任务""" def get_task_code(self) -> str: return "ORDERS" def execute(self) -> dict: """执行订单数据ETL""" self.logger.info(f"开始执行 {self.get_task_code()} 任务") # 1. 获取时间窗口 window_start, window_end, window_minutes = self._get_time_window() # 2. 调用API获取数据 params = { "storeId": self.config.get("app.store_id"), "startTime": TypeParser.format_timestamp(window_start, self.tz), "endTime": TypeParser.format_timestamp(window_end, self.tz), } try: records, pages_meta = self.api.get_paginated( endpoint="/order/list", params=params, page_size=self.config.get("api.page_size", 200), data_path=("data",) ) # 3. 解析并清洗数据 parsed_records = [] for rec in records: parsed = self._parse_order(rec) if parsed: parsed_records.append(parsed) # 4. 加载数据 loader = OrderLoader(self.db) store_id = self.config.get("app.store_id") inserted, updated, skipped = loader.upsert_orders( parsed_records, store_id ) # 5. 提交事务 self.db.commit() counts = { "fetched": len(records), "inserted": inserted, "updated": updated, "skipped": skipped, "errors": 0 } self.logger.info( f"{self.get_task_code()} 完成: {counts}" ) return self._build_result("SUCCESS", counts) except Exception as e: self.db.rollback() self.logger.error(f"{self.get_task_code()} 失败", exc_info=True) raise def _parse_order(self, raw: dict) -> dict: """解析单条订单记录""" try: return { "store_id": self.config.get("app.store_id"), "order_id": TypeParser.parse_int(raw.get("orderId")), "order_no": raw.get("orderNo"), "member_id": TypeParser.parse_int(raw.get("memberId")), "table_id": TypeParser.parse_int(raw.get("tableId")), "order_time": TypeParser.parse_timestamp(raw.get("orderTime"), self.tz), "end_time": TypeParser.parse_timestamp(raw.get("endTime"), self.tz), "total_amount": TypeParser.parse_decimal(raw.get("totalAmount")), "discount_amount": TypeParser.parse_decimal(raw.get("discountAmount")), "final_amount": TypeParser.parse_decimal(raw.get("finalAmount")), "pay_status": raw.get("payStatus"), "order_status": raw.get("orderStatus"), "remark": raw.get("remark"), "raw_data": json.dumps(raw, ensure_ascii=False) } except Exception as e: self.logger.warning(f"解析订单失败: {e}, 原始数据: {raw}") return None