update shopee entity parse

This commit is contained in:
2026-02-06 10:58:21 +08:00
parent 266c7eaeae
commit 091b4cf1b1
@@ -4,46 +4,59 @@ declare(strict_types=1);
namespace App\Platform\Shopee\EntityParse;
use App\Constants\ProductStatus;
use App\Model\Company;
use App\Model\Model as Entity;
use App\Model\Store;
use App\Platform\AbstractProductParse;
use App\Platform\Shopee\Constants\OrderStatus;
use App\Constants\PaymentMethod;
use Carbon\Carbon;
use Hyperf\Collection\LazyCollection;
use Hyperf\Context\ApplicationContext;
use Psr\Log\LoggerInterface;
use InvalidArgumentException;
/**
* Shopee 订单解析器
* Shopee 产品解析器
*
* 继承 AbstractOrderParse, 实现 Shopee 平台特定的 Order 解析逻辑
* 实现 OrderContract 契约中定义的 parseOrderItems 方法
* @TODO 待实现:参照 Tmall\EntityParse\Product 实现 Shopee 产品数据解析
*
* @attention 此类文件名为 Product.php,但实际处理订单数据,建议重命名为 Order.php
* Shopee 产品原始数据结构示例:
* {
* "item_id": 123456789,
* "item_name": "商品名称",
* "item_sku": "SKU001",
* "item_status": "NORMAL",
* "price_info": { "current_price": 99.00, "currency": "SGD" },
* "stock_info": { "current_stock": 100 },
* "image": { "image_url_list": ["https://..."] },
* "model_list": [
* { "model_id": 111, "model_sku": "SKU001-A", "current_price": 99.00, "stock_info": { "current_stock": 50 } }
* ],
* "create_time": 1640000000,
* "update_time": 1640100000
* }
*
* 状态映射:
* - NORMAL -> ACTIVE
* - BANNED -> BANNED
* - UNLIST -> INACTIVE
* - REVIEWING -> REVIEWING
* - SELLER_DELETE -> SELLER_DELETE
* - SHOPEE_DELETE -> PLATFORM_DELETE
*/
class Product extends AbstractProductParse
{
/**
* 公司作用域匹配
*
* 从 metadata 中提取 company_id,然后查询数据库获取公司对象
*
* @param array $metadata
* @return Company
* @throws InvalidArgumentException
*/
public function companyScopeMatch(array $metadata): Company
{
// 验证必需字段
if (!isset($metadata['company_id'])) {
throw new InvalidArgumentException('company_id is required in metadata');
}
$company_id = $metadata['company_id'];
$company = Company::find($company_id);
if (!$company) {
@@ -56,29 +69,25 @@ class Product extends AbstractProductParse
/**
* 店铺作用域匹配
*
* 从 metadata 中提取 store_id,然后查询数据库获取店铺对象
*
* @param array $metadata
* @return Store
* @throws InvalidArgumentException
*/
public function storeScopeMatch(array $metadata): Store
{
// 验证必需字段
if (!isset($metadata['platform_store_id'])) {
throw new InvalidArgumentException('platform_store_id is required in metadata');
}
$platform_store_id = $metadata['platform_store_id'];
$shopee_platform_id = 25;
$store = Store::where('platform_id','=', $shopee_platform_id)
$store = Store::where('platform_id', '=', $shopee_platform_id)
->where('platform_store_id', '=', $platform_store_id)
->first();
if (!$store) {
throw new InvalidArgumentException("Platform shopee store id {$shopee_platform_id} not found");
throw new InvalidArgumentException("Shopee store with platform_store_id {$platform_store_id} not found");
}
return $store;
@@ -87,152 +96,136 @@ class Product extends AbstractProductParse
/**
* 实体数据映射
*
* 将原始数据映射为可供 Model 使用的数组集合
* @TODO 待实现:解析 Shopee 产品原始数据
*
* @attention 当前返回格式为 ['order' => [...], 'items' => [...]]
* 但 ProductConsumer 第 153-157 行期望直接返回订单数据数组(参考 Tmall 实现)
* 需要调整返回格式以兼容 ProductConsumer 的 upsert 操作
*
* @TODO 调整返回格式:
* - 方案1:改为直接返回订单数据数组(与 Tmall 一致)
* - 方案2:修改 ProductConsumer 以支持当前的嵌套结构
*
* @param array $raw_data 原始数据数组,通常来自 $data['raw_data']
* @return LazyCollection 返回 LazyCollection,每个元素为可供 Model::fill() 使用的数组
* @param array $raw_data 原始数据数组
* @return LazyCollection
*/
public function entityMap(array $raw_data): LazyCollection
{
// 使用 LazyCollection 进行延迟处理,提高性能
// TODO: 实现 Shopee 产品数据映射
// 参考 Tmall\EntityParse\Product::entityMap() 实现
return LazyCollection::make(function () use ($raw_data) {
// 如果 raw_data 是单个记录,转换为数组
$records = isset($raw_data[0]) ? $raw_data : [$raw_data];
foreach ($records as $record) {
dump($record);
// TODO: 解析 model_list(规格列表)
// 无规格时返回单条记录,有规格时每个 model 返回一条记录
yield $this->mapSingleProduct($record, null);
}
});
}
/**
* 映射单个产品记录
*
* @TODO 待实现:根据 Shopee 实际数据结构完善字段映射
*
* @param array $record 商品主记录
* @param array|null $model 规格记录
* @return array
*/
private function mapSingleProduct(array $record, ?array $model): array
{
$raw = \json_encode($record);
$platform_item_id = (string) ($record['item_id'] ?? '');
$platform_model_id = $model ? (string) ($model['model_id'] ?? '') : null;
return [
'company_id' => $this->getCompany()->id,
'platform_id' => $this->getPlatform()->id,
'store_id' => $this->getStore()->id,
'status_id' => $this->getProductStatusId($record['item_status'] ?? 'NORMAL'),
'type_id' => 1,
'warehouse_id' => null,
'sub_warehouse_id' => null,
'platform_item_id' => $platform_item_id,
'platform_model_id' => $platform_model_id,
'origin_sku_id' => $model['model_sku'] ?? $record['item_sku'] ?? null,
'mapped_sku_id' => null,
'barcode' => null,
'hscode' => null,
'bundled' => null,
'price' => $model['current_price'] ?? $record['price_info']['current_price'] ?? '0.00',
'currency' => $record['price_info']['currency'] ?? 'USD',
'num' => $model['stock_info']['current_stock'] ?? $record['stock_info']['current_stock'] ?? 0,
'url' => null,
'picture' => $record['image']['image_url_list'][0] ?? null,
'name' => $record['item_name'] ?? null,
'raw' => $raw,
'ext' => null,
'hash' => \md5($raw),
'created_date' => isset($record['create_time'])
? Carbon::createFromTimestamp($record['create_time'])
: null,
'updated_date' => isset($record['update_time'])
? Carbon::createFromTimestamp($record['update_time'])
: null,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
];
}
/**
* 获取唯一键字段(对应数据库唯一索引)
*
* 对应数据库约束:
* UNIQUE INDEX orders_store_platform_order_unique (store_id, platform_order_id)
* 获取唯一键字段
*
* @return array
*/
public function getUniqueBy(): array
{
return ['store_id', 'platform_product_id'];
return ['store_id', 'platform_item_id', 'platform_model_id'];
}
/**
* 获取可更新字段列表
*
* 排除:主键、唯一键、创建时间、关联 ID
*
* @return array
*/
public function getUpdateFields(): array
{
// 手动指定(推荐:明确且高效,无数据库查询开销)
return [
'order_status_id',
'payment_method_id',
'buyer_user_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',
'updated_date',
'paid_date',
'shipping_date',
'zipcode',
'city',
'province',
'country',
'status_id',
'type_id',
'warehouse_id',
'sub_warehouse_id',
'origin_sku_id',
'mapped_sku_id',
'barcode',
'hscode',
'bundled',
'price',
'currency',
'num',
'url',
'picture',
'name',
'raw',
'ext',
'hash',
'updated_date',
'updated_at',
];
// 动态计算方案(如果表字段经常变化,可以使用):
// $entity = $this->entityMatch([
// 'company_id' => $this->getCompany()->id,
// 'platform_id' => $this->getPlatform()->id,
// 'store_id' => $this->getStore()->id,
// ]);
// $excludeFields = array_merge(
// ['id', 'created_at', 'created_date', 'company_id', 'platform_id'],
// $this->getUniqueBy()
// );
// return $this->getTableColumnsExcept($entity, $excludeFields);
}
/**
* 根据 Shopee 产品状态确定对应的本地订单状态
* 获取产品状态 ID
*
* @required ProductConsumer 要求实现此方法(第 130-132 行)
* @see \App\Constants\OrderStatus
* 将 Shopee 产品状态映射到本地 ProductStatus 枚举
*
* @param string $platform_order_status Shopee 平台订单状态
* @return int 本地订单状态 ID
* @param string $platform_status Shopee 平台状态
* @return int
*/
public function getProductStatusId(string $platform_order_status): int
public function getProductStatusId(string $platform_status): int
{
}
/**
* Shopee 产品状态到本地产品状态的映射表
*
* @see \App\Platform\Shopee\Constants\ProductStatus Shopee 产品订单状态枚举
* @see \App\Constants\OrderStatus 本地产品状态枚举
*
* @return array<string, int>
*/
private function ProducttatusMap(): array
{
return [
// 未付款 -> 等待付款
'UNPAID' => \App\Constants\OrderStatus::PAYMENT_PENDING->value,
// 可发货(已付款,等待卖家安排发货)-> 付款完成
'READY_TO_SHIP' => \App\Constants\OrderStatus::PAYMENT_COMPLETE->value,
// 已处理(卖家已安排发货并获取物流单号)-> 等待发货
'PROCESSED' => \App\Constants\OrderStatus::AWAITING_SHIPMENT->value,
// 重新发货(3PL 取件失败,需要重新安排发货)-> 等待发货
'RETRY_SHIP' => \App\Constants\OrderStatus::AWAITING_SHIPMENT->value,
// 已发货(包裹已交给 3PL 或已被 3PL 取走)-> 已发货
'SHIPPED' => \App\Constants\OrderStatus::SHIPPED->value,
// 待确认收货(买家已收到订单)-> 已发货
'TO_CONFIRM_RECEIVE' => \App\Constants\OrderStatus::SHIPPED->value,
// 取消中(订单取消正在处理)-> 取消请求中
'IN_CANCEL' => \App\Constants\OrderStatus::CANCEL_REQUESTED->value,
// 已取消 -> 取消确认
'CANCELLED' => \App\Constants\OrderStatus::CANCEL_CONFIRMED->value,
// 退货中(买家请求退货,退货正在处理)-> 取消请求中
'TO_RETURN' => \App\Constants\OrderStatus::CANCEL_REQUESTED->value,
// 已完成 -> 完成
'COMPLETED' => \App\Constants\OrderStatus::FINISHED->value,
$status_map = [
'NORMAL' => ProductStatus::ACTIVE->value,
'BANNED' => ProductStatus::BANNED->value,
'UNLIST' => ProductStatus::INACTIVE->value,
'REVIEWING' => ProductStatus::REVIEWING->value,
'SELLER_DELETE' => ProductStatus::SELLER_DELETE->value,
'SHOPEE_DELETE' => ProductStatus::PLATFORM_DELETE->value,
];
}
return $status_map[$platform_status] ?? ProductStatus::ACTIVE->value;
}
}