add order entity parse
This commit is contained in:
@@ -4,10 +4,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Platform\Tmall\EntityParse;
|
namespace App\Platform\Tmall\EntityParse;
|
||||||
|
|
||||||
|
use App\Constants\OrderStatus;
|
||||||
use App\Model\Company;
|
use App\Model\Company;
|
||||||
use App\Model\Model as Entity;
|
use App\Model\Model as Entity;
|
||||||
use App\Model\Store;
|
use App\Model\Store;
|
||||||
use App\Entity\Parse\EntityParse;
|
use App\Entity\Parse\EntityParse;
|
||||||
|
use App\Constants\PaymentMethod;
|
||||||
|
use App\Constants\OrderType;
|
||||||
use Hyperf\Collection\LazyCollection;
|
use Hyperf\Collection\LazyCollection;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
@@ -88,20 +91,45 @@ class Order extends EntityParse
|
|||||||
$records = isset($rawData[0]) ? $rawData : [$rawData];
|
$records = isset($rawData[0]) ? $rawData : [$rawData];
|
||||||
|
|
||||||
foreach ($records as $record) {
|
foreach ($records as $record) {
|
||||||
|
|
||||||
|
$raw = \json_encode($record);
|
||||||
// 映射每条原始数据到 Model 可用的数组格式
|
// 映射每条原始数据到 Model 可用的数组格式
|
||||||
yield [
|
yield [
|
||||||
'platform_id' => $this->getPlatform()->id,
|
|
||||||
'company_id' => $this->getCompany()->id,
|
'company_id' => $this->getCompany()->id,
|
||||||
|
'platform_id' => $this->getPlatform()->id,
|
||||||
'store_id' => $this->getStore()->id,
|
'store_id' => $this->getStore()->id,
|
||||||
'unique_id' => $record['unique_id'] ?? $this->getData()['unique_id'] ?? null,
|
'order_status_id' => $this->getOrderStatusId($record['status']),
|
||||||
'raw_data' => json_encode($record),
|
'platform_order_id' => $record['tid'],
|
||||||
// 根据实际业务需求映射其他字段
|
'payment_method_id' => $this->getPaymentMethodId(),
|
||||||
// 例如:
|
'presale' => false,
|
||||||
// 'order_id' => $record['order_id'] ?? null,
|
'total_amount' => $record['total_fee'],
|
||||||
// 'order_status' => $record['order_status'] ?? null,
|
'total_paid' => $record['payment'],
|
||||||
// 'order_amount' => $record['order_amount'] ?? 0,
|
'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'],
|
||||||
|
'raw_hash' => \md5($raw),
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
'updated_at' => date('Y-m-d H:i:s'),
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -115,8 +143,9 @@ class Order extends EntityParse
|
|||||||
*/
|
*/
|
||||||
public function getUniqueBy(): array
|
public function getUniqueBy(): array
|
||||||
{
|
{
|
||||||
// 天猫订单的唯一性由店铺 + 平台订单号确定
|
// 天猫订单的唯一性由店铺 + 平台订单号确定(实际上由平台订单号就已经足够)
|
||||||
return ['store_id', 'platform_order_id'];
|
// @attention create_date 为数据库强制要求,必需携带
|
||||||
|
return ['store_id', 'platform_order_id', 'created_date'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,14 +159,39 @@ class Order extends EntityParse
|
|||||||
public function getUpdateFields(): array
|
public function getUpdateFields(): array
|
||||||
{
|
{
|
||||||
// 方案1:手动指定可更新字段(推荐,最明确)
|
// 方案1:手动指定可更新字段(推荐,最明确)
|
||||||
|
// 根据实际业务需求添加其他可更新字段
|
||||||
return [
|
return [
|
||||||
|
'company_id',
|
||||||
|
'platform_id',
|
||||||
|
'store_id',
|
||||||
'order_status_id',
|
'order_status_id',
|
||||||
|
'platform_order_id',
|
||||||
'payment_method_id',
|
'payment_method_id',
|
||||||
'buyer_user_id',
|
'presale',
|
||||||
'total_amount',
|
'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',
|
'updated_date',
|
||||||
|
'paid_date',
|
||||||
|
'shipping_date',
|
||||||
|
'zipcode',
|
||||||
|
'city',
|
||||||
|
'province',
|
||||||
|
'country',
|
||||||
'raw',
|
'raw',
|
||||||
// 根据实际业务需求添加其他可更新字段
|
'ext',
|
||||||
|
'buyer_user_id',
|
||||||
|
'raw_hash',
|
||||||
|
'updated_at', // 更新时刷新,created_at 不包含以保留原始创建时间
|
||||||
];
|
];
|
||||||
|
|
||||||
// 方案2:动态计算(如果字段较多且经常变动)
|
// 方案2:动态计算(如果字段较多且经常变动)
|
||||||
@@ -148,4 +202,125 @@ class Order extends EntityParse
|
|||||||
// );
|
// );
|
||||||
// return $this->getTableColumnsExcept($entity, $excludeFields);
|
// return $this->getTableColumnsExcept($entity, $excludeFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据淘宝订单状态确定对应的 Tools 订单状态
|
||||||
|
*
|
||||||
|
* @param string $platformOrderStatus 淘宝平台订单状态
|
||||||
|
* @return int Tools 订单状态 ID
|
||||||
|
*/
|
||||||
|
public function getOrderStatusId(string $platformOrderStatus): int
|
||||||
|
{
|
||||||
|
$statusMap = $this->orderStatusMap();
|
||||||
|
|
||||||
|
return $statusMap[$platformOrderStatus] ?? OrderStatus::PAYMENT_COMPLETE->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 淘宝订单状态到 Tools 订单状态的映射
|
||||||
|
*
|
||||||
|
* @return array<string, int>
|
||||||
|
*/
|
||||||
|
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 $rawData
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function formatOrderItemsFromRaw(array $rawData, array $platform_orders_id_to_local_db_order_id_map): array
|
||||||
|
{
|
||||||
|
// 由于 $rawData 是批量数据,包含多条订单结果,因此订单子项需要从集合中提取
|
||||||
|
// Tmall 平台响应体的数据格式为: collection->payload->orders
|
||||||
|
// $platform_orders_id_to_local_db_order_id_map 内部元素数据格式为 [platform_order_id => local db order id]
|
||||||
|
|
||||||
|
if(empty($rawData['orders'])){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = [];
|
||||||
|
|
||||||
|
foreach ($rawData as $raw_orders) {
|
||||||
|
foreach ($raw_orders['orders'] as $raw_order_item){
|
||||||
|
// 数据库中父订单 id
|
||||||
|
$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']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tmall 订单子项映射转换
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function tmallOrderItemMap(array $item, string $platform_order_id, int $parent_order_id, string $parent_order_created_date): array
|
||||||
|
{
|
||||||
|
|
||||||
|
//@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' => $platform_order_id,
|
||||||
|
'sub_order_id' => $item['oid'],
|
||||||
|
// @attention sku 的处理需要仅以规范和约束,确保 sku 准确
|
||||||
|
'sub_order_type_id' => '',
|
||||||
|
'product_id' => '',
|
||||||
|
'platform_product_id' =>$item['num_iid'],
|
||||||
|
'product_sku' => $item['outer_sku_id'],
|
||||||
|
'product_barcode' => '',
|
||||||
|
'unit_price' => $item['price'],
|
||||||
|
'quantity' => $item['num'],
|
||||||
|
'discount' => $item['discount_fee'],
|
||||||
|
'total' => $item['divide_order_fee'],
|
||||||
|
// @attention 扩展字段,用来存储其他信息
|
||||||
|
'ext' => '',
|
||||||
|
'created_date' => $parent_order_created_date,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user