update tmall order parse

This commit is contained in:
2026-02-05 10:38:36 +08:00
parent fccc80761c
commit f24e6dd52c
@@ -7,10 +7,12 @@ namespace App\Platform\Tmall\EntityParse;
use App\Constants\OrderStatus;
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\Constants\PaymentMethod;
use App\Constants\OrderType;
use Carbon\Carbon;
use Hyperf\Collection\LazyCollection;
use InvalidArgumentException;
@@ -268,39 +270,121 @@ class Order extends EntityParse
*
* @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
public function formatOrderItemsFromRaw(array $raw_data, array $platform_orders_id_to_local_db_order_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 = [];
$product_keys = []; // 索引 => 查询键
foreach ($raw_data as $raw_orders) {
$parent_order_created_date = Carbon::parse($raw_orders['created']);
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);
// 记录当前索引
$index = count($items);
// 先添加 itemproduct_id 初始为 0
$items[] = $this->tmallOrderItemMap($raw_order_item, $platform_order_id, $db_order_id, $parent_order_created_date, 0);
// 记录该索引对应的产品查询键 (Tmall 使用 num_iid 作为 item_idsku_id 作为 model_id)
$model_id = !empty($raw_order_item['sku_id']) ? (string)$raw_order_item['sku_id'] : null;
$product_keys[$index] = $this->buildProductMapKey((string)$raw_order_item['num_iid'], $model_id);
}
}
// 批量查询产品 ID 并更新 items
if (!empty($product_keys)) {
$products_id_map = $this->batchQueryProducts($product_keys);
foreach ($product_keys as $index => $key) {
if (isset($products_id_map[$key])) {
$items[$index]['product_id'] = $products_id_map[$key];
}
}
}
return $items;
}
/**
* 构建产品映射键
*
* @param string $item_id 平台商品 ID
* @param string|null $model_id 平台 SKU ID
* @return string
*/
private function buildProductMapKey(string $item_id, ?string $model_id): string
{
return $item_id . ':' . ($model_id ?? 'null');
}
/**
* 批量查询产品 ID
*
* 使用 PostgreSQL VALUES + JOIN 语法优化,避免生成冗长的 OR 条件链
*
* @param array $product_keys 索引 => 查询键 的映射
* @return array 查询键 => 产品 ID 的映射
*/
private function batchQueryProducts(array $product_keys): array
{
$store_id = $this->getStore()->id;
$unique_keys = array_unique(array_values($product_keys));
if (empty($unique_keys)) {
return [];
}
// 构建 VALUES 子句和绑定参数
$values = [];
$bindings = [];
foreach ($unique_keys as $key) {
[$item_id, $model_id] = explode(':', $key, 2);
$values[] = '(?::text, ?::text)';
$bindings[] = $item_id;
$bindings[] = $model_id === 'null' ? null : $model_id;
}
$valuesClause = implode(', ', $values);
$bindings[] = $store_id;
// PostgreSQL 原生 SQLVALUES 作为驱动表(小表在左侧)
// store_id 条件移入 JOIN ON 子句,让索引过滤更早介入
$sql = "
SELECT p.id, p.platform_item_id, p.platform_model_id
FROM (VALUES {$valuesClause}) AS v(item_id, model_id)
INNER JOIN products p
ON p.store_id = ?
AND p.platform_item_id = v.item_id
AND (p.platform_model_id = v.model_id OR (v.model_id IS NULL AND p.platform_model_id IS NULL))
";
$products = \Hyperf\DbConnection\Db::select($sql, $bindings);
$map = [];
foreach ($products as $product) {
$key = $this->buildProductMapKey($product->platform_item_id, $product->platform_model_id);
$map[$key] = $product->id;
}
return $map;
}
/**
* 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
private function tmallOrderItemMap(array $item, string $platform_order_id, int $parent_order_id, Carbon $parent_order_created_date, int $local_product_id = 0): array
{
// $item = [