files as $file) { if (is_file($file)) { unlink($file); } } parent::tearDown(); } public function test_import_then_page_filter_and_export(): void { $this->allowPage(); $result = app(PlantingDetailImporter::class)->import($this->csvFixture(), $this->company->id, true, null, 'test-import'); $this->assertSame(2, $result['inserted']); $this->assertSame('2665.3600', $result['selling_price']); $this->assertSame('2665.8600', $result['payment_amount']); $this->assertSame('2026-06-01', $result['date_min']); $this->assertSame('2026-07-15', $result['date_max']); $page = $this->loginAs()->get(route('business.pages.show', [ 'section' => 'planting-data', 'page' => 'planting-details', ])); $page->assertOk() ->assertSee('种菜明细表') ->assertSee('3306215028042824171') ->assertSee('260529-659019537933390') ->assertSee('2,665.35') ->assertSee('阿里巴巴-常州乐畅家居有限公司'); // 时间筛选是可用的日期区间控件:点整块开日历、单个清除、快捷区间按钮 $page->assertSee('id="planting-date-from"', false) ->assertSee('id="planting-date-to"', false) ->assertSee('data-planting-clear="planting-date-from"', false) ->assertSee('data-planting-range="this-month"', false) ->assertSee('showPicker', false) ->assertSee('addEventListener(\'change\'', false); // 按店铺 + 日期筛选 $filtered = $this->loginAs()->get(route('business.pages.show', [ 'section' => 'planting-data', 'page' => 'planting-details', 'store' => '拼多多-亿家达实木家具官方旗舰店', 'date_from' => '2026-07-01', ])); $filtered->assertOk() ->assertSee('260529-659019537933390') ->assertDontSee('3306215028042824171'); // 导出:表头 + 行数与页面筛选一致 $export = $this->loginAs()->get(route('business.planting-data.planting-details.export', [ 'store' => '拼多多-亿家达实木家具官方旗舰店', ])); $export->assertOk()->assertDownload(); $csv = $export->streamedContent(); $this->assertStringContainsString('日期,订单编号,财务售价', explode("\n", $csv)[0]); $this->assertStringContainsString('260529-659019537933390', $csv); $this->assertStringNotContainsString('3306215028042824171', $csv); $this->assertStringContainsString('2026-07-15', $csv); } public function test_importer_handles_excel_serial_dates_and_grouped_amounts(): void { $path = $this->writeFile('planting.xlsx'); $book = new Spreadsheet(); $sheet = $book->getActiveSheet(); $sheet->fromArray([ ['日期', '订单编号', '财务售价', '财务运费', '财务佣金', '京喜差价', '扣款', '财务空包费', '财务打款金额', '笔数', '备注', '正确店铺', '负责人', '账户', '类型', '创建人', '标签', '所属利润中心', '负责平台', 'ID'], [46174, 'ORDER-1', '1,234.56', 0, '0.5', 0, 0, 0, '1,235.06', 2, '', '天猫-亿家达旗舰店', '仝孟欣', '', 'CCDD', '齐静春', 'CCDD', '运营中心A', '', 'ID-1'], // 无效日期(空)+ 无效订单号 → 跳过 ['', '', 10, 0, 0, 0, 0, 0, 10, 1, '', '天猫-亿家达旗舰店', '', '', '', '', '', '', '', ''], ]); (new Xlsx($book))->save($path); $book->disconnectWorksheets(); $result = app(PlantingDetailImporter::class)->import($path, $this->company->id, true, null, 'test-xlsx'); $this->assertSame(1, $result['inserted']); $this->assertSame(1, $result['skipped']); $this->assertSame('2026-06-01', $result['date_min']); $record = PlantingDetail::query()->where('company_id', $this->company->id)->firstOrFail(); $this->assertSame('2026-06-01', $record->bill_date->toDateString()); $this->assertSame('1234.5600', $record->finance_selling_price); $this->assertSame('1235.0600', $record->finance_payment_amount); $this->assertSame(2, $record->pieces); $this->assertSame('CCDD', $record->type); $this->assertSame('运营中心A', $record->profit_center); } /** 源表 ID 列存在「一个格子多个 ID、换行分隔」的行,导入要保留而不是报错截断。 */ public function test_importer_keeps_multi_line_external_ids(): void { $longId = implode("\n", ['10205993844217', '10205981846604', '10205993844217', '10210832117878']); $path = $this->writeFile('planting-multi-id.csv'); $handle = fopen($path, 'wb'); fputcsv($handle, ['日期', '订单编号', '财务售价', '财务运费', '财务佣金', '京喜差价', '扣款', '财务空包费', '财务打款金额', '笔数', '备注', '正确店铺', '负责人', '账户', '类型', '创建人', '标签', '所属利润中心', '负责平台', 'ID']); fputcsv($handle, ['2026-03-05', 'ORDER-9', '1356', '0', '0', '0', '0', '0', '1356', '1', '', '京喜-招财邸喜店工厂店', '李金林', '6228760405003956861', '', '骆冰', '', '运营中心A', '', $longId]); fclose($handle); $result = app(PlantingDetailImporter::class)->import($path, $this->company->id, true, null, 'test-multi-id'); $this->assertSame(1, $result['inserted']); $record = PlantingDetail::query()->where('company_id', $this->company->id)->firstOrFail(); $this->assertSame($longId, $record->external_id); } private function csvFixture(): string { $path = $this->writeFile('planting.csv'); $rows = [ ['日期', '订单编号', '财务售价', '财务运费', '财务佣金', '京喜差价', '扣款', '财务空包费', '财务打款金额', '笔数', '备注', '正确店铺', '负责人', '账户', '类型', '创建人', '标签', '所属利润中心', '负责平台', 'ID'], ['2026-06-01', '3306215028042824171', '2665.35', '0', '0', '0', '0', '0', '2665.35', '1', '', '阿里巴巴-常州乐畅家居有限公司', '叶颖龙', '6222031202029761854', '', '勇武', 'AABB', '运营中心B', '', '1056008452997'], ['2026-07-15', '260529-659019537933390', '0.01', '0', '0.5', '0', '0', '0', '0.51', '1', '', '拼多多-亿家达实木家具官方旗舰店', '屠锦超', '6222031211003375839', 'SSDD', '玄鸟', 'SSDD', '运营中心G', '', '959767499187'], ]; $handle = fopen($path, 'wb'); foreach ($rows as $row) { fputcsv($handle, $row); } fclose($handle); return $path; } private function writeFile(string $name): string { $path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('planting-', true) . '-' . $name; $this->files[] = $path; return $path; } private function allowPage(): void { $this->user->attachPermission( Permission::where('name', 'read-admin-panel')->firstOrFail() ); } }