diff --git a/modules/EcommerceFinance/Repositories/StoreReceivingAlipayBillMirrorRepository.php b/modules/EcommerceFinance/Repositories/StoreReceivingAlipayBillMirrorRepository.php index a330c75d..cf27c36a 100644 --- a/modules/EcommerceFinance/Repositories/StoreReceivingAlipayBillMirrorRepository.php +++ b/modules/EcommerceFinance/Repositories/StoreReceivingAlipayBillMirrorRepository.php @@ -72,13 +72,9 @@ class StoreReceivingAlipayBillMirrorRepository $total = $useRecordedCount ? (int) $recordedCount : (clone $query)->count(); $summary = $this->summary($query, $filters, $channel); - $billRows = $query - ->select('b.*') - ->orderBy($sortColumn, $direction) - ->orderBy('b.Id', $direction) - ->forPage($page, $perPage) - ->get() - ->all(); + $billRows = $this->pageRows( + $query, $sortColumn, $direction, $page, $perPage, $filters, $channel, + ); $shopNames = $this->shopNames($billRows); $rows = collect($billRows) ->map(fn (object $row): array => $this->mapRowFor($row, $shopNames[(string) $row->shop_id] ?? null, $mapping)) @@ -188,6 +184,49 @@ class StoreReceivingAlipayBillMirrorRepository return $this->mirror->connection()->table('ops_jst_original_bill_info as b'); } + /** @return array */ + private function pageRows( + Builder $query, + string $sortColumn, + string $direction, + int $page, + int $perPage, + array $filters, + ?string $channel, + ): array { + if ($channel === null || ($filters['bill_item'] ?? '') === '') { + return $query->select('b.*') + ->orderBy($sortColumn, $direction) + ->orderBy('b.Id', $direction) + ->forPage($page, $perPage) + ->get() + ->all(); + } + + $idQuery = clone $query; + if ($idQuery->getConnection()->getDriverName() === 'mysql') { + $idQuery->forceIndex('idx_original_bill_channel_shop'); + } + $ids = $idQuery->select('b.Id') + ->orderBy($sortColumn, $direction) + ->orderBy('b.Id', $direction) + ->forPage($page, $perPage) + ->pluck('b.Id') + ->all(); + if ($ids === []) { + return []; + } + + $rowsById = $this->billQuery()->whereIn('b.Id', $ids)->select('b.*')->get() + ->keyBy(static fn (object $row): string => (string) $row->Id); + + return collect($ids) + ->map(static fn (mixed $id): ?object => $rowsById->get((string) $id)) + ->filter() + ->values() + ->all(); + } + /** @return array{income:float,expense:float} */ private function summary(Builder $billQuery, array $filters, ?string $channel = null): array { diff --git a/tests/Unit/EcommerceFinance/StoreReceivingAlipayBillMirrorRepositoryTest.php b/tests/Unit/EcommerceFinance/StoreReceivingAlipayBillMirrorRepositoryTest.php index 7093520e..8522d57f 100644 --- a/tests/Unit/EcommerceFinance/StoreReceivingAlipayBillMirrorRepositoryTest.php +++ b/tests/Unit/EcommerceFinance/StoreReceivingAlipayBillMirrorRepositoryTest.php @@ -318,6 +318,30 @@ class StoreReceivingAlipayBillMirrorRepositoryTest extends TestCase $this->assertSame('1', $rows[0]['record_code']); } + public function test_douyin_bill_item_filter_pages_through_ids_and_preserves_order(): void + { + $this->markReady(); + $db = DB::connection('business_mirror'); + $db->table('ops_jst_original_bill_info')->insert([ + $this->row(1, 7, '2026-08-01 09:00:00', '1', 10, 'TouTiaoFXGZJ'), + $this->row(2, 7, '2026-08-03 09:00:00', '1', 20, 'TouTiaoFXGZJ'), + $this->row(3, 7, '2026-08-02 09:00:00', '1', 30, 'TouTiaoFXGZJ'), + ]); + $db->flushQueryLog(); + $db->enableQueryLog(); + + $result = (new StoreReceivingDouyinBillMirrorRepository($this->repository))->paginate( + ['bill_item' => '交易佣'], 'occurred_at', 'desc', 1, 2, + ); + + $this->assertSame(['2', '3'], array_column($result['data'], 'record_code')); + $queries = $db->getQueryLog(); + $this->assertCount(1, array_filter($queries, static fn (array $query): bool => str_contains($query['query'], 'select "b"."Id"'))); + $this->assertCount(1, array_filter($queries, static fn (array $query): bool => str_contains($query['query'], 'select "b".*') + && str_contains($query['query'], 'where "b"."Id" in'))); + $db->disableQueryLog(); + } + private function markReady(): void { foreach ([StoreReceivingAlipayBillMirrorRepository::DATASET, StoreReceivingAlipayBillMirrorRepository::SHOP_DATASET] as $dataset) {