fix order item fail to save

This commit is contained in:
2026-02-02 15:13:46 +08:00
parent 033bebe11e
commit 39ef3acc1f
2 changed files with 85 additions and 25 deletions
+22 -15
View File
@@ -12,7 +12,6 @@ use Hyperf\Amqp\Message\ConsumerMessage;
use Hyperf\Amqp\Result; use Hyperf\Amqp\Result;
use Hyperf\Amqp\Producer; use Hyperf\Amqp\Producer;
use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Message\AMQPMessage;
use Hyperf\Di\Annotation\Inject;
use Hyperf\DbConnection\Db; use Hyperf\DbConnection\Db;
use App\Model\OrderItem; use App\Model\OrderItem;
use Exception; use Exception;
@@ -186,6 +185,7 @@ class OrderConsumer extends ConsumerMessage
// 在数据库事务中尝试对 $entityMapResult 中的元素进行持久化,如果没有问题, 则返回 ACK,否则这是 NACK 且 回滚事务。 // 在数据库事务中尝试对 $entityMapResult 中的元素进行持久化,如果没有问题, 则返回 ACK,否则这是 NACK 且 回滚事务。
return Result::ACK; return Result::ACK;
} catch (Throwable $error) { } catch (Throwable $error) {
dump("=== Error Caught ==="); dump("=== Error Caught ===");
dump("Error: " . $error->getMessage()); dump("Error: " . $error->getMessage());
@@ -322,6 +322,14 @@ class OrderConsumer extends ConsumerMessage
*/ */
protected function processOrderItems(array $items_by_platform_order_id): void protected function processOrderItems(array $items_by_platform_order_id): void
{ {
dump('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
dump('processOrderItems');
dump($items_by_platform_order_id);
dump('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
if (empty($items_by_platform_order_id)) { if (empty($items_by_platform_order_id)) {
dump('No order items to process'); dump('No order items to process');
return; return;
@@ -331,16 +339,11 @@ class OrderConsumer extends ConsumerMessage
$all_items_to_upsert = []; $all_items_to_upsert = [];
$item_sub_order_ids_by_platform_order_id = []; // 记录每个平台订单的新子项 ID 列表 $item_sub_order_ids_by_platform_order_id = []; // 记录每个平台订单的新子项 ID 列表
foreach ($items_by_platform_order_id as $platform_order_id => $items) { foreach ($items_by_platform_order_id as $item) {
$sub_order_ids = []; $platform_order_id = $item['platform_order_id'];
// order_id 已由 formatOrderItemsFromRaw 通过 idMapping 填充
foreach ($items as $item) { $all_items_to_upsert[] = $item;
// order_id 已由 formatOrderItemsFromRaw 通过 idMapping 填充 $item_sub_order_ids_by_platform_order_id[$platform_order_id] = $item['sub_order_id'];
$all_items_to_upsert[] = $item;
$sub_order_ids[] = $item['sub_order_id'];
}
$item_sub_order_ids_by_platform_order_id[$platform_order_id] = $sub_order_ids;
} }
if (empty($all_items_to_upsert)) { if (empty($all_items_to_upsert)) {
@@ -378,6 +381,7 @@ class OrderConsumer extends ConsumerMessage
// 4. 批量删除不在新数据中的旧 OrderItem(完全同步策略) // 4. 批量删除不在新数据中的旧 OrderItem(完全同步策略)
// 利用 hypertable 按 created_date 分区的特性,确保删除条件包含 created_date 以触发分区裁剪 // 利用 hypertable 按 created_date 分区的特性,确保删除条件包含 created_date 以触发分区裁剪
// 此部分业务应该很少被调用,订单子项新增或删减的情况很少见 // 此部分业务应该很少被调用,订单子项新增或删减的情况很少见
$this->deleteObsoleteOrderItems($all_items_to_upsert); $this->deleteObsoleteOrderItems($all_items_to_upsert);
dump("Order items processing completed"); dump("Order items processing completed");
@@ -405,9 +409,10 @@ class OrderConsumer extends ConsumerMessage
$new_item_keys = []; // 集合 B $new_item_keys = []; // 集合 B
foreach ($new_items as $item) { foreach ($new_items as $item) {
// 统一格式化为 Y-m-d H:i:s(不带时区),确保与数据库查询结果匹配
$created_date = $item['created_date'] instanceof \DateTimeInterface $created_date = $item['created_date'] instanceof \DateTimeInterface
? $item['created_date']->format('Y-m-d H:i:sP') ? $item['created_date']->format('Y-m-d H:i:s')
: $item['created_date']; : (new \DateTime($item['created_date']))->format('Y-m-d H:i:s');
// 订单级别的键(用于限定查询范围) // 订单级别的键(用于限定查询范围)
$order_key = sprintf('%d|%s|%s', $item['store_id'], $item['platform_order_id'], $created_date); $order_key = sprintf('%d|%s|%s', $item['store_id'], $item['platform_order_id'], $created_date);
@@ -448,9 +453,10 @@ class OrderConsumer extends ConsumerMessage
$created_dates_to_delete = []; $created_dates_to_delete = [];
foreach ($existing_items as $existing) { foreach ($existing_items as $existing) {
// 统一格式化为 Y-m-d H:i:s(不带时区),与新数据保持一致
$existing_created_date = $existing->created_date instanceof \DateTimeInterface $existing_created_date = $existing->created_date instanceof \DateTimeInterface
? $existing->created_date->format('Y-m-d H:i:sP') ? $existing->created_date->format('Y-m-d H:i:s')
: (string) $existing->created_date; : (new \DateTime((string) $existing->created_date))->format('Y-m-d H:i:s');
$existing_key = sprintf( $existing_key = sprintf(
'%d|%s|%s|%s', '%d|%s|%s|%s',
@@ -467,6 +473,7 @@ class OrderConsumer extends ConsumerMessage
} }
} }
// 4. 批量删除(利用 hypertable 主键 (id, created_date) 进行高效删除) // 4. 批量删除(利用 hypertable 主键 (id, created_date) 进行高效删除)
if (!empty($ids_to_delete)) { if (!empty($ids_to_delete)) {
$deleted = OrderItem::query() $deleted = OrderItem::query()
@@ -267,9 +267,15 @@ class Order extends EntityParse
* orderItems 的输出结果为 \App\Model\OrderItem::fill() 可以直接使用的数据格式 * orderItems 的输出结果为 \App\Model\OrderItem::fill() 可以直接使用的数据格式
* *
* @param array $raw_data * @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 * @return array
*/ */
public function formatOrderItemsFromRaw(array $raw_data, array $platform_orders_id_to_local_db_order_id_map): 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 是批量数据,包含多条订单结果,因此订单子项需要从集合中提取 // 由于 $raw_data 是批量数据,包含多条订单结果,因此订单子项需要从集合中提取
// Tmall 平台响应体的数据格式为: collection->payload->orders // Tmall 平台响应体的数据格式为: collection->payload->orders
@@ -278,10 +284,12 @@ class Order extends EntityParse
$items = []; $items = [];
foreach ($raw_data as $raw_orders) { foreach ($raw_data as $raw_orders) {
foreach ($raw_orders['orders'] as $raw_order_item) { foreach ($raw_orders['orders']['order'] as $raw_order_item) {
// 数据库中父订单 id // 数据库中父订单 id
$db_order_id = $platform_orders_id_to_local_db_order_id_map[$raw_orders['tid']]; $db_order_id = $platform_orders_id_to_local_db_order_id_map[$raw_orders['tid']];
$items[] = $this->tmallOrderItemMap($raw_order_item, $raw_orders['tid'], $db_order_id, $raw_orders['created']); $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);
} }
} }
@@ -292,20 +300,65 @@ class Order extends EntityParse
* Tmall 订单子项映射转换 * Tmall 订单子项映射转换
* @return void * @return void
*/ */
private function tmallOrderItemMap(array $item, string $platform_order_id, int $parent_order_id, string $parent_order_created_date): array 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 的业务映射需进一步补全 //@TODO order item 的业务映射需进一步补全
return [ return [
'company_id' => $this->getCompany()->id, 'company_id' => $this->getCompany()->id,
'platform_id' => $this->getPlatform()->id, 'platform_id' => $this->getPlatform()->id,
'store_id' => $this->getStore()->id, 'store_id' => $this->getStore()->id,
'order_id' => $parent_order_id, 'order_id' => $parent_order_id,
'platform_order_id' => $platform_order_id, 'platform_order_id' => strval($platform_order_id),
'sub_order_id' => $item['oid'], 'sub_order_id' => $item['oid'],
// @attention sku 的处理需要仅以规范和约束,确保 sku 准确 // @attention sku 的处理需要仅以规范和约束,确保 sku 准确
'sub_order_type_id' => '', 'sub_order_type_id' => null,
'product_id' => '', // @attention 表示未找到产品 id
'product_id' => $local_product_id,
'platform_product_id' =>$item['num_iid'], 'platform_product_id' =>$item['num_iid'],
// @attention @TODO 需要对 运营侧的产品维护做进一步规范 // @attention @TODO 需要对 运营侧的产品维护做进一步规范
'product_sku' => $item['outer_sku_id'] ?? null, 'product_sku' => $item['outer_sku_id'] ?? null,
@@ -316,7 +369,7 @@ class Order extends EntityParse
'discount' => $item['discount_fee'], 'discount' => $item['discount_fee'],
'total' => $item['divide_order_fee'], 'total' => $item['divide_order_fee'],
// @attention 扩展字段,用来存储其他信息 // @attention 扩展字段,用来存储其他信息
'ext' => '', 'ext' => null,
'created_date' => $parent_order_created_date, 'created_date' => $parent_order_created_date,
]; ];
} }