calls[] = ['method' => 'scalar', 'sql' => $sql, 'bindings' => $bindings]; return 1; } public function select(string $sql, array $bindings = []): array { $this->calls[] = ['method' => 'select', 'sql' => $sql, 'bindings' => $bindings]; return [[ 'id' => 42, 'shopName' => '测试京东店铺', 'amount' => -12.345, 'balanceAmount' => 98.765, 'orderTypeName' => '快车扣费', 'pk' => '流水-1', 'createDate' => '2026-08-03 12:00:00', 'updateTime' => '2026-08-03 12:01:00', 'statusName' => '成功', 'remark' => '备注', 'creatTime' => '2026-08-03 12:00:00', 'settleTime' => '2026-08-04 00:00:00', 'invoiceApplyTypeName' => '推广费开票', ]]; } public function first(string $sql, array $bindings = []): ?array { $this->calls[] = ['method' => 'first', 'sql' => $sql, 'bindings' => $bindings]; return ['amount_total' => 12.345, 'balance_total' => 98.765, '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 JdWalletBillRepository($factory); $recharge = $repository->paginateRecharge(null, '2026-08-03', '2026-08-03', 1, 25); $consumption = $repository->paginateConsumption(null, '2026-08-03', '2026-08-03', 1, 25); $summary = $repository->summaryConsumption(null, '2026-08-03', '2026-08-03'); $this->assertSame(1, $recharge['total']); $this->assertSame('2026-08-03 12:00:00', $recharge['rows'][0]['recharge_time']); $this->assertSame('成功', $recharge['rows'][0]['status']); $this->assertSame(12.35, $consumption['rows'][0]['amount']); $this->assertSame('推广费开票', $consumption['rows'][0]['notes']); $this->assertSame(12.35, $summary['amount_total']); $this->assertStringContainsString('ABS(amount)', $query->calls[4]['sql']); $this->assertStringContainsString('< DATEADD(day, 1, CAST(? AS date))', $query->calls[0]['sql']); $this->assertSame(['2026-08-03 00:00:00', '2026-08-03'], $query->calls[0]['bindings']); } }