2026_08_24_140000_create_agent_system_tables.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. use Illuminate\Database\Migrations\Migration;
  3. use Illuminate\Database\Schema\Blueprint;
  4. use Illuminate\Support\Facades\Schema;
  5. return new class extends Migration {
  6. public function up(): void
  7. {
  8. if (!Schema::hasTable('agents')) {
  9. Schema::create('agents', function (Blueprint $table) {
  10. $table->id();
  11. $table->unsignedBigInteger('parent_id')->nullable()->index();
  12. $table->string('path', 512)->default('/')->index();
  13. $table->unsignedTinyInteger('level')->default(1);
  14. $table->string('username', 64)->unique();
  15. $table->string('password');
  16. $table->string('withdraw_password')->default('');
  17. $table->string('real_name', 128)->default('');
  18. $table->string('invitation_code', 32)->unique();
  19. $table->decimal('balance', 18, 4)->default(0);
  20. $table->decimal('frozen_balance', 18, 4)->default(0);
  21. $table->decimal('deposit_fee_rate', 8, 4)->default(0);
  22. $table->decimal('withdraw_fee_rate', 8, 4)->default(0);
  23. $table->decimal('flow_commission_rate', 8, 4)->default(0);
  24. $table->decimal('profit_commission_rate', 8, 4)->default(0);
  25. $table->unsignedTinyInteger('status')->default(1)->index();
  26. $table->timestamp('last_login_at')->nullable();
  27. $table->string('last_login_ip', 64)->default('');
  28. $table->unsignedBigInteger('created_by')->nullable();
  29. $table->timestamps();
  30. $table->index(['level', 'status']);
  31. });
  32. }
  33. if (!Schema::hasTable('agent_tokens')) {
  34. Schema::create('agent_tokens', function (Blueprint $table) {
  35. $table->id();
  36. $table->unsignedBigInteger('agent_id')->unique();
  37. $table->char('token_hash', 64)->unique();
  38. $table->timestamp('expires_at')->index();
  39. $table->timestamp('last_used_at')->nullable();
  40. $table->string('ip', 64)->default('');
  41. $table->string('device', 16)->default('');
  42. $table->timestamps();
  43. });
  44. }
  45. if (!Schema::hasTable('agent_domains')) {
  46. Schema::create('agent_domains', function (Blueprint $table) {
  47. $table->id();
  48. $table->unsignedBigInteger('agent_id')->index();
  49. $table->string('type', 16)->comment('pc/h5')->index();
  50. $table->string('domain', 255)->index();
  51. $table->string('host', 255)->index();
  52. $table->unsignedTinyInteger('status')->default(1);
  53. $table->timestamps();
  54. $table->unique(['agent_id', 'type'], 'uniq_agent_domain_type');
  55. });
  56. }
  57. if (!Schema::hasTable('agent_login_logs')) {
  58. Schema::create('agent_login_logs', function (Blueprint $table) {
  59. $table->id();
  60. $table->unsignedBigInteger('agent_id')->index();
  61. $table->string('username', 64);
  62. $table->string('domain', 255)->default('');
  63. $table->string('ip', 64)->default('')->index();
  64. $table->string('country', 128)->default('');
  65. $table->string('region', 128)->default('');
  66. $table->string('city', 128)->default('');
  67. $table->string('device', 16)->default('')->index();
  68. $table->string('user_agent', 512)->default('');
  69. $table->timestamp('login_at')->index();
  70. $table->timestamps();
  71. });
  72. }
  73. if (!Schema::hasTable('agent_balance_logs')) {
  74. Schema::create('agent_balance_logs', function (Blueprint $table) {
  75. $table->id();
  76. $table->unsignedBigInteger('agent_id')->index();
  77. $table->string('type', 32)->index();
  78. $table->decimal('amount', 18, 4);
  79. $table->decimal('before_balance', 18, 4);
  80. $table->decimal('after_balance', 18, 4);
  81. $table->string('reference_type', 64)->default('');
  82. $table->unsignedBigInteger('reference_id')->nullable();
  83. $table->string('operator_type', 16)->default('system');
  84. $table->unsignedBigInteger('operator_id')->nullable();
  85. $table->string('idempotency_key', 96)->unique();
  86. $table->string('remark', 500)->default('');
  87. $table->timestamps();
  88. $table->index(['agent_id', 'created_at']);
  89. });
  90. }
  91. if (!Schema::hasTable('agent_withdraw_accounts')) {
  92. Schema::create('agent_withdraw_accounts', function (Blueprint $table) {
  93. $table->id();
  94. $table->unsignedBigInteger('agent_id')->index();
  95. $table->string('type', 32)->index();
  96. $table->string('name', 128)->default('');
  97. $table->string('account', 255);
  98. $table->string('bank_name', 128)->default('');
  99. $table->string('network', 32)->default('');
  100. $table->json('details')->nullable();
  101. $table->unsignedTinyInteger('status')->default(1);
  102. $table->timestamps();
  103. });
  104. }
  105. if (!Schema::hasTable('agent_withdrawals')) {
  106. Schema::create('agent_withdrawals', function (Blueprint $table) {
  107. $table->id();
  108. $table->string('order_no', 40)->unique();
  109. $table->string('request_key', 96)->unique();
  110. $table->unsignedBigInteger('agent_id')->index();
  111. $table->unsignedBigInteger('account_id')->nullable();
  112. $table->string('account_type', 32)->default('');
  113. $table->text('account_snapshot');
  114. $table->decimal('amount', 18, 4);
  115. $table->decimal('fee', 18, 4)->default(0);
  116. $table->decimal('actual_amount', 18, 4);
  117. $table->string('status', 24)->default('pending')->index();
  118. $table->string('remark', 500)->default('');
  119. $table->string('audit_remark', 500)->default('');
  120. $table->unsignedBigInteger('audit_admin_id')->nullable();
  121. $table->timestamp('audited_at')->nullable();
  122. $table->timestamp('paid_at')->nullable();
  123. $table->timestamps();
  124. $table->index(['agent_id', 'created_at']);
  125. });
  126. }
  127. if (!Schema::hasTable('agent_commission_rules')) {
  128. Schema::create('agent_commission_rules', function (Blueprint $table) {
  129. $table->id();
  130. $table->unsignedBigInteger('agent_id')->index();
  131. $table->decimal('flow_rate', 8, 4)->default(0);
  132. $table->decimal('profit_rate', 8, 4)->default(0);
  133. $table->date('effective_from')->index();
  134. $table->unsignedTinyInteger('status')->default(1);
  135. $table->unsignedBigInteger('created_by')->nullable();
  136. $table->timestamps();
  137. $table->index(['agent_id', 'status', 'effective_from'], 'idx_agent_commission_rule');
  138. $table->unique(['agent_id', 'effective_from'], 'uniq_agent_commission_effective');
  139. });
  140. }
  141. if (!Schema::hasTable('agent_commissions')) {
  142. Schema::create('agent_commissions', function (Blueprint $table) {
  143. $table->id();
  144. $table->date('settlement_date');
  145. $table->unsignedBigInteger('agent_id')->index();
  146. $table->string('type', 16)->comment('flow/profit');
  147. $table->decimal('base_amount', 18, 4)->default(0);
  148. $table->decimal('rate', 8, 4)->default(0);
  149. $table->decimal('amount', 18, 4)->default(0);
  150. $table->unsignedBigInteger('bet_count')->default(0);
  151. $table->string('status', 16)->default('pending')->index();
  152. $table->json('snapshot')->nullable();
  153. $table->timestamp('credited_at')->nullable();
  154. $table->timestamps();
  155. $table->unique(['settlement_date', 'agent_id', 'type'], 'uniq_agent_commission_daily');
  156. });
  157. }
  158. if (!Schema::hasTable('agent_daily_stats')) {
  159. Schema::create('agent_daily_stats', function (Blueprint $table) {
  160. $table->id();
  161. $table->date('stat_date');
  162. $table->unsignedBigInteger('agent_id')->index();
  163. $table->unsignedInteger('direct_agents')->default(0);
  164. $table->unsignedInteger('direct_members')->default(0);
  165. $table->decimal('member_balance', 18, 4)->default(0);
  166. $table->decimal('deposit_amount', 18, 4)->default(0);
  167. $table->decimal('withdraw_amount', 18, 4)->default(0);
  168. $table->decimal('manual_credit', 18, 4)->default(0);
  169. $table->decimal('manual_debit', 18, 4)->default(0);
  170. $table->decimal('bonus_amount', 18, 4)->default(0);
  171. $table->decimal('rebate_amount', 18, 4)->default(0);
  172. $table->decimal('bet_amount', 18, 4)->default(0);
  173. $table->decimal('valid_bet_amount', 18, 4)->default(0);
  174. $table->unsignedBigInteger('bet_count')->default(0);
  175. $table->decimal('win_loss', 18, 4)->default(0);
  176. $table->decimal('commission_amount', 18, 4)->default(0);
  177. $table->decimal('company_profit', 18, 4)->default(0);
  178. $table->timestamps();
  179. $table->unique(['stat_date', 'agent_id'], 'uniq_agent_daily_stat');
  180. });
  181. }
  182. if (Schema::hasTable('users') && !Schema::hasColumn('users', 'agent_id')) {
  183. Schema::table('users', function (Blueprint $table) {
  184. $table->unsignedBigInteger('agent_id')->nullable()->index();
  185. });
  186. }
  187. }
  188. public function down(): void
  189. {
  190. if (Schema::hasTable('users') && Schema::hasColumn('users', 'agent_id')) {
  191. Schema::table('users', function (Blueprint $table) {
  192. $table->dropColumn('agent_id');
  193. });
  194. }
  195. foreach ([
  196. 'agent_daily_stats', 'agent_commissions', 'agent_commission_rules',
  197. 'agent_withdrawals', 'agent_withdraw_accounts', 'agent_balance_logs',
  198. 'agent_login_logs', 'agent_domains', 'agent_tokens', 'agents',
  199. ] as $table) {
  200. Schema::dropIfExists($table);
  201. }
  202. }
  203. };