*/ public array $calls = []; public function scalar(string $sql, array $bindings = []): mixed { $this->calls[] = compact('sql', 'bindings') + ['method' => 'scalar']; return 1; } public function select(string $sql, array $bindings = []): array { $this->calls[] = compact('sql', 'bindings') + ['method' => 'select']; return [[ 'shopName' => '测试店铺', 'uniTransTime' => '2026-07-23 12:00:00', 'transTime' => '2026-07-23', 'amount' => 15050, 'balance' => 990050, 'comment' => '测试流水', 'finType' => 'DEBIT', 'bizType' => 'INTEL_CHARGE_POST', 'tradeType' => '', ]]; } public function first(string $sql, array $bindings = []): ?array { $this->calls[] = compact('sql', 'bindings') + ['method' => 'first']; return [ 'income_total_raw' => 15050, 'expense_total_raw' => 0, 'cnt' => 1, ]; } }; $factory = new class($query) extends UpstreamReadOnlyQueryFactory { public function __construct(private readonly UpstreamReadOnlyQuery $query) { } public function forSource(string $source): UpstreamReadOnlyQuery { TestCase::assertSame('jiansun', $source); return $this->query; } }; $repository = new TmallTaobaoSpreadBillRepository($factory); $page = $repository->paginate('测试店铺', '2026-07-01', '2026-07-23', 'income', 1, 25); $summary = $repository->summary('测试店铺', '2026-07-01', '2026-07-23', 'income'); $this->assertSame(1, $page['total']); $this->assertSame(150.5, $page['rows'][0]['amount']); $this->assertSame(9900.5, $page['rows'][0]['balance']); $this->assertSame('收入', $page['rows'][0]['income_expense_type']); $this->assertSame('充值', $page['rows'][0]['transaction_type']); $this->assertSame(150.5, $summary['income_total']); $this->assertSame(150.5, $summary['net']); $this->assertStringContainsString('finType = \'DEBIT\'', $query->calls[0]['sql']); $this->assertSame( ['测试店铺', '2026-07-01', '2026-07-23'], $query->calls[0]['bindings'] ); $this->assertStringContainsString('finType = \'DEBIT\'', $query->calls[1]['sql']); $this->assertStringContainsString('finType = \'DEBIT\'', $query->calls[2]['sql']); } }