diff --git a/modules/EcommerceFinance/View/BillOffsetPageData.php b/modules/EcommerceFinance/View/BillOffsetPageData.php index befdaeb2..68ebb8d1 100644 --- a/modules/EcommerceFinance/View/BillOffsetPageData.php +++ b/modules/EcommerceFinance/View/BillOffsetPageData.php @@ -45,10 +45,13 @@ class BillOffsetPageData $summary = $result['summary'] ?? $summary; $sync = $result['sync'] ?? $sync; } catch (Throwable $exception) { - if (! str_contains($exception->getMessage(), 'bill_offset_mirror_not_ready')) { + $mirrorNotReady = str_contains($exception->getMessage(), 'bill_offset_mirror_not_ready'); + if (! $mirrorNotReady) { report($exception); } - $error = '账单冲减镜像尚未完成首次同步,当前不把空镜像解释为没有数据。'; + $error = $mirrorNotReady + ? '账单冲减镜像尚未完成首次同步,当前不把空镜像解释为没有数据。' + : '账单冲减数据暂时无法读取,请稍后重试。'; } return [ diff --git a/resources/views/business/pages/order-data/bill-offset.blade.php b/resources/views/business/pages/order-data/bill-offset.blade.php index 6fe889cd..9bb8df8a 100644 --- a/resources/views/business/pages/order-data/bill-offset.blade.php +++ b/resources/views/business/pages/order-data/bill-offset.blade.php @@ -108,10 +108,12 @@ diff --git a/tests/Feature/Business/PagesTest.php b/tests/Feature/Business/PagesTest.php index d8d037ca..5c09a8da 100644 --- a/tests/Feature/Business/PagesTest.php +++ b/tests/Feature/Business/PagesTest.php @@ -306,6 +306,22 @@ class PagesTest extends FeatureTestCase ->assertSeeText('数据状态:SUCCEEDED'); } + public function testBillOffsetPageShowsReadFailureSeparatelyFromAnUnreadyMirror(): void + { + $this->user->attachPermission( + Permission::where('name', 'read-admin-panel')->firstOrFail() + ); + $repository = Mockery::mock(BillOffsetMirrorRepository::class); + $repository->shouldReceive('paginate')->once()->andThrow(new \RuntimeException('database unavailable')); + $this->app->instance(BillOffsetMirrorRepository::class, $repository); + + $this->loginAs()->get(route('business.pages.show', [ + 'section' => 'order-data', 'page' => 'bill-offset', + ]))->assertOk() + ->assertSeeText('账单冲减数据暂时无法读取,请稍后重试。') + ->assertDontSeeText('账单冲减镜像尚未完成首次同步,当前不把空镜像解释为没有数据。'); + } + public function testBillOffsetExportReturnsCsvForTheFilteredRows(): void { $this->user->attachPermission( @@ -338,6 +354,42 @@ class PagesTest extends FeatureTestCase $this->assertStringContainsString('-20', $csv); } + public function testBillOffsetExportIncludesAllPagesForTheSameFilters(): void + { + $this->user->attachPermission( + Permission::where('name', 'read-admin-panel')->firstOrFail() + ); + $repository = Mockery::mock(BillOffsetMirrorRepository::class); + $filters = [ + 'from' => '2026-08-01', 'to' => '2026-08-31', 'order_no' => '', 'shop_name' => '', 'sku_id' => '', + ]; + $repository->shouldReceive('paginate')->once()->with($filters, 1, 100)->andReturn([ + 'data' => [[ + 'internal_order_no' => 'ORDER-1', 'online_order_no' => 'ONLINE-1', 'shop_name' => '店铺一', + 'shop_code' => 'SHOP-1', 'product_code' => 'SKU-1', 'style_code' => 'STYLE-1', + 'shop_product_code' => 'SP-1', 'shop_style_code' => 'SI-1', 'amount' => -20, + ]], + 'total' => 101, 'sync' => ['status' => 'succeeded'], + ]); + $repository->shouldReceive('paginate')->once()->with($filters, 2, 100)->andReturn([ + 'data' => [[ + 'internal_order_no' => 'ORDER-101', 'online_order_no' => 'ONLINE-101', 'shop_name' => '店铺一', + 'shop_code' => 'SHOP-1', 'product_code' => 'SKU-101', 'style_code' => 'STYLE-101', + 'shop_product_code' => 'SP-101', 'shop_style_code' => 'SI-101', 'amount' => 18.25, + ]], + 'total' => 101, 'sync' => ['status' => 'succeeded'], + ]); + $this->app->instance(BillOffsetMirrorRepository::class, $repository); + + $csv = $this->loginAs()->get(route('business.bill-offset.export', [ + 'from' => '2026-08-01', 'to' => '2026-08-31', + ]))->streamedContent(); + + $this->assertStringContainsString('ORDER-1', $csv); + $this->assertStringContainsString('ORDER-101', $csv); + $this->assertSame(3, substr_count($csv, "\n")); + } + public function testFinancialAfterSalesPageRendersMirroredJushuitanRefunds(): void { $this->user->attachPermission( diff --git a/tests/Unit/EcommerceFinance/BillOffsetMirrorRepositoryTest.php b/tests/Unit/EcommerceFinance/BillOffsetMirrorRepositoryTest.php index 7e82c470..569f9739 100644 --- a/tests/Unit/EcommerceFinance/BillOffsetMirrorRepositoryTest.php +++ b/tests/Unit/EcommerceFinance/BillOffsetMirrorRepositoryTest.php @@ -64,11 +64,13 @@ class BillOffsetMirrorRepositoryTest extends TestCase DB::connection('business_mirror')->table('ops_jst_original_bill_info')->insert([ ['Id' => 1, 'fee_time' => '2026-08-01 10:00:00', 'fee_name' => '500112冲减收入', 'inout_type' => '收入', 'so_id' => 'SO-1', 'sku_id' => 'SKU-1', 'amount' => -20], ['Id' => 2, 'fee_time' => '2026-08-02 10:00:00', 'fee_name' => '500112冲减收入', 'inout_type' => '收入', 'so_id' => 'SO-2', 'sku_id' => 'SKU-2', 'amount' => 18.25], + ['Id' => 3, 'fee_time' => '2026-08-03 10:00:00', 'fee_name' => '冲减收入', 'inout_type' => '收入', 'so_id' => 'SO-3', 'sku_id' => 'SKU-3', 'amount' => 7], ['Id' => 4, 'fee_time' => '2026-08-01 10:00:00', 'fee_name' => '订单收入', 'inout_type' => '收入', 'so_id' => 'SO-1', 'sku_id' => 'SKU-1', 'amount' => 100], ]); DB::connection('business_mirror')->table('ops_jst_orders')->insert([ ['o_id' => 1001, 'so_id' => 'SO-1', 'shop_name' => '测试店铺', 'shop_id' => 'SHOP-1'], ['o_id' => 1002, 'so_id' => 'SO-2', 'shop_name' => '其他店铺', 'shop_id' => 'SHOP-2'], + ['o_id' => 1003, 'so_id' => 'SO-3', 'shop_name' => '历史店铺', 'shop_id' => 'SHOP-3'], ]); DB::connection('business_mirror')->table('ops_jst_order_item')->insert([ ['o_id' => 1001, 'sku_id' => 'SKU-1', 'i_id' => 'STYLE-1', 'shop_sku_id' => 'SP-1', 'shop_i_id' => 'SI-1'], @@ -82,6 +84,11 @@ class BillOffsetMirrorRepositoryTest extends TestCase $this->assertSame('STYLE-1', $result['data'][0]['style_code']); $this->assertSame(-20.0, $result['summary']['amount']); $this->assertSame('succeeded', $result['sync']['status']); + + $all = $this->repository->paginate([], 1, 10); + $this->assertSame(3, $all['total']); + $this->assertSame(5.25, $all['summary']['amount']); + $this->assertSame('SO-3', $all['data'][0]['online_order_no']); } public function test_it_rejects_unready_mirror(): void diff --git a/tests/Unit/EcommerceFinance/OrderDataMirrorRepositoryTest.php b/tests/Unit/EcommerceFinance/OrderDataMirrorRepositoryTest.php index f602b41e..fed58fee 100644 --- a/tests/Unit/EcommerceFinance/OrderDataMirrorRepositoryTest.php +++ b/tests/Unit/EcommerceFinance/OrderDataMirrorRepositoryTest.php @@ -76,6 +76,7 @@ class OrderDataMirrorRepositoryTest extends TestCase $this->assertSame(40.0, $row['product_cost']); $this->assertSame(1.0, $row['post_return_quantity']); $this->assertSame('https://item.jd.com/1001.html', $row['product_link']); + $this->assertNull($row['account_500112']); $this->assertNull($row['account_8001201']); } diff --git a/tests/Unit/EcommerceFinance/OrderDataRepositoryTest.php b/tests/Unit/EcommerceFinance/OrderDataRepositoryTest.php index 2e061c04..de6f9c2a 100644 --- a/tests/Unit/EcommerceFinance/OrderDataRepositoryTest.php +++ b/tests/Unit/EcommerceFinance/OrderDataRepositoryTest.php @@ -101,6 +101,7 @@ class OrderDataRepositoryTest extends TestCase $this->assertSame('https://item.jd.com/1001.html', $result['rows'][0]['product_link']); $this->assertSame('AF-1', $result['rows'][0]['after_sales_no']); $this->assertSame(1.0, $result['rows'][0]['post_return_quantity']); + $this->assertNull($result['rows'][0]['account_500112']); $this->assertNull($result['rows'][0]['account_8001201']); }