diff --git a/docs/配件补发扣款.md b/docs/配件补发扣款.md index 6e05f117..15839847 100644 --- a/docs/配件补发扣款.md +++ b/docs/配件补发扣款.md @@ -17,3 +17,5 @@ - 实际Blade页面检查:分类局部切换、分页、多候选提示、异常金额及手机/桌面布局。 - 导出检查:路由优先级、本页权限、后台鉴权、UTF-8 BOM及公式保护。 - 使用现有数据连接进行了真实业务月份只读匹配及性能验证。 + +首发快递、首发单号、所属月份以独立三列显示,多候选按同一顺序对应。支持交易单号、补发单号、补发快递、补发日期、原始/处理后条码、补发运费、匹配状态、首发快递、首发单号、所属月份及可扣金额筛选;文本和金额支持包含匹配。筛选覆盖全部业务月记录,汇总、分类数量、分页和CSV导出沿用相同条件。多个首发筛选必须由同一候选满足;清空筛选保留业务月份。 diff --git a/modules/EcommerceFinance/View/AccessoryReshipPageData.php b/modules/EcommerceFinance/View/AccessoryReshipPageData.php index 242fa5a1..a52f118e 100644 --- a/modules/EcommerceFinance/View/AccessoryReshipPageData.php +++ b/modules/EcommerceFinance/View/AccessoryReshipPageData.php @@ -15,17 +15,49 @@ class AccessoryReshipPageData $month = request()->query('month', now()->format('Y-m')); abort_unless(is_string($month) && preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $month) && (int) substr($month, 0, 4) >= 2000, 422, '请选择有效业务月份。'); $status = request()->query('match_status', 'matched'); - return ['month' => $month, 'match_status' => in_array($status, ['matched', 'unmatched', 'all'], true) ? $status : 'matched']; + $filters = ['month' => $month, 'match_status' => in_array($status, ['matched', 'unmatched', 'all'], true) ? $status : 'matched']; + foreach (['trade_no','express_no','courier','ship_date','barcode','normalized_barcode','freight','original_courier','original_express_no','original_month','deduction_amount'] as $field) { + $value = request()->query($field, ''); + abort_unless(is_string($value) && mb_strlen($value) <= 200, 422, '筛选条件格式无效。'); + $filters[$field] = trim($value); + } + return $filters; } public function rows(array $filters): \Generator { $start = \Carbon\Carbon::createFromFormat('!Y-m', $filters['month']); foreach ($this->shipping->accessoryReshipBatches($start->format('Y-m-d'), $start->copy()->addMonth()->format('Y-m-d'), $start->copy()->subMonths(2)->format('Y-m-d')) as $batch) { - foreach ($this->matcher->match($batch['accessories'], $batch['originals']) as $row) yield $row; + foreach ($this->matcher->match($batch['accessories'], $batch['originals']) as $row) { + if ($this->matchesFilters($row, $filters)) yield $row; + } } } + public function matchesFilters(array $row, array $filters): bool + { + $values = [ + 'trade_no' => $row['trade_no'], 'express_no' => ($row['express_no'] ?? ''), + 'courier' => ($row['express_name1'] ?? '') ?: ($row['express_name2'] ?? ''), + 'ship_date' => substr((string) ($row['ship_time'] ?? ''), 0, 10), + 'barcode' => $row['barcode'], 'normalized_barcode' => $row['normalized_barcode'], + 'freight' => $row['freight_cents'] === null ? '待核实' : number_format($row['freight_cents'] / 100, 2, '.', ''), + 'deduction_amount' => $row['deduction_cents'] === null ? '待核实' : number_format($row['deduction_cents'] / 100, 2, '.', ''), + ]; + foreach ($values as $field => $value) { + if (($filters[$field] ?? '') !== '' && mb_stripos((string) $value, $filters[$field]) === false) return false; + } + $originalFilters = array_filter(['courier' => $filters['original_courier'] ?? '', 'express_no' => $filters['original_express_no'] ?? '', 'month' => $filters['original_month'] ?? ''], static fn ($value) => $value !== ''); + if (!$originalFilters) return true; + foreach ($row['matches'] as $match) { + foreach ($originalFilters as $field => $value) { + if (mb_stripos((string) $match[$field], $value) === false) continue 2; + } + return true; + } + return false; + } + public function page(): array { $filters = $this->filters(); diff --git a/resources/views/business/pages/courier-payables/accessory-reship-deductions.blade.php b/resources/views/business/pages/courier-payables/accessory-reship-deductions.blade.php index 53d26dbd..8325d9d9 100644 --- a/resources/views/business/pages/courier-payables/accessory-reship-deductions.blade.php +++ b/resources/views/business/pages/courier-payables/accessory-reship-deductions.blade.php @@ -8,9 +8,13 @@
按交易单号及条形码匹配首发快递,核算配件补发运费。
| {{ $heading }} | @endforeach + @foreach (['交易单号','补发快递单号','补发快递','补发日期','原始条形码','处理后条形码','补发运费','匹配状态','首发快递','首发单号','所属月份','可扣金额','说明'] as $heading){{ $heading }} | @endforeach|||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {{ $row['trade_no'] }} | {{ $row['express_no'] }} | {{ $row['express_name1'] ?: $row['express_name2'] }} | {{ substr((string) $row['ship_time'], 0, 10) }} | {{ $row['barcode'] }} | {{ $row['normalized_barcode'] }} | {{ $row['freight_cents'] === null ? '待核实' : number_format($row['freight_cents'] / 100, 2) }} | {{ $row['status'] === 'matched' ? '可扣款' : '未匹配不扣款' }} |
- @forelse ($row['matches'] as $match) {{ $match['courier'] ?: '快递名称待核实' }} @empty — @endforelse
+ @forelse ($row['matches'] as $match){{ $match['express_no'] }} ({{ $match['month'] }}) {{ $match['courier'] ?: '快递名称待核实' }} @empty — @endforelse
+ | @forelse ($row['matches'] as $match) {{ $match['express_no'] }} @empty — @endforelse | @forelse ($row['matches'] as $match) {{ $match['month'] }} @empty — @endforelse
| {{ $row['deduction_cents'] === null ? '待核实' : number_format($row['deduction_cents'] / 100, 2) }} | {{ $row['freight_cents'] === null ? '运费缺失或异常' : (count($row['matches']) > 1 ? '多候选,确认归属后扣款;仅计一次' : ($row['status'] === 'unmatched' ? '三个月内未匹配首发快递单号' : '待核对')) }} |
| {{ $reshipError ?: '当前月份及分类暂无记录,请调整业务月份或分类。' }} | ||||||||||||
| {{ $reshipError ?: '当前筛选条件下暂无记录,请清空筛选或调整业务月份、分类。' }} | ||||||||||||