From 066066b2ac7b825fe2d9543ef17907546da2a77b Mon Sep 17 00:00:00 2001 From: Nick Zeng Date: Wed, 11 Feb 2026 10:52:01 +0800 Subject: [PATCH] update shopee refund parse --- .../Platform/Shopee/EntityParse/Refund.php | 168 ++++++++++++++---- 1 file changed, 130 insertions(+), 38 deletions(-) diff --git a/backend/app/Platform/Shopee/EntityParse/Refund.php b/backend/app/Platform/Shopee/EntityParse/Refund.php index f2f9810..8d58255 100644 --- a/backend/app/Platform/Shopee/EntityParse/Refund.php +++ b/backend/app/Platform/Shopee/EntityParse/Refund.php @@ -8,6 +8,7 @@ use App\Constants\RefundStatus; use App\Constants\RefundType; use App\Platform\Shopee\Constants\ReturnStatus as ShopeeReturnStatus; use App\Model\Company; +use App\Model\Order; use App\Model\Store; use App\Entity\Parse\EntityParse; use Carbon\Carbon; @@ -22,6 +23,12 @@ use InvalidArgumentException; */ class Refund extends EntityParse { + /** + * 缓存 entityMap 中查询到的订单日期映射,供 formatRefundItemsFromRaw 复用 + * [store_id:platform_order_id => ['order_created_date' => ..., 'order_paid_date' => ...]] + */ + protected array $orderDatesMap = []; + /** * 公司作用域匹配 * @@ -82,44 +89,47 @@ class Refund extends EntityParse */ public function entityMap(array $raw_data): LazyCollection { - return LazyCollection::make(function () use ($raw_data) { - $records = isset($raw_data[0]) ? $raw_data : [$raw_data]; - $tz = $this->getStore()->getTimezoneString(); + $records = isset($raw_data[0]) ? $raw_data : [$raw_data]; + $tz = $this->getStore()->getTimezoneString(); + $mapped = []; - foreach ($records as $record) { - $raw = \json_encode($record); - $refund_amount = (float) ($record['refund_amount'] ?? 0); + foreach ($records as $record) { + $raw = \json_encode($record); + $refund_amount = (float) ($record['refund_amount'] ?? 0); - yield [ - 'company_id' => $this->getCompany()->id, - 'platform_id' => $this->getPlatform()->id, - 'store_id' => $this->getStore()->id, - 'order_id' => $record['t_order_id'] ?? null, - 'platform_order_id' => $record['order_sn'], - 'platform_refund_id' => $record['return_sn'], - 'refund_status_id' => $this->getRefundStatusId($record['status']), - 'refund_type_id' => $this->getRefundTypeId($record), - 'reason' => $record['text_reason'] ?? $record['reason'] ?? null, - 'refund_amount' => $refund_amount, - 'freight_refund' => 0, - 'refund_total' => $refund_amount, - 'currency' => $record['currency'] ?? 'USD', - 'buyer_user_id' => $record['user']['username'] ?? null, - 'order_created_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), - 'order_paid_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), - 'created_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), - 'updated_date' => isset($record['update_time']) ? Carbon::createFromTimestamp($record['update_time'], $tz)->format('Y-m-d H:i:sP') : null, - 'completed_date' => ($record['status'] === 'CLOSED' || $record['status'] === 'ACCEPTED') && isset($record['update_time']) - ? Carbon::createFromTimestamp($record['update_time'], $tz)->format('Y-m-d H:i:sP') - : null, - 'raw' => $raw, - 'ext' => null, - 'hash' => \md5($raw), - 'created_at' => Carbon::now()->format('Y-m-d H:i:sP'), - 'updated_at' => Carbon::now()->format('Y-m-d H:i:sP'), - ]; - } - }); + $mapped[] = [ + 'company_id' => $this->getCompany()->id, + 'platform_id' => $this->getPlatform()->id, + 'store_id' => $this->getStore()->id, + 'order_id' => $record['t_order_id'] ?? null, + 'platform_order_id' => $record['order_sn'], + 'platform_refund_id' => $record['return_sn'], + 'refund_status_id' => $this->getRefundStatusId($record['status']), + 'refund_type_id' => $this->getRefundTypeId($record), + 'reason' => $record['text_reason'] ?? $record['reason'] ?? null, + 'refund_amount' => $refund_amount, + 'freight_refund' => 0, + 'refund_total' => $refund_amount, + 'currency' => $record['currency'] ?? 'USD', + 'buyer_user_id' => $record['user']['username'] ?? null, + 'order_created_date' => null, + 'order_paid_date' => null, + 'created_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), + 'updated_date' => isset($record['update_time']) ? Carbon::createFromTimestamp($record['update_time'], $tz)->format('Y-m-d H:i:sP') : null, + 'completed_date' => ($record['status'] === 'CLOSED' || $record['status'] === 'ACCEPTED') && isset($record['update_time']) + ? Carbon::createFromTimestamp($record['update_time'], $tz)->format('Y-m-d H:i:sP') + : null, + 'raw' => $raw, + 'ext' => null, + 'hash' => \md5($raw), + 'created_at' => Carbon::now()->format('Y-m-d H:i:sP'), + 'updated_at' => Carbon::now()->format('Y-m-d H:i:sP'), + ]; + } + + $mapped = $this->fillOrderDates($mapped); + + return LazyCollection::make($mapped); } /** @@ -148,6 +158,8 @@ class Refund extends EntityParse 'freight_refund', 'refund_total', 'buyer_user_id', + 'order_created_date', + 'order_paid_date', 'updated_date', 'completed_date', 'raw', @@ -198,8 +210,8 @@ class Refund extends EntityParse 'platform_product_id' => strval($item['item_id']), 'quantity' => $item['amount'] ?? 0, 'refund_amount' => (float) ($item['refund_amount'] ?? 0), - 'order_created_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), - 'order_paid_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), + 'order_created_date' => $this->orderDatesMap[$this->getStore()->id . ':' . $record['order_sn']]['order_created_date'] ?? null, + 'order_paid_date' => $this->orderDatesMap[$this->getStore()->id . ':' . $record['order_sn']]['order_paid_date'] ?? null, 'created_date' => Carbon::createFromTimestamp($record['create_time'], $tz)->format('Y-m-d H:i:sP'), 'updated_date' => isset($record['update_time']) ? Carbon::createFromTimestamp($record['update_time'], $tz)->format('Y-m-d H:i:sP') : null, 'completed_date' => ($record['status'] === 'CLOSED' || $record['status'] === 'ACCEPTED') && isset($record['update_time']) @@ -216,6 +228,86 @@ class Refund extends EntityParse return $items; } + /** + * 根据退款子项的 store_id + platform_order_id 查询订单, + * 将 order_created_date 和 order_paid_date 填入 $items 数组 + * + * @param array $items 数据数组(refunds 或 refund_items) + * @return array 填充了订单日期的数组 + */ + protected function fillOrderDates(array $items): array + { + // 收集尚未缓存的 lookup 条件 + $lookups = []; + foreach ($items as $item) { + $key = $item['store_id'] . ':' . $item['platform_order_id']; + if (!isset($this->orderDatesMap[$key]) && !isset($lookups[$key])) { + $lookups[$key] = [ + 'store_id' => $item['store_id'], + 'platform_order_id' => $item['platform_order_id'], + 'created_date' => $item['created_date'], + ]; + } + } + + // 仅查询未缓存的部分 + if (!empty($lookups)) { + $newDates = $this->queryOrderDates($lookups); + $this->orderDatesMap = array_merge($this->orderDatesMap, $newDates); + dump("Matched " . count($newDates) . " orders for " . count($lookups) . " refund item lookups"); + } + + foreach ($items as &$item) { + $key = $item['store_id'] . ':' . $item['platform_order_id']; + if (isset($this->orderDatesMap[$key])) { + $item['order_created_date'] = $this->orderDatesMap[$key]['order_created_date']; + $item['order_paid_date'] = $this->orderDatesMap[$key]['order_paid_date']; + } + } + unset($item); + + return $items; + } + + /** + * 根据 store_id + platform_order_id 批量查询订单的创建时间和付款时间 + * + * shopee 平台订单周期长,搜索周期改为 4 个月 + * 订单搜索范围:[退款 created_date - 4个月, 退款 created_date] + * + * @param array $lookups [key => ['store_id', 'platform_order_id', 'created_date']] + * @return array [store_id:platform_order_id => ['order_created_date' => ..., 'order_paid_date' => ...]] + */ + protected function queryOrderDates(array $lookups): array + { + $orders = Order::query() + ->where(function ($query) use ($lookups) { + foreach ($lookups as $lookup) { + $createdDate = Carbon::parse($lookup['created_date']); + $query->orWhere(function ($q) use ($lookup, $createdDate) { + $q->where('store_id', $lookup['store_id']) + ->where('platform_order_id', $lookup['platform_order_id']) + ->whereBetween('created_date', [ + $createdDate->copy()->subMonths(4), + $createdDate, + ]); + }); + } + }) + ->get(['store_id', 'platform_order_id', 'created_date', 'paid_date']); + + $map = []; + foreach ($orders as $order) { + $key = $order->store_id . ':' . $order->platform_order_id; + $map[$key] = [ + 'order_created_date' => $order->created_date, + 'order_paid_date' => $order->paid_date, + ]; + } + + return $map; + } + /** * 将 Shopee 退款状态映射为系统退款状态 ID *