From 9c106bf692001b99a07a2788e3af73df1cebae30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=98=8A=E5=A4=A9?= <442384644@qq.com> Date: Fri, 16 Oct 2026 15:15:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E8=AE=A2=E5=8D=95=E5=88=97=E8=A1=A8):=20?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=B3=A8=E5=85=A5=E5=94=AE=E5=90=8E=E5=8D=95?= =?UTF-8?q?=E5=8F=B7=E4=BF=AE=E5=A4=8D=E6=9F=A5=E7=9C=8B=E5=94=AE=E5=90=8E?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 列表与详情两条 order_buttons 组装路径不一致,列表缺 after_sale_no 致 viewAfterSale 跳转报「售后单信息异常」;按订单号一次批量取最新售后单注入按钮参数,避免逐行点查 --- backend/app/dao/order/AfterSaleDao.php | 29 +++++++++++ .../order/OrderCenterUserServices.php | 49 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/backend/app/dao/order/AfterSaleDao.php b/backend/app/dao/order/AfterSaleDao.php index bf0f53b92..5a934ac72 100644 --- a/backend/app/dao/order/AfterSaleDao.php +++ b/backend/app/dao/order/AfterSaleDao.php @@ -155,6 +155,35 @@ class AfterSaleDao extends BaseDao return $model ? (string)($model['after_sale_no'] ?? '') : ''; } + /** + * 批量查询多个订单的最新售后单号 + * 与 getLatestNoByOrderNo 同口径(每单取 id 最大一条),一次查询避免逐单点查 + * @param array $orderNos 订单号数组 + * @return array 返回以 order_no 为键的最新售后单号映射,无售后记录的订单不在结果中 + */ + public function getLatestNoMapByOrderNos(array $orderNos): array + { + if (empty($orderNos)) { + return []; + } + $rows = $this->getModel() + ->whereIn('order_no', $orderNos) + ->where('is_del', 0) + ->order('id DESC') + ->field('order_no, after_sale_no') + ->select() + ->toArray(); + $map = []; + foreach ($rows as $row) { + $orderNo = (string)($row['order_no'] ?? ''); + // 按 id 倒序遍历,每个订单号首次命中即其最新一条售后单 + if ($orderNo !== '' && !isset($map[$orderNo])) { + $map[$orderNo] = (string)($row['after_sale_no'] ?? ''); + } + } + return $map; + } + /** * 统计指定订单的售后数量 * @param string $orderNo diff --git a/backend/app/services/order/OrderCenterUserServices.php b/backend/app/services/order/OrderCenterUserServices.php index 70d969d37..4b28efb23 100644 --- a/backend/app/services/order/OrderCenterUserServices.php +++ b/backend/app/services/order/OrderCenterUserServices.php @@ -3,6 +3,7 @@ declare(strict_types=1); namespace app\services\order; +use app\dao\order\AfterSaleDao; use app\model\order\OrderCenter; use app\services\pay\PayRecordServices; use app\services\order\StoreCartServices; @@ -105,6 +106,10 @@ class OrderCenterUserServices extends OrderCenterServices $item['type_label'] = $this->resolveTypeLabel($item); } + // 为 viewAfterSale 按钮批量注入 after_sale_no(与详情接口 getOrderButtonsFromHandler 同口径) + // 前端 viewAfterSale action 依赖 params.after_sale_no 才能跳转到售后详情页 + $this->injectAfterSaleNoForList($list); + $eventData = ['list' => &$list]; // 触发事件,允许第三方扩展订单列表 event('OrderCenterListExtend', $eventData); @@ -113,6 +118,50 @@ class OrderCenterUserServices extends OrderCenterServices return compact('total', 'list'); } + /** + * 为列表项 viewAfterSale 按钮批量注入 after_sale_no + * 取订单最新一条售后单(不限状态),与详情接口 getOrderButtonsFromHandler 同口径; + * 仅含该按钮的订单才参与查询,按订单号一次批量取回,避免逐行点查 + * @param array $list 订单列表(引用传递,原地补齐按钮参数) + */ + protected function injectAfterSaleNoForList(array &$list): void + { + $orderNos = []; + foreach ($list as $item) { + foreach ($item['order_buttons'] ?? [] as $button) { + if (($button['action'] ?? '') === 'viewAfterSale') { + $orderNos[(string)($item['order_no'] ?? '')] = true; + break; + } + } + } + $orderNos = array_filter(array_keys($orderNos)); + if (empty($orderNos)) { + return; + } + + try { + $map = $this->app->make(AfterSaleDao::class)->getLatestNoMapByOrderNos($orderNos); + } catch (\Throwable $e) { + Log::warning('[OrderCenter] injectAfterSaleNoForList failed: ' . $e->getMessage()); + return; + } + + foreach ($list as &$item) { + $afterSaleNo = $map[(string)($item['order_no'] ?? '')] ?? ''; + if ($afterSaleNo === '') { + continue; + } + foreach ($item['order_buttons'] as &$button) { + if (($button['action'] ?? '') === 'viewAfterSale') { + $button['params'] = array_merge($button['params'] ?? [], ['after_sale_no' => $afterSaleNo]); + } + } + unset($button); + } + unset($item); + } + /** * 批量加载列表项的扩展表子状态 * 按 source_type 分组后一次性查询各扩展表,避免 N+1