diff --git a/backend/app/Platform/AbstractOrderParse.php b/backend/app/Platform/AbstractOrderParse.php index dfbe50f..5e208f7 100644 --- a/backend/app/Platform/AbstractOrderParse.php +++ b/backend/app/Platform/AbstractOrderParse.php @@ -16,15 +16,26 @@ use InvalidArgumentException; abstract class AbstractOrderParse extends EntityParse implements OrderContract { /** - * 解析订单子项数据(抽象方法,由子类实现) - * + * 从原始数据格式化订单子项(抽象方法,由子类实现) + * * 每个平台有自己的订单子项数据结构,需要各自实现具体的解析逻辑 - * - * @param array $orderItems 原始订单子项数组 - * @param string $platformOrderId 平台订单 ID - * @return array 解析后的订单子项数据数组 + * + * @var $platform_orders_id_to_local_db_order_id_map + * - 为 平台订单 id 与 本地父级订单 id 的映射数组 + * - 用来维护父订单和值订单的关系 + * */ - abstract public function parseOrderItems(array $orderItems, string $platformOrderId): array; + abstract public function formatOrderItemsFromRaw(array $raw_data, array $platform_orders_id_to_local_db_order_id_map): array; + + /** + * 获取本地订单状态 ID(抽象方法,由子类实现) + */ + abstract public function getOrderStatusId(string $platform_order_status): int; + + /** + * 获取支付方式 ID(抽象方法,由子类实现) + */ + abstract public function getPaymentMethodId(): int; /** * 通用辅助方法:验证订单必需字段 diff --git a/backend/app/Platform/OrderConsumer.php b/backend/app/Platform/OrderConsumer.php index 1a8e728..420cc3b 100644 --- a/backend/app/Platform/OrderConsumer.php +++ b/backend/app/Platform/OrderConsumer.php @@ -111,26 +111,6 @@ class OrderConsumer extends ConsumerMessage dump("Processing " . count($data_to_upsert) . " order(s) with batch upsert"); - // 检测订单解析器是否实现了 getOrderItems 方法 - if( !method_exists($parse, 'formatOrderItemsFromRaw')){ - throw new Exception('formatOrderItemsFromRaw method must be implemented in ' . $parse::class ); - } - - //@TODO order type 也需要进一步确定 app/Constants/OrderType.php - - // 检测订单解析器是否实现了 getOrderStatusId 方法 - // 该方法处理了电商平台订单状态到本地订单状态枚举值 \App\Constants\OrderStatus 的映射 - if( !method_exists($parse, 'getOrderStatusId')){ - throw new Exception('getOrderStatusId method must be implemented in ' . $parse::class ); - } - - // 检测订单解析器是否实现了 getPaymentMethodId 方法 - // 该方法处理了电商平台订单付款方式的枚举值 \App\Constants\PaymentMethod 的映射 - if( !method_exists($parse, 'getPaymentMethodId')){ - throw new Exception('getPaymentMethodId method must be implemented in ' . $parse::class ); - } - - // 收集订单数据 $orders_data = $data_to_upsert; $raw_data = $data['data'] ?? []; diff --git a/backend/app/Platform/OrderContract.php b/backend/app/Platform/OrderContract.php index 9636bef..5791964 100644 --- a/backend/app/Platform/OrderContract.php +++ b/backend/app/Platform/OrderContract.php @@ -13,16 +13,31 @@ namespace App\Platform; interface OrderContract { /** - * 解析订单子项数据 + * 从原始数据格式化订单子项 * - * @param array $orderItems 原始订单子项数组 - * @param string $platformOrderId 平台订单 ID + * @param array $raw_data 原始数据数组 + * @param array $platform_orders_id_to_local_db_order_id_map 平台订单 ID => 本地数据库订单 ID 映射 * @return array 解析后的订单子项数据数组,每个元素包含: - * - company_id, platform_id, store_id - * - platform_order_id, sub_order_id - * - product_id, platform_product_id - * - unit_price, quantity, discount, total - * 等字段 + * - company_id, platform_id, store_id + * - platform_order_id, sub_order_id + * - product_id, platform_product_id + * - unit_price, quantity, discount, total + * 等字段 */ - public function parseOrderItems(array $orderItems, string $platformOrderId): array; + public function formatOrderItemsFromRaw(array $raw_data, array $platform_orders_id_to_local_db_order_id_map): array; + + /** + * 获取本地订单状态 ID + * + * @param string $platform_order_status 平台订单状态字符串 + * @return int 本地订单状态 ID + */ + public function getOrderStatusId(string $platform_order_status): int; + + /** + * 获取支付方式 ID + * + * @return int 支付方式 ID + */ + public function getPaymentMethodId(): int; } diff --git a/backend/app/Platform/Shopee/EntityParse/Order.php b/backend/app/Platform/Shopee/EntityParse/Order.php index 479ca47..1fe68b2 100644 --- a/backend/app/Platform/Shopee/EntityParse/Order.php +++ b/backend/app/Platform/Shopee/EntityParse/Order.php @@ -21,7 +21,7 @@ use InvalidArgumentException; * Shopee 订单解析器 * * 继承 AbstractOrderParse,实现 Shopee 平台特定的订单解析逻辑 - * 实现 OrderContract 契约中定义的 parseOrderItems 方法 + * 通过 AbstractOrderParse 自动满足 OrderContract 契约 */ class Order extends AbstractOrderParse { @@ -110,11 +110,6 @@ class Order extends AbstractOrderParse dump($record); - $_origin_order_item = $record['item_list']; // 'item_list' 为来自 shopee 原始数据的 订单子项信息 - - // 解析订单子项数据,传入 platform_order_id(实现 OrderContract 契约方法) - $order_items = $this->parseOrderItems($_origin_order_item, $record['order_sn']); - // 根据实际业务需求映射其他字段 // 映射每条原始数据到 Order Model 可用的数组格式 // @attention 此处业务决定了 电商平台数据 和 数据仓库 之间的映射关系 @@ -164,50 +159,6 @@ class Order extends AbstractOrderParse }); } - /** - * 解析订单子项数据(实现 OrderContract 契约方法) - * - * Shopee API 文档:https://open.shopee.com/documents/v2/v2.order.get_order_detail?module=94&type=1 - * - * @param array $order_items Shopee 原始订单子项数组 - * @param string $platform_order_id 平台订单 ID (order_sn) - * @return array 解析后的订单子项数据数组 - */ - public function parseOrderItems(array $order_items, string $platform_order_id): array - { - $parsed_items = []; - - foreach ($order_items as $item) { - // 价格和数量 - $original_price = (float)($item['model_original_price'] ?? 0); - $discounted_price = (float)($item['model_discounted_price'] ?? $original_price); - $quantity = (int)($item['model_quantity_purchased'] ?? 1); - - // SKU: 优先使用 model_sku(变体SKU),如果为空则使用 item_sku(商品SKU) - $sku = !empty($item['model_sku']) ? $item['model_sku'] : ($item['item_sku'] ?? ''); - - $parsed_items[] = [ - 'company_id' => $this->getCompany()->id, - 'platform_id' => 25, - 'store_id' => $this->getStore()->id, - 'platform_order_id' => $platform_order_id, // 平台订单 ID(从 order_sn 传入) - 'sub_order_id' => (string)$item['order_item_id'], // 使用 order_item_id 作为订单子项的唯一标识 - 'sub_order_type_id' => 0, - 'product_id' => 0, // 需要根据 platform_product_id 匹配,暂设为 0 - 'platform_product_id' => (string)$item['item_id'], // Shopee 商品 ID - 'product_sku' => $sku, - 'product_barcode' => '', - 'unit_price' => $discounted_price, // 实际成交单价(折扣后) - 'quantity' => $quantity, - 'discount' => ($original_price - $discounted_price) * $quantity, // 总折扣金额 - 'total' => $discounted_price * $quantity, // 总金额 = 折扣价 × 数量 - 'ext' => null, // 原始信息已在 Order.raw 中记录,此处留空 - ]; - } - - return $parsed_items; - } - /** * 获取唯一键字段(对应数据库唯一索引) * @@ -500,10 +451,10 @@ class Order extends AbstractOrderParse 'product_sku' => $item['model_sku'] ?? $item['item_sku'] ?? null, // @attention @TODO 需要对 运营侧的产品维护做进一步规范 'product_barcode' => null, - 'unit_price' => $item['model_original_price'], - 'quantity' => $item['model_quantity_purchased'], - 'discount' => $item['model_original_price'] - $item['model_quantity_purchased'] ?? 0, - 'total' => $item['model_quantity_purchased'], + 'unit_price' => (float)($item['model_discounted_price'] ?? $item['model_original_price'] ?? 0), + 'quantity' => (int)($item['model_quantity_purchased'] ?? 1), + 'discount' => ((float)($item['model_original_price'] ?? 0) - (float)($item['model_discounted_price'] ?? $item['model_original_price'] ?? 0)) * (int)($item['model_quantity_purchased'] ?? 1), + 'total' => (float)($item['model_discounted_price'] ?? $item['model_original_price'] ?? 0) * (int)($item['model_quantity_purchased'] ?? 1), // @attention 扩展字段,用来存储其他信息 'ext' => null, 'created_date' => $parent_order_created_date, diff --git a/backend/app/Platform/Tmall/EntityParse/Order.php b/backend/app/Platform/Tmall/EntityParse/Order.php index 20568eb..40b7ab0 100644 --- a/backend/app/Platform/Tmall/EntityParse/Order.php +++ b/backend/app/Platform/Tmall/EntityParse/Order.php @@ -9,7 +9,7 @@ use App\Model\Company; use App\Model\Model as Entity; use App\Model\Product; use App\Model\Store; -use App\Entity\Parse\EntityParse; +use App\Platform\AbstractOrderParse; use App\Constants\PaymentMethod; use App\Constants\OrderType; use Carbon\Carbon; @@ -21,7 +21,7 @@ use InvalidArgumentException; * * 展示如何继承 EntityParse 实现自定义解析逻辑 */ -class Order extends EntityParse +class Order extends AbstractOrderParse { /** * 公司作用域匹配