instance('config', new Repository(['app' => ['timezone' => 'Asia/Shanghai']])); Facade::setFacadeApplication($app); $db = new Manager($app); $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']); $db->setAsGlobal(); $db->bootEloquent(); $app->instance('db', $db->getDatabaseManager()); $app->bind('db.schema', fn () => $db->schema()); $db->schema()->create('agents', function (Blueprint $t) { $t->id(); $t->string('username'); $t->string('path'); }); $db->schema()->create('users', function (Blueprint $t) { $t->id(); $t->string('member_id'); $t->integer('agent_id'); $t->string('username'); $t->string('first_name')->default(''); $t->integer('status')->default(1); $t->string('register_ip')->default(''); $t->string('register_domain')->default(''); $t->timestamps(); }); $db->schema()->create('wallets', function (Blueprint $t) { $t->id(); $t->string('member_id'); $t->decimal('available_balance', 24, 10)->default(0); $t->decimal('frozen_balance', 24, 10)->default(0); }); foreach (['recharges', 'withdraws', 'payment_orders'] as $table) { $db->schema()->create($table, function (Blueprint $t) { $t->id(); $t->string('member_id'); $t->integer('status'); $t->integer('type')->nullable(); $t->decimal('amount', 24, 10); $t->timestamps(); }); } $db->schema()->create('balance_logs', function (Blueprint $t) { $t->id(); $t->string('member_id'); $t->string('change_type'); $t->integer('related_id')->nullable(); $t->decimal('amount', 24, 10); $t->timestamps(); }); DB::table('agents')->insert(['id' => 1, 'username' => 'agent', 'path' => '1']); DB::table('users')->insert(['member_id' => 'm1', 'username' => 'member', 'agent_id' => 1]); DB::table('wallets')->insert(['member_id' => 'm1']); } protected function tearDown(): void { DB::disconnect(); Facade::clearResolvedInstances(); parent::tearDown(); } public function test_successful_frontend_manual_orders_count_as_deposits_and_admin_credits_remain_separate(): void { $base = ['member_id' => 'm1', 'amount' => 10, 'created_at' => '2026-10-25 12:00:00']; DB::table('recharges')->insert($base + ['status' => 1]); DB::table('withdraws')->insert($base + ['status' => 1]); foreach ([PaymentOrderService::TYPE_PAY, PaymentOrderService::TYPE_SELF_PAY, PaymentOrderService::TYPE_PAYOUT, PaymentOrderService::TYPE_SELF_PAYOUT] as $type) { DB::table('payment_orders')->insert($base + ['type' => $type, 'status' => PaymentOrderService::STATUS_SUCCESS]); } foreach ([PaymentOrderService::TYPE_PAY, PaymentOrderService::TYPE_SELF_PAY] as $type) { foreach ([0, 1, 3, 4, 5, 6] as $status) { DB::table('payment_orders')->insert($base + ['type' => $type, 'status' => $status]); } DB::table('payment_orders')->insert(array_merge($base, ['type' => $type, 'status' => PaymentOrderService::STATUS_SUCCESS, 'created_at' => '2026-10-24 12:00:00'])); DB::table('payment_orders')->insert(array_merge($base, ['type' => $type, 'status' => PaymentOrderService::STATUS_SUCCESS, 'member_id' => 'unrelated'])); } DB::table('balance_logs')->insert($base + ['change_type' => '人工充值']); $result = (new AgentMemberService(new AgentReportService()))->finance(Agent::findOrFail(1), [ 'start_date' => '2026-10-25', 'end_date' => '2026-10-25', ]); $member = $result['list'][0]; $this->assertSame(3, $member->recharge_count); $this->assertSame('30.0000', $member->recharge_amount); $this->assertSame('10.0000', $member->manual_credit); $this->assertSame(3, $member->withdraw_count); $this->assertSame('30.0000', $member->withdraw_amount); } }