TestAgentStatsTest.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Http\Controllers\admin\Agent as AdminAgent;
  4. use App\Models\Agent\Agent;
  5. use App\Models\Agent\AgentSetting;
  6. use App\Services\Agent\AgentDomainService;
  7. use App\Services\Agent\AgentEquityService;
  8. use App\Services\Agent\AgentPeriodReportService;
  9. use App\Services\Agent\AgentReportService;
  10. use App\Services\Agent\AgentWalletService;
  11. use App\Services\MemberDailyReportService;
  12. use App\Support\StatsScope;
  13. use Illuminate\Database\Schema\Blueprint;
  14. use Illuminate\Http\Request;
  15. use Illuminate\Support\Facades\DB;
  16. use Illuminate\Support\Facades\Schema;
  17. use PHPUnit\Framework\TestCase;
  18. use Tests\Support\AgentTestEnvironment;
  19. /** 测试代理:名下会员和自身资金不进统计;测试代理自己的后台照常显示;切换后跟随代理当前设置。今天 2026-09-07。 */
  20. class TestAgentStatsTest extends TestCase
  21. {
  22. use AgentTestEnvironment;
  23. private Agent $real;
  24. private Agent $test;
  25. private Agent $shareholder;
  26. private function seed(): void
  27. {
  28. if (!Schema::hasColumn('users', 'from')) Schema::table('users', fn (Blueprint $t) => $t->integer('from')->nullable());
  29. $this->real = $this->agent();
  30. $this->test = $this->agents->create(['username' => 'testagent', 'password' => 'secret1', 'type' => Agent::TYPE_JOINT, 'is_test' => 1]);
  31. $this->shareholder = $this->agent(Agent::TYPE_EQUITY);
  32. foreach (['r1' => $this->real->id, 't1' => $this->test->id, 'free' => null] as $memberId => $agentId) {
  33. $id = DB::table('users')->insertGetId(['member_id' => $memberId, 'username' => $memberId, 'agent_id' => $agentId, 'from' => 1, 'created_at' => '2026-09-07 08:00:00']);
  34. DB::table('recharges')->insert(['member_id' => $memberId, 'status' => 1, 'amount' => 100, 'created_at' => '2026-09-07 09:00:00']);
  35. DB::table('member_daily_reports')->insert(['report_date' => '2026-09-07', 'user_id' => $id, 'member_id' => $memberId, 'agent_id' => $agentId,
  36. 'deposit_amount' => 100, 'bet_count' => 1, 'bet_amount' => 10, 'categories' => '{}', 'created_at' => now(), 'updated_at' => now()]);
  37. }
  38. }
  39. public function test_admin_creates_edits_and_filters_test_agents(): void
  40. {
  41. $this->seed();
  42. $this->assertSame(1, $this->test->fresh()->is_test);
  43. $this->assertSame(0, $this->real->fresh()->is_test);
  44. $this->agents->update($this->real, ['is_test' => 1]);
  45. $this->assertSame(1, $this->real->fresh()->is_test);
  46. $this->agents->update($this->real, ['is_test' => 0, 'status' => 1]);
  47. $request = Request::create('/admin/agent', 'GET', ['is_test' => 1]);
  48. $request->user = (object) ['id' => 1];
  49. $this->app->instance('request', $request);
  50. $list = (new AdminAgent())->index($request, new AgentDomainService())->getData(true)['data']['list'];
  51. $this->assertSame(['testagent'], array_column($list, 'username'));
  52. $this->assertSame(1, $list[0]['is_test']);
  53. }
  54. public function test_admin_and_shareholder_stats_skip_test_members_but_test_agent_sees_its_own(): void
  55. {
  56. $this->seed();
  57. $reports = new AgentReportService();
  58. // 入股股东的全平台统计:不含测试会员
  59. $platform = $reports->dashboard($this->shareholder, '2026-09-07', '2026-09-07');
  60. $this->assertSame([2, '200.0000'], [$platform['member_count'], $platform['deposit_amount']]);
  61. $period = (new AgentPeriodReportService())->report($this->shareholder, ['period' => 'day', 'start_date' => '2026-09-07', 'end_date' => '2026-09-07']);
  62. $this->assertSame(['200.0000', 2], [$period['totals']['deposit_amount'], $period['totals']['new_members']]);
  63. // 测试代理自己的后台照常显示
  64. $own = $reports->dashboard($this->test, '2026-09-07', '2026-09-07');
  65. $this->assertSame([1, '100.0000'], [$own['member_count'], $own['deposit_amount']]);
  66. $this->assertSame(1, (new MemberDailyReportService())->paginate(['start_date' => '2026-09-07', 'end_date' => '2026-09-07'], $this->test)['total']);
  67. // 总后台:会员盈亏日报、代理报表不含测试数据
  68. $daily = (new MemberDailyReportService())->paginate(['start_date' => '2026-09-07', 'end_date' => '2026-09-07']);
  69. $this->assertSame(['free', 'r1'], collect($daily['list'])->pluck('member_id')->sort()->values()->all());
  70. $this->assertSame('200.0000', $daily['totals']['deposit_amount']);
  71. $agentRows = array_column($reports->reportRows(null, ['start_date' => '2026-09-07'])['list'], 'username');
  72. $this->assertNotContains('testagent', $agentRows);
  73. $this->assertContains($this->real->username, $agentRows);
  74. $this->assertSame(['testagent'], array_column($reports->reportRows($this->test, ['start_date' => '2026-09-07'])['list'], 'username'), 'test agent still sees its own report');
  75. // 按会员 / 按代理的资金表
  76. $this->assertSame(200.0, (float) StatsScope::excludeTestMembers(DB::table('recharges'))->sum('amount'));
  77. DB::table('agent_withdrawals')->insert([
  78. ['order_no' => 'AW1', 'request_key' => 'k1', 'agent_id' => $this->test->id, 'account_snapshot' => '{}', 'amount' => 50, 'actual_amount' => 50, 'status' => 'paid'],
  79. ['order_no' => 'AW2', 'request_key' => 'k2', 'agent_id' => $this->real->id, 'account_snapshot' => '{}', 'amount' => 30, 'actual_amount' => 30, 'status' => 'paid'],
  80. ]);
  81. $this->assertSame(30.0, (float) StatsScope::excludeTestAgents(DB::table('agent_withdrawals'))->sum('amount'), 'test agent own money is left out');
  82. }
  83. /** 入股股东的独立后台把后台模拟会员算进全平台;总后台、合营代理、游客都不受影响;开关关掉后恢复只算真实会员。 */
  84. public function test_shareholder_platform_stats_include_simulated_members(): void
  85. {
  86. $this->seed();
  87. (require dirname(__DIR__, 2) . '/database/migrations/2026_11_11_120000_add_user_type_to_users.php')->up();
  88. foreach (['sim1' => 2, 'guest1' => 1] as $memberId => $type) {
  89. $id = DB::table('users')->insertGetId(['member_id' => $memberId, 'username' => $memberId, 'agent_id' => null, 'from' => 2, 'user_type' => $type, 'created_at' => '2026-09-07 08:00:00']);
  90. DB::table('recharges')->insert(['member_id' => $memberId, 'status' => 1, 'amount' => 100, 'created_at' => '2026-09-07 09:00:00']);
  91. DB::table('member_daily_reports')->insert(['report_date' => '2026-09-07', 'user_id' => $id, 'member_id' => $memberId, 'agent_id' => null,
  92. 'deposit_amount' => 100, 'bet_count' => 1, 'bet_amount' => 10, 'categories' => '{}', 'created_at' => now(), 'updated_at' => now()]);
  93. }
  94. $reports = new AgentReportService();
  95. $day = ['period' => 'day', 'start_date' => '2026-09-07', 'end_date' => '2026-09-07'];
  96. $shareholder = fn () => [$reports->dashboard($this->shareholder, '2026-09-07', '2026-09-07')['member_count'],
  97. $reports->dashboard($this->shareholder, '2026-09-07', '2026-09-07')['deposit_amount'],
  98. (new AgentPeriodReportService())->report($this->shareholder, $day)['totals']['deposit_amount'],
  99. (new AgentPeriodReportService())->report($this->shareholder, $day)['totals']['new_members']];
  100. $this->assertSame([3, '300.0000', '300.0000', 3], $shareholder(), 'r1 + free + the simulated member; not the guest or the test member');
  101. // 总后台和合营代理看到的不变
  102. $daily = (new MemberDailyReportService())->paginate(['start_date' => '2026-09-07', 'end_date' => '2026-09-07']);
  103. $this->assertSame(['free', 'r1'], collect($daily['list'])->pluck('member_id')->sort()->values()->all());
  104. $this->assertSame([1, '100.0000'], [$reports->dashboard($this->real, '2026-09-07', '2026-09-07')['member_count'], $reports->dashboard($this->real, '2026-09-07', '2026-09-07')['deposit_amount']]);
  105. $this->assertSame(['free', 'r1'], StatsScope::realUsers(DB::table('users'))->orderBy('member_id')->pluck('member_id')->all());
  106. DB::table('config')->insert(['field' => 'simulation_show_to_equity_agents', 'val' => '0']);
  107. $this->assertSame([2, '200.0000', '200.0000', 2], $shareholder(), 'switched off: real members only');
  108. }
  109. public function test_switching_the_flag_moves_history_in_and_out(): void
  110. {
  111. $this->seed();
  112. $reports = new AgentReportService();
  113. $this->assertSame('200.0000', $reports->dashboard($this->shareholder, '2026-09-07', '2026-09-07')['deposit_amount']);
  114. $this->agents->update($this->real, ['is_test' => 1]);
  115. $this->assertSame('100.0000', $reports->dashboard($this->shareholder, '2026-09-07', '2026-09-07')['deposit_amount'], 'existing members follow the agent');
  116. $this->agents->update($this->real, ['is_test' => 0]);
  117. $this->agents->update($this->test, ['is_test' => 0]);
  118. $this->assertSame('300.0000', $reports->dashboard($this->shareholder, '2026-09-07', '2026-09-07')['deposit_amount']);
  119. }
  120. public function test_equity_summary_skips_test_shareholders(): void
  121. {
  122. $this->seed();
  123. AgentSetting::current()->update(['equity_enabled' => 1, 'equity_price_per_percent' => 1000, 'equity_min_percent' => 0.1, 'equity_max_percent' => 1]);
  124. $equity = new AgentEquityService(new AgentWalletService());
  125. $testShareholder = $this->agents->create(['username' => 'testholder', 'password' => 'secret1', 'type' => Agent::TYPE_EQUITY, 'is_test' => 1]);
  126. foreach ([$this->shareholder, $testShareholder] as $holder) {
  127. Agent::query()->whereKey($holder->id)->update(['balance' => 1000, 'realtime_balance' => 1000]);
  128. $equity->order($holder->fresh(), '0.5');
  129. }
  130. $page = $equity->paginate([]);
  131. $this->assertSame(2, $page['total'], 'list still shows both');
  132. $this->assertSame(['0.5000', '500.0000', '0.5000'], [$page['summary']['completed_percent'], $page['summary']['completed_amount'], $page['summary']['total_equity_percent']]);
  133. $this->assertSame(1, collect($page['list'])->firstWhere('agent_id', $testShareholder->id)->agent->is_test);
  134. }
  135. }