From 447f60344251ed29f21ca6ff964a59997200b9cd Mon Sep 17 00:00:00 2001
From: zhoushengchen <3057083327@qq.com>
Date: Wed, 2 Sep 2026 12:00:00 +0800
Subject: [PATCH 1/7] feat: add courier surcharge prototype page
---
app/Http/Controllers/Business/Pages.php | 101 ++++++++++++++
config/business_navigation.php | 1 +
.../courier-surcharge.blade.php | 128 ++++++++++++++++++
.../Business/CourierSurchargePageTest.php | 56 ++++++++
4 files changed, 286 insertions(+)
create mode 100644 resources/views/business/pages/courier-payables/courier-surcharge.blade.php
create mode 100644 tests/Feature/Business/CourierSurchargePageTest.php
diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php
index 8c64d641..891bfc9d 100644
--- a/app/Http/Controllers/Business/Pages.php
+++ b/app/Http/Controllers/Business/Pages.php
@@ -447,11 +447,112 @@ class Pages extends Controller
'board-deductions' => $this->contentForBoardDeductions(),
'supplier-payables-report' => $this->contentForSupplierPayablesReport(),
'payable-cloud-warehouse-vehicle-fee' => $this->contentForDingPayableWorkflows(),
+ 'courier-surcharge' => $this->contentForCourierSurcharge(),
'platform-promotion-accounts' => app(PlatformPromotionAccountPageData::class)->content($tab),
default => null,
};
}
+ /**
+ * 快递附加费规则落地原型。
+ *
+ * 这里使用脱敏演示数据,先把文档中的结算模式、判定依据和可结状态
+ * 以页面形式呈现;真实上游镜像接入应沿用独立的同步任务和只读 Repository。
+ */
+ protected function contentForCourierSurcharge(): array
+ {
+ $rows = collect([
+ [
+ 'number' => 'SF20260901001', 'courier' => '曹县德邦', 'type' => '超长费',
+ 'mode' => '一口价判断', 'basis' => '最长边 172 cm > 160 cm,按 8 元/单',
+ 'amount' => 8.00, 'status' => '可结', 'reason' => '',
+ 'dimensions' => '172 × 68 × 54 cm', 'weight' => '36 kg', 'volume' => '0.63 m³',
+ 'returned' => '否', 'source' => '规则配置(演示)',
+ ],
+ [
+ 'number' => 'SF20260901002', 'courier' => '曹县德邦', 'type' => '改地址',
+ 'mode' => '聚工单客服核实', 'basis' => '等待聚工单客服核实明细',
+ 'amount' => 30.00, 'status' => '待核实', 'reason' => '缺少客服核实结果',
+ 'dimensions' => '120 × 45 × 40 cm', 'weight' => '18 kg', 'volume' => '0.22 m³',
+ 'returned' => '否', 'source' => '聚工单(待同步)',
+ ],
+ [
+ 'number' => 'SF20260901003', 'courier' => '常州松宇货运', 'type' => '送货费',
+ 'mode' => '一口价判断', 'basis' => '体积 8.4 m³ ≤ 10 m³,按 50 元/单',
+ 'amount' => 50.00, 'status' => '可结', 'reason' => '',
+ 'dimensions' => '240 × 140 × 250 cm', 'weight' => '420 kg', 'volume' => '8.4 m³',
+ 'returned' => '否', 'source' => '规则配置(演示)',
+ ],
+ [
+ 'number' => 'SF20260901004', 'courier' => '霸州百世快运-雅柏', 'type' => '退回费',
+ 'mode' => '一口价判断', 'basis' => '结算重量 18 kg × 2 元/kg',
+ 'amount' => 36.00, 'status' => '可结', 'reason' => '',
+ 'dimensions' => '110 × 50 × 45 cm', 'weight' => '18 kg', 'volume' => '0.25 m³',
+ 'returned' => '是', 'source' => '规则配置(演示)',
+ ],
+ [
+ 'number' => 'SF20260901005', 'courier' => '北京韵达-佰硕', 'type' => '异形件',
+ 'mode' => '一口价判断', 'basis' => '尺寸/重量未命中当月阶梯标准',
+ 'amount' => 0.00, 'status' => '不可结', 'reason' => '未匹配到有效阶梯价格',
+ 'dimensions' => '205 × 95 × 88 cm', 'weight' => '72 kg', 'volume' => '1.71 m³',
+ 'returned' => '否', 'source' => '规则配置(演示)',
+ ],
+ [
+ 'number' => 'SF20260901006', 'courier' => '菏泽顺帆', 'type' => '发出运费附加',
+ 'mode' => '附加费等于发出运费', 'basis' => '关联发货记录运费 88 元',
+ 'amount' => 88.00, 'status' => '可结', 'reason' => '',
+ 'dimensions' => '100 × 40 × 35 cm', 'weight' => '15 kg', 'volume' => '0.14 m³',
+ 'returned' => '否', 'source' => '发货运费(演示)',
+ ],
+ ]);
+
+ $clean = static fn (mixed $value, int $length = 60): string => mb_substr(trim((string) $value), 0, $length);
+ $filters = [
+ 'keyword' => $clean(request('keyword', ''), 40),
+ 'courier' => $clean(request('courier', ''), 40),
+ 'type' => $clean(request('type', ''), 40),
+ 'mode' => $clean(request('mode', ''), 40),
+ 'status' => $clean(request('status', ''), 20),
+ ];
+ $filtered = $rows->filter(static function (array $row) use ($filters): bool {
+ foreach (['courier', 'type', 'mode', 'status'] as $key) {
+ if ($filters[$key] !== '' && $row[$key] !== $filters[$key]) {
+ return false;
+ }
+ }
+ if ($filters['keyword'] !== ''
+ && ! str_contains($row['number'], $filters['keyword'])
+ && ! str_contains($row['basis'], $filters['keyword'])) {
+ return false;
+ }
+
+ return true;
+ })->values();
+
+ return [
+ 'view' => 'business.pages.courier-payables.courier-surcharge',
+ 'courierSurchargeRows' => $filtered,
+ 'courierSurchargeFilters' => $filters,
+ 'courierSurchargeSummary' => [
+ 'total' => $filtered->count(),
+ 'ready' => $filtered->where('status', '可结')->count(),
+ 'pending' => $filtered->where('status', '待核实')->count(),
+ 'blocked' => $filtered->where('status', '不可结')->count(),
+ 'amount' => $filtered->sum('amount'),
+ ],
+ 'courierSurchargeOptions' => [
+ 'couriers' => $rows->pluck('courier')->unique()->sort()->values(),
+ // 文档定义的十类附加费全部进入筛选器,即使当前演示样例暂未覆盖每一类。
+ 'types' => collect([
+ '退回费', '拦截费', '改地址', '异形件', '超长费',
+ '上楼费', '送货费', '超区费', '安装费', '保费', '发出运费附加',
+ ]),
+ 'modes' => $rows->pluck('mode')->unique()->values(),
+ 'statuses' => ['可结', '待核实', '不可结'],
+ ],
+ ];
+ }
+
protected function contentForDingPayableWorkflows(): array
{
$normalizeDate = static function (mixed $value): string {
diff --git a/config/business_navigation.php b/config/business_navigation.php
index 781fabee..0f3ec568 100644
--- a/config/business_navigation.php
+++ b/config/business_navigation.php
@@ -430,6 +430,7 @@ return [
['slug' => 'compensation-details', 'title' => '赔偿明细'],
['slug' => 'advance-details', 'title' => '借支明细'],
['slug' => 'other-adjustments', 'title' => '其他扣款补款'],
+ ['slug' => 'courier-surcharge', 'title' => '快递附加费'],
['slug' => 'payable-cloud-warehouse-vehicle-fee', 'title' => '应付云仓车费'],
['slug' => 'courier-payables-report', 'title' => '快递应付表'],
],
diff --git a/resources/views/business/pages/courier-payables/courier-surcharge.blade.php b/resources/views/business/pages/courier-payables/courier-surcharge.blade.php
new file mode 100644
index 00000000..da278e5b
--- /dev/null
+++ b/resources/views/business/pages/courier-payables/courier-surcharge.blade.php
@@ -0,0 +1,128 @@
+@php
+ $rows = $courierSurchargeRows ?? collect();
+ $filters = $courierSurchargeFilters ?? [];
+ $summary = $courierSurchargeSummary ?? [];
+ $options = $courierSurchargeOptions ?? [];
+ $statusClass = static fn (string $status): string => match ($status) {
+ '可结' => 'is-ready',
+ '待核实' => 'is-pending',
+ default => 'is-blocked',
+ };
+@endphp
+
+
+
+
+
+
science
+
页面原型 · 演示数据 当前展示的是《快递附加费汇报-9.1.docx》整理出的判定逻辑与脱敏样例,尚未接入共享业务镜像。接入真实数据时,页面将沿用固定只读 Repository、稳定游标和业务镜像。
+
+
+
+
+
当前明细
{{ $summary['total'] ?? 0 }} 条
+
可结
{{ $summary['ready'] ?? 0 }} 条
+
待核实
{{ $summary['pending'] ?? 0 }} 条
+
预计附加费
¥{{ number_format((float) ($summary['amount'] ?? 0), 2) }}
+
+
+
+
tune筛选附加费明细
共 {{ $summary['blocked'] ?? 0 }} 条暂不可结
+
+
+
+
+
account_tree四种结算模式
按快递报价和业务凭证自动选择
+
+
1聚工单客服核实改地址、上楼费、超区费、安装费、保费等,读取客服核实明细。
+
2一口价判断按长宽高、最长边、重量或体积匹配当月固定标准。
+
3等于发出运费附加费直接关联发货记录运费,必要时按双向运费计算。
+
4快递账单结算读取乙方账单,大金额或异常记录转客服复核。
+
+
+
+
+
fact_check判定结果
金额为含税前的演示值,真实金额以业务镜像为准
+
+
+ | 业务单号 | 快递渠道 | 附加费类型 | 结算模式 | 判定依据 | 应付金额 | 状态 | 不可结原因 | 基础字段 | 数据来源 |
+
+ @forelse ($rows as $row)
+
+ | {{ $row['number'] }} | {{ $row['courier'] }} | {{ $row['type'] }} | {{ $row['mode'] }} | {{ $row['basis'] }} | ¥{{ number_format((float) $row['amount'], 2) }} | {{ $row['status'] }} | {{ $row['reason'] ?: '—' }} |
+ 展开尺寸:{{ $row['dimensions'] }} 重量:{{ $row['weight'] }} 体积:{{ $row['volume'] }} 是否退回:{{ $row['returned'] }} | {{ $row['source'] }} |
+
+ @empty
+ 没有符合筛选条件的附加费明细。 |
+ @endforelse
+
+
+
+
+
+
+
+
退回费通用参考:2 元/kg × 结算重量;部分渠道直接取发出运费。
拦截费匹配查件结扣单类型或客服核实;部分渠道按单价,部分渠道按发出运费 × 2。
超长 / 异形件先取最长边,再按当月阶梯标准匹配;超过 160 cm 或 200 cm 的渠道单独计费。
送货费按体积判断,例如 10 立方米以下 50 元/单。
聚工单类改地址、上楼费、超区费、安装费和保费必须有客服核实结果。
双向运费 / 发出运费部分渠道附加费等于发出运费;方建顺心捷达、国荣圆通等拦截费按发出运费 × 2。
账单复核快递账单先读取乙方明细,大金额或异常记录转客服复核。
不可结处理缺少凭证、未命中标准或账单异常时保留原因,进入人工复核队列。
+
+
diff --git a/tests/Feature/Business/CourierSurchargePageTest.php b/tests/Feature/Business/CourierSurchargePageTest.php
new file mode 100644
index 00000000..2d58f8f8
--- /dev/null
+++ b/tests/Feature/Business/CourierSurchargePageTest.php
@@ -0,0 +1,56 @@
+user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
+
+ $this->loginAs()
+ ->get(route('business.pages.show', [
+ 'section' => 'courier-payables',
+ 'page' => 'courier-surcharge',
+ ]))
+ ->assertOk()
+ ->assertSeeText('快递附加费')
+ ->assertSeeText('页面原型 · 演示数据')
+ ->assertSeeText('四种结算模式')
+ ->assertSeeText('聚工单客服核实')
+ ->assertSeeText('一口价判断')
+ ->assertSeeText('附加费等于发出运费')
+ ->assertSeeText('快递账单结算')
+ ->assertSeeText('曹县德邦')
+ ->assertSeeText('超长费')
+ ->assertSeeText('可结')
+ ->assertSeeText('待核实')
+ ->assertSeeText('不可结')
+ ->assertSeeText('拦截费')
+ ->assertSeeText('文档规则速览');
+
+ }
+
+ public function test_courier_surcharge_page_filters_demo_rows_without_touching_a_repository(): void
+ {
+ $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
+
+ $this->loginAs()
+ ->get(route('business.pages.show', [
+ 'section' => 'courier-payables',
+ 'page' => 'courier-surcharge',
+ 'courier' => '常州松宇货运',
+ 'status' => '可结',
+ ]))
+ ->assertOk()
+ ->assertSeeText('常州松宇货运')
+ ->assertSeeText('送货费')
+ ->assertSeeText('¥50.00')
+ ->assertSeeText('当前明细')
+ ->assertDontSee('
曹县德邦 | ', false)
+ ->assertDontSee('霸州百世快运-雅柏 | ', false);
+ }
+}
--
2.47.2
From eec68672718e9163b91f9ed4921ceed1f7272a99 Mon Sep 17 00:00:00 2001
From: zhoushengchen <3057083327@qq.com>
Date: Wed, 2 Sep 2026 13:20:07 +0800
Subject: [PATCH 2/7] feat: reshape surcharge page into quote maintenance
---
app/Http/Controllers/Business/Pages.php | 78 +++----
config/business_navigation.php | 2 +-
.../courier-surcharge.blade.php | 215 +++++++++---------
.../Business/CourierSurchargePageTest.php | 34 +--
4 files changed, 161 insertions(+), 168 deletions(-)
diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php
index 891bfc9d..60b2a205 100644
--- a/app/Http/Controllers/Business/Pages.php
+++ b/app/Http/Controllers/Business/Pages.php
@@ -454,55 +454,49 @@ class Pages extends Controller
}
/**
- * 快递附加费规则落地原型。
+ * 快递附加费报价维护原型。
*
- * 这里使用脱敏演示数据,先把文档中的结算模式、判定依据和可结状态
- * 以页面形式呈现;真实上游镜像接入应沿用独立的同步任务和只读 Repository。
+ * 报价维护与后续附加费结算分开:本页只负责渠道、类型、结算方式、
+ * 计价标准和生效时间的维护展示,结算页将来根据这些规则读取业务镜像。
*/
protected function contentForCourierSurcharge(): array
{
$rows = collect([
[
- 'number' => 'SF20260901001', 'courier' => '曹县德邦', 'type' => '超长费',
- 'mode' => '一口价判断', 'basis' => '最长边 172 cm > 160 cm,按 8 元/单',
- 'amount' => 8.00, 'status' => '可结', 'reason' => '',
- 'dimensions' => '172 × 68 × 54 cm', 'weight' => '36 kg', 'volume' => '0.63 m³',
- 'returned' => '否', 'source' => '规则配置(演示)',
+ 'id' => 'SUR-001', 'courier' => '曹县德邦', 'type' => '超长费',
+ 'mode' => '按尺寸/最长边', 'standard' => '最长边 > 160 cm:8 元/单',
+ 'condition' => '最长边超过 160 cm', 'effective_at' => '2026-09-01',
+ 'status' => '已启用', 'remark' => '大件渠道标准',
],
[
- 'number' => 'SF20260901002', 'courier' => '曹县德邦', 'type' => '改地址',
- 'mode' => '聚工单客服核实', 'basis' => '等待聚工单客服核实明细',
- 'amount' => 30.00, 'status' => '待核实', 'reason' => '缺少客服核实结果',
- 'dimensions' => '120 × 45 × 40 cm', 'weight' => '18 kg', 'volume' => '0.22 m³',
- 'returned' => '否', 'source' => '聚工单(待同步)',
+ 'id' => 'SUR-002', 'courier' => '曹县德邦', 'type' => '拦截费',
+ 'mode' => '固定单价', 'standard' => '20 元/单(小件)',
+ 'condition' => '查件结扣单类型=拦截', 'effective_at' => '2026-09-01',
+ 'status' => '已启用', 'remark' => '小件渠道适用',
],
[
- 'number' => 'SF20260901003', 'courier' => '常州松宇货运', 'type' => '送货费',
- 'mode' => '一口价判断', 'basis' => '体积 8.4 m³ ≤ 10 m³,按 50 元/单',
- 'amount' => 50.00, 'status' => '可结', 'reason' => '',
- 'dimensions' => '240 × 140 × 250 cm', 'weight' => '420 kg', 'volume' => '8.4 m³',
- 'returned' => '否', 'source' => '规则配置(演示)',
+ 'id' => 'SUR-003', 'courier' => '常州松宇货运', 'type' => '送货费',
+ 'mode' => '按体积', 'standard' => '体积 ≤ 10 m³:50 元/单',
+ 'condition' => '计费体积不超过 10 m³', 'effective_at' => '2026-09-01',
+ 'status' => '已启用', 'remark' => '送货上门费用',
],
[
- 'number' => 'SF20260901004', 'courier' => '霸州百世快运-雅柏', 'type' => '退回费',
- 'mode' => '一口价判断', 'basis' => '结算重量 18 kg × 2 元/kg',
- 'amount' => 36.00, 'status' => '可结', 'reason' => '',
- 'dimensions' => '110 × 50 × 45 cm', 'weight' => '18 kg', 'volume' => '0.25 m³',
- 'returned' => '是', 'source' => '规则配置(演示)',
+ 'id' => 'SUR-004', 'courier' => '霸州百世快运-雅柏', 'type' => '退回费',
+ 'mode' => '按重量', 'standard' => '2 元/kg',
+ 'condition' => '退回件,按结算重量计费', 'effective_at' => '2026-09-01',
+ 'status' => '已启用', 'remark' => '退回费通用标准',
],
[
- 'number' => 'SF20260901005', 'courier' => '北京韵达-佰硕', 'type' => '异形件',
- 'mode' => '一口价判断', 'basis' => '尺寸/重量未命中当月阶梯标准',
- 'amount' => 0.00, 'status' => '不可结', 'reason' => '未匹配到有效阶梯价格',
- 'dimensions' => '205 × 95 × 88 cm', 'weight' => '72 kg', 'volume' => '1.71 m³',
- 'returned' => '否', 'source' => '规则配置(演示)',
+ 'id' => 'SUR-005', 'courier' => '常州德邦', 'type' => '上楼费',
+ 'mode' => '聚工单客服核实', 'standard' => '读取聚工单附加费明细',
+ 'condition' => '存在客服核实的上楼工单', 'effective_at' => '2026-09-01',
+ 'status' => '已启用', 'remark' => '不在本页直接填写金额',
],
[
- 'number' => 'SF20260901006', 'courier' => '菏泽顺帆', 'type' => '发出运费附加',
- 'mode' => '附加费等于发出运费', 'basis' => '关联发货记录运费 88 元',
- 'amount' => 88.00, 'status' => '可结', 'reason' => '',
- 'dimensions' => '100 × 40 × 35 cm', 'weight' => '15 kg', 'volume' => '0.14 m³',
- 'returned' => '否', 'source' => '发货运费(演示)',
+ 'id' => 'SUR-006', 'courier' => '方建顺心捷达', 'type' => '拦截费',
+ 'mode' => '发出运费倍数', 'standard' => '发出运费 × 2',
+ 'condition' => '拦截成功,关联发出运费', 'effective_at' => '2026-09-01',
+ 'status' => '已启用', 'remark' => '双向运费',
],
]);
@@ -521,8 +515,10 @@ class Pages extends Controller
}
}
if ($filters['keyword'] !== ''
- && ! str_contains($row['number'], $filters['keyword'])
- && ! str_contains($row['basis'], $filters['keyword'])) {
+ && ! str_contains($row['courier'], $filters['keyword'])
+ && ! str_contains($row['type'], $filters['keyword'])
+ && ! str_contains($row['standard'], $filters['keyword'])
+ && ! str_contains($row['condition'], $filters['keyword'])) {
return false;
}
@@ -535,10 +531,10 @@ class Pages extends Controller
'courierSurchargeFilters' => $filters,
'courierSurchargeSummary' => [
'total' => $filtered->count(),
- 'ready' => $filtered->where('status', '可结')->count(),
- 'pending' => $filtered->where('status', '待核实')->count(),
- 'blocked' => $filtered->where('status', '不可结')->count(),
- 'amount' => $filtered->sum('amount'),
+ 'active' => $filtered->where('status', '已启用')->count(),
+ 'inactive' => $filtered->where('status', '已停用')->count(),
+ 'couriers' => $filtered->pluck('courier')->unique()->count(),
+ 'types' => $filtered->pluck('type')->unique()->count(),
],
'courierSurchargeOptions' => [
'couriers' => $rows->pluck('courier')->unique()->sort()->values(),
@@ -547,8 +543,8 @@ class Pages extends Controller
'退回费', '拦截费', '改地址', '异形件', '超长费',
'上楼费', '送货费', '超区费', '安装费', '保费', '发出运费附加',
]),
- 'modes' => $rows->pluck('mode')->unique()->values(),
- 'statuses' => ['可结', '待核实', '不可结'],
+ 'modes' => collect(['固定单价', '按重量', '按体积', '按尺寸/最长边', '聚工单客服核实', '取发出运费', '发出运费倍数', '按账单']),
+ 'statuses' => ['已启用', '已停用'],
],
];
}
diff --git a/config/business_navigation.php b/config/business_navigation.php
index 0f3ec568..cfdb968c 100644
--- a/config/business_navigation.php
+++ b/config/business_navigation.php
@@ -430,7 +430,7 @@ return [
['slug' => 'compensation-details', 'title' => '赔偿明细'],
['slug' => 'advance-details', 'title' => '借支明细'],
['slug' => 'other-adjustments', 'title' => '其他扣款补款'],
- ['slug' => 'courier-surcharge', 'title' => '快递附加费'],
+ ['slug' => 'courier-surcharge', 'title' => '附加费报价维护'],
['slug' => 'payable-cloud-warehouse-vehicle-fee', 'title' => '应付云仓车费'],
['slug' => 'courier-payables-report', 'title' => '快递应付表'],
],
diff --git a/resources/views/business/pages/courier-payables/courier-surcharge.blade.php b/resources/views/business/pages/courier-payables/courier-surcharge.blade.php
index da278e5b..ecf3570c 100644
--- a/resources/views/business/pages/courier-payables/courier-surcharge.blade.php
+++ b/resources/views/business/pages/courier-payables/courier-surcharge.blade.php
@@ -3,126 +3,123 @@
$filters = $courierSurchargeFilters ?? [];
$summary = $courierSurchargeSummary ?? [];
$options = $courierSurchargeOptions ?? [];
- $statusClass = static fn (string $status): string => match ($status) {
- '可结' => 'is-ready',
- '待核实' => 'is-pending',
- default => 'is-blocked',
- };
+ $statusClass = static fn (string $status): string => $status === '已启用' ? 'is-active' : 'is-inactive';
@endphp
-
+
-
-
science
-
页面原型 · 演示数据 当前展示的是《快递附加费汇报-9.1.docx》整理出的判定逻辑与脱敏样例,尚未接入共享业务镜像。接入真实数据时,页面将沿用固定只读 Repository、稳定游标和业务镜像。
+
edit_note附加费报价维护原型 · 演示数据 先维护“快递 + 附加费类型 + 结算方式 + 标准 + 生效条件”,后续结算页面将按启用中的报价规则计算。当前新增、编辑和启停操作只在本页演示,刷新后恢复样例,尚未写入共享业务镜像。
+
+
+
+
当前规则
{{ $summary['total'] ?? 0 }} 条
+
已启用
{{ $summary['active'] ?? 0 }} 条
+
已停用
{{ $summary['inactive'] ?? 0 }} 条
+
覆盖快递
{{ $summary['couriers'] ?? 0 }} 家
-
-
-
当前明细
{{ $summary['total'] ?? 0 }} 条
-
可结
{{ $summary['ready'] ?? 0 }} 条
-
待核实
{{ $summary['pending'] ?? 0 }} 条
-
预计附加费
¥{{ number_format((float) ($summary['amount'] ?? 0), 2) }}
-
-
-
-
tune筛选附加费明细
共 {{ $summary['blocked'] ?? 0 }} 条暂不可结
-