diff --git a/app/Business/CourierPayableSummaryStore.php b/app/Business/CourierPayableSummaryStore.php index ffe12e9e..66af5a21 100644 --- a/app/Business/CourierPayableSummaryStore.php +++ b/app/Business/CourierPayableSummaryStore.php @@ -20,7 +20,10 @@ class CourierPayableSummaryStore private const MAX_COLUMNS = 200; - private const MAX_ROWS = 10000; + private const MAX_ROWS_BY_PAGE = [ + 'freight-difference' => 500_000, + 'other-surcharge-summary' => 500_000, + ]; private const MAX_CELL_LENGTH = 10000; @@ -31,6 +34,13 @@ class CourierPayableSummaryStore return self::PAGES[$page]; } + public function maxRows(string $page): int + { + $this->title($page); + + return self::MAX_ROWS_BY_PAGE[$page]; + } + /** * @return array{version:int,headers:list,rows:list>,source_name:string,imported_at:string,imported_by:int|null}|null */ @@ -72,7 +82,7 @@ class CourierPayableSummaryStore $reader = IOFactory::createReaderForFile($file->getRealPath()); $reader->setReadDataOnly(true); $spreadsheet = $reader->load($file->getRealPath()); - [$headers, $rows] = $this->readSpreadsheet($spreadsheet); + [$headers, $rows] = $this->readSpreadsheet($spreadsheet, $page); } catch (ValidationException $exception) { throw $exception; } catch (Throwable $exception) { @@ -128,8 +138,10 @@ class CourierPayableSummaryStore } /** @return array{0:list,1:list>} */ - private function readSpreadsheet($spreadsheet): array + private function readSpreadsheet($spreadsheet, string $page): array { + $maxRows = $this->maxRows($page); + foreach ($spreadsheet->getWorksheetIterator() as $worksheet) { $rawRows = $worksheet->toArray(null, false, true, false); $headerIndex = $this->headerIndex($rawRows); @@ -169,9 +181,9 @@ class CourierPayableSummaryStore $rows[] = $row; - if (count($rows) > self::MAX_ROWS) { + if (count($rows) > $maxRows) { throw ValidationException::withMessages([ - 'import' => '单次最多导入 ' . number_format(self::MAX_ROWS) . ' 条汇总数据,请拆分文件后重试。', + 'import' => '单次最多导入 ' . number_format($maxRows) . ' 条汇总数据,请拆分文件后重试。', ]); } } diff --git a/tests/Feature/Business/CourierPayableSummaryPagesTest.php b/tests/Feature/Business/CourierPayableSummaryPagesTest.php index 24e21a6e..d5934a9c 100644 --- a/tests/Feature/Business/CourierPayableSummaryPagesTest.php +++ b/tests/Feature/Business/CourierPayableSummaryPagesTest.php @@ -340,6 +340,35 @@ class CourierPayableSummaryPagesTest extends FeatureTestCase $this->assertStringContainsString("\t=待确认", $content); } + public function test_summary_imports_accept_more_than_ten_thousand_rows(): void + { + $store = app(CourierPayableSummaryStore::class); + $this->assertSame(500000, $store->maxRows('freight-difference')); + $this->assertSame(500000, $store->maxRows('other-surcharge-summary')); + + $rows = ["快递公司,结算月份\n"]; + for ($index = 1; $index <= 10001; $index++) { + $rows[] = "测试快递,2026-08\n"; + } + + foreach (['freight-difference', 'other-surcharge-summary'] as $page) { + $file = UploadedFile::fake()->createWithContent($page . '.csv', implode('', $rows)); + + $this->loginAs()->post(route('business.courier-payable-summaries.import', [ + 'summaryPage' => $page, + ]), ['import' => $file]) + ->assertRedirect(route('business.pages.show', [ + 'section' => 'courier-payables', + 'page' => $page, + ])) + ->assertSessionHas('success', '导入完成:10001 条数据,2 个字段。') + ->assertSessionDoesntHaveErrors('import'); + + $snapshot = $store->snapshot((int) $this->company->id, $page); + $this->assertCount(10001, $snapshot['rows']); + } + } + public function test_summary_actions_require_the_matching_page_permission(): void { $this->withExceptionHandling();