diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php index e00dd173..dc234aaa 100644 --- a/app/Http/Controllers/Business/Pages.php +++ b/app/Http/Controllers/Business/Pages.php @@ -4100,8 +4100,12 @@ class Pages extends Controller })); } - // 货款/退货明细较宽,固定每页 15 行,减少纵向滚动并保持横向核对区稳定。 - $perPage = in_array($dataset, ['payment-reconciliation', 'return-reconciliation'], true) ? 15 : 50; + // 宽表固定每页 15 行,减少纵向滚动并保持横向核对区稳定。 + $perPage = in_array($dataset, [ + 'payment-reconciliation', + 'return-reconciliation', + 'supplier-payables-report', + ], true) ? 15 : 50; $currentPage = max((int) request('page', 1), 1); return [ diff --git a/resources/views/business/pages/partials/final-dataset-table.blade.php b/resources/views/business/pages/partials/final-dataset-table.blade.php index 251736b7..3f782fbe 100644 --- a/resources/views/business/pages/partials/final-dataset-table.blade.php +++ b/resources/views/business/pages/partials/final-dataset-table.blade.php @@ -9,6 +9,8 @@ $finalKeyword = $payablesFinal['keyword'] ?? ''; $finalActions = $payablesFinal['actions'] ?? ''; $finalMaintenance = ['dataset' => $finalDataset, 'fields' => $finalFields]; + $freezeThroughSupplier = $finalDataset === 'supplier-payables-report'; + $freezeThroughSupplierFields = ['summary_month', 'checker', 'settlement_method', 'company', 'supplier']; @endphp
@@ -42,6 +44,15 @@ .payables-final-table .is-number { text-align: right; } .payables-final-table .is-empty td { height: 8rem; color: var(--vip-content-muted, #595959); text-align: center; } .payables-final-pagination { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.75rem 1rem; color: var(--vip-content-muted, #595959); font-size: 0.8125rem; } + .payables-final-table--freeze-through-supplier { border-collapse: separate; border-spacing: 0; } + .payables-final-table--freeze-through-supplier th, + .payables-final-table--freeze-through-supplier td { border-right: 1px solid var(--vip-border, #D8D2C7); } + .payables-final-table--freeze-through-supplier th:last-child, + .payables-final-table--freeze-through-supplier td:last-child { border-right: 0; } + .payables-final-table--freeze-through-supplier tbody tr:hover td { background: #FBF8F0; } + .payables-final-freeze-column { position: sticky; z-index: 1; background: var(--vip-surface, #FFFFFF); } + .payables-final-table thead .payables-final-freeze-column { z-index: 3; background: var(--vip-content-accent-soft, #F7F0DE); } + .payables-final-freeze-edge { box-shadow: inset -2px 0 0 var(--vip-content-accent, #B9954F); }
@@ -77,12 +88,26 @@
- +
$freezeThroughSupplier, + ])> - + @foreach ($finalFields as $field) - + @php $freezeField = $freezeThroughSupplier && in_array($field['name'], $freezeThroughSupplierFields, true); @endphp + @endforeach @@ -90,10 +115,21 @@ @forelse ($finalRows ?? [] as $index => $row) - + @foreach ($finalFields as $field) @php $value = $row[$field['name']] ?? null; @endphp -
序号 $freezeThroughSupplier]) + >序号 $field['type'] === 'number'])>{{ $field['label'] }} $field['type'] === 'number', + 'payables-final-freeze-column' => $freezeField, + 'payables-final-freeze-edge' => $freezeThroughSupplier && $field['name'] === 'supplier', + ]) + >{{ $field['label'] }}
{{ ($finalRows->firstItem() ?? 1) + $index }} $freezeThroughSupplier]) + >{{ ($finalRows->firstItem() ?? 1) + $index }} $field['type'] === 'number'])> + @php $freezeField = $freezeThroughSupplier && in_array($field['name'], $freezeThroughSupplierFields, true); @endphp + $field['type'] === 'number', + 'payables-final-freeze-column' => $freezeField, + 'payables-final-freeze-edge' => $freezeThroughSupplier && $field['name'] === 'supplier', + ]) + > @if ($value === null || $value === '') - @elseif ($field['type'] === 'number' && is_numeric($value)) @@ -119,7 +155,7 @@ 上一页 @endif 第 {{ $finalRows?->currentPage() ?? 1 }} 页 / 共 {{ $finalRows?->lastPage() ?? 1 }} 页 - · 每页 {{ $finalRows?->perPage() ?? (in_array($finalDataset, ['payment-reconciliation', 'return-reconciliation'], true) ? 15 : 50) }} 条 + · 每页 {{ $finalRows?->perPage() ?? (in_array($finalDataset, ['payment-reconciliation', 'return-reconciliation', 'supplier-payables-report'], true) ? 15 : 50) }} 条 @if ($finalRows?->hasMorePages()) 下一页 @endif @@ -128,6 +164,51 @@ +@if ($freezeThroughSupplier) + +@endif + @include('business.pages.supplier-payables.maintenance-blade-modal', [ 'content' => ['supplierPayableMaintenance' => $finalMaintenance], 'supplierMaintenanceAction' => $finalActions, diff --git a/tests/Feature/Business/SupplierPayableFinalPagesTest.php b/tests/Feature/Business/SupplierPayableFinalPagesTest.php index 954453f1..5ed99193 100644 --- a/tests/Feature/Business/SupplierPayableFinalPagesTest.php +++ b/tests/Feature/Business/SupplierPayableFinalPagesTest.php @@ -295,6 +295,53 @@ class SupplierPayableFinalPagesTest extends FeatureTestCase ->assertDontSeeText('PM-01'); } + public function test_final_supplier_payables_report_paginates_and_freezes_through_supplier(): void + { + $records = []; + for ($index = 1; $index <= 20; $index++) { + $records[sprintf('supplier-payable:%02d', $index)] = [ + 'summary_month' => '2026-09', + 'checker' => sprintf('对账人%02d', $index), + 'settlement_method' => '月结', + 'company' => sprintf('供应商主体%02d', $index), + 'supplier' => sprintf('SUP-%02d', $index), + 'express_freight' => '0', + ]; + } + app(SupplierPayableOverrideStore::class)->saveBatch( + 'final:supplier:supplier-payables-report', + $records, + (int) $this->company->id, + (int) $this->user->id, + ); + + $baseUrl = route('business.pages.show', [ + 'company_id' => (int) $this->company->id, + 'section' => 'supplier-payables-final', + 'page' => 'supplier-payables-report', + ]); + $url = fn (int $page): string => $baseUrl . '?page=' . $page; + + $this->loginAs()->get($url(1)) + ->assertOk() + ->assertSee('payables-final-table--freeze-through-supplier', false) + ->assertSee('data-final-column="summary_month"', false) + ->assertSee('data-final-column="supplier"', false) + ->assertSee('payables-final-freeze-edge', false) + ->assertSee('data-caiwu-replay', false) + ->assertSeeText('每页 15 条') + ->assertSeeText('第 1 页 / 共 2 页') + ->assertSeeText('SUP-01') + ->assertDontSeeText('SUP-16'); + + $this->loginAs()->get($url(2)) + ->assertOk() + ->assertSeeText('第 2 页 / 共 2 页') + ->assertSeeText('SUP-16') + ->assertSeeText('SUP-20') + ->assertDontSeeText('SUP-01'); + } + public function test_final_import_reads_files_larger_than_one_chunk(): void { $lines = ['月份,入库单号,采购单号,日期,供应商,货号,商品编码,规格名称,数量,单价,金额,预估单价,预估金额,供应商商品编码,备注,仓库名称,快递名称,快递单号,未发出,对账人'];