$this->getCompany()->id, 'platform_id' => $this->getPlatform()->id, 'store_id' => $this->getStore()->id, 'order_status_id' => $this->getOrderStatusId($record['status']), 'platform_order_id' => $record['tid'], 'payment_method_id' => $this->getPaymentMethodId(), 'presale' => false, 'total_amount' => $record['total_fee'], 'total_paid' => $record['payment'], 'total_discount' => $record['discount_fee'], // 实际收到的金额,如果平台有商家补贴,此金额需要重新计算 - 部分退款订单也影响此字段的值 'total_received' => $record['received_payment'], 'freight_fee' => 0, 'tax_fee' => 0, 'discount_fee' => 0, 'commission_fee' => 0, 'coupon_amount' => 0, 'voucher_amount' => 0, 'order_type_id' => OrderType::Normor_Order->value, 'created_date' => $record['created'], 'updated_date' => $record['modified'] ?? null, 'paid_date' => $record['pay_time'] ?? null, 'shipping_date' => $record['consign_time'] ?? null, 'zipcode' => $record['receiver_zip'] ?? '', 'city' => $record['receiver_city'] ?? '', 'province' => $record['receiver_state'] ?? '', 'country' => 'CN', 'raw' => $raw, 'ext' => null, 'buyer_user_id' => $record['buyer_open_uid'], 'hash' => \md5($raw), 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), ]; } }); } /** * 获取实体的唯一键字段(用于 upsert 的 uniqueBy 参数) * * 定义订单的唯一约束字段组合 * * @return array 唯一键字段名数组 */ public function getUniqueBy(): array { // 天猫订单的唯一性由店铺 + 平台订单号确定(实际上由平台订单号就已经足够) // @attention create_date 为数据库强制要求,必需携带 return ['store_id', 'platform_order_id', 'created_date']; } /** * 获取可更新的字段列表(用于 upsert 的 update 参数) * * 明确定义哪些字段在更新时可以被修改 * 排除:主键、唯一键、创建时间、关联 ID 等不应变更的字段 * * @return array 可更新字段名数组 */ public function getUpdateFields(): array { // 方案1:手动指定可更新字段(推荐,最明确) // 根据实际业务需求添加其他可更新字段 return [ 'company_id', 'platform_id', 'store_id', 'order_status_id', 'platform_order_id', 'payment_method_id', 'presale', 'total_amount', 'total_paid', 'total_discount', 'total_received', 'freight_fee', 'tax_fee', 'discount_fee', 'commission_fee', 'coupon_amount', 'voucher_amount', 'order_type_id', 'created_date', 'updated_date', 'paid_date', 'shipping_date', 'zipcode', 'city', 'province', 'country', 'raw', 'ext', 'buyer_user_id', 'raw_hash', 'updated_at', // 更新时刷新,created_at 不包含以保留原始创建时间 ]; // 方案2:动态计算(如果字段较多且经常变动) // $entity = $this->entityMatch($this->getData()); // $excludeFields = array_merge( // ['id', 'created_at', 'created_date', 'company_id', 'platform_id'], // $this->getUniqueBy() // ); // return $this->getTableColumnsExcept($entity, $excludeFields); } /** * 根据淘宝订单状态确定对应的 Tools 订单状态 * * @param string $platform_order_status 淘宝平台订单状态 * @return int Tools 订单状态 ID */ public function getOrderStatusId(string $platform_order_status): int { $status_map = $this->orderStatusMap(); return $status_map[$platform_order_status] ?? OrderStatus::PAYMENT_COMPLETE->value; } /** * 淘宝订单状态到 Tools 订单状态的映射 * * @return array */ private function orderStatusMap(): array { return [ // Payment pending (1) 'TRADE_NO_CREATE_PAY' => OrderStatus::PAYMENT_PENDING->value, // 没有创建支付宝交易 'WAIT_BUYER_PAY' => OrderStatus::PAYMENT_PENDING->value, // 等待买家付款 'PAY_PENDING' => OrderStatus::PAYMENT_PENDING->value, // 国际信用卡支付付款确认中 'WAIT_PRE_AUTH_CONFIRM' => OrderStatus::PAYMENT_PENDING->value, // 0元购合约中 // Payment fail (2) 'TRADE_CLOSED_BY_TAOBAO' => OrderStatus::PAYMENT_FAIL->value, // 付款以前,卖家或买家主动关闭交易 // Payment complete (3) 'SELLER_CONSIGNED_PART' => OrderStatus::PAYMENT_COMPLETE->value, // 卖家部分发货 'WAIT_SELLER_SEND_GOODS' => OrderStatus::PAYMENT_COMPLETE->value, // 等待卖家发货,即:买家已付款 // Awaiting shipment (4) 'PAID_FORBID_CONSIGN' => OrderStatus::AWAITING_SHIPMENT->value, // 拼团中订单或者发货强管控的订单,已付款但禁止发货 // Shipped (5) 'WAIT_BUYER_CONFIRM_GOODS' => OrderStatus::SHIPPED->value, // 等待买家确认收货,即:卖家已发货 'TRADE_BUYER_SIGNED' => OrderStatus::SHIPPED->value, // 买家已签收,货到付款专用 // Finished (8) 'TRADE_FINISHED' => OrderStatus::FINISHED->value, // 交易成功 // Cancel before shipping (9) 'TRADE_CLOSED' => OrderStatus::CANCEL_BEFORE_SHIPPING->value, // 付款以后用户退款成功,交易自动关闭 ]; } public function getPaymentMethodId() : int { // @attention 暂时固定返回支付方式为支付宝, 其他平台需要定义付款方式映射 return PaymentMethod::ALIPAY_CN->value; } /** * * orderItems 的输出结果为 \App\Model\OrderItem::fill() 可以直接使用的数据格式 * * @param array $raw_data * @param array $platform_orders_id_to_local_db_order_id_map * * * @param array $order_items_to_product_id_map = [ * num_iid => local_db_product_id * ] * @return array */ public function formatOrderItemsFromRaw(array $raw_data, array $platform_orders_id_to_local_db_order_id_map, array $order_items_to_product_id_map = []): array { // 由于 $raw_data 是批量数据,包含多条订单结果,因此订单子项需要从集合中提取 // Tmall 平台响应体的数据格式为: collection->payload->orders // $platform_orders_id_to_local_db_order_id_map 内部元素数据格式为 [platform_order_id => local db order id] $items = []; foreach ($raw_data as $raw_orders) { foreach ($raw_orders['orders']['order'] as $raw_order_item) { // 数据库中父订单 id $db_order_id = $platform_orders_id_to_local_db_order_id_map[$raw_orders['tid']]; $platform_order_id = strval($raw_orders['tid']); $local_product_id = empty($order_items_to_product_id_map) || !isset($order_items_to_product_id_map[$raw_order_item['num_iid']]) ? 0 : $order_items_to_product_id_map[$raw_order_item['num_iid']]; $items[] = $this->tmallOrderItemMap($raw_order_item, $platform_order_id, $db_order_id, $raw_orders['created'], $local_product_id); } } return $items; } /** * Tmall 订单子项映射转换 * @return void */ private function tmallOrderItemMap(array $item, string $platform_order_id, int $parent_order_id, string $parent_order_created_date, int $local_product_id = 0): array { // $item = [ // "adjust_fee" => "0.00", // "buyer_rate" => false, // "cid" => 50026872, // "consign_due_time" => "2_5", // "discount_fee" => "231.98", // "divide_order_fee" => "504.00", // "is_bybt_order" => false, // "is_daixiao" => false, // "is_idle" => "0", // "is_jzfx" => false, // "is_oversold" => false, // "nr_outer_iid" => "768990037900", // "num" => 1, // "num_iid" => 637901668632, // "oid" => 4932549972242808538, // "oid_str" => "4932549972242808538", // "order_attr" => "{"esDate":"2025-12-14","pushTime":"2025-12-09 11:30:00"}", // "order_from" => "WAP,WAP", // "outer_iid" => "768990037900", // "outer_sku_id" => "768990037900", // "part_mjz_discount" => "15.00", // "payment" => "504.00", // "pic_path" => "https://img.alicdn.com/bao/uploaded/i4/2413132940/O1CN01duCukP1XaZLX2jVQy_!!2413132940.jpg", // "price" => "693.00", // "refund_status" => "NO_REFUND", // "s_tariff_fee" => "0.00", // "seller_rate" => false, // "seller_type" => "B", // "sku_id" => "6123547511321", // "sku_properties_name" => "颜色分类:高倍Omega鱼油软胶囊 180粒/瓶", // "snapshot_url" => "za:4932549972242808538_1", // "status" => "WAIT_SELLER_SEND_GOODS", // "store_code" => "STORE_11388627", // "sub_order_tax_fee" => "57.98", // "sub_order_tax_promotion_fee" => "0.00", // "sub_order_tax_rate" => "0", // "tax_coupon_discount" => "57.98", // "tax_free" => true, // "title" => "【优惠价】NordicNaturals挪威小鱼dha深海鱼油Omega3成人rTG高纯度epa胶囊", // "total_fee" => "461.02", // ] //@TODO order item 的业务映射需进一步补全 return [ 'company_id' => $this->getCompany()->id, 'platform_id' => $this->getPlatform()->id, 'store_id' => $this->getStore()->id, 'order_id' => $parent_order_id, 'platform_order_id' => strval($platform_order_id), 'sub_order_id' => $item['oid'], // @attention sku 的处理需要仅以规范和约束,确保 sku 准确 'sub_order_type_id' => null, // @attention 表示未找到产品 id 'product_id' => $local_product_id, 'platform_product_id' =>$item['num_iid'], // @attention @TODO 需要对 运营侧的产品维护做进一步规范 'product_sku' => $item['outer_sku_id'] ?? null, // @attention @TODO 需要对 运营侧的产品维护做进一步规范 'product_barcode' => null, 'unit_price' => $item['price'], 'quantity' => $item['num'], 'discount' => $item['discount_fee'], 'total' => $item['divide_order_fee'], // @attention 扩展字段,用来存储其他信息 'ext' => null, 'created_date' => $parent_order_created_date, ]; } }