From 28f99acebc1da4f74aa3d419662f682fe49eecbe Mon Sep 17 00:00:00 2001
From: zhoushengchen <3057083327@qq.com>
Date: Wed, 23 Sep 2026 16:41:22 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=86=E9=99=84=E5=8A=A0=E8=B4=B9?=
=?UTF-8?q?=E6=8A=A5=E4=BB=B7=E5=92=8C=E7=BB=93=E7=AE=97=E6=95=B4=E5=90=88?=
=?UTF-8?q?=E4=B8=BA=E5=90=8C=E4=B8=80=E5=85=A5=E5=8F=A3=E7=9A=84=E4=B8=A4?=
=?UTF-8?q?=E4=B8=AA=E9=A1=B5=E7=AD=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
(cherry picked from commit a83347aef3c9069df2f521df9b4cbe1096255a33)
---
app/Http/Controllers/Business/Pages.php | 45 +++-
config/business_navigation.php | 9 +-
.../courier-surcharge-settlement.blade.php | 201 ++++++++++++++++++
.../courier-surcharge-workspace.blade.php | 63 ++++++
.../Business/CourierSurchargePageTest.php | 3 +-
.../CourierSurchargeSettlementPageTest.php | 93 ++++++++
6 files changed, 401 insertions(+), 13 deletions(-)
create mode 100644 resources/views/business/pages/courier-payables/courier-surcharge-settlement.blade.php
create mode 100644 resources/views/business/pages/courier-payables/courier-surcharge-workspace.blade.php
create mode 100644 tests/Feature/Business/CourierSurchargeSettlementPageTest.php
diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php
index 907d6cc6..e0e96ec9 100644
--- a/app/Http/Controllers/Business/Pages.php
+++ b/app/Http/Controllers/Business/Pages.php
@@ -324,6 +324,15 @@ class Pages extends Controller
abort_if(empty($sectionConfig), 403, '当前账号没有该页面权限。');
+ // Keep the old direct URL working after settlement becomes a tab.
+ if ($section === 'courier-payables' && $page === 'courier-surcharge-settlement') {
+ return redirect()->route('business.pages.show', array_merge(request()->query(), [
+ 'section' => $section,
+ 'page' => 'courier-surcharge',
+ 'tab' => 'settlement',
+ ]));
+ }
+
$pages = collect($sectionConfig['pages'] ?? []);
if ($pages->isEmpty()) {
@@ -390,6 +399,18 @@ class Pages extends Controller
}
if ($tab === null) {
+ if ($page === 'courier-surcharge') {
+ $activeTab = $tabs->first();
+
+ return view('business.pages.show', $this->viewData(
+ $sectionConfig,
+ $pageConfig,
+ $tabs,
+ $activeTab,
+ $this->resolveContent($page, $activeTab['slug']),
+ ));
+ }
+
return $this->redirectToPage($sectionConfig, $pageConfig);
}
@@ -2645,7 +2666,7 @@ class Pages extends Controller
'online-daifa-price' => $this->contentForOnlineDaifaPrice(),
'product-costs' => $this->contentForProductCosts(),
'financial-analysis' => $this->contentForFinancialAnalysis(),
- 'courier-surcharge' => $this->contentForCourierSurcharge(),
+ 'courier-surcharge' => $this->contentForCourierSurcharge($tab),
'freight-difference', 'other-surcharge-summary', 'return-fee' => $this->contentForCourierPayableSummary($page),
'shipping-data' => $this->contentForShippingData(),
'return-pickup-management' => $this->contentForReturnPickupManagement(),
@@ -3644,24 +3665,26 @@ class Pages extends Controller
];
}
- protected function contentForCourierSurcharge(): array
+ protected function contentForCourierSurcharge(?string $tab = null): array
{
$clean = static fn (mixed $value, int $length = 60): string => mb_substr(trim((string) $value), 0, $length);
+ $quoteInput = $tab === 'settlement' ? [] : request()->query();
$filters = [
- 'keyword' => $clean(request('keyword', ''), 40),
- 'courier' => $clean(request('courier', ''), 40),
- 'type' => $clean(request('type', ''), 40),
- 'mode' => $clean(request('mode', ''), 40),
- 'scope' => $clean(request('scope', ''), 20),
- 'reconciler' => $clean(request('reconciler', ''), 40),
- 'supplier' => $clean(request('supplier', ''), 191),
- 'status' => $clean(request('status', ''), 20),
+ 'keyword' => $clean($quoteInput['keyword'] ?? '', 40),
+ 'courier' => $clean($quoteInput['courier'] ?? '', 40),
+ 'type' => $clean($quoteInput['type'] ?? '', 40),
+ 'mode' => $clean($quoteInput['mode'] ?? '', 40),
+ 'scope' => $clean($quoteInput['scope'] ?? '', 20),
+ 'reconciler' => $clean($quoteInput['reconciler'] ?? '', 40),
+ 'supplier' => $clean($quoteInput['supplier'] ?? '', 191),
+ 'status' => $clean($quoteInput['status'] ?? '', 20),
];
$data = $this->courierSurchargeQuotes->pageData($filters);
$auditReady = $this->courierSurchargeAudits->ready();
return [
- 'view' => 'business.pages.courier-payables.courier-surcharge',
+ 'view' => 'business.pages.courier-payables.courier-surcharge-workspace',
+ 'courierSurchargeActiveTab' => $tab ?? 'quotes',
'courierSurchargeRows' => $data['rows'],
'courierSurchargeFilters' => $filters,
'courierSurchargeSummary' => $data['summary'],
diff --git a/config/business_navigation.php b/config/business_navigation.php
index bed51c82..37e03707 100644
--- a/config/business_navigation.php
+++ b/config/business_navigation.php
@@ -712,7 +712,14 @@ $navigation = [
['slug' => 'compensation-details', 'title' => '赔偿明细'],
['slug' => 'advance-details', 'title' => '借支明细'],
['slug' => 'other-adjustments', 'title' => '其他扣款补款'],
- ['slug' => 'courier-surcharge', 'title' => '附加费报价维护'],
+ [
+ 'slug' => 'courier-surcharge',
+ 'title' => '附加费报价维护',
+ 'tabs' => [
+ ['slug' => 'quotes', 'title' => '附加费报价'],
+ ['slug' => 'settlement', 'title' => '附加费结算'],
+ ],
+ ],
['slug' => 'payable-cloud-warehouse-vehicle-fee', 'title' => '应付云仓车费'],
['slug' => 'courier-payables-report', 'title' => '快递应付表'],
['slug' => 'freight-difference', 'title' => '运费差'],
diff --git a/resources/views/business/pages/courier-payables/courier-surcharge-settlement.blade.php b/resources/views/business/pages/courier-payables/courier-surcharge-settlement.blade.php
new file mode 100644
index 00000000..20069ec9
--- /dev/null
+++ b/resources/views/business/pages/courier-payables/courier-surcharge-settlement.blade.php
@@ -0,0 +1,201 @@
+@php
+ $rows = $courierSurchargeSettlementRows ?? collect();
+ $columns = [
+ ['key' => 'courier_name', 'label' => '快递名称', 'fixed' => 'true'],
+ ['key' => 'waybill', 'label' => '单号'],
+ ['key' => 'platform_product_id', 'label' => '平台商品ID'],
+ ['key' => 'product_code', 'label' => '商品编码'],
+ ['key' => 'shop_name', 'label' => '店铺名称'],
+ ['key' => 'online_order_no', 'label' => '线上订单号'],
+ ['key' => 'length', 'label' => '长'],
+ ['key' => 'width', 'label' => '宽'],
+ ['key' => 'height', 'label' => '高'],
+ ['key' => 'volume', 'label' => '体积'],
+ ['key' => 'inspection_type', 'label' => '查件类型'],
+ ['key' => 'inspection_original', 'label' => '查件原件'],
+ ['key' => 'return_waybill_no', 'label' => '退回单号'],
+ ['key' => 'settlement_weight', 'label' => '结算重量'],
+ ['key' => 'settlement_amount', 'label' => '结算金额', 'fixed' => 'end'],
+ ];
+ $filterValue = static fn (string $key): string => trim((string) request()->query($key, ''));
+ $displayValue = static function (mixed $value, string $key): string {
+ if ($value === null || $value === '') {
+ return '—';
+ }
+
+ if ($key === 'settlement_amount' && is_numeric($value)) {
+ return number_format((float) $value, 2, '.', '');
+ }
+
+ return (string) $value;
+ };
+@endphp
+
+
+
+
+ @foreach ($columns as $column)
+
+
+ @forelse ($rows as $row)
+ {{ $column['label'] }}
+ @endforeach
+
+ @foreach ($columns as $column)
+
+ @empty
+ {{ $displayValue(data_get($row, $column['key']), $column['key']) }}
+ @endforeach
+
+ @endforelse
+
+