feat: 彩票业务迁移并补全后台权限与代理结算体系
This commit is contained in:
49
database/migrations/0001_01_01_000000_create_users_table.php
Normal file
49
database/migrations/0001_01_01_000000_create_users_table.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
Schema::dropIfExists('sessions');
|
||||
}
|
||||
};
|
||||
35
database/migrations/0001_01_01_000001_create_cache_table.php
Normal file
35
database/migrations/0001_01_01_000001_create_cache_table.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('cache', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->mediumText('value');
|
||||
$table->bigInteger('expiration')->index();
|
||||
});
|
||||
|
||||
Schema::create('cache_locks', function (Blueprint $table) {
|
||||
$table->string('key')->primary();
|
||||
$table->string('owner');
|
||||
$table->bigInteger('expiration')->index();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('cache');
|
||||
Schema::dropIfExists('cache_locks');
|
||||
}
|
||||
};
|
||||
57
database/migrations/0001_01_01_000002_create_jobs_table.php
Normal file
57
database/migrations/0001_01_01_000002_create_jobs_table.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedSmallInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
|
||||
Schema::create('job_batches', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->string('name');
|
||||
$table->integer('total_jobs');
|
||||
$table->integer('pending_jobs');
|
||||
$table->integer('failed_jobs');
|
||||
$table->longText('failed_job_ids');
|
||||
$table->mediumText('options')->nullable();
|
||||
$table->integer('cancelled_at')->nullable();
|
||||
$table->integer('created_at');
|
||||
$table->integer('finished_at')->nullable();
|
||||
});
|
||||
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
Schema::dropIfExists('job_batches');
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('currencies', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('code', 16)->unique();
|
||||
$table->string('name', 64);
|
||||
$table->unsignedTinyInteger('decimal_places')->default(2);
|
||||
$table->boolean('is_enabled')->default(true);
|
||||
$table->boolean('is_bettable')->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('currencies');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('players', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('site_code', 64);
|
||||
$table->string('site_player_id', 128);
|
||||
$table->string('username', 128)->nullable();
|
||||
$table->string('nickname', 128)->nullable();
|
||||
$table->string('default_currency', 16)->default('NPR');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('0=active,1=frozen,2=blocked');
|
||||
$table->timestamp('last_login_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['site_code', 'site_player_id'], 'uk_players_site_player');
|
||||
$table->index('status', 'idx_players_status');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('players');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('admin_users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name', 128);
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('0=active,1=disabled');
|
||||
$table->timestamp('last_login_at')->nullable();
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_users');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('admin_roles', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('slug', 64)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('admin_permissions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('slug', 128)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('admin_role_permissions', function (Blueprint $table) {
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->foreignId('permission_id')->constrained('admin_permissions')->cascadeOnDelete();
|
||||
$table->primary(['role_id', 'permission_id']);
|
||||
});
|
||||
|
||||
Schema::create('admin_user_roles', function (Blueprint $table) {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->primary(['admin_user_id', 'role_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_user_roles');
|
||||
Schema::dropIfExists('admin_role_permissions');
|
||||
Schema::dropIfExists('admin_permissions');
|
||||
Schema::dropIfExists('admin_roles');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('player_wallets', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->string('wallet_type', 32)->default('lottery');
|
||||
$table->string('currency_code', 16);
|
||||
$table->bigInteger('balance')->default(0);
|
||||
$table->bigInteger('frozen_balance')->default(0);
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('0=active,1=frozen');
|
||||
$table->unsignedBigInteger('version')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['player_id', 'wallet_type', 'currency_code'], 'uk_player_wallets_player_type_currency');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('player_wallets');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('wallet_txns', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('txn_no', 64)->unique();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->foreignId('wallet_id')->constrained('player_wallets')->cascadeOnDelete();
|
||||
$table->string('biz_type', 32);
|
||||
$table->string('biz_no', 64)->nullable();
|
||||
$table->unsignedTinyInteger('direction')->comment('1=in,2=out');
|
||||
$table->bigInteger('amount');
|
||||
$table->bigInteger('balance_before');
|
||||
$table->bigInteger('balance_after');
|
||||
$table->string('status', 32);
|
||||
$table->string('external_ref_no', 64)->nullable();
|
||||
$table->string('idempotent_key', 64)->nullable();
|
||||
$table->string('remark', 255)->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['player_id', 'created_at'], 'idx_wallet_txns_player_time');
|
||||
$table->index(['biz_type', 'biz_no'], 'idx_wallet_txns_biz');
|
||||
$table->unique(['idempotent_key', 'biz_type'], 'uk_wallet_txns_idempotent_biz');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('wallet_txns');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('transfer_orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('transfer_no', 64)->unique();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->string('direction', 16);
|
||||
$table->string('currency_code', 16);
|
||||
$table->bigInteger('amount');
|
||||
$table->string('idempotent_key', 64)->unique();
|
||||
$table->string('status', 32);
|
||||
$table->json('external_request_payload')->nullable();
|
||||
$table->json('external_response_payload')->nullable();
|
||||
$table->string('external_ref_no', 64)->nullable();
|
||||
$table->string('fail_reason', 255)->nullable();
|
||||
$table->timestamp('finished_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['player_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('transfer_orders');
|
||||
}
|
||||
};
|
||||
35
database/migrations/2026_05_08_100007_create_draws_table.php
Normal file
35
database/migrations/2026_05_08_100007_create_draws_table.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('draws', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('draw_no', 32)->unique();
|
||||
$table->date('business_date');
|
||||
$table->unsignedInteger('sequence_no');
|
||||
$table->string('status', 32);
|
||||
$table->timestamp('start_time')->nullable();
|
||||
$table->timestamp('close_time')->nullable();
|
||||
$table->timestamp('draw_time')->nullable();
|
||||
$table->timestamp('cooling_end_time')->nullable();
|
||||
$table->string('result_source', 16)->nullable()->comment('rng|manual');
|
||||
$table->unsignedInteger('current_result_version')->default(0);
|
||||
$table->unsignedInteger('settle_version')->default(0);
|
||||
$table->boolean('is_reopened')->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['status', 'draw_time'], 'idx_draws_status_draw_time');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('draws');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('draw_result_batches', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->unsignedInteger('result_version');
|
||||
$table->string('source_type', 16)->comment('rng|manual');
|
||||
$table->string('rng_seed_hash', 128)->nullable();
|
||||
$table->text('raw_seed_encrypted')->nullable();
|
||||
$table->string('status', 32);
|
||||
$table->foreignId('created_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->foreignId('confirmed_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->timestamp('confirmed_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['draw_id', 'result_version'], 'uk_draw_result_batches_draw_version');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('draw_result_batches');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('draw_result_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->foreignId('result_batch_id')->constrained('draw_result_batches')->cascadeOnDelete();
|
||||
$table->string('prize_type', 32);
|
||||
$table->unsignedInteger('prize_index')->default(0);
|
||||
$table->char('number_4d', 4);
|
||||
$table->char('suffix_3d', 3)->nullable();
|
||||
$table->char('suffix_2d', 2)->nullable();
|
||||
$table->unsignedTinyInteger('head_digit')->nullable();
|
||||
$table->unsignedTinyInteger('tail_digit')->nullable();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->index(['draw_id', 'prize_type', 'prize_index'], 'idx_draw_result_items_draw_prize');
|
||||
$table->index(['draw_id', 'number_4d'], 'idx_draw_result_items_draw_number');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('draw_result_items');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 默认 User 登录未使用:业务玩家为 players,后台为 admin_users。
|
||||
* sessions 表仍保留(SESSION_DRIVER=database),其 user_id 可为空,不依赖 users。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::dropIfExists('password_reset_tokens');
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('password_reset_tokens', function (Blueprint $table) {
|
||||
$table->string('email')->primary();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('play_types', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('play_code', 32)->unique();
|
||||
$table->string('category', 16);
|
||||
$table->unsignedTinyInteger('dimension')->nullable()->comment('2/3/4');
|
||||
$table->string('bet_mode', 32)->nullable();
|
||||
$table->string('display_name_zh', 64)->nullable();
|
||||
$table->string('display_name_en', 64)->nullable();
|
||||
$table->string('display_name_ne', 64)->nullable();
|
||||
$table->boolean('is_enabled')->default(true);
|
||||
$table->integer('sort_order')->default(0);
|
||||
$table->boolean('supports_multi_number')->default(false);
|
||||
$table->json('reserved_rule_json')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('play_types');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('play_config_versions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('version_no');
|
||||
$table->string('status', 16);
|
||||
$table->timestamp('effective_at')->nullable();
|
||||
$table->foreignId('updated_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->string('reason', 255)->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('play_config_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('version_id')->constrained('play_config_versions')->cascadeOnDelete();
|
||||
$table->string('play_code', 32);
|
||||
$table->boolean('is_enabled')->default(true);
|
||||
$table->bigInteger('min_bet_amount')->default(0);
|
||||
$table->bigInteger('max_bet_amount')->default(0);
|
||||
$table->integer('display_order')->default(0);
|
||||
$table->text('rule_text_zh')->nullable();
|
||||
$table->text('rule_text_en')->nullable();
|
||||
$table->text('rule_text_ne')->nullable();
|
||||
$table->json('extra_config_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['version_id', 'play_code'], 'uk_play_config_items_version_play');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('play_config_items');
|
||||
Schema::dropIfExists('play_config_versions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('odds_versions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('version_no');
|
||||
$table->string('status', 16);
|
||||
$table->timestamp('effective_at')->nullable();
|
||||
$table->foreignId('updated_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->string('reason', 255)->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('odds_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('version_id')->constrained('odds_versions')->cascadeOnDelete();
|
||||
$table->string('play_code', 32);
|
||||
$table->string('prize_scope', 32);
|
||||
$table->bigInteger('odds_value')->default(0);
|
||||
$table->decimal('rebate_rate', 8, 4)->default(0);
|
||||
$table->decimal('commission_rate', 8, 4)->default(0);
|
||||
$table->string('currency_code', 16);
|
||||
$table->json('extra_config_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['version_id', 'play_code'], 'idx_odds_items_version_play');
|
||||
$table->unique(
|
||||
['version_id', 'play_code', 'prize_scope', 'currency_code'],
|
||||
'uk_odds_items_version_play_prize_currency'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('odds_items');
|
||||
Schema::dropIfExists('odds_versions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('risk_cap_versions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('version_no');
|
||||
$table->string('status', 16);
|
||||
$table->timestamp('effective_at')->nullable();
|
||||
$table->foreignId('updated_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->string('reason', 255)->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('risk_cap_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('version_id')->constrained('risk_cap_versions')->cascadeOnDelete();
|
||||
$table->foreignId('draw_id')->nullable()->constrained('draws')->nullOnDelete();
|
||||
$table->char('normalized_number', 4);
|
||||
$table->bigInteger('cap_amount');
|
||||
$table->string('cap_type', 16);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['version_id', 'draw_id', 'normalized_number'], 'idx_risk_cap_items_lookup');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('risk_cap_items');
|
||||
Schema::dropIfExists('risk_cap_versions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('ticket_orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('order_no', 64)->unique();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->string('currency_code', 16);
|
||||
$table->bigInteger('total_bet_amount')->default(0);
|
||||
$table->bigInteger('total_rebate_amount')->default(0);
|
||||
$table->bigInteger('total_actual_deduct')->default(0);
|
||||
$table->bigInteger('total_estimated_payout')->default(0);
|
||||
$table->string('status', 32);
|
||||
$table->string('submit_source', 16)->default('h5');
|
||||
$table->string('client_trace_id', 64)->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['player_id', 'draw_id'], 'idx_ticket_orders_player_draw');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ticket_orders');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('ticket_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('ticket_no', 64)->unique();
|
||||
$table->foreignId('order_id')->constrained('ticket_orders')->cascadeOnDelete();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->string('original_number', 32)->nullable();
|
||||
$table->char('normalized_number', 4);
|
||||
$table->string('play_code', 32);
|
||||
$table->unsignedTinyInteger('dimension')->nullable()->comment('2/3/4');
|
||||
$table->unsignedTinyInteger('digit_slot')->nullable()->comment('千百十个位,领域字典');
|
||||
$table->string('bet_mode', 32)->nullable();
|
||||
$table->bigInteger('unit_bet_amount')->default(0);
|
||||
$table->bigInteger('total_bet_amount')->default(0);
|
||||
$table->decimal('rebate_rate_snapshot', 8, 4)->default(0);
|
||||
$table->decimal('commission_rate_snapshot', 8, 4)->default(0);
|
||||
$table->bigInteger('actual_deduct_amount')->default(0);
|
||||
$table->json('odds_snapshot_json')->nullable();
|
||||
$table->json('rule_snapshot_json')->nullable();
|
||||
$table->unsignedInteger('combination_count')->default(1);
|
||||
$table->bigInteger('estimated_max_payout')->default(0);
|
||||
$table->bigInteger('risk_locked_amount')->default(0);
|
||||
$table->string('status', 32);
|
||||
$table->string('fail_reason_code', 32)->nullable();
|
||||
$table->string('fail_reason_text', 255)->nullable();
|
||||
$table->bigInteger('win_amount')->default(0);
|
||||
$table->bigInteger('jackpot_win_amount')->default(0);
|
||||
$table->timestamp('settled_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['player_id', 'draw_id'], 'idx_ticket_items_player_draw');
|
||||
$table->index(['draw_id', 'status'], 'idx_ticket_items_draw_status');
|
||||
$table->index(['draw_id', 'normalized_number'], 'idx_ticket_items_draw_number');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ticket_items');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('ticket_combinations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('ticket_item_id')->constrained('ticket_items')->cascadeOnDelete();
|
||||
$table->unsignedInteger('combination_no')->default(0);
|
||||
$table->char('number_4d', 4);
|
||||
$table->bigInteger('bet_amount')->default(0);
|
||||
$table->bigInteger('estimated_payout')->default(0);
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->index('ticket_item_id', 'idx_ticket_combinations_item');
|
||||
$table->index('number_4d', 'idx_ticket_combinations_number');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('ticket_combinations');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('risk_pools', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->char('normalized_number', 4);
|
||||
$table->bigInteger('total_cap_amount')->default(0);
|
||||
$table->bigInteger('locked_amount')->default(0);
|
||||
$table->bigInteger('remaining_amount')->default(0);
|
||||
$table->unsignedTinyInteger('sold_out_status')->default(0);
|
||||
$table->unsignedBigInteger('version')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['draw_id', 'normalized_number'], 'uk_risk_pools_draw_number');
|
||||
$table->index(['draw_id', 'sold_out_status'], 'idx_risk_pools_draw_soldout');
|
||||
});
|
||||
|
||||
Schema::create('risk_pool_lock_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->char('normalized_number', 4);
|
||||
$table->foreignId('ticket_item_id')->nullable()->constrained('ticket_items')->nullOnDelete();
|
||||
$table->string('action_type', 16);
|
||||
$table->bigInteger('amount')->default(0);
|
||||
$table->string('source_reason', 32)->nullable();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->index(['draw_id', 'normalized_number'], 'idx_risk_lock_logs_draw_number');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('risk_pool_lock_logs');
|
||||
Schema::dropIfExists('risk_pools');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('settlement_batches', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->foreignId('result_batch_id')->constrained('draw_result_batches')->cascadeOnDelete();
|
||||
$table->unsignedInteger('settle_version')->default(1);
|
||||
$table->string('status', 32);
|
||||
$table->unsignedInteger('total_ticket_count')->default(0);
|
||||
$table->unsignedInteger('total_win_count')->default(0);
|
||||
$table->bigInteger('total_payout_amount')->default(0);
|
||||
$table->bigInteger('total_jackpot_payout_amount')->default(0);
|
||||
$table->string('review_status', 32)->default('pending');
|
||||
$table->foreignId('reviewed_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->timestamp('reviewed_at')->nullable();
|
||||
$table->string('review_remark', 255)->nullable();
|
||||
$table->timestamp('paid_at')->nullable();
|
||||
$table->timestamp('started_at')->nullable();
|
||||
$table->timestamp('finished_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['draw_id', 'settle_version'], 'idx_settlement_batches_draw_version');
|
||||
});
|
||||
|
||||
Schema::create('ticket_settlement_details', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('settlement_batch_id')->constrained('settlement_batches')->cascadeOnDelete();
|
||||
$table->foreignId('ticket_item_id')->constrained('ticket_items')->cascadeOnDelete();
|
||||
$table->string('matched_prize_tier', 32)->nullable();
|
||||
$table->bigInteger('win_amount')->default(0);
|
||||
$table->bigInteger('jackpot_allocation_amount')->default(0);
|
||||
$table->json('match_detail_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['settlement_batch_id', 'ticket_item_id'], 'uk_ticket_settlement_batch_ticket');
|
||||
});
|
||||
|
||||
Schema::create('jackpot_pools', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('currency_code', 16)->unique();
|
||||
$table->bigInteger('current_amount')->default(0);
|
||||
$table->decimal('contribution_rate', 8, 4)->default(0);
|
||||
$table->bigInteger('trigger_threshold')->default(0);
|
||||
$table->decimal('payout_rate', 8, 4)->default(0);
|
||||
$table->unsignedInteger('force_trigger_draw_gap')->default(0);
|
||||
$table->bigInteger('min_bet_amount')->default(0);
|
||||
$table->unsignedTinyInteger('status')->default(0)->comment('0=off,1=on');
|
||||
$table->foreignId('last_trigger_draw_id')->nullable()->constrained('draws')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('jackpot_contributions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('jackpot_pool_id')->constrained('jackpot_pools')->cascadeOnDelete();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->foreignId('ticket_item_id')->nullable()->constrained('ticket_items')->nullOnDelete();
|
||||
$table->bigInteger('contribution_amount')->default(0);
|
||||
$table->string('currency_code', 16);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['draw_id', 'player_id'], 'idx_jackpot_contrib_draw_player');
|
||||
});
|
||||
|
||||
Schema::create('jackpot_payout_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('draw_id')->constrained('draws')->cascadeOnDelete();
|
||||
$table->foreignId('jackpot_pool_id')->constrained('jackpot_pools')->cascadeOnDelete();
|
||||
$table->string('trigger_type', 32);
|
||||
$table->bigInteger('total_payout_amount')->default(0);
|
||||
$table->unsignedInteger('winner_count')->default(0);
|
||||
$table->json('trigger_snapshot_json')->nullable();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jackpot_payout_logs');
|
||||
Schema::dropIfExists('jackpot_contributions');
|
||||
Schema::dropIfExists('jackpot_pools');
|
||||
Schema::dropIfExists('ticket_settlement_details');
|
||||
Schema::dropIfExists('settlement_batches');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('report_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('job_no', 64)->unique();
|
||||
$table->foreignId('admin_user_id')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->string('report_type', 64);
|
||||
$table->string('export_format', 16)->default('csv');
|
||||
$table->json('filter_json')->nullable();
|
||||
$table->string('status', 32);
|
||||
$table->string('output_path', 512)->nullable();
|
||||
$table->text('error_message')->nullable();
|
||||
$table->timestamp('finished_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('audit_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('operator_type', 16);
|
||||
$table->unsignedBigInteger('operator_id')->default(0);
|
||||
$table->string('module_code', 32)->nullable();
|
||||
$table->string('action_code', 32)->nullable();
|
||||
$table->string('target_type', 32)->nullable();
|
||||
$table->string('target_id', 64)->nullable();
|
||||
$table->json('before_json')->nullable();
|
||||
$table->json('after_json')->nullable();
|
||||
$table->string('ip', 64)->nullable();
|
||||
$table->string('user_agent', 255)->nullable();
|
||||
$table->timestamp('created_at')->useCurrent();
|
||||
|
||||
$table->index(['operator_type', 'operator_id', 'created_at'], 'idx_audit_logs_operator_time');
|
||||
$table->index(['module_code', 'action_code'], 'idx_audit_logs_module_action');
|
||||
});
|
||||
|
||||
Schema::create('system_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('job_key', 128)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->string('schedule_cron', 64)->nullable();
|
||||
$table->boolean('is_enabled')->default(true);
|
||||
$table->timestamp('last_started_at')->nullable();
|
||||
$table->timestamp('last_finished_at')->nullable();
|
||||
$table->string('last_status', 32)->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('reconcile_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('job_no', 64)->unique();
|
||||
$table->string('reconcile_type', 32);
|
||||
$table->string('status', 32);
|
||||
$table->timestamp('period_start')->nullable();
|
||||
$table->timestamp('period_end')->nullable();
|
||||
$table->json('summary_json')->nullable();
|
||||
$table->timestamp('finished_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('reconcile_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('reconcile_job_id')->constrained('reconcile_jobs')->cascadeOnDelete();
|
||||
$table->string('side_a_ref', 128)->nullable();
|
||||
$table->string('side_b_ref', 128)->nullable();
|
||||
$table->bigInteger('difference_amount')->default(0);
|
||||
$table->string('status', 32);
|
||||
$table->timestamp('resolved_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('reconcile_items');
|
||||
Schema::dropIfExists('reconcile_jobs');
|
||||
Schema::dropIfExists('system_jobs');
|
||||
Schema::dropIfExists('audit_logs');
|
||||
Schema::dropIfExists('report_jobs');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 【任务 3 · 配置中心】键值运行时配置。
|
||||
*
|
||||
* 与 `config/*.php` / `.env` 分工:
|
||||
* - 密钥、站点 URL 等仍以 env 为准,不进库或不在此表明文扩写密钥;
|
||||
* - 可随时由运营调整的开关、限额类配置放本表,读时走 LotterySettings 带缓存。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('lottery_settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('setting_key', 160)->unique();
|
||||
$table->json('value_json');
|
||||
$table->string('group_name', 64)->default('general')->comment('控制台分组展示用');
|
||||
$table->string('description_zh')->nullable()->comment('运维说明');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('group_name', 'idx_lottery_settings_group');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('lottery_settings');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->text('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 将历史上重复时间戳的 migration 文件名同步到 migrations 表,避免重命名后被视为未执行。
|
||||
*
|
||||
* 新装库:UPDATE 命中 0 行,无影响。
|
||||
* 已有库:把旧文件名改为新文件名,与重命名后的 PHP 文件一致。
|
||||
*
|
||||
* 若从旧文件名升级且 `php artisan migrate` 报「列已存在」等重复执行错误,请先单独执行本文件再全量 migrate:
|
||||
* php artisan migrate --path=database/migrations/2026_05_09_119999_rename_duplicate_migration_filenames_in_table.php
|
||||
* php artisan migrate
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var array<string, string> */
|
||||
private const RENAMES = [
|
||||
'2026_05_09_120000_add_username_and_nullable_email_to_admin_users' => '2026_05_09_120001_add_username_and_nullable_email_to_admin_users',
|
||||
'2026_05_09_120000_migrate_draw_status_to_domain_dict' => '2026_05_09_120002_migrate_draw_status_to_domain_dict',
|
||||
'2026_05_25_120000_consolidate_play_display_name_columns' => '2026_05_25_120001_consolidate_play_display_name_columns',
|
||||
'2026_05_25_120000_expand_audit_logs_target_type' => '2026_05_25_120002_expand_audit_logs_target_type',
|
||||
'2026_05_25_120000_refine_admin_permission_granularity' => '2026_05_25_120003_refine_admin_permission_granularity',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
foreach (self::RENAMES as $from => $to) {
|
||||
DB::table('migrations')->where('migration', $from)->update(['migration' => $to]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
foreach (self::RENAMES as $from => $to) {
|
||||
DB::table('migrations')->where('migration', $to)->update(['migration' => $from]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('username', 64)->nullable()->after('id');
|
||||
});
|
||||
|
||||
$this->backfillUsernames();
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('username', 64)->nullable(false)->change();
|
||||
$table->unique('username');
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->dropUnique(['email']);
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('email')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->dropUnique(['username']);
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->dropColumn('username');
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('email')->nullable(false)->change();
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->unique('email');
|
||||
});
|
||||
}
|
||||
|
||||
private function backfillUsernames(): void
|
||||
{
|
||||
$reserved = [];
|
||||
|
||||
foreach (DB::table('admin_users')->orderBy('id')->cursor() as $row) {
|
||||
$email = (string) $row->email;
|
||||
$local = Str::lower(Str::before($email, '@'));
|
||||
$slug = preg_replace('/[^a-z0-9._-]/', '', $local);
|
||||
$base = Str::substr($slug !== '' ? $slug : 'admin'.(string) $row->id, 0, 50);
|
||||
if ($base === '') {
|
||||
$base = 'admin'.(string) $row->id;
|
||||
}
|
||||
|
||||
$candidate = $base;
|
||||
$n = 0;
|
||||
while (in_array($candidate, $reserved, true)
|
||||
|| DB::table('admin_users')->where('username', $candidate)->where('id', '!=', $row->id)->exists()) {
|
||||
$n++;
|
||||
$suffix = '_'.$n;
|
||||
$candidate = Str::substr($base, 0, 64 - strlen($suffix)).$suffix;
|
||||
}
|
||||
|
||||
$reserved[] = $candidate;
|
||||
|
||||
DB::table('admin_users')->where('id', $row->id)->update(['username' => $candidate]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 将旧版期号状态值迁移为《04-领域字典》约定。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('draws')->where('status', 'pending_review')->update(['status' => 'review']);
|
||||
DB::table('draws')->where('status', 'published')->update(['status' => 'cooldown']);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('draws')->where('status', 'review')->update(['status' => 'pending_review']);
|
||||
DB::table('draws')->where('status', 'cooldown')->update(['status' => 'published']);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('reconcile_jobs', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')
|
||||
->nullable()
|
||||
->constrained('admin_users')
|
||||
->nullOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('reconcile_jobs', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('admin_user_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('admin_user_permissions', function (Blueprint $table) {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('permission_id')->constrained('admin_permissions')->cascadeOnDelete();
|
||||
$table->primary(['admin_user_id', 'permission_id']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_user_permissions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,728 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$this->createTables();
|
||||
$this->seedInitialData();
|
||||
$this->migrateLegacyAssignments();
|
||||
$this->dropLegacyTables();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->recreateLegacyTables();
|
||||
$this->migrateBackToLegacyTables();
|
||||
|
||||
Schema::dropIfExists('admin_user_site_roles');
|
||||
Schema::dropIfExists('admin_user_menu_actions');
|
||||
Schema::dropIfExists('admin_user_data_scopes');
|
||||
Schema::dropIfExists('admin_role_menu_actions');
|
||||
Schema::dropIfExists('admin_role_api_resources');
|
||||
Schema::dropIfExists('admin_role_menus');
|
||||
Schema::dropIfExists('admin_role_data_scopes');
|
||||
Schema::dropIfExists('admin_api_resource_bindings');
|
||||
Schema::dropIfExists('admin_api_resources');
|
||||
Schema::dropIfExists('admin_menu_actions');
|
||||
Schema::dropIfExists('admin_action_catalog');
|
||||
Schema::dropIfExists('admin_menus');
|
||||
Schema::dropIfExists('admin_data_scopes');
|
||||
Schema::dropIfExists('admin_sites');
|
||||
}
|
||||
|
||||
private function createTables(): void
|
||||
{
|
||||
Schema::create('admin_sites', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('code', 64)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->string('currency_code', 16)->default('NPR');
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->boolean('is_default')->default(false);
|
||||
$table->json('extra_json')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::table('admin_roles', function (Blueprint $table): void {
|
||||
$table->string('code', 64)->nullable()->after('id');
|
||||
$table->text('description')->nullable()->after('name');
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled')->after('description');
|
||||
$table->boolean('is_system')->default(false)->after('status');
|
||||
$table->unsignedInteger('sort_order')->default(0)->after('is_system');
|
||||
});
|
||||
|
||||
DB::table('admin_roles')->update([
|
||||
'code' => DB::raw('slug'),
|
||||
'status' => 1,
|
||||
'is_system' => true,
|
||||
'sort_order' => 0,
|
||||
]);
|
||||
|
||||
Schema::table('admin_roles', function (Blueprint $table): void {
|
||||
$table->string('code', 64)->nullable(false)->change();
|
||||
$table->unique('code');
|
||||
});
|
||||
|
||||
Schema::create('admin_menus', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('parent_id')->nullable()->constrained('admin_menus')->nullOnDelete();
|
||||
$table->string('menu_type', 24)->comment('directory|menu|page');
|
||||
$table->string('code', 128)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->string('path', 255)->nullable();
|
||||
$table->string('route_name', 255)->nullable();
|
||||
$table->string('component', 255)->nullable();
|
||||
$table->string('icon', 128)->nullable();
|
||||
$table->string('active_menu_code', 128)->nullable();
|
||||
$table->unsignedInteger('sort_order')->default(0);
|
||||
$table->boolean('is_visible')->default(true);
|
||||
$table->boolean('is_cache')->default(false);
|
||||
$table->boolean('is_external')->default(false);
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->json('meta_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['parent_id', 'sort_order'], 'idx_admin_menus_parent_sort');
|
||||
});
|
||||
|
||||
Schema::create('admin_action_catalog', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('code', 64)->unique();
|
||||
$table->string('name', 64);
|
||||
$table->unsignedInteger('sort_order')->default(0);
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('admin_menu_actions', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('menu_id')->constrained('admin_menus')->cascadeOnDelete();
|
||||
$table->foreignId('action_id')->constrained('admin_action_catalog')->cascadeOnDelete();
|
||||
$table->string('permission_code', 128)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['menu_id', 'action_id'], 'uk_admin_menu_actions_menu_action');
|
||||
$table->index(['menu_id', 'status'], 'idx_admin_menu_actions_menu_status');
|
||||
});
|
||||
|
||||
Schema::create('admin_api_resources', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('code', 128)->unique();
|
||||
$table->string('module_code', 64);
|
||||
$table->string('name', 128);
|
||||
$table->string('http_method', 16);
|
||||
$table->string('uri_pattern', 255);
|
||||
$table->string('route_name', 255)->nullable();
|
||||
$table->string('auth_mode', 24)->default('permission_required')->comment('login_only|permission_required|internal_only');
|
||||
$table->boolean('is_audit_required')->default(false);
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->json('meta_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['module_code', 'status'], 'idx_admin_api_resources_module_status');
|
||||
});
|
||||
|
||||
Schema::create('admin_api_resource_bindings', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('api_resource_id')->constrained('admin_api_resources')->cascadeOnDelete();
|
||||
$table->foreignId('menu_action_id')->constrained('admin_menu_actions')->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['api_resource_id', 'menu_action_id'], 'uk_admin_api_bindings_api_action');
|
||||
});
|
||||
|
||||
Schema::create('admin_data_scopes', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('code', 64)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->string('scope_type', 32)->comment('all_sites|site_only|site_all_data|site_single_player|self_only');
|
||||
$table->string('module_code', 64)->nullable();
|
||||
$table->text('description')->nullable();
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('admin_role_menus', function (Blueprint $table): void {
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->foreignId('menu_id')->constrained('admin_menus')->cascadeOnDelete();
|
||||
$table->primary(['role_id', 'menu_id']);
|
||||
});
|
||||
|
||||
Schema::create('admin_role_menu_actions', function (Blueprint $table): void {
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->foreignId('menu_action_id')->constrained('admin_menu_actions')->cascadeOnDelete();
|
||||
$table->primary(['role_id', 'menu_action_id']);
|
||||
});
|
||||
|
||||
Schema::create('admin_role_api_resources', function (Blueprint $table): void {
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->foreignId('api_resource_id')->constrained('admin_api_resources')->cascadeOnDelete();
|
||||
$table->primary(['role_id', 'api_resource_id']);
|
||||
});
|
||||
|
||||
Schema::create('admin_role_data_scopes', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->foreignId('site_id')->nullable()->constrained('admin_sites')->nullOnDelete();
|
||||
$table->foreignId('data_scope_id')->constrained('admin_data_scopes')->cascadeOnDelete();
|
||||
$table->string('module_code', 64)->nullable();
|
||||
$table->json('constraint_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['role_id', 'site_id', 'data_scope_id', 'module_code'], 'uk_admin_role_data_scopes');
|
||||
});
|
||||
|
||||
Schema::create('admin_user_site_roles', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('site_id')->constrained('admin_sites')->cascadeOnDelete();
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->timestamp('granted_at')->nullable();
|
||||
$table->primary(['admin_user_id', 'site_id', 'role_id'], 'pk_admin_user_site_roles');
|
||||
});
|
||||
|
||||
Schema::create('admin_user_menu_actions', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('site_id')->nullable()->constrained('admin_sites')->nullOnDelete();
|
||||
$table->foreignId('menu_action_id')->constrained('admin_menu_actions')->cascadeOnDelete();
|
||||
$table->timestamp('granted_at')->nullable();
|
||||
$table->primary(['admin_user_id', 'site_id', 'menu_action_id'], 'pk_admin_user_menu_actions');
|
||||
});
|
||||
|
||||
Schema::create('admin_user_data_scopes', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('site_id')->nullable()->constrained('admin_sites')->nullOnDelete();
|
||||
$table->foreignId('data_scope_id')->constrained('admin_data_scopes')->cascadeOnDelete();
|
||||
$table->string('module_code', 64)->nullable();
|
||||
$table->json('constraint_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['admin_user_id', 'site_id', 'data_scope_id', 'module_code'], 'uk_admin_user_data_scopes');
|
||||
});
|
||||
}
|
||||
|
||||
private function seedInitialData(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
DB::table('admin_sites')->insert([
|
||||
'code' => 'default_site',
|
||||
'name' => '默认站点',
|
||||
'currency_code' => 'NPR',
|
||||
'status' => 1,
|
||||
'is_default' => true,
|
||||
'extra_json' => json_encode(['source' => 'migration'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
DB::table('admin_action_catalog')->insert([
|
||||
['code' => 'view', 'name' => '查看', 'sort_order' => 10, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'create', 'name' => '新增', 'sort_order' => 20, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'update', 'name' => '编辑', 'sort_order' => 30, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'delete', 'name' => '删除', 'sort_order' => 40, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'review', 'name' => '审核', 'sort_order' => 50, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'publish', 'name' => '发布', 'sort_order' => 60, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'export', 'name' => '导出', 'sort_order' => 70, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'manage', 'name' => '管理', 'sort_order' => 80, 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
]);
|
||||
|
||||
DB::table('admin_data_scopes')->insert([
|
||||
['code' => 'all_sites', 'name' => '全站点', 'scope_type' => 'all_sites', 'module_code' => null, 'description' => '可访问所有站点数据', 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'site_only', 'name' => '指定站点', 'scope_type' => 'site_only', 'module_code' => null, 'description' => '仅限授权站点登录和访问', 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'site_all_data', 'name' => '站点内全部数据', 'scope_type' => 'site_all_data', 'module_code' => null, 'description' => '可访问站点内全部业务数据', 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'site_single_player', 'name' => '站点内单玩家', 'scope_type' => 'site_single_player', 'module_code' => 'player_service', 'description' => '仅限按指定玩家处理客诉与查单', 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
['code' => 'self_only', 'name' => '仅本人相关', 'scope_type' => 'self_only', 'module_code' => 'audit', 'description' => '仅可查看与自身相关的数据', 'status' => 1, 'created_at' => $now, 'updated_at' => $now],
|
||||
]);
|
||||
|
||||
$this->seedMenuTree($now);
|
||||
$this->seedApiResources($now);
|
||||
}
|
||||
|
||||
private function seedMenuTree(Carbon $now): void
|
||||
{
|
||||
$menus = [
|
||||
['parent_code' => null, 'menu_type' => 'menu', 'code' => 'dashboard', 'name' => '仪表盘', 'path' => '/admin', 'route_name' => 'admin.dashboard', 'component' => 'dashboard/index', 'icon' => 'layout-dashboard', 'sort_order' => 10],
|
||||
['parent_code' => null, 'menu_type' => 'directory', 'code' => 'draw', 'name' => '开奖管理', 'path' => '/admin/draws', 'route_name' => null, 'component' => null, 'icon' => 'dice-5', 'sort_order' => 20],
|
||||
['parent_code' => 'draw', 'menu_type' => 'page', 'code' => 'draw.results', 'name' => '开奖结果', 'path' => '/admin/draws', 'route_name' => 'admin.draws.index', 'component' => 'draw/results', 'icon' => null, 'sort_order' => 10],
|
||||
['parent_code' => 'draw', 'menu_type' => 'page', 'code' => 'draw.review', 'name' => '开奖审核', 'path' => '/admin/draws/review', 'route_name' => 'admin.draws.review', 'component' => 'draw/review', 'icon' => null, 'sort_order' => 20],
|
||||
['parent_code' => null, 'menu_type' => 'directory', 'code' => 'config', 'name' => '运营配置', 'path' => '/admin/config', 'route_name' => null, 'component' => null, 'icon' => 'sliders-horizontal', 'sort_order' => 30],
|
||||
['parent_code' => 'config', 'menu_type' => 'page', 'code' => 'config.play', 'name' => '玩法开关', 'path' => '/admin/config/play-switches', 'route_name' => 'admin.config.play', 'component' => 'config/play', 'icon' => null, 'sort_order' => 10],
|
||||
['parent_code' => 'config', 'menu_type' => 'page', 'code' => 'config.odds', 'name' => '赔率配置', 'path' => '/admin/config/odds', 'route_name' => 'admin.config.odds', 'component' => 'config/odds', 'icon' => null, 'sort_order' => 20],
|
||||
['parent_code' => 'config', 'menu_type' => 'page', 'code' => 'config.risk_cap', 'name' => '封顶配置', 'path' => '/admin/config/play-limits', 'route_name' => 'admin.config.risk_cap', 'component' => 'config/risk-cap', 'icon' => null, 'sort_order' => 30],
|
||||
['parent_code' => 'config', 'menu_type' => 'page', 'code' => 'config.jackpot', 'name' => 'Jackpot 配置', 'path' => '/admin/jackpot/pools', 'route_name' => 'admin.jackpot.pools', 'component' => 'config/jackpot', 'icon' => null, 'sort_order' => 40],
|
||||
['parent_code' => null, 'menu_type' => 'page', 'code' => 'risk.monitor', 'name' => '风控监控', 'path' => '/admin/risk', 'route_name' => 'admin.risk.monitor', 'component' => 'risk/monitor', 'icon' => 'shield-alert', 'sort_order' => 40],
|
||||
['parent_code' => null, 'menu_type' => 'page', 'code' => 'settlement.batch', 'name' => '结算批次', 'path' => '/admin/settlement-batches', 'route_name' => 'admin.settlement.batches', 'component' => 'settlement/batches', 'icon' => 'receipt-text', 'sort_order' => 50],
|
||||
['parent_code' => null, 'menu_type' => 'directory', 'code' => 'service', 'name' => '客服财务', 'path' => '/admin/service-desk', 'route_name' => null, 'component' => null, 'icon' => 'hand-helping', 'sort_order' => 60],
|
||||
['parent_code' => 'service', 'menu_type' => 'page', 'code' => 'service.players', 'name' => '玩家查询', 'path' => '/admin/players', 'route_name' => 'admin.players.index', 'component' => 'service/players', 'icon' => null, 'sort_order' => 10],
|
||||
['parent_code' => 'service', 'menu_type' => 'page', 'code' => 'service.tickets', 'name' => '玩家注单', 'path' => '/admin/tickets', 'route_name' => 'admin.tickets.index', 'component' => 'service/tickets', 'icon' => null, 'sort_order' => 20],
|
||||
['parent_code' => 'service', 'menu_type' => 'page', 'code' => 'service.wallet', 'name' => '钱包流水', 'path' => '/admin/wallet/transactions', 'route_name' => 'admin.wallet.transactions', 'component' => 'service/wallet', 'icon' => null, 'sort_order' => 30],
|
||||
['parent_code' => 'service', 'menu_type' => 'page', 'code' => 'service.reconcile', 'name' => '对账管理', 'path' => '/admin/reconcile', 'route_name' => 'admin.reconcile.index', 'component' => 'service/reconcile', 'icon' => null, 'sort_order' => 40],
|
||||
['parent_code' => 'service', 'menu_type' => 'page', 'code' => 'service.audit', 'name' => '审计日志', 'path' => '/admin/audit-logs', 'route_name' => 'admin.audit.index', 'component' => 'service/audit', 'icon' => null, 'sort_order' => 60],
|
||||
['parent_code' => null, 'menu_type' => 'page', 'code' => 'system.admin_user', 'name' => '管理员权限', 'path' => '/admin/admin-users', 'route_name' => 'admin.system.admin-users', 'component' => 'system/admin-users', 'icon' => 'users-round', 'sort_order' => 70],
|
||||
['parent_code' => null, 'menu_type' => 'page', 'code' => 'system.admin_role', 'name' => '角色管理', 'path' => '/admin/admin-roles', 'route_name' => 'admin.system.admin-roles', 'component' => 'system/admin-roles', 'icon' => 'shield-check', 'sort_order' => 71],
|
||||
];
|
||||
|
||||
$menuIds = [];
|
||||
foreach ($menus as $menu) {
|
||||
$menuIds[$menu['code']] = DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => $menu['parent_code'] === null ? null : $menuIds[$menu['parent_code']],
|
||||
'menu_type' => $menu['menu_type'],
|
||||
'code' => $menu['code'],
|
||||
'name' => $menu['name'],
|
||||
'path' => $menu['path'],
|
||||
'route_name' => $menu['route_name'],
|
||||
'component' => $menu['component'],
|
||||
'icon' => $menu['icon'],
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => $menu['sort_order'],
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$actionIds = DB::table('admin_action_catalog')->pluck('id', 'code');
|
||||
$menuActions = [
|
||||
['menu_code' => 'draw.results', 'action_code' => 'view', 'permission_code' => 'draw.results.view', 'name' => '开奖结果查看'],
|
||||
['menu_code' => 'draw.review', 'action_code' => 'review', 'permission_code' => 'draw.review.review', 'name' => '开奖审核'],
|
||||
['menu_code' => 'draw.review', 'action_code' => 'publish', 'permission_code' => 'draw.review.publish', 'name' => '开奖发布'],
|
||||
['menu_code' => 'config.play', 'action_code' => 'manage', 'permission_code' => 'config.play.manage', 'name' => '玩法开关管理'],
|
||||
['menu_code' => 'config.odds', 'action_code' => 'manage', 'permission_code' => 'config.odds.manage', 'name' => '赔率配置管理'],
|
||||
['menu_code' => 'config.risk_cap', 'action_code' => 'view', 'permission_code' => 'config.risk_cap.view', 'name' => '封顶配置查看'],
|
||||
['menu_code' => 'config.risk_cap', 'action_code' => 'manage', 'permission_code' => 'config.risk_cap.manage', 'name' => '封顶配置管理'],
|
||||
['menu_code' => 'config.jackpot', 'action_code' => 'view', 'permission_code' => 'config.jackpot.view', 'name' => 'Jackpot 查看'],
|
||||
['menu_code' => 'config.jackpot', 'action_code' => 'manage', 'permission_code' => 'config.jackpot.manage', 'name' => 'Jackpot 管理'],
|
||||
['menu_code' => 'risk.monitor', 'action_code' => 'view', 'permission_code' => 'risk.monitor.view', 'name' => '风控监控查看'],
|
||||
['menu_code' => 'settlement.batch', 'action_code' => 'view', 'permission_code' => 'settlement.batch.view', 'name' => '结算查看'],
|
||||
['menu_code' => 'settlement.batch', 'action_code' => 'review', 'permission_code' => 'settlement.batch.review', 'name' => '结算审核'],
|
||||
['menu_code' => 'settlement.batch', 'action_code' => 'manage', 'permission_code' => 'settlement.batch.manage', 'name' => '结算执行'],
|
||||
['menu_code' => 'service.players', 'action_code' => 'view', 'permission_code' => 'service.players.view', 'name' => '玩家查询查看'],
|
||||
['menu_code' => 'service.players', 'action_code' => 'manage', 'permission_code' => 'service.players.manage', 'name' => '玩家查询管理'],
|
||||
['menu_code' => 'service.players', 'action_code' => 'update', 'permission_code' => 'service.players.freeze', 'name' => '冻结解冻玩家'],
|
||||
['menu_code' => 'service.tickets', 'action_code' => 'view', 'permission_code' => 'service.tickets.view', 'name' => '玩家注单查看'],
|
||||
['menu_code' => 'service.wallet', 'action_code' => 'view', 'permission_code' => 'service.wallet.view', 'name' => '钱包流水查看'],
|
||||
['menu_code' => 'service.wallet', 'action_code' => 'manage', 'permission_code' => 'service.wallet.manage', 'name' => '钱包流水管理'],
|
||||
['menu_code' => 'service.reconcile', 'action_code' => 'view', 'permission_code' => 'service.reconcile.view', 'name' => '对账查看'],
|
||||
['menu_code' => 'service.reconcile', 'action_code' => 'manage', 'permission_code' => 'service.reconcile.manage', 'name' => '对账管理'],
|
||||
['menu_code' => 'service.audit', 'action_code' => 'view', 'permission_code' => 'service.audit.view', 'name' => '审计查看'],
|
||||
['menu_code' => 'system.admin_user', 'action_code' => 'manage', 'permission_code' => 'system.admin_user.manage', 'name' => '管理员权限管理'],
|
||||
['menu_code' => 'system.admin_role', 'action_code' => 'manage', 'permission_code' => 'system.admin_role.manage', 'name' => '角色权限管理'],
|
||||
];
|
||||
|
||||
foreach ($menuActions as $row) {
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => $menuIds[$row['menu_code']],
|
||||
'action_id' => $actionIds[$row['action_code']],
|
||||
'permission_code' => $row['permission_code'],
|
||||
'name' => $row['name'],
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function seedApiResources(Carbon $now): void
|
||||
{
|
||||
$resources = [
|
||||
['code' => 'admin.dashboard', 'module_code' => 'dashboard', 'name' => '后台仪表盘', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/dashboard', 'route_name' => 'api.v1.admin.dashboard', 'auth_mode' => 'login_only', 'is_audit_required' => false, 'permission_codes' => []],
|
||||
['code' => 'admin.draws.index', 'module_code' => 'draw', 'name' => '期开奖列表', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/draws', 'route_name' => 'api.v1.admin.draws.index', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['draw.results.view']],
|
||||
['code' => 'admin.draws.show', 'module_code' => 'draw', 'name' => '期开奖详情', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/draws/{draw}', 'route_name' => 'api.v1.admin.draws.show', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['draw.results.view']],
|
||||
['code' => 'admin.draws.publish', 'module_code' => 'draw', 'name' => '开奖发布', 'http_method' => 'POST', 'uri_pattern' => '/api/v1/admin/draws/{draw}/result-batches/{batch}/publish', 'route_name' => 'api.v1.admin.draws.result-batches.publish', 'auth_mode' => 'permission_required', 'is_audit_required' => true, 'permission_codes' => ['draw.review.publish']],
|
||||
['code' => 'admin.draws.settlement.run', 'module_code' => 'settlement', 'name' => '执行结算', 'http_method' => 'POST', 'uri_pattern' => '/api/v1/admin/draws/{draw}/settlement/run', 'route_name' => 'api.v1.admin.draws.settlement.run', 'auth_mode' => 'permission_required', 'is_audit_required' => true, 'permission_codes' => ['settlement.batch.manage', 'settlement.batch.review']],
|
||||
['code' => 'admin.wallet.transactions', 'module_code' => 'wallet', 'name' => '钱包流水查询', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/wallet/transactions', 'route_name' => 'api.v1.admin.wallet.transactions', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['service.wallet.view', 'service.wallet.manage']],
|
||||
['code' => 'admin.wallet.transfer-orders', 'module_code' => 'wallet', 'name' => '转账单查询', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/wallet/transfer-orders', 'route_name' => 'api.v1.admin.wallet.transfer-orders', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['service.wallet.view', 'service.wallet.manage']],
|
||||
['code' => 'admin.players.wallets', 'module_code' => 'player_service', 'name' => '玩家钱包查看', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/players/{player}/wallets', 'route_name' => 'api.v1.admin.players.wallets', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['service.players.manage', 'service.wallet.view']],
|
||||
['code' => 'admin.players.ticket-items', 'module_code' => 'player_service', 'name' => '玩家注单查看', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/players/{player}/ticket-items', 'route_name' => 'api.v1.admin.players.ticket-items.index', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['service.players.manage', 'service.tickets.view']],
|
||||
['code' => 'admin.reconcile.index', 'module_code' => 'reconcile', 'name' => '对账任务列表', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/reconcile-jobs', 'route_name' => 'api.v1.admin.reconcile-jobs.index', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['service.reconcile.view', 'service.reconcile.manage']],
|
||||
['code' => 'admin.reconcile.store', 'module_code' => 'reconcile', 'name' => '创建对账任务', 'http_method' => 'POST', 'uri_pattern' => '/api/v1/admin/reconcile-jobs', 'route_name' => 'api.v1.admin.reconcile-jobs.store', 'auth_mode' => 'permission_required', 'is_audit_required' => true, 'permission_codes' => ['service.reconcile.manage']],
|
||||
['code' => 'admin.audit.index', 'module_code' => 'audit', 'name' => '审计日志查询', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/audit-logs', 'route_name' => 'api.v1.admin.audit-logs.index', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['service.audit.view']],
|
||||
['code' => 'admin.admin-users.index', 'module_code' => 'system', 'name' => '管理员列表', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/admin-users', 'route_name' => 'api.v1.admin.admin-users.index', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['system.admin_user.manage']],
|
||||
['code' => 'admin.admin-users.permission-catalog', 'module_code' => 'system', 'name' => '管理员权限目录', 'http_method' => 'GET', 'uri_pattern' => '/api/v1/admin/admin-user-permission-catalog', 'route_name' => 'api.v1.admin.admin-users.permission-catalog', 'auth_mode' => 'permission_required', 'is_audit_required' => false, 'permission_codes' => ['system.admin_user.manage']],
|
||||
['code' => 'admin.admin-users.permissions.sync', 'module_code' => 'system', 'name' => '管理员权限同步', 'http_method' => 'PUT', 'uri_pattern' => '/api/v1/admin/admin-users/{admin_user}/permissions', 'route_name' => 'api.v1.admin.admin-users.permissions.sync', 'auth_mode' => 'permission_required', 'is_audit_required' => true, 'permission_codes' => ['system.admin_user.manage']],
|
||||
];
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId([
|
||||
'code' => $resource['code'],
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
if (! isset($menuActionIds[$permissionCode])) {
|
||||
continue;
|
||||
}
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => $resourceId,
|
||||
'menu_action_id' => $menuActionIds[$permissionCode],
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function migrateLegacyAssignments(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$defaultSiteId = (int) DB::table('admin_sites')->where('is_default', true)->value('id');
|
||||
|
||||
$legacyRoles = DB::table('admin_roles')
|
||||
->select('id', 'code', 'slug', 'name')
|
||||
->get();
|
||||
|
||||
$legacyRoleAssignments = DB::table('admin_user_roles')->get();
|
||||
foreach ($legacyRoleAssignments as $row) {
|
||||
$legacyRoleId = (int) $row->role_id;
|
||||
DB::table('admin_user_site_roles')->insert([
|
||||
'admin_user_id' => (int) $row->admin_user_id,
|
||||
'site_id' => $defaultSiteId,
|
||||
'role_id' => $legacyRoleId,
|
||||
'granted_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$legacyPermissionById = DB::table('admin_permissions')->pluck('slug', 'id');
|
||||
$legacyRolePermissions = DB::table('admin_role_permissions')->get()->groupBy('role_id');
|
||||
$legacyUserPermissions = DB::table('admin_user_permissions')->get()->groupBy('admin_user_id');
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$apiResourceIdsByPermission = DB::table('admin_api_resource_bindings')
|
||||
->join('admin_menu_actions', 'admin_menu_actions.id', '=', 'admin_api_resource_bindings.menu_action_id')
|
||||
->select('admin_menu_actions.permission_code', 'admin_api_resource_bindings.api_resource_id')
|
||||
->get()
|
||||
->groupBy('permission_code')
|
||||
->map(static fn ($rows) => $rows->pluck('api_resource_id')->all());
|
||||
$menuIdsByPermission = DB::table('admin_menu_actions')
|
||||
->join('admin_menus', 'admin_menus.id', '=', 'admin_menu_actions.menu_id')
|
||||
->pluck('admin_menus.id', 'admin_menu_actions.permission_code');
|
||||
|
||||
$legacyToNewPermissionMap = [
|
||||
'prd.users.manage' => ['service.players.manage'],
|
||||
'prd.users.view_finance' => ['service.players.view', 'service.wallet.view'],
|
||||
'prd.users.view_cs' => ['service.players.view', 'service.tickets.view'],
|
||||
'prd.play_switch.manage' => ['config.play.manage'],
|
||||
'prd.odds.manage' => ['config.odds.manage'],
|
||||
'prd.risk_cap.manage' => ['config.risk_cap.manage'],
|
||||
'prd.risk_cap.view' => ['config.risk_cap.view'],
|
||||
'prd.rebate.manage' => ['config.odds.manage'],
|
||||
'prd.rebate.view' => ['config.odds.manage'],
|
||||
'prd.jackpot.manage' => ['config.jackpot.manage'],
|
||||
'prd.jackpot.view' => ['config.jackpot.view'],
|
||||
'prd.draw_result.manage' => ['draw.results.view', 'draw.review.review', 'draw.review.publish', 'risk.monitor.view'],
|
||||
'prd.draw_result.view' => ['draw.results.view', 'risk.monitor.view'],
|
||||
'prd.payout.manage' => ['settlement.batch.manage', 'settlement.batch.view'],
|
||||
'prd.payout.review' => ['settlement.batch.review', 'settlement.batch.view'],
|
||||
'prd.payout.view' => ['settlement.batch.view'],
|
||||
'prd.wallet_reconcile.manage' => ['service.wallet.manage', 'service.reconcile.manage'],
|
||||
'prd.wallet_reconcile.view' => ['service.wallet.view', 'service.reconcile.view'],
|
||||
'prd.wallet_reconcile.view_cs' => ['service.wallet.view', 'service.reconcile.view'],
|
||||
'prd.audit.all' => ['service.audit.view'],
|
||||
'prd.audit.self' => ['service.audit.view'],
|
||||
'prd.audit.finance' => ['service.audit.view'],
|
||||
'prd.admin_user.manage' => ['system.admin_user.manage'],
|
||||
'prd.player_freeze.manage' => ['service.players.freeze'],
|
||||
'prd.wallet_adjust.manage' => ['service.wallet.manage'],
|
||||
'prd.draw_reopen.manage' => ['draw.review.publish'],
|
||||
];
|
||||
|
||||
foreach ($legacyRoles as $role) {
|
||||
$roleId = (int) $role->id;
|
||||
|
||||
$grantedPermissions = [];
|
||||
foreach ($legacyRolePermissions->get((int) $role->id, collect()) as $pivot) {
|
||||
$permissionId = (int) $pivot->permission_id;
|
||||
$legacySlug = $legacyPermissionById[$permissionId] ?? null;
|
||||
if (! is_string($legacySlug)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($legacyToNewPermissionMap[$legacySlug] ?? [] as $permissionCode) {
|
||||
$grantedPermissions[$permissionCode] = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($grantedPermissions) as $permissionCode) {
|
||||
if (isset($menuIdsByPermission[$permissionCode])) {
|
||||
$this->grantMenuWithAncestors($roleId, (int) $menuIdsByPermission[$permissionCode]);
|
||||
}
|
||||
if (isset($menuActionIds[$permissionCode])) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => $roleId,
|
||||
'menu_action_id' => (int) $menuActionIds[$permissionCode],
|
||||
]);
|
||||
}
|
||||
foreach ($apiResourceIdsByPermission[$permissionCode] ?? [] as $apiResourceId) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => $roleId,
|
||||
'api_resource_id' => (int) $apiResourceId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$roleCode = (string) ($role->code ?: $role->slug);
|
||||
$this->assignRoleDataScopes($roleId, $roleCode, $defaultSiteId, $now);
|
||||
}
|
||||
|
||||
foreach ($legacyUserPermissions as $adminUserId => $pivots) {
|
||||
$grantedPermissions = [];
|
||||
foreach ($pivots as $pivot) {
|
||||
$permissionId = (int) $pivot->permission_id;
|
||||
$legacySlug = $legacyPermissionById[$permissionId] ?? null;
|
||||
if (! is_string($legacySlug)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($legacyToNewPermissionMap[$legacySlug] ?? [] as $permissionCode) {
|
||||
$grantedPermissions[$permissionCode] = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($grantedPermissions) as $permissionCode) {
|
||||
if (! isset($menuActionIds[$permissionCode])) {
|
||||
continue;
|
||||
}
|
||||
DB::table('admin_user_menu_actions')->updateOrInsert([
|
||||
'admin_user_id' => (int) $adminUserId,
|
||||
'site_id' => $defaultSiteId,
|
||||
'menu_action_id' => (int) $menuActionIds[$permissionCode],
|
||||
], [
|
||||
'granted_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function assignRoleDataScopes(int $roleId, string $roleCode, int $siteId, Carbon $now): void
|
||||
{
|
||||
$dataScopeIds = DB::table('admin_data_scopes')->pluck('id', 'code');
|
||||
|
||||
$rows = match ($roleCode) {
|
||||
'super_admin' => [
|
||||
['scope_code' => 'all_sites', 'module_code' => null],
|
||||
['scope_code' => 'site_all_data', 'module_code' => null],
|
||||
],
|
||||
'risk_operator' => [
|
||||
['scope_code' => 'site_only', 'module_code' => null],
|
||||
['scope_code' => 'site_all_data', 'module_code' => 'risk'],
|
||||
['scope_code' => 'self_only', 'module_code' => 'audit'],
|
||||
],
|
||||
'finance' => [
|
||||
['scope_code' => 'site_only', 'module_code' => null],
|
||||
['scope_code' => 'site_all_data', 'module_code' => 'wallet'],
|
||||
['scope_code' => 'site_all_data', 'module_code' => 'settlement'],
|
||||
['scope_code' => 'site_all_data', 'module_code' => 'report'],
|
||||
['scope_code' => 'site_all_data', 'module_code' => 'reconcile'],
|
||||
],
|
||||
'customer_service' => [
|
||||
['scope_code' => 'site_only', 'module_code' => null],
|
||||
['scope_code' => 'site_single_player', 'module_code' => 'player_service'],
|
||||
],
|
||||
default => [
|
||||
['scope_code' => 'site_only', 'module_code' => null],
|
||||
],
|
||||
};
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$scopeId = $dataScopeIds[$row['scope_code']] ?? null;
|
||||
if ($scopeId === null) {
|
||||
continue;
|
||||
}
|
||||
DB::table('admin_role_data_scopes')->insert([
|
||||
'role_id' => $roleId,
|
||||
'site_id' => $row['scope_code'] === 'all_sites' ? null : $siteId,
|
||||
'data_scope_id' => (int) $scopeId,
|
||||
'module_code' => $row['module_code'],
|
||||
'constraint_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function grantMenuWithAncestors(int $roleId, int $menuId): void
|
||||
{
|
||||
$currentMenuId = $menuId;
|
||||
|
||||
while ($currentMenuId > 0) {
|
||||
DB::table('admin_role_menus')->updateOrInsert([
|
||||
'role_id' => $roleId,
|
||||
'menu_id' => $currentMenuId,
|
||||
]);
|
||||
|
||||
$parentId = DB::table('admin_menus')->where('id', $currentMenuId)->value('parent_id');
|
||||
$currentMenuId = $parentId === null ? 0 : (int) $parentId;
|
||||
}
|
||||
}
|
||||
|
||||
private function dropLegacyTables(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_user_permissions');
|
||||
Schema::dropIfExists('admin_user_roles');
|
||||
Schema::dropIfExists('admin_role_permissions');
|
||||
Schema::dropIfExists('admin_permissions');
|
||||
}
|
||||
|
||||
private function recreateLegacyTables(): void
|
||||
{
|
||||
Schema::table('admin_roles', function (Blueprint $table): void {
|
||||
$table->dropUnique(['code']);
|
||||
$table->dropColumn(['code', 'description', 'status', 'is_system', 'sort_order']);
|
||||
});
|
||||
|
||||
Schema::create('admin_permissions', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('slug', 128)->unique();
|
||||
$table->string('name', 128);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('admin_role_permissions', function (Blueprint $table): void {
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->foreignId('permission_id')->constrained('admin_permissions')->cascadeOnDelete();
|
||||
$table->primary(['role_id', 'permission_id']);
|
||||
});
|
||||
|
||||
Schema::create('admin_user_roles', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->primary(['admin_user_id', 'role_id']);
|
||||
});
|
||||
|
||||
Schema::create('admin_user_permissions', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('permission_id')->constrained('admin_permissions')->cascadeOnDelete();
|
||||
$table->primary(['admin_user_id', 'permission_id']);
|
||||
});
|
||||
}
|
||||
|
||||
private function migrateBackToLegacyTables(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$legacyPermissions = [
|
||||
['slug' => 'prd.users.manage', 'name' => '用户管理·可管理'],
|
||||
['slug' => 'prd.users.view_finance', 'name' => '用户管理·财务查看'],
|
||||
['slug' => 'prd.users.view_cs', 'name' => '用户管理·客服单用户'],
|
||||
['slug' => 'prd.play_switch.manage', 'name' => '玩法开关·可管理'],
|
||||
['slug' => 'prd.odds.manage', 'name' => '赔率配置·可管理'],
|
||||
['slug' => 'prd.risk_cap.manage', 'name' => '封顶配置·可管理'],
|
||||
['slug' => 'prd.risk_cap.view', 'name' => '封顶配置·查看'],
|
||||
['slug' => 'prd.rebate.manage', 'name' => '佣金/回水·可管理'],
|
||||
['slug' => 'prd.rebate.view', 'name' => '佣金/回水·查看'],
|
||||
['slug' => 'prd.jackpot.manage', 'name' => 'Jackpot 配置·可管理'],
|
||||
['slug' => 'prd.jackpot.view', 'name' => 'Jackpot 配置·查看'],
|
||||
['slug' => 'prd.draw_result.manage', 'name' => '开奖结果录入·可管理'],
|
||||
['slug' => 'prd.draw_result.view', 'name' => '开奖结果·查看'],
|
||||
['slug' => 'prd.draw_reopen.manage', 'name' => '开奖结果重开·可管理'],
|
||||
['slug' => 'prd.payout.manage', 'name' => '派彩确认·可管理'],
|
||||
['slug' => 'prd.payout.review', 'name' => '派彩确认·可审核'],
|
||||
['slug' => 'prd.payout.view', 'name' => '派彩确认·查看'],
|
||||
['slug' => 'prd.wallet_reconcile.manage', 'name' => '钱包对账·可管理'],
|
||||
['slug' => 'prd.wallet_reconcile.view', 'name' => '钱包对账·查看'],
|
||||
['slug' => 'prd.wallet_reconcile.view_cs', 'name' => '钱包对账·客服单用户'],
|
||||
['slug' => 'prd.wallet_adjust.manage', 'name' => '补单/冲正·可管理'],
|
||||
['slug' => 'prd.audit.all', 'name' => '审计日志·全部'],
|
||||
['slug' => 'prd.audit.self', 'name' => '审计日志·自身相关'],
|
||||
['slug' => 'prd.audit.finance', 'name' => '审计日志·资金相关'],
|
||||
['slug' => 'prd.player_freeze.manage', 'name' => '冻结/解冻玩家·可管理'],
|
||||
['slug' => 'prd.admin_user.manage', 'name' => '后台用户权限管理·可管理'],
|
||||
];
|
||||
|
||||
foreach ($legacyPermissions as $permission) {
|
||||
DB::table('admin_permissions')->insert([
|
||||
'slug' => $permission['slug'],
|
||||
'name' => $permission['name'],
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$permissionIds = DB::table('admin_permissions')->pluck('id', 'slug');
|
||||
$roleCodeMap = DB::table('admin_roles')->pluck('id', 'slug');
|
||||
|
||||
$rolePermissionMap = [
|
||||
'super_admin' => array_keys($permissionIds->all()),
|
||||
'risk_operator' => [
|
||||
'prd.play_switch.manage',
|
||||
'prd.odds.manage',
|
||||
'prd.risk_cap.manage',
|
||||
'prd.rebate.manage',
|
||||
'prd.jackpot.manage',
|
||||
'prd.draw_result.manage',
|
||||
'prd.payout.review',
|
||||
'prd.wallet_reconcile.view',
|
||||
'prd.audit.self',
|
||||
'prd.player_freeze.manage',
|
||||
],
|
||||
'finance' => [
|
||||
'prd.users.view_finance',
|
||||
'prd.risk_cap.view',
|
||||
'prd.rebate.view',
|
||||
'prd.jackpot.view',
|
||||
'prd.draw_result.view',
|
||||
'prd.payout.view',
|
||||
'prd.wallet_reconcile.manage',
|
||||
'prd.wallet_adjust.manage',
|
||||
'prd.audit.finance',
|
||||
],
|
||||
'customer_service' => [
|
||||
'prd.users.view_cs',
|
||||
'prd.draw_result.view',
|
||||
'prd.wallet_reconcile.view_cs',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($rolePermissionMap as $roleCode => $permissionSlugs) {
|
||||
$roleId = $roleCodeMap[$roleCode] ?? null;
|
||||
if ($roleId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($permissionSlugs as $slug) {
|
||||
$permissionId = $permissionIds[$slug] ?? null;
|
||||
if ($permissionId === null) {
|
||||
continue;
|
||||
}
|
||||
DB::table('admin_role_permissions')->insert([
|
||||
'role_id' => (int) $roleId,
|
||||
'permission_id' => (int) $permissionId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$userRoles = DB::table('admin_user_site_roles')
|
||||
->select('admin_user_id', 'role_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
foreach ($userRoles as $row) {
|
||||
DB::table('admin_user_roles')->insert([
|
||||
'admin_user_id' => (int) $row->admin_user_id,
|
||||
'role_id' => (int) $row->role_id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('play_config_items', function (Blueprint $table): void {
|
||||
$table->string('category', 16)->nullable()->after('play_code');
|
||||
$table->unsignedTinyInteger('dimension')->nullable()->after('category');
|
||||
$table->string('bet_mode', 32)->nullable()->after('dimension');
|
||||
$table->string('display_name_zh', 64)->nullable()->after('bet_mode');
|
||||
$table->string('display_name_en', 64)->nullable()->after('display_name_zh');
|
||||
$table->string('display_name_ne', 64)->nullable()->after('display_name_en');
|
||||
$table->boolean('supports_multi_number')->default(false)->after('display_name_ne');
|
||||
$table->json('reserved_rule_json')->nullable()->after('supports_multi_number');
|
||||
});
|
||||
|
||||
$playTypes = DB::table('play_types')
|
||||
->select([
|
||||
'play_code',
|
||||
'category',
|
||||
'dimension',
|
||||
'bet_mode',
|
||||
'display_name_zh',
|
||||
'display_name_en',
|
||||
'display_name_ne',
|
||||
'supports_multi_number',
|
||||
'reserved_rule_json',
|
||||
])
|
||||
->get()
|
||||
->keyBy('play_code');
|
||||
|
||||
DB::table('play_config_items')
|
||||
->select(['id', 'play_code'])
|
||||
->orderBy('id')
|
||||
->chunkById(200, function ($rows) use ($playTypes): void {
|
||||
foreach ($rows as $row) {
|
||||
$pt = $playTypes->get($row->play_code);
|
||||
if ($pt === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('play_config_items')
|
||||
->where('id', $row->id)
|
||||
->update([
|
||||
'category' => $pt->category,
|
||||
'dimension' => $pt->dimension,
|
||||
'bet_mode' => $pt->bet_mode,
|
||||
'display_name_zh' => $pt->display_name_zh,
|
||||
'display_name_en' => $pt->display_name_en,
|
||||
'display_name_ne' => $pt->display_name_ne,
|
||||
'supports_multi_number' => (bool) $pt->supports_multi_number,
|
||||
'reserved_rule_json' => $pt->reserved_rule_json,
|
||||
]);
|
||||
}
|
||||
}, 'id');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('play_config_items', function (Blueprint $table): void {
|
||||
$table->dropColumn([
|
||||
'category',
|
||||
'dimension',
|
||||
'bet_mode',
|
||||
'display_name_zh',
|
||||
'display_name_en',
|
||||
'display_name_ne',
|
||||
'supports_multi_number',
|
||||
'reserved_rule_json',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('jackpot_pools', function (Blueprint $table): void {
|
||||
$table->json('combo_trigger_play_codes')->nullable()->after('min_bet_amount');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('jackpot_pools', function (Blueprint $table): void {
|
||||
$table->dropColumn('combo_trigger_play_codes');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ticket_orders', function (Blueprint $table): void {
|
||||
$table->unsignedInteger('play_config_version_no')->default(0)->after('client_trace_id');
|
||||
$table->unsignedInteger('odds_version_no')->default(0)->after('play_config_version_no');
|
||||
$table->unsignedInteger('risk_cap_version_no')->default(0)->after('odds_version_no');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ticket_orders', function (Blueprint $table): void {
|
||||
$table->dropColumn([
|
||||
'play_config_version_no',
|
||||
'odds_version_no',
|
||||
'risk_cap_version_no',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
DB::table('admin_role_api_resources')->delete();
|
||||
|
||||
$roleResourceRows = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_api_resource_bindings as arb', 'arb.menu_action_id', '=', 'rma.menu_action_id')
|
||||
->select('rma.role_id', 'arb.api_resource_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
foreach ($roleResourceRows as $row) {
|
||||
DB::table('admin_role_api_resources')->insert([
|
||||
'role_id' => (int) $row->role_id,
|
||||
'api_resource_id' => (int) $row->api_resource_id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 保持数据升级可逆风险最低:不在 down 中尝试删除资源,避免误删线上已使用授权关系。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$currencyCodes = DB::table('currencies')
|
||||
->where('is_enabled', true)
|
||||
->where('is_bettable', true)
|
||||
->pluck('code')
|
||||
->filter(static fn ($code): bool => is_string($code) && trim($code) !== '')
|
||||
->map(static fn (string $code): string => strtoupper($code))
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
if ($currencyCodes->isEmpty()) {
|
||||
$currencyCodes = collect([strtoupper((string) config('lottery.default_currency', 'NPR'))]);
|
||||
}
|
||||
|
||||
foreach ($currencyCodes as $currencyCode) {
|
||||
$exists = DB::table('jackpot_pools')->where('currency_code', $currencyCode)->exists();
|
||||
if ($exists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('jackpot_pools')->insert([
|
||||
'currency_code' => $currencyCode,
|
||||
'current_amount' => 0,
|
||||
'contribution_rate' => '0.0200',
|
||||
'trigger_threshold' => 100_000_000,
|
||||
'payout_rate' => '0.5000',
|
||||
'force_trigger_draw_gap' => 100,
|
||||
'min_bet_amount' => 100,
|
||||
'status' => 0,
|
||||
'last_trigger_draw_id' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 保留奖池配置与水位,避免回滚误删运营数据。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use App\Support\AdminPermissionBridge;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('admin_role_legacy_permissions', function (Blueprint $table): void {
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->string('permission_slug', 128);
|
||||
$table->timestamps();
|
||||
|
||||
$table->primary(['role_id', 'permission_slug'], 'pk_admin_role_legacy_permissions');
|
||||
});
|
||||
|
||||
$now = now();
|
||||
$roleCodes = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_menu_actions as ma', 'ma.id', '=', 'rma.menu_action_id')
|
||||
->where('ma.status', 1)
|
||||
->select('rma.role_id', 'ma.permission_code')
|
||||
->get()
|
||||
->groupBy('role_id');
|
||||
|
||||
foreach ($roleCodes as $roleId => $rows) {
|
||||
$slugs = AdminPermissionBridge::legacySlugsGrantedByMenuActionCodes(
|
||||
$rows->pluck('permission_code')->all(),
|
||||
);
|
||||
foreach ($slugs as $slug) {
|
||||
DB::table('admin_role_legacy_permissions')->insert([
|
||||
'role_id' => (int) $roleId,
|
||||
'permission_slug' => $slug,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_role_legacy_permissions');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use App\Support\AdminPermissionBridge;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$actionCatalogId = (int) DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
|
||||
$adminUserMenuId = (int) DB::table('admin_menus')->where('code', 'system.admin_user')->value('id');
|
||||
|
||||
if ($adminUserMenuId > 0) {
|
||||
$adminUserMenu = DB::table('admin_menus')->where('id', $adminUserMenuId)->first();
|
||||
DB::table('admin_menus')->updateOrInsert(
|
||||
['code' => 'system.admin_role'],
|
||||
[
|
||||
'parent_id' => $adminUserMenu->parent_id,
|
||||
'menu_type' => 'page',
|
||||
'name' => '角色管理',
|
||||
'path' => '/admin/admin-roles',
|
||||
'route_name' => 'admin.system.admin-roles',
|
||||
'component' => 'system/admin-roles',
|
||||
'icon' => 'shield-check',
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => ((int) $adminUserMenu->sort_order) + 1,
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$menuId = (int) DB::table('admin_menus')->where('code', 'system.admin_role')->value('id');
|
||||
|
||||
if ($actionCatalogId > 0 && $menuId > 0) {
|
||||
DB::table('admin_menu_actions')->updateOrInsert(
|
||||
['permission_code' => 'system.admin_role.manage'],
|
||||
[
|
||||
'menu_id' => $menuId,
|
||||
'action_id' => $actionCatalogId,
|
||||
'name' => '角色权限管理',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$adminRoleSlug = 'prd.admin_role.manage';
|
||||
$adminUserSlug = 'prd.admin_user.manage';
|
||||
$roleIds = DB::table('admin_role_legacy_permissions')
|
||||
->where('permission_slug', $adminUserSlug)
|
||||
->pluck('role_id')
|
||||
->all();
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
DB::table('admin_role_legacy_permissions')->updateOrInsert(
|
||||
[
|
||||
'role_id' => (int) $roleId,
|
||||
'permission_slug' => $adminRoleSlug,
|
||||
],
|
||||
[
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
|
||||
foreach (AdminPermissionBridge::menuActionCodesForLegacy($adminRoleSlug) as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不回滚授权数据,避免删除线上已经显式授予的角色管理权限。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$playersMenuId = (int) DB::table('admin_menus')->where('code', 'service.players')->value('id');
|
||||
$updateActionId = (int) DB::table('admin_action_catalog')->where('code', 'update')->value('id');
|
||||
|
||||
if ($playersMenuId > 0 && $updateActionId > 0) {
|
||||
DB::table('admin_menu_actions')->updateOrInsert(
|
||||
['permission_code' => 'service.players.freeze'],
|
||||
[
|
||||
'menu_id' => $playersMenuId,
|
||||
'action_id' => $updateActionId,
|
||||
'name' => '冻结解冻玩家',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$playerResourceBindings = [
|
||||
'admin.players.index' => ['service.players.manage', 'service.players.view'],
|
||||
'admin.players.store' => ['service.players.manage'],
|
||||
'admin.players.show' => ['service.players.manage', 'service.players.view'],
|
||||
'admin.players.update' => ['service.players.manage'],
|
||||
'admin.players.destroy' => ['service.players.manage'],
|
||||
'admin.players.freeze' => ['service.players.freeze'],
|
||||
'admin.players.unfreeze' => ['service.players.freeze'],
|
||||
'admin.players.wallets' => ['service.players.manage', 'service.wallet.view'],
|
||||
'admin.players.ticket-items' => ['service.players.manage', 'service.tickets.view'],
|
||||
];
|
||||
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
if (($resource['module_code'] ?? null) !== 'player_service') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
$permissionCodes = $playerResourceBindings[$resource['code']] ?? $resource['permission_codes'];
|
||||
foreach ($permissionCodes as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不回滚授权绑定,避免误删线上已调整的资源权限关系。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', 'admin.tickets.index')
|
||||
->value('id');
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId([
|
||||
'code' => 'admin.tickets.index',
|
||||
'module_code' => 'ticket',
|
||||
'name' => '后台注单列表',
|
||||
'http_method' => 'GET',
|
||||
'uri_pattern' => '/api/v1/admin/tickets',
|
||||
'route_name' => 'api.v1.admin.tickets.index',
|
||||
'auth_mode' => 'permission_required',
|
||||
'is_audit_required' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$menuActionId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'service.tickets.view')
|
||||
->value('id');
|
||||
|
||||
if ($menuActionId !== null) {
|
||||
$exists = DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', $resourceId)
|
||||
->where('menu_action_id', $menuActionId)
|
||||
->exists();
|
||||
|
||||
if (! $exists) {
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => $resourceId,
|
||||
'menu_action_id' => $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', 'admin.tickets.index')
|
||||
->value('id');
|
||||
|
||||
if ($resourceId !== null) {
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', $resourceId)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', $resourceId)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.currencies.'),
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$roleResourceRows = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_api_resource_bindings as arb', 'arb.menu_action_id', '=', 'rma.menu_action_id')
|
||||
->join('admin_api_resources as ar', 'ar.id', '=', 'arb.api_resource_id')
|
||||
->whereIn('ar.code', array_column($resources, 'code'))
|
||||
->select('rma.role_id', 'arb.api_resource_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
foreach ($roleResourceRows as $row) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $row->role_id,
|
||||
'api_resource_id' => (int) $row->api_resource_id,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceCodes = ['admin.currencies.index', 'admin.currencies.store', 'admin.currencies.update'];
|
||||
|
||||
$resourceIds = DB::table('admin_api_resources')
|
||||
->whereIn('code', $resourceCodes)
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
if ($resourceIds === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_role_api_resources')
|
||||
->whereIn('api_resource_id', $resourceIds)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->whereIn('api_resource_id', $resourceIds)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resources')
|
||||
->whereIn('id', $resourceIds)
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('odds_items', function (Blueprint $table) {
|
||||
// 添加 dimension 字段用于按 2D/3D/4D 配置佣金
|
||||
$table->unsignedTinyInteger('dimension')->nullable()->after('prize_scope')->comment('2/3/4 维度,佣金按维度配置');
|
||||
|
||||
// 删除旧的唯一约束
|
||||
$table->dropUnique('uk_odds_items_version_play_prize_currency');
|
||||
|
||||
// 添加新的唯一约束:佣金按 dimension + currency_code 配置
|
||||
// 赔率仍按 play_code + prize_scope + currency_code 配置
|
||||
$table->unique(
|
||||
['version_id', 'play_code', 'prize_scope', 'currency_code', 'dimension'],
|
||||
'uk_odds_items_version_play_prize_currency_dimension'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('odds_items', function (Blueprint $table) {
|
||||
// 删除新的唯一约束
|
||||
$table->dropUnique('uk_odds_items_version_play_prize_currency_dimension');
|
||||
|
||||
// 恢复旧的唯一约束
|
||||
$table->unique(
|
||||
['version_id', 'play_code', 'prize_scope', 'currency_code'],
|
||||
'uk_odds_items_version_play_prize_currency'
|
||||
);
|
||||
|
||||
// 删除 dimension 字段
|
||||
$table->dropColumn('dimension');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$resource = collect(AdminAuthorizationRegistry::resources())
|
||||
->first(static fn (array $item): bool => $item['code'] === 'admin.currencies.destroy');
|
||||
|
||||
if ($resource === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$roleResourceRows = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_api_resource_bindings as arb', 'arb.menu_action_id', '=', 'rma.menu_action_id')
|
||||
->where('arb.api_resource_id', (int) $resourceId)
|
||||
->select('rma.role_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
foreach ($roleResourceRows as $row) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $row->role_id,
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', 'admin.currencies.destroy')
|
||||
->value('id');
|
||||
|
||||
if ($resourceId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_role_api_resources')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$serviceMenuId = (int) DB::table('admin_menus')->where('code', 'service')->value('id');
|
||||
$manageActionId = (int) DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
|
||||
|
||||
if ($serviceMenuId > 0) {
|
||||
DB::table('admin_menus')->updateOrInsert(
|
||||
['code' => 'service.currency'],
|
||||
[
|
||||
'parent_id' => $serviceMenuId,
|
||||
'menu_type' => 'page',
|
||||
'name' => '币种管理',
|
||||
'path' => '/admin/settings/currencies',
|
||||
'route_name' => 'admin.settings.currencies',
|
||||
'component' => 'settings/currencies',
|
||||
'icon' => null,
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => 70,
|
||||
'is_visible' => false,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$currencyMenuId = (int) DB::table('admin_menus')->where('code', 'service.currency')->value('id');
|
||||
if ($currencyMenuId > 0 && $manageActionId > 0) {
|
||||
DB::table('admin_menu_actions')->updateOrInsert(
|
||||
['permission_code' => 'service.currency.manage'],
|
||||
[
|
||||
'menu_id' => $currencyMenuId,
|
||||
'action_id' => $manageActionId,
|
||||
'name' => '币种管理',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if (Schema::hasTable('admin_permissions')) {
|
||||
DB::table('admin_permissions')->updateOrInsert(
|
||||
['slug' => 'prd.currency.manage'],
|
||||
[
|
||||
'name' => '币种管理·可管理',
|
||||
'updated_at' => $now,
|
||||
'created_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$currencyActionId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'service.currency.manage')
|
||||
->value('id');
|
||||
|
||||
if ($currencyActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roleIds = DB::table('admin_role_legacy_permissions')
|
||||
->where('permission_slug', 'prd.users.manage')
|
||||
->pluck('role_id')
|
||||
->all();
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
DB::table('admin_role_legacy_permissions')->updateOrInsert(
|
||||
[
|
||||
'role_id' => (int) $roleId,
|
||||
'permission_slug' => 'prd.currency.manage',
|
||||
],
|
||||
[
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert(
|
||||
[
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => (int) $currencyActionId,
|
||||
],
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
$currencyResourceIds = DB::table('admin_api_resources')
|
||||
->whereIn('code', [
|
||||
'admin.currencies.index',
|
||||
'admin.currencies.store',
|
||||
'admin.currencies.update',
|
||||
'admin.currencies.destroy',
|
||||
])
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
foreach ($currencyResourceIds as $resourceId) {
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $currencyActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$roleResourceRows = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_api_resource_bindings as arb', 'arb.menu_action_id', '=', 'rma.menu_action_id')
|
||||
->whereIn('arb.api_resource_id', $currencyResourceIds)
|
||||
->select('rma.role_id', 'arb.api_resource_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
foreach ($roleResourceRows as $row) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $row->role_id,
|
||||
'api_resource_id' => (int) $row->api_resource_id,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不自动回滚线上角色与资源绑定,避免误删已调整的授权。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('admin_menus')
|
||||
->where('code', 'service.currency')
|
||||
->update([
|
||||
'path' => '/admin/currencies',
|
||||
'route_name' => 'admin.currencies',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('admin_menus')
|
||||
->where('code', 'service.currency')
|
||||
->update([
|
||||
'path' => '/admin/settings/currencies',
|
||||
'route_name' => 'admin.settings.currencies',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$actionViewId = DB::table('admin_action_catalog')->where('code', 'view')->value('id');
|
||||
if ($actionViewId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$serviceMenuId = DB::table('admin_menus')->where('code', 'service')->value('id');
|
||||
if ($serviceMenuId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$reportMenuId = DB::table('admin_menus')->where('code', 'service.report')->value('id');
|
||||
if ($reportMenuId === null) {
|
||||
$reportMenuId = DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => $serviceMenuId,
|
||||
'menu_type' => 'page',
|
||||
'code' => 'service.report',
|
||||
'name' => '报表中心',
|
||||
'path' => '/admin/reports',
|
||||
'route_name' => 'admin.reports.index',
|
||||
'component' => 'service/reports',
|
||||
'icon' => null,
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => 50,
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
if (! isset($menuActionIds['service.report.view'])) {
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => (int) $reportMenuId,
|
||||
'action_id' => (int) $actionViewId,
|
||||
'permission_code' => 'service.report.view',
|
||||
'name' => '报表中心查看',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
}
|
||||
|
||||
$reportResourceCodes = [
|
||||
'admin.reports.daily-profit',
|
||||
'admin.reports.player-win-loss',
|
||||
'admin.reports.play-dimension',
|
||||
'admin.reports.rebate-commission',
|
||||
'admin.report-jobs.index',
|
||||
'admin.report-jobs.store',
|
||||
'admin.report-jobs.show',
|
||||
'admin.report-jobs.download',
|
||||
];
|
||||
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
if (! in_array($resource['code'], $reportResourceCodes, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$superRoleId = DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
|
||||
if ($superRoleId !== null && isset($menuActionIds['service.report.view'])) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $superRoleId,
|
||||
'menu_action_id' => (int) $menuActionIds['service.report.view'],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$codes = [
|
||||
'admin.reports.daily-profit',
|
||||
'admin.reports.player-win-loss',
|
||||
'admin.reports.play-dimension',
|
||||
'admin.reports.rebate-commission',
|
||||
'admin.report-jobs.index',
|
||||
'admin.report-jobs.store',
|
||||
'admin.report-jobs.show',
|
||||
'admin.report-jobs.download',
|
||||
];
|
||||
|
||||
$resourceIds = DB::table('admin_api_resources')->whereIn('code', $codes)->pluck('id');
|
||||
foreach ($resourceIds as $resourceId) {
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
|
||||
$menuActionId = DB::table('admin_menu_actions')->where('permission_code', 'service.report.view')->value('id');
|
||||
if ($menuActionId !== null) {
|
||||
DB::table('admin_role_menu_actions')->where('menu_action_id', (int) $menuActionId)->delete();
|
||||
DB::table('admin_menu_actions')->where('id', (int) $menuActionId)->delete();
|
||||
}
|
||||
|
||||
DB::table('admin_menus')->where('code', 'service.report')->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const STALE_RESOURCE_CODES = [
|
||||
'admin.reports.index',
|
||||
'admin.reports.store',
|
||||
'admin.reconcile.index',
|
||||
'admin.reconcile.store',
|
||||
'admin.draws.publish',
|
||||
];
|
||||
|
||||
/** @var list<string> */
|
||||
private const REPORT_RESOURCE_CODES = [
|
||||
'admin.reports.daily-profit',
|
||||
'admin.reports.player-win-loss',
|
||||
'admin.reports.play-dimension',
|
||||
'admin.reports.rebate-commission',
|
||||
'admin.report-jobs.index',
|
||||
'admin.report-jobs.store',
|
||||
'admin.report-jobs.show',
|
||||
'admin.report-jobs.download',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$this->deleteStaleApiResources();
|
||||
$this->ensureReportViewOnRolesWithReportLegacy();
|
||||
$this->syncReportResourceBindings($now);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 绑定收紧与角色补权为数据修复,不回滚以免再现漂移。
|
||||
}
|
||||
|
||||
private function deleteStaleApiResources(): void
|
||||
{
|
||||
$resourceIds = DB::table('admin_api_resources')
|
||||
->whereIn('code', self::STALE_RESOURCE_CODES)
|
||||
->pluck('id');
|
||||
|
||||
foreach ($resourceIds as $resourceId) {
|
||||
$id = (int) $resourceId;
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', $id)->delete();
|
||||
DB::table('admin_api_resources')->where('id', $id)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureReportViewOnRolesWithReportLegacy(): void
|
||||
{
|
||||
$menuActionId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'service.report.view')
|
||||
->where('status', 1)
|
||||
->value('id');
|
||||
|
||||
if ($menuActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$reportSlugs = ['prd.report.view', 'prd.report.all', 'prd.report.risk', 'prd.report.finance', 'prd.report.player'];
|
||||
$roleIds = DB::table('admin_role_legacy_permissions')
|
||||
->whereIn('permission_slug', $reportSlugs)
|
||||
->distinct()
|
||||
->pluck('role_id');
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function syncReportResourceBindings(Carbon $now): void
|
||||
{
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$registryByCode = [];
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
$registryByCode[$resource['code']] = $resource;
|
||||
}
|
||||
|
||||
foreach (self::REPORT_RESOURCE_CODES as $code) {
|
||||
$resource = $registryByCode[$code] ?? null;
|
||||
if ($resource === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $code)->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 移除未接入业务或已由其它表替代的冗余表:
|
||||
* - system_jobs:从未使用
|
||||
* - admin_role_menus:侧栏改由 prd.* + Registry 驱动
|
||||
* - admin_role_api_resources:鉴权由 role_menu_actions + bindings 实时推导
|
||||
* - admin_*_data_scopes:数据范围未落地
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_user_data_scopes');
|
||||
Schema::dropIfExists('admin_role_data_scopes');
|
||||
Schema::dropIfExists('admin_data_scopes');
|
||||
Schema::dropIfExists('admin_role_api_resources');
|
||||
Schema::dropIfExists('admin_role_menus');
|
||||
Schema::dropIfExists('system_jobs');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 冗余表删除为单向清理,不回滚。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
use App\Models\AdminRole;
|
||||
use App\Support\AdminPermissionBridge;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('admin_role_legacy_permissions')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roleIds = DB::table('admin_roles')->pluck('id');
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
$legacySlugs = DB::table('admin_role_legacy_permissions')
|
||||
->where('role_id', (int) $roleId)
|
||||
->pluck('permission_slug')
|
||||
->all();
|
||||
|
||||
$slugs = AdminPermissionBridge::normalizeCanonicalLegacySlugs(
|
||||
is_array($legacySlugs) ? $legacySlugs : [],
|
||||
);
|
||||
|
||||
if ($slugs === []) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$role = AdminRole::query()->find((int) $roleId);
|
||||
if ($role !== null) {
|
||||
$role->syncLegacyPermissionSlugs($slugs);
|
||||
}
|
||||
}
|
||||
|
||||
Schema::dropIfExists('admin_role_legacy_permissions');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 单向清理:slug 已合并,权限以 admin_role_menu_actions 为准。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use App\Models\LotterySetting;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 玩法规则 HTML:由单键 frontend.play_rules_html 拆分为 zh/en/ne 三语键。
|
||||
* 已有内容迁移到 frontend.play_rules_html_zh。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
private const LEGACY_KEY = 'frontend.play_rules_html';
|
||||
|
||||
private const I18N_KEYS = [
|
||||
'frontend.play_rules_html_zh' => '玩家端玩法规则页 HTML(中文)',
|
||||
'frontend.play_rules_html_en' => '玩家端玩法规则页 HTML(English)',
|
||||
'frontend.play_rules_html_ne' => '玩家端玩法规则页 HTML(नेपाली)',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$legacyRow = LotterySetting::query()->where('setting_key', self::LEGACY_KEY)->first();
|
||||
$legacyValue = $legacyRow?->value_json;
|
||||
|
||||
foreach (self::I18N_KEYS as $key => $description) {
|
||||
if (LotterySetting::query()->where('setting_key', $key)->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = '';
|
||||
if ($key === 'frontend.play_rules_html_zh' && is_string($legacyValue) && trim($legacyValue) !== '') {
|
||||
$value = $legacyValue;
|
||||
}
|
||||
|
||||
LotterySetting::query()->create([
|
||||
'setting_key' => $key,
|
||||
'value_json' => $value,
|
||||
'group_name' => 'frontend',
|
||||
'description_zh' => $description,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
LotterySetting::query()
|
||||
->whereIn('setting_key', array_keys(self::I18N_KEYS))
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
foreach (['play_types', 'play_config_items'] as $table) {
|
||||
Schema::table($table, function (Blueprint $blueprint): void {
|
||||
$blueprint->string('display_name', 64)->nullable()->after('bet_mode');
|
||||
});
|
||||
|
||||
DB::table($table)->update([
|
||||
'display_name' => DB::raw(
|
||||
"COALESCE(
|
||||
NULLIF(TRIM(display_name_zh), ''),
|
||||
NULLIF(TRIM(display_name_en), ''),
|
||||
NULLIF(TRIM(display_name_ne), ''),
|
||||
play_code
|
||||
)",
|
||||
),
|
||||
]);
|
||||
|
||||
Schema::table($table, function (Blueprint $blueprint): void {
|
||||
$blueprint->dropColumn(['display_name_zh', 'display_name_en', 'display_name_ne']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
foreach (['play_types', 'play_config_items'] as $table) {
|
||||
Schema::table($table, function (Blueprint $blueprint): void {
|
||||
$blueprint->string('display_name_zh', 64)->nullable()->after('bet_mode');
|
||||
$blueprint->string('display_name_en', 64)->nullable()->after('display_name_zh');
|
||||
$blueprint->string('display_name_ne', 64)->nullable()->after('display_name_en');
|
||||
});
|
||||
|
||||
DB::table($table)->update([
|
||||
'display_name_zh' => DB::raw('display_name'),
|
||||
'display_name_en' => DB::raw('display_name'),
|
||||
'display_name_ne' => DB::raw('display_name'),
|
||||
]);
|
||||
|
||||
Schema::table($table, function (Blueprint $blueprint): void {
|
||||
$blueprint->dropColumn('display_name');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* admin_api_resources.code 最长可达 128;中间件将完整 code 写入 audit_logs.target_type。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('audit_logs', function (Blueprint $table): void {
|
||||
$table->string('target_type', 128)->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('audit_logs', function (Blueprint $table): void {
|
||||
$table->string('target_type', 32)->nullable()->change();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$actionIds = DB::table('admin_action_catalog')->pluck('id', 'code');
|
||||
$menuIds = DB::table('admin_menus')->pluck('id', 'code');
|
||||
|
||||
$walletMenuId = $menuIds['service.wallet'] ?? null;
|
||||
$updateActionId = $actionIds['update'] ?? null;
|
||||
if ($walletMenuId !== null && $updateActionId !== null) {
|
||||
$exists = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'service.wallet.adjust')
|
||||
->exists();
|
||||
|
||||
if (! $exists) {
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => $walletMenuId,
|
||||
'action_id' => $updateActionId,
|
||||
'permission_code' => 'service.wallet.adjust',
|
||||
'name' => '钱包补单/冲正',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$oddsMenuId = $menuIds['config.odds'] ?? null;
|
||||
$viewActionId = $actionIds['view'] ?? null;
|
||||
if ($oddsMenuId !== null && $viewActionId !== null) {
|
||||
$exists = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'config.odds.view')
|
||||
->exists();
|
||||
|
||||
if (! $exists) {
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => $oddsMenuId,
|
||||
'action_id' => $viewActionId,
|
||||
'permission_code' => 'config.odds.view',
|
||||
'name' => '赔率配置查看',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('admin_menu_actions')
|
||||
->whereIn('permission_code', ['service.wallet.adjust', 'config.odds.view'])
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const STALE_PERMISSION_CODES = [
|
||||
'dashboard.view',
|
||||
'service.reports.view',
|
||||
'service.reports.export',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$menuActionIds = DB::table('admin_menu_actions')
|
||||
->whereIn('permission_code', self::STALE_PERMISSION_CODES)
|
||||
->pluck('id');
|
||||
|
||||
if ($menuActionIds->isNotEmpty()) {
|
||||
DB::table('admin_menu_actions')
|
||||
->whereIn('id', $menuActionIds->all())
|
||||
->delete();
|
||||
}
|
||||
|
||||
$staleReportMenuId = DB::table('admin_menus')
|
||||
->where('code', 'service.reports')
|
||||
->value('id');
|
||||
|
||||
if ($staleReportMenuId !== null) {
|
||||
$hasActions = DB::table('admin_menu_actions')
|
||||
->where('menu_id', (int) $staleReportMenuId)
|
||||
->exists();
|
||||
|
||||
if (! $hasActions) {
|
||||
DB::table('admin_menus')
|
||||
->where('id', (int) $staleReportMenuId)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 数据清理迁移,不回滚以免再现僵尸 permission_code。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
$resource = collect(AdminAuthorizationRegistry::resources())
|
||||
->firstWhere('code', 'admin.dashboard.analytics');
|
||||
|
||||
if ($resource === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', 'admin.dashboard.analytics')
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => 'admin.dashboard.analytics',
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$actionId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', $permissionCode)
|
||||
->value('id');
|
||||
if ($actionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $actionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', 'admin.dashboard.analytics')
|
||||
->value('id');
|
||||
|
||||
if ($resourceId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('settlement_batches', function (Blueprint $table): void {
|
||||
if (! Schema::hasColumn('settlement_batches', 'review_status')) {
|
||||
$table->string('review_status', 32)->default('pending')->after('total_jackpot_payout_amount');
|
||||
}
|
||||
if (! Schema::hasColumn('settlement_batches', 'reviewed_by')) {
|
||||
$table->foreignId('reviewed_by')->nullable()->after('review_status')->constrained('admin_users')->nullOnDelete();
|
||||
}
|
||||
if (! Schema::hasColumn('settlement_batches', 'reviewed_at')) {
|
||||
$table->timestamp('reviewed_at')->nullable()->after('reviewed_by');
|
||||
}
|
||||
if (! Schema::hasColumn('settlement_batches', 'review_remark')) {
|
||||
$table->string('review_remark', 255)->nullable()->after('reviewed_at');
|
||||
}
|
||||
if (! Schema::hasColumn('settlement_batches', 'paid_at')) {
|
||||
$table->timestamp('paid_at')->nullable()->after('review_remark');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('settlement_batches', function (Blueprint $table): void {
|
||||
if (Schema::hasColumn('settlement_batches', 'paid_at')) {
|
||||
$table->dropColumn('paid_at');
|
||||
}
|
||||
if (Schema::hasColumn('settlement_batches', 'review_remark')) {
|
||||
$table->dropColumn('review_remark');
|
||||
}
|
||||
if (Schema::hasColumn('settlement_batches', 'reviewed_at')) {
|
||||
$table->dropColumn('reviewed_at');
|
||||
}
|
||||
if (Schema::hasColumn('settlement_batches', 'reviewed_by')) {
|
||||
$table->dropForeign(['reviewed_by']);
|
||||
$table->dropColumn('reviewed_by');
|
||||
}
|
||||
if (Schema::hasColumn('settlement_batches', 'review_status')) {
|
||||
$table->dropColumn('review_status');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminPermissionBridge;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<array{menu_code: string, action_code: string, permission_code: string, name: string}> */
|
||||
private const NEW_MENU_ACTIONS = [
|
||||
['menu_code' => 'dashboard', 'action_code' => 'view', 'permission_code' => 'dashboard.view', 'name' => '仪表盘查看'],
|
||||
['menu_code' => 'service.report', 'action_code' => 'export', 'permission_code' => 'service.report.export', 'name' => '报表导出'],
|
||||
['menu_code' => 'risk.monitor', 'action_code' => 'manage', 'permission_code' => 'risk.monitor.manage', 'name' => '风控监控管理'],
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuIds = DB::table('admin_menus')->pluck('id', 'code');
|
||||
$actionIds = DB::table('admin_action_catalog')->pluck('id', 'code');
|
||||
|
||||
$menuActionIds = [];
|
||||
foreach (self::NEW_MENU_ACTIONS as $row) {
|
||||
$menuId = $menuIds[$row['menu_code']] ?? null;
|
||||
$actionId = $actionIds[$row['action_code']] ?? null;
|
||||
if ($menuId === null || $actionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$exists = DB::table('admin_menu_actions')
|
||||
->where('permission_code', $row['permission_code'])
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
$menuActionIds[$row['permission_code']] = (int) DB::table('admin_menu_actions')
|
||||
->where('permission_code', $row['permission_code'])
|
||||
->value('id');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$menuActionIds[$row['permission_code']] = (int) DB::table('admin_menu_actions')->insertGetId([
|
||||
'menu_id' => (int) $menuId,
|
||||
'action_id' => (int) $actionId,
|
||||
'permission_code' => $row['permission_code'],
|
||||
'name' => $row['name'],
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->grantMenuActionsToAllRoles($menuActionIds, $now);
|
||||
$this->grantReportExportToReportViewRoles($menuActionIds['service.report.export'] ?? null, $now);
|
||||
$this->grantTicketsViewToLegacyRoles($menuActionIds, $now);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$codes = array_column(self::NEW_MENU_ACTIONS, 'permission_code');
|
||||
$ids = DB::table('admin_menu_actions')->whereIn('permission_code', $codes)->pluck('id');
|
||||
foreach ($ids as $id) {
|
||||
DB::table('admin_role_menu_actions')->where('menu_action_id', (int) $id)->delete();
|
||||
DB::table('admin_user_menu_actions')->where('menu_action_id', (int) $id)->delete();
|
||||
DB::table('admin_api_resource_bindings')->where('menu_action_id', (int) $id)->delete();
|
||||
DB::table('admin_menu_actions')->where('id', (int) $id)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, int> $menuActionIds
|
||||
*/
|
||||
private function grantMenuActionsToAllRoles(array $menuActionIds, Carbon $now): void
|
||||
{
|
||||
$dashboardId = $menuActionIds['dashboard.view'] ?? null;
|
||||
if ($dashboardId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roleIds = DB::table('admin_roles')->pluck('id');
|
||||
foreach ($roleIds as $roleId) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => $dashboardId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function grantReportExportToReportViewRoles(?int $exportMenuActionId, Carbon $now): void
|
||||
{
|
||||
if ($exportMenuActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$viewMenuActionId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'service.report.view')
|
||||
->value('id');
|
||||
|
||||
if ($viewMenuActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roleIds = DB::table('admin_role_menu_actions')
|
||||
->where('menu_action_id', (int) $viewMenuActionId)
|
||||
->distinct()
|
||||
->pluck('role_id');
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => $exportMenuActionId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 原注单入口依赖多种 prd.*;迁移为独立的 prd.tickets.view。
|
||||
*
|
||||
* @param array<string, int> $menuActionIds
|
||||
*/
|
||||
private function grantTicketsViewToLegacyRoles(array $menuActionIds, Carbon $now): void
|
||||
{
|
||||
$ticketsViewId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'service.tickets.view')
|
||||
->value('id');
|
||||
|
||||
if ($ticketsViewId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$legacySlugs = [
|
||||
'prd.users.view_cs',
|
||||
'prd.users.manage',
|
||||
'prd.users.view_finance',
|
||||
'prd.draw_result.view',
|
||||
'prd.draw_result.manage',
|
||||
'prd.payout.view',
|
||||
'prd.payout.review',
|
||||
'prd.payout.manage',
|
||||
];
|
||||
|
||||
$roleIds = $this->roleIdsWithAnyLegacySlug($legacySlugs);
|
||||
|
||||
foreach ($roleIds as $roleId) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => (int) $ticketsViewId,
|
||||
]);
|
||||
}
|
||||
|
||||
$riskViewId = DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'risk.monitor.view')
|
||||
->value('id');
|
||||
$riskManageId = $menuActionIds['risk.monitor.manage'] ?? null;
|
||||
|
||||
if ($riskManageId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$riskRoleIds = $this->roleIdsWithAnyLegacySlug([
|
||||
'prd.draw_result.manage',
|
||||
'prd.draw_result.view',
|
||||
'prd.risk.manage',
|
||||
'prd.risk.view',
|
||||
]);
|
||||
|
||||
foreach ($riskRoleIds as $roleId) {
|
||||
if ($riskViewId !== null) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => (int) $riskViewId,
|
||||
]);
|
||||
}
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $roleId,
|
||||
'menu_action_id' => (int) $riskManageId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过角色已授权的 menu_action 反推曾拥有指定 prd.* 的角色(legacy 表已废弃)。
|
||||
*
|
||||
* @param list<string> $legacySlugs
|
||||
* @return list<int>
|
||||
*/
|
||||
private function roleIdsWithAnyLegacySlug(array $legacySlugs): array
|
||||
{
|
||||
$codes = [];
|
||||
foreach ($legacySlugs as $slug) {
|
||||
$codes = array_merge($codes, AdminPermissionBridge::menuActionCodesForLegacy($slug));
|
||||
}
|
||||
$codes = array_values(array_unique($codes));
|
||||
|
||||
if ($codes === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')
|
||||
->whereIn('permission_code', $codes)
|
||||
->where('status', 1)
|
||||
->pluck('id');
|
||||
|
||||
if ($menuActionIds->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return DB::table('admin_role_menu_actions')
|
||||
->whereIn('menu_action_id', $menuActionIds->map(fn ($id) => (int) $id)->all())
|
||||
->distinct()
|
||||
->pluck('role_id')
|
||||
->map(fn ($id) => (int) $id)
|
||||
->all();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ticket_orders', function (Blueprint $table): void {
|
||||
$table->unique(
|
||||
['player_id', 'draw_id', 'client_trace_id'],
|
||||
'uniq_ticket_orders_player_draw_trace',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('ticket_orders', function (Blueprint $table): void {
|
||||
$table->dropUnique('uniq_ticket_orders_player_draw_trace');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
|
||||
if (! DB::table('admin_action_catalog')->where('code', 'manual_burst')->exists()) {
|
||||
DB::table('admin_action_catalog')->insert([
|
||||
'code' => 'manual_burst',
|
||||
'name' => '手动爆池',
|
||||
'sort_order' => 85,
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$jackpotMenuId = (int) DB::table('admin_menus')->where('code', 'config.jackpot')->value('id');
|
||||
$manualBurstActionId = (int) DB::table('admin_action_catalog')->where('code', 'manual_burst')->value('id');
|
||||
|
||||
if ($jackpotMenuId <= 0 || $manualBurstActionId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_menu_actions')->updateOrInsert(
|
||||
['permission_code' => 'jackpot.pool.manual_burst'],
|
||||
[
|
||||
'menu_id' => $jackpotMenuId,
|
||||
'action_id' => $manualBurstActionId,
|
||||
'name' => 'Jackpot 手动爆池',
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
|
||||
if (Schema::hasTable('admin_permissions')) {
|
||||
DB::table('admin_permissions')->updateOrInsert(
|
||||
['slug' => 'prd.jackpot.manual_burst'],
|
||||
[
|
||||
'name' => 'Jackpot 手动爆池·仅超管',
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
$menuActionId = (int) DB::table('admin_menu_actions')
|
||||
->where('permission_code', 'jackpot.pool.manual_burst')
|
||||
->value('id');
|
||||
|
||||
$superRoleId = (int) DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
|
||||
if ($superRoleId > 0 && $menuActionId > 0) {
|
||||
if (Schema::hasTable('admin_role_legacy_permissions')) {
|
||||
DB::table('admin_role_legacy_permissions')->updateOrInsert(
|
||||
[
|
||||
'role_id' => $superRoleId,
|
||||
'permission_slug' => 'prd.jackpot.manual_burst',
|
||||
],
|
||||
[
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert(
|
||||
[
|
||||
'role_id' => $superRoleId,
|
||||
'menu_action_id' => $menuActionId,
|
||||
],
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', 'admin.jackpot.pools.manual-burst')
|
||||
->value('id');
|
||||
|
||||
if ($resourceId !== null && $menuActionId > 0) {
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
if ($superRoleId > 0 && Schema::hasTable('admin_role_api_resources')) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => $superRoleId,
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 避免误删线上已调整的授权绑定。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('admin_sites', function (Blueprint $table): void {
|
||||
$table->string('wallet_api_url', 512)->nullable()->after('extra_json');
|
||||
$table->string('wallet_debit_path', 128)->default('/wallet/debit-for-lottery')->after('wallet_api_url');
|
||||
$table->string('wallet_credit_path', 128)->default('/wallet/credit-from-lottery')->after('wallet_debit_path');
|
||||
$table->string('wallet_balance_path', 128)->default('/wallet/balance')->after('wallet_credit_path');
|
||||
$table->text('wallet_api_key_encrypted')->nullable()->after('wallet_balance_path');
|
||||
$table->text('sso_jwt_secret_encrypted')->nullable()->after('wallet_api_key_encrypted');
|
||||
$table->unsignedSmallInteger('wallet_timeout_seconds')->default(10)->after('sso_jwt_secret_encrypted');
|
||||
$table->json('iframe_allowed_origins')->nullable()->after('wallet_timeout_seconds');
|
||||
$table->string('lottery_h5_base_url', 512)->nullable()->after('iframe_allowed_origins');
|
||||
$table->text('notes')->nullable()->after('lottery_h5_base_url');
|
||||
});
|
||||
|
||||
$this->seedIntegrationMenuActions();
|
||||
$this->backfillDefaultSiteFromEnv();
|
||||
$this->syncIntegrationApiResources();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceIds = DB::table('admin_api_resources')
|
||||
->where('code', 'like', 'admin.integration-sites.%')
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
if ($resourceIds !== []) {
|
||||
DB::table('admin_role_api_resources')->whereIn('api_resource_id', $resourceIds)->delete();
|
||||
DB::table('admin_api_resource_bindings')->whereIn('api_resource_id', $resourceIds)->delete();
|
||||
DB::table('admin_api_resources')->whereIn('id', $resourceIds)->delete();
|
||||
}
|
||||
|
||||
Schema::table('admin_sites', function (Blueprint $table): void {
|
||||
$table->dropColumn([
|
||||
'wallet_api_url',
|
||||
'wallet_debit_path',
|
||||
'wallet_credit_path',
|
||||
'wallet_balance_path',
|
||||
'wallet_api_key_encrypted',
|
||||
'sso_jwt_secret_encrypted',
|
||||
'wallet_timeout_seconds',
|
||||
'iframe_allowed_origins',
|
||||
'lottery_h5_base_url',
|
||||
'notes',
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
private function seedIntegrationMenuActions(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$viewActionId = DB::table('admin_action_catalog')->where('code', 'view')->value('id');
|
||||
$manageActionId = DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
|
||||
if ($viewActionId === null || $manageActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$configMenuId = DB::table('admin_menus')->where('code', 'config')->value('id');
|
||||
if ($configMenuId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$integrationMenuId = DB::table('admin_menus')->where('code', 'config.integration')->value('id');
|
||||
if ($integrationMenuId === null) {
|
||||
$integrationMenuId = DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => (int) $configMenuId,
|
||||
'menu_type' => 'page',
|
||||
'code' => 'config.integration',
|
||||
'name' => '主站接入站点',
|
||||
'path' => '/admin/config/integration-sites',
|
||||
'route_name' => 'admin.config.integration',
|
||||
'component' => 'config/integration',
|
||||
'icon' => null,
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => 45,
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
['permission_code' => 'integration.site.view', 'action_id' => (int) $viewActionId, 'name' => '接入站点查看'],
|
||||
['permission_code' => 'integration.site.manage', 'action_id' => (int) $manageActionId, 'name' => '接入站点管理'],
|
||||
] as $row) {
|
||||
$exists = DB::table('admin_menu_actions')
|
||||
->where('permission_code', $row['permission_code'])
|
||||
->exists();
|
||||
if ($exists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => (int) $integrationMenuId,
|
||||
'action_id' => $row['action_id'],
|
||||
'permission_code' => $row['permission_code'],
|
||||
'name' => $row['name'],
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function backfillDefaultSiteFromEnv(): void
|
||||
{
|
||||
$siteId = DB::table('admin_sites')->where('is_default', true)->value('id')
|
||||
?? DB::table('admin_sites')->orderBy('id')->value('id');
|
||||
|
||||
if ($siteId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$walletUrl = env('MAIN_SITE_WALLET_API_URL');
|
||||
$ssoSecret = env('MAIN_SITE_SSO_JWT_SECRET');
|
||||
$walletKey = env('MAIN_SITE_WALLET_API_KEY');
|
||||
|
||||
$payload = [
|
||||
'updated_at' => Carbon::now(),
|
||||
];
|
||||
|
||||
if (is_string($walletUrl) && trim($walletUrl) !== '') {
|
||||
$payload['wallet_api_url'] = rtrim(trim($walletUrl), '/');
|
||||
}
|
||||
|
||||
$debitPath = env('MAIN_SITE_WALLET_DEBIT_PATH');
|
||||
if (is_string($debitPath) && $debitPath !== '') {
|
||||
$payload['wallet_debit_path'] = $debitPath;
|
||||
}
|
||||
|
||||
$creditPath = env('MAIN_SITE_WALLET_CREDIT_PATH');
|
||||
if (is_string($creditPath) && $creditPath !== '') {
|
||||
$payload['wallet_credit_path'] = $creditPath;
|
||||
}
|
||||
|
||||
$balancePath = env('MAIN_SITE_WALLET_BALANCE_PATH');
|
||||
if (is_string($balancePath) && $balancePath !== '') {
|
||||
$payload['wallet_balance_path'] = $balancePath;
|
||||
}
|
||||
|
||||
$timeout = env('MAIN_SITE_WALLET_TIMEOUT');
|
||||
if (is_numeric($timeout)) {
|
||||
$payload['wallet_timeout_seconds'] = max(1, (int) $timeout);
|
||||
}
|
||||
|
||||
if (is_string($ssoSecret) && $ssoSecret !== '') {
|
||||
$payload['sso_jwt_secret_encrypted'] = encrypt($ssoSecret);
|
||||
}
|
||||
|
||||
if (is_string($walletKey) && $walletKey !== '') {
|
||||
$payload['wallet_api_key_encrypted'] = encrypt($walletKey);
|
||||
}
|
||||
|
||||
if (count($payload) > 1) {
|
||||
DB::table('admin_sites')->where('id', (int) $siteId)->update($payload);
|
||||
}
|
||||
}
|
||||
|
||||
private function syncIntegrationApiResources(): void
|
||||
{
|
||||
if (! Schema::hasTable('admin_api_resources')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.integration-sites.'),
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 为已执行 140000 的环境补种 integration 权限动作并同步 API 绑定。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$viewActionId = DB::table('admin_action_catalog')->where('code', 'view')->value('id');
|
||||
$manageActionId = DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
|
||||
if ($viewActionId === null || $manageActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$configMenuId = DB::table('admin_menus')->where('code', 'config')->value('id');
|
||||
if ($configMenuId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$integrationMenuId = DB::table('admin_menus')->where('code', 'config.integration')->value('id');
|
||||
if ($integrationMenuId === null) {
|
||||
$integrationMenuId = DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => (int) $configMenuId,
|
||||
'menu_type' => 'page',
|
||||
'code' => 'config.integration',
|
||||
'name' => '主站接入站点',
|
||||
'path' => '/admin/config/integration-sites',
|
||||
'route_name' => 'admin.config.integration',
|
||||
'component' => 'config/integration',
|
||||
'icon' => null,
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => 45,
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
['permission_code' => 'integration.site.view', 'action_id' => (int) $viewActionId, 'name' => '接入站点查看'],
|
||||
['permission_code' => 'integration.site.manage', 'action_id' => (int) $manageActionId, 'name' => '接入站点管理'],
|
||||
] as $row) {
|
||||
if (DB::table('admin_menu_actions')->where('permission_code', $row['permission_code'])->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => (int) $integrationMenuId,
|
||||
'action_id' => $row['action_id'],
|
||||
'permission_code' => $row['permission_code'],
|
||||
'name' => $row['name'],
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.integration-sites.'),
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 保留 menu_actions / bindings,避免回滚后超管无法管理已创建的接入站点。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* `dashboard.view` 在 2026_05_26 才写入 admin_menu_actions,此前 sync 无法绑定
|
||||
* admin.dashboard / admin.dashboard.analytics,导致 permission_required 资源无 bindings。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 数据修复迁移:不在 down 中回滚 bindings,避免误删线上授权关系。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$duplicateIds = DB::table('jackpot_contributions')
|
||||
->select('ticket_item_id')
|
||||
->whereNotNull('ticket_item_id')
|
||||
->groupBy('ticket_item_id')
|
||||
->havingRaw('count(*) > 1')
|
||||
->pluck('ticket_item_id');
|
||||
|
||||
foreach ($duplicateIds as $ticketItemId) {
|
||||
$rows = DB::table('jackpot_contributions')
|
||||
->where('ticket_item_id', $ticketItemId)
|
||||
->orderByDesc('id')
|
||||
->pluck('id');
|
||||
$keep = $rows->shift();
|
||||
if ($keep !== null && $rows->isNotEmpty()) {
|
||||
DB::table('jackpot_contributions')->whereIn('id', $rows->all())->delete();
|
||||
}
|
||||
}
|
||||
|
||||
Schema::table('jackpot_contributions', function (Blueprint $table): void {
|
||||
$table->unique('ticket_item_id', 'uk_jackpot_contributions_ticket_item');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('jackpot_contributions', function (Blueprint $table): void {
|
||||
$table->dropUnique('uk_jackpot_contributions_ticket_item');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('jackpot_pool_adjustments', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('adjustment_no', 32)->unique();
|
||||
$table->foreignId('jackpot_pool_id')->constrained('jackpot_pools')->cascadeOnDelete();
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->bigInteger('amount_delta')->comment('signed minor units; + increase pool');
|
||||
$table->bigInteger('balance_before');
|
||||
$table->bigInteger('balance_after');
|
||||
$table->string('reason', 500);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['jackpot_pool_id', 'created_at'], 'idx_jackpot_pool_adjustments_pool_created');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('jackpot_pool_adjustments');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const RESOURCE_CODES = [
|
||||
'admin.jackpot.pools.adjustments.index',
|
||||
'admin.jackpot.pools.adjustments.store',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$resources = collect(AdminAuthorizationRegistry::resources())
|
||||
->filter(fn (array $item): bool => in_array($item['code'], self::RESOURCE_CODES, true))
|
||||
->values();
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$roleResourceRows = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_api_resource_bindings as arb', 'arb.menu_action_id', '=', 'rma.menu_action_id')
|
||||
->where('arb.api_resource_id', (int) $resourceId)
|
||||
->select('rma.role_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
if (Schema::hasTable('admin_role_api_resources')) {
|
||||
foreach ($roleResourceRows as $row) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $row->role_id,
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
foreach (self::RESOURCE_CODES as $code) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $code)->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Schema::hasTable('admin_role_api_resources')) {
|
||||
DB::table('admin_role_api_resources')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
}
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 对齐高频查询路径(PostgreSQL B-tree)。
|
||||
*
|
||||
* - ticket_orders:按 draw_id 结算/后台汇总
|
||||
* - wallet_txns / ticket_items:player_id + ORDER BY id DESC 分页
|
||||
* - draws:business_date 筛选 + draw_time 排序(往期/报表)
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ticket_orders', function (Blueprint $table): void {
|
||||
$table->index('draw_id', 'idx_ticket_orders_draw_id');
|
||||
});
|
||||
|
||||
Schema::table('wallet_txns', function (Blueprint $table): void {
|
||||
$table->index(['player_id', 'id'], 'idx_wallet_txns_player_id');
|
||||
});
|
||||
|
||||
Schema::table('ticket_items', function (Blueprint $table): void {
|
||||
$table->index(['player_id', 'id'], 'idx_ticket_items_player_id');
|
||||
});
|
||||
|
||||
Schema::table('draws', function (Blueprint $table): void {
|
||||
$table->index(['business_date', 'draw_time'], 'idx_draws_business_date_draw_time');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('draws', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_draws_business_date_draw_time');
|
||||
});
|
||||
|
||||
Schema::table('ticket_items', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_ticket_items_player_id');
|
||||
});
|
||||
|
||||
Schema::table('wallet_txns', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_wallet_txns_player_id');
|
||||
});
|
||||
|
||||
Schema::table('ticket_orders', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_ticket_orders_draw_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
private const RESOURCE_CODE = 'admin.settings.batch-update';
|
||||
|
||||
private const CLONE_BINDINGS_FROM = 'admin.settings.update';
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$resource = collect(AdminAuthorizationRegistry::resources())
|
||||
->first(fn (array $item): bool => $item['code'] === self::RESOURCE_CODE);
|
||||
|
||||
if ($resource === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
$sourceResourceId = DB::table('admin_api_resources')
|
||||
->where('code', self::CLONE_BINDINGS_FROM)
|
||||
->value('id');
|
||||
|
||||
if ($sourceResourceId !== null) {
|
||||
$bindings = DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $sourceResourceId)
|
||||
->get(['menu_action_id']);
|
||||
|
||||
foreach ($bindings as $binding) {
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $binding->menu_action_id,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (Schema::hasTable('admin_role_api_resources')) {
|
||||
$roleResourceRows = DB::table('admin_role_menu_actions as rma')
|
||||
->join('admin_api_resource_bindings as arb', 'arb.menu_action_id', '=', 'rma.menu_action_id')
|
||||
->where('arb.api_resource_id', (int) $resourceId)
|
||||
->select('rma.role_id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
foreach ($roleResourceRows as $row) {
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $row->role_id,
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', self::RESOURCE_CODE)->value('id');
|
||||
if ($resourceId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Schema::hasTable('admin_role_api_resources')) {
|
||||
DB::table('admin_role_api_resources')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
}
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('agent_nodes', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('admin_site_id')->constrained('admin_sites')->cascadeOnDelete();
|
||||
$table->foreignId('parent_id')->nullable()->constrained('agent_nodes')->nullOnDelete();
|
||||
$table->string('path', 512);
|
||||
$table->unsignedSmallInteger('depth')->default(0);
|
||||
$table->string('code', 64);
|
||||
$table->string('name', 128);
|
||||
$table->unsignedTinyInteger('status')->default(1)->comment('1=enabled,0=disabled');
|
||||
$table->foreignId('created_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->json('extra_json')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['admin_site_id', 'code'], 'uk_agent_nodes_site_code');
|
||||
$table->index(['admin_site_id', 'parent_id'], 'idx_agent_nodes_site_parent');
|
||||
$table->index('path', 'idx_agent_nodes_path');
|
||||
});
|
||||
|
||||
Schema::create('admin_user_agents', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')->primary()->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('agent_node_id')->constrained('agent_nodes')->cascadeOnDelete();
|
||||
$table->boolean('is_primary')->default(true);
|
||||
$table->timestamp('granted_at')->nullable();
|
||||
});
|
||||
|
||||
$this->seedRootAgentNodes();
|
||||
$this->backfillAdminUserAgents();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('admin_user_agents');
|
||||
Schema::dropIfExists('agent_nodes');
|
||||
}
|
||||
|
||||
private function seedRootAgentNodes(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$sites = DB::table('admin_sites')->orderBy('id')->get(['id', 'code', 'name']);
|
||||
|
||||
foreach ($sites as $site) {
|
||||
if (DB::table('agent_nodes')->where('admin_site_id', (int) $site->id)->where('depth', 0)->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$code = 'root-'.(string) $site->code;
|
||||
$nodeId = DB::table('agent_nodes')->insertGetId([
|
||||
'admin_site_id' => (int) $site->id,
|
||||
'parent_id' => null,
|
||||
'path' => '/',
|
||||
'depth' => 0,
|
||||
'code' => $code,
|
||||
'name' => (string) $site->name,
|
||||
'status' => 1,
|
||||
'created_by' => null,
|
||||
'extra_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
DB::table('agent_nodes')->where('id', $nodeId)->update([
|
||||
'path' => '/'.$nodeId.'/',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function backfillAdminUserAgents(): void
|
||||
{
|
||||
$superRoleId = DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
|
||||
$now = Carbon::now();
|
||||
|
||||
$userIds = DB::table('admin_users')->pluck('id');
|
||||
foreach ($userIds as $userId) {
|
||||
$userId = (int) $userId;
|
||||
if (DB::table('admin_user_agents')->where('admin_user_id', $userId)->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($superRoleId !== null) {
|
||||
$isSuper = DB::table('admin_user_site_roles')
|
||||
->where('admin_user_id', $userId)
|
||||
->where('role_id', (int) $superRoleId)
|
||||
->exists();
|
||||
if ($isSuper) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$siteId = DB::table('admin_user_site_roles')
|
||||
->where('admin_user_id', $userId)
|
||||
->orderBy('site_id')
|
||||
->value('site_id');
|
||||
|
||||
if ($siteId === null) {
|
||||
$siteId = DB::table('admin_sites')->where('is_default', true)->value('id')
|
||||
?? DB::table('admin_sites')->orderBy('id')->value('id');
|
||||
}
|
||||
|
||||
if ($siteId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rootId = DB::table('agent_nodes')
|
||||
->where('admin_site_id', (int) $siteId)
|
||||
->where('depth', 0)
|
||||
->value('id');
|
||||
|
||||
if ($rootId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_user_agents')->insert([
|
||||
'admin_user_id' => $userId,
|
||||
'agent_node_id' => (int) $rootId,
|
||||
'is_primary' => true,
|
||||
'granted_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$viewActionId = DB::table('admin_action_catalog')->where('code', 'view')->value('id');
|
||||
$manageActionId = DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
|
||||
if ($viewActionId === null || $manageActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$systemMenuId = DB::table('admin_menus')->where('code', 'system')->value('id');
|
||||
if ($systemMenuId === null) {
|
||||
$systemMenuId = DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => null,
|
||||
'menu_type' => 'directory',
|
||||
'code' => 'system',
|
||||
'name' => '系统',
|
||||
'path' => null,
|
||||
'route_name' => null,
|
||||
'component' => null,
|
||||
'icon' => null,
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => 90,
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$agentMenuId = DB::table('admin_menus')->where('code', 'system.agents')->value('id');
|
||||
if ($agentMenuId === null) {
|
||||
$agentMenuId = DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => (int) $systemMenuId,
|
||||
'menu_type' => 'page',
|
||||
'code' => 'system.agents',
|
||||
'name' => '代理管理',
|
||||
'path' => '/admin/agents',
|
||||
'route_name' => 'admin.agents',
|
||||
'component' => 'agents/index',
|
||||
'icon' => null,
|
||||
'active_menu_code' => null,
|
||||
'sort_order' => 25,
|
||||
'is_visible' => true,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
foreach ([
|
||||
['permission_code' => 'agent.node.view', 'action_id' => (int) $viewActionId, 'name' => '代理节点查看'],
|
||||
['permission_code' => 'agent.node.manage', 'action_id' => (int) $manageActionId, 'name' => '代理节点管理'],
|
||||
] as $row) {
|
||||
if (DB::table('admin_menu_actions')->where('permission_code', $row['permission_code'])->exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => (int) $agentMenuId,
|
||||
'action_id' => $row['action_id'],
|
||||
'permission_code' => $row['permission_code'],
|
||||
'name' => $row['name'],
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.agent-nodes.'),
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
$permissionCodes = $resource['permission_codes'] ?? [];
|
||||
foreach ($permissionCodes as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('admin_role_api_resources')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$superRoleId = DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
|
||||
if ($superRoleId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $superRoleId,
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
], []);
|
||||
}
|
||||
|
||||
$menuActionIdList = DB::table('admin_menu_actions')
|
||||
->whereIn('permission_code', ['agent.node.view', 'agent.node.manage'])
|
||||
->pluck('id');
|
||||
|
||||
foreach ($menuActionIdList as $menuActionId) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $superRoleId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$codes = [
|
||||
'admin.agent-nodes.tree',
|
||||
'admin.agent-nodes.store',
|
||||
'admin.agent-nodes.show',
|
||||
'admin.agent-nodes.update',
|
||||
'admin.agent-nodes.children',
|
||||
];
|
||||
|
||||
foreach ($codes as $code) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $code)->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Schema::hasTable('admin_role_api_resources')) {
|
||||
DB::table('admin_role_api_resources')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
}
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
|
||||
DB::table('admin_menu_actions')
|
||||
->whereIn('permission_code', ['agent.node.view', 'agent.node.manage'])
|
||||
->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('admin_roles', function (Blueprint $table): void {
|
||||
$table->foreignId('owner_agent_id')->nullable()->after('sort_order')->constrained('agent_nodes')->nullOnDelete();
|
||||
$table->foreignId('delegated_from_role_id')->nullable()->after('owner_agent_id')->constrained('admin_roles')->nullOnDelete();
|
||||
$table->string('scope_type', 16)->default('system')->after('delegated_from_role_id');
|
||||
});
|
||||
|
||||
Schema::create('admin_user_agent_roles', function (Blueprint $table): void {
|
||||
$table->foreignId('admin_user_id')->constrained('admin_users')->cascadeOnDelete();
|
||||
$table->foreignId('agent_node_id')->constrained('agent_nodes')->cascadeOnDelete();
|
||||
$table->foreignId('role_id')->constrained('admin_roles')->cascadeOnDelete();
|
||||
$table->timestamp('granted_at')->nullable();
|
||||
$table->primary(['admin_user_id', 'agent_node_id', 'role_id'], 'pk_admin_user_agent_roles');
|
||||
});
|
||||
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->foreignId('agent_node_id')->nullable()->after('site_code')->constrained('agent_nodes')->nullOnDelete();
|
||||
$table->index(['site_code', 'agent_node_id'], 'idx_players_site_agent');
|
||||
});
|
||||
|
||||
DB::table('admin_roles')->update(['scope_type' => 'system']);
|
||||
|
||||
$this->backfillAdminUserAgentRoles();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_players_site_agent');
|
||||
$table->dropConstrainedForeignId('agent_node_id');
|
||||
});
|
||||
|
||||
Schema::dropIfExists('admin_user_agent_roles');
|
||||
|
||||
Schema::table('admin_roles', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('delegated_from_role_id');
|
||||
$table->dropConstrainedForeignId('owner_agent_id');
|
||||
$table->dropColumn('scope_type');
|
||||
});
|
||||
}
|
||||
|
||||
private function backfillAdminUserAgentRoles(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$rows = DB::table('admin_user_site_roles as usr')
|
||||
->join('admin_user_agents as uaa', 'uaa.admin_user_id', '=', 'usr.admin_user_id')
|
||||
->join('agent_nodes as an', static function ($join): void {
|
||||
$join->on('an.id', '=', 'uaa.agent_node_id')
|
||||
->on('an.admin_site_id', '=', 'usr.site_id');
|
||||
})
|
||||
->select(['usr.admin_user_id', 'uaa.agent_node_id', 'usr.role_id', 'usr.granted_at'])
|
||||
->get();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
DB::table('admin_user_agent_roles')->updateOrInsert(
|
||||
[
|
||||
'admin_user_id' => (int) $row->admin_user_id,
|
||||
'agent_node_id' => (int) $row->agent_node_id,
|
||||
'role_id' => (int) $row->role_id,
|
||||
],
|
||||
[
|
||||
'granted_at' => $row->granted_at ?? $now,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 代理角色/账号 API 绑定到已有 agent.node.view / agent.node.manage 动作(同菜单下 action 唯一)。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.agent-roles.')
|
||||
|| str_starts_with((string) $resource['code'], 'admin.agent-admin-users.'),
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] ?? [] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('admin_role_api_resources')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$superRoleId = DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
|
||||
if ($superRoleId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_role_api_resources')->updateOrInsert([
|
||||
'role_id' => (int) $superRoleId,
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$codes = [
|
||||
'admin.agent-roles.update',
|
||||
'admin.agent-roles.destroy',
|
||||
'admin.agent-roles.permissions.sync',
|
||||
'admin.agent-roles.index',
|
||||
'admin.agent-roles.store',
|
||||
'admin.agent-admin-users.index',
|
||||
'admin.agent-admin-users.store',
|
||||
'admin.agent-admin-users.roles.sync',
|
||||
];
|
||||
|
||||
foreach ($codes as $code) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $code)->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Schema::hasTable('admin_role_api_resources')) {
|
||||
DB::table('admin_role_api_resources')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
}
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('agent_delegation_grants', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('parent_agent_id')->constrained('agent_nodes')->cascadeOnDelete();
|
||||
$table->foreignId('child_agent_id')->constrained('agent_nodes')->cascadeOnDelete();
|
||||
$table->foreignId('menu_action_id')->constrained('admin_menu_actions')->cascadeOnDelete();
|
||||
$table->boolean('can_delegate')->default(false);
|
||||
$table->foreignId('granted_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->timestamp('granted_at')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['child_agent_id', 'menu_action_id'], 'uk_agent_delegation_child_action');
|
||||
$table->index(['parent_agent_id', 'child_agent_id'], 'idx_agent_delegation_parent_child');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('agent_delegation_grants');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 将未归属玩家挂到对应主站根代理(与 agent_nodes depth=0 1:1)。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! \Illuminate\Support\Facades\Schema::hasColumn('players', 'agent_node_id')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$roots = DB::table('agent_nodes as an')
|
||||
->join('admin_sites as s', 's.id', '=', 'an.admin_site_id')
|
||||
->where('an.depth', 0)
|
||||
->get(['an.id as root_id', 's.code as site_code']);
|
||||
|
||||
foreach ($roots as $root) {
|
||||
DB::table('players')
|
||||
->where('site_code', (string) $root->site_code)
|
||||
->whereNull('agent_node_id')
|
||||
->update(['agent_node_id' => (int) $root->root_id]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不回滚归属,避免误清空业务绑定。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
/**
|
||||
* 代理「节点 / 角色 / 账号」查看与管理拆分为独立 permission_code,避免只勾一项却获得全部管理能力。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$viewActionId = DB::table('admin_action_catalog')->where('code', 'view')->value('id');
|
||||
$manageActionId = DB::table('admin_action_catalog')->where('code', 'manage')->value('id');
|
||||
if ($viewActionId === null || $manageActionId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$agentMenuId = (int) DB::table('admin_menus')->where('code', 'system.agents')->value('id');
|
||||
if ($agentMenuId === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rolesMenuId = $this->ensureChildMenu($agentMenuId, 'system.agents.roles', '代理角色', $now);
|
||||
$usersMenuId = $this->ensureChildMenu($agentMenuId, 'system.agents.users', '代理账号', $now);
|
||||
|
||||
$this->ensureMenuAction((int) $rolesMenuId, (int) $viewActionId, 'agent.role.view', '代理角色查看', $now);
|
||||
$this->ensureMenuAction((int) $rolesMenuId, (int) $manageActionId, 'agent.role.manage', '代理角色管理', $now);
|
||||
$this->ensureMenuAction((int) $usersMenuId, (int) $viewActionId, 'agent.user.view', '代理账号查看', $now);
|
||||
$this->ensureMenuAction((int) $usersMenuId, (int) $manageActionId, 'agent.user.manage', '代理账号管理', $now);
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$nodeViewId = $menuActionIds['agent.node.view'] ?? null;
|
||||
$nodeManageId = $menuActionIds['agent.node.manage'] ?? null;
|
||||
$roleViewId = $menuActionIds['agent.role.view'] ?? null;
|
||||
$roleManageId = $menuActionIds['agent.role.manage'] ?? null;
|
||||
$userViewId = $menuActionIds['agent.user.view'] ?? null;
|
||||
$userManageId = $menuActionIds['agent.user.manage'] ?? null;
|
||||
|
||||
if ($nodeViewId !== null && $roleViewId !== null && $userViewId !== null) {
|
||||
$roleIdsWithNodeView = DB::table('admin_role_menu_actions')
|
||||
->where('menu_action_id', (int) $nodeViewId)
|
||||
->pluck('role_id')
|
||||
->unique()
|
||||
->all();
|
||||
|
||||
foreach ($roleIdsWithNodeView as $roleId) {
|
||||
foreach ([$roleViewId, $userViewId] as $actionId) {
|
||||
$this->attachRoleMenuAction((int) $roleId, (int) $actionId, $now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($nodeManageId !== null && $roleManageId !== null && $userManageId !== null) {
|
||||
$roleIdsWithNodeManage = DB::table('admin_role_menu_actions')
|
||||
->where('menu_action_id', (int) $nodeManageId)
|
||||
->pluck('role_id')
|
||||
->unique()
|
||||
->all();
|
||||
|
||||
foreach ($roleIdsWithNodeManage as $roleId) {
|
||||
foreach ([$roleManageId, $userManageId] as $actionId) {
|
||||
$this->attachRoleMenuAction((int) $roleId, (int) $actionId, $now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => str_starts_with((string) $resource['code'], 'admin.agent-')
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] ?? [] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureChildMenu(int $parentId, string $code, string $name, Carbon $now): int
|
||||
{
|
||||
$existing = DB::table('admin_menus')->where('code', $code)->value('id');
|
||||
if ($existing !== null) {
|
||||
return (int) $existing;
|
||||
}
|
||||
|
||||
return (int) DB::table('admin_menus')->insertGetId([
|
||||
'parent_id' => $parentId,
|
||||
'menu_type' => 'button',
|
||||
'code' => $code,
|
||||
'name' => $name,
|
||||
'path' => null,
|
||||
'route_name' => null,
|
||||
'component' => null,
|
||||
'icon' => null,
|
||||
'active_menu_code' => 'system.agents',
|
||||
'sort_order' => 0,
|
||||
'is_visible' => false,
|
||||
'is_cache' => false,
|
||||
'is_external' => false,
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
private function ensureMenuAction(int $menuId, int $actionId, string $permissionCode, string $name, Carbon $now): void
|
||||
{
|
||||
if (DB::table('admin_menu_actions')->where('permission_code', $permissionCode)->exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_menu_actions')->insert([
|
||||
'menu_id' => $menuId,
|
||||
'action_id' => $actionId,
|
||||
'permission_code' => $permissionCode,
|
||||
'name' => $name,
|
||||
'status' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
|
||||
private function attachRoleMenuAction(int $roleId, int $menuActionId, Carbon $now): void
|
||||
{
|
||||
$exists = DB::table('admin_role_menu_actions')
|
||||
->where('role_id', $roleId)
|
||||
->where('menu_action_id', $menuActionId)
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_role_menu_actions')->insert([
|
||||
'role_id' => $roleId,
|
||||
'menu_action_id' => $menuActionId,
|
||||
]);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$codes = ['agent.role.view', 'agent.role.manage', 'agent.user.view', 'agent.user.manage'];
|
||||
$actionIds = DB::table('admin_menu_actions')->whereIn('permission_code', $codes)->pluck('id')->all();
|
||||
|
||||
if ($actionIds !== []) {
|
||||
DB::table('admin_role_menu_actions')->whereIn('menu_action_id', $actionIds)->delete();
|
||||
DB::table('admin_api_resource_bindings')->whereIn('menu_action_id', $actionIds)->delete();
|
||||
DB::table('admin_menu_actions')->whereIn('permission_code', $codes)->delete();
|
||||
}
|
||||
|
||||
DB::table('admin_menus')->whereIn('code', ['system.agents.roles', 'system.agents.users'])->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/** 补齐代理账号删除 API 资源(admin.agent-admin-users.destroy)。 */
|
||||
return new class extends Migration
|
||||
{
|
||||
private const RESOURCE_CODE = 'admin.agent-admin-users.destroy';
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$resource = collect(AdminAuthorizationRegistry::resources())
|
||||
->firstWhere('code', self::RESOURCE_CODE);
|
||||
|
||||
if ($resource === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', self::RESOURCE_CODE)
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => self::RESOURCE_CODE,
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', self::RESOURCE_CODE)
|
||||
->value('id');
|
||||
|
||||
if ($resourceId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$sites = DB::table('admin_sites')->orderBy('id')->get(['id', 'code']);
|
||||
|
||||
foreach ($sites as $site) {
|
||||
$siteId = (int) $site->id;
|
||||
$code = (string) $site->code;
|
||||
$legacyCode = 'root-'.$code;
|
||||
|
||||
$root = DB::table('agent_nodes')
|
||||
->where('admin_site_id', $siteId)
|
||||
->where('depth', 0)
|
||||
->first(['id', 'code']);
|
||||
|
||||
if ($root === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((string) $root->code === $legacyCode) {
|
||||
$conflict = DB::table('agent_nodes')
|
||||
->where('admin_site_id', $siteId)
|
||||
->where('code', $code)
|
||||
->where('id', '!=', (int) $root->id)
|
||||
->exists();
|
||||
if (! $conflict) {
|
||||
DB::table('agent_nodes')->where('id', (int) $root->id)->update([
|
||||
'code' => $code,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$sites = DB::table('admin_sites')->orderBy('id')->get(['id', 'code']);
|
||||
|
||||
foreach ($sites as $site) {
|
||||
$siteId = (int) $site->id;
|
||||
$code = (string) $site->code;
|
||||
|
||||
DB::table('agent_nodes')
|
||||
->where('admin_site_id', $siteId)
|
||||
->where('depth', 0)
|
||||
->where('code', $code)
|
||||
->update([
|
||||
'code' => 'root-'.$code,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('agent_profiles', function (Blueprint $table): void {
|
||||
$table->foreignId('agent_node_id')->primary()->constrained('agent_nodes')->cascadeOnDelete();
|
||||
$table->decimal('total_share_rate', 5, 2)->default(0)->comment('总占成 0-100');
|
||||
$table->unsignedBigInteger('credit_limit')->default(0);
|
||||
$table->unsignedBigInteger('allocated_credit')->default(0);
|
||||
$table->unsignedBigInteger('used_credit')->default(0);
|
||||
$table->decimal('rebate_limit', 8, 4)->default(0);
|
||||
$table->decimal('default_player_rebate', 8, 4)->default(0);
|
||||
$table->string('settlement_cycle', 16)->default('weekly');
|
||||
$table->boolean('can_grant_extra_rebate')->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('player_credit_accounts', function (Blueprint $table): void {
|
||||
$table->foreignId('player_id')->primary()->constrained('players')->cascadeOnDelete();
|
||||
$table->unsignedBigInteger('credit_limit')->default(0);
|
||||
$table->unsignedBigInteger('used_credit')->default(0);
|
||||
$table->unsignedBigInteger('frozen_credit')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('player_rebate_profiles', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->string('game_type', 32)->default('*');
|
||||
$table->boolean('inherit_from_agent')->default(true);
|
||||
$table->decimal('rebate_rate', 8, 4)->default(0);
|
||||
$table->decimal('extra_rebate_rate', 8, 4)->default(0);
|
||||
$table->timestamps();
|
||||
$table->unique(['player_id', 'game_type']);
|
||||
});
|
||||
|
||||
Schema::create('settlement_periods', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('admin_site_id')->constrained('admin_sites')->cascadeOnDelete();
|
||||
$table->timestamp('period_start');
|
||||
$table->timestamp('period_end');
|
||||
$table->string('status', 16)->default('open');
|
||||
$table->timestamps();
|
||||
$table->index(['admin_site_id', 'status']);
|
||||
});
|
||||
|
||||
Schema::create('settlement_bills', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('settlement_period_id')->constrained('settlement_periods')->cascadeOnDelete();
|
||||
$table->string('bill_type', 16);
|
||||
$table->string('owner_type', 16);
|
||||
$table->unsignedBigInteger('owner_id');
|
||||
$table->string('counterparty_type', 16);
|
||||
$table->unsignedBigInteger('counterparty_id');
|
||||
$table->bigInteger('gross_win_loss')->default(0);
|
||||
$table->bigInteger('rebate_amount')->default(0);
|
||||
$table->bigInteger('adjustment_amount')->default(0);
|
||||
$table->bigInteger('net_amount')->default(0);
|
||||
$table->bigInteger('paid_amount')->default(0);
|
||||
$table->bigInteger('unpaid_amount')->default(0);
|
||||
$table->string('status', 16)->default('pending');
|
||||
$table->timestamp('confirmed_at')->nullable();
|
||||
$table->timestamps();
|
||||
$table->index(['settlement_period_id', 'bill_type']);
|
||||
});
|
||||
|
||||
Schema::create('rebate_records', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->foreignId('settlement_period_id')->nullable()->constrained('settlement_periods')->nullOnDelete();
|
||||
$table->string('game_type', 32)->default('*');
|
||||
$table->unsignedBigInteger('valid_bet_amount')->default(0);
|
||||
$table->decimal('rebate_rate', 8, 4)->default(0);
|
||||
$table->unsignedBigInteger('rebate_amount')->default(0);
|
||||
$table->string('rebate_type', 16)->default('basic');
|
||||
$table->foreignId('owner_agent_id')->nullable()->constrained('agent_nodes')->nullOnDelete();
|
||||
$table->string('status', 16)->default('pending');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('rebate_allocations', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('rebate_record_id')->constrained('rebate_records')->cascadeOnDelete();
|
||||
$table->foreignId('settlement_bill_id')->nullable()->constrained('settlement_bills')->nullOnDelete();
|
||||
$table->string('participant_type', 16);
|
||||
$table->unsignedBigInteger('participant_id')->default(0);
|
||||
$table->decimal('actual_share_rate', 5, 2)->default(0);
|
||||
$table->bigInteger('allocated_amount')->default(0);
|
||||
$table->string('allocation_rule', 32)->default('share');
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('payment_records', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('settlement_bill_id')->constrained('settlement_bills')->cascadeOnDelete();
|
||||
$table->string('payer_type', 16);
|
||||
$table->unsignedBigInteger('payer_id');
|
||||
$table->string('payee_type', 16);
|
||||
$table->unsignedBigInteger('payee_id');
|
||||
$table->bigInteger('amount');
|
||||
$table->string('method', 32)->nullable();
|
||||
$table->string('status', 16)->default('pending');
|
||||
$table->foreignId('created_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->foreignId('confirmed_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->timestamp('confirmed_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('credit_ledger', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('owner_type', 16);
|
||||
$table->unsignedBigInteger('owner_id');
|
||||
$table->bigInteger('amount');
|
||||
$table->string('reason', 64);
|
||||
$table->string('ref_type', 32)->nullable();
|
||||
$table->unsignedBigInteger('ref_id')->nullable();
|
||||
$table->timestamps();
|
||||
$table->index(['owner_type', 'owner_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('credit_ledger');
|
||||
Schema::dropIfExists('payment_records');
|
||||
Schema::dropIfExists('rebate_allocations');
|
||||
Schema::dropIfExists('rebate_records');
|
||||
Schema::dropIfExists('settlement_bills');
|
||||
Schema::dropIfExists('settlement_periods');
|
||||
Schema::dropIfExists('player_rebate_profiles');
|
||||
Schema::dropIfExists('player_credit_accounts');
|
||||
Schema::dropIfExists('agent_profiles');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
use App\Support\AdminAgentLineSettlementPermissionMenuActionSync;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 代理账单 / 线路开通等 API 写入 admin_api_resources,并补齐 settlement.agent.* menu_action。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const RESOURCE_CODE_PREFIXES = [
|
||||
'admin.settlement-bills.',
|
||||
'admin.settlement-periods.',
|
||||
'admin.settlement-payments.',
|
||||
'admin.settlement-adjustments.',
|
||||
'admin.settlement-reports.',
|
||||
'admin.credit-ledger.',
|
||||
'admin.agent-lines.',
|
||||
'admin.agent-nodes.profile.',
|
||||
];
|
||||
|
||||
/** @var list<string> */
|
||||
private const MENU_ACTION_CODES = [
|
||||
'settlement.agent.view',
|
||||
'settlement.agent.manage',
|
||||
'agent.line.provision',
|
||||
'agent.profile.manage',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
AdminAgentLineSettlementPermissionMenuActionSync::syncMissing();
|
||||
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
|
||||
$resources = array_values(array_filter(
|
||||
AdminAuthorizationRegistry::resources(),
|
||||
static fn (array $resource): bool => self::matchesResourceCode((string) $resource['code']),
|
||||
));
|
||||
|
||||
foreach ($resources as $resource) {
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->grantSuperAdminMenuActions();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
foreach (AdminAuthorizationRegistry::resources() as $resource) {
|
||||
if (! self::matchesResourceCode((string) $resource['code'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $resource['code'])->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static function matchesResourceCode(string $code): bool
|
||||
{
|
||||
foreach (self::RESOURCE_CODE_PREFIXES as $prefix) {
|
||||
if (str_starts_with($code, $prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function grantSuperAdminMenuActions(): void
|
||||
{
|
||||
$superRoleId = DB::table('admin_roles')->where('slug', 'super_admin')->value('id');
|
||||
if ($superRoleId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menuActionIds = DB::table('admin_menu_actions')
|
||||
->whereIn('permission_code', self::MENU_ACTION_CODES)
|
||||
->pluck('id');
|
||||
|
||||
foreach ($menuActionIds as $menuActionId) {
|
||||
DB::table('admin_role_menu_actions')->updateOrInsert([
|
||||
'role_id' => (int) $superRoleId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
]);
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('admin_role_legacy_permissions')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (['prd.settlement.agent.view', 'prd.settlement.agent.manage', 'prd.agent-line.provision', 'prd.agent.profile.manage'] as $slug) {
|
||||
DB::table('admin_role_legacy_permissions')->updateOrInsert([
|
||||
'role_id' => (int) $superRoleId,
|
||||
'permission_slug' => $slug,
|
||||
], []);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('agent_profiles', function (Blueprint $table): void {
|
||||
$table->boolean('can_create_child_agent')->default(false)->after('can_grant_extra_rebate');
|
||||
$table->boolean('can_create_player')->default(true)->after('can_create_child_agent');
|
||||
});
|
||||
|
||||
\Illuminate\Support\Facades\DB::table('agent_profiles')->update([
|
||||
'can_create_child_agent' => true,
|
||||
'can_create_player' => true,
|
||||
]);
|
||||
|
||||
\App\Support\AgentDefaultRolePermissions::ensurePlatformAgentRole();
|
||||
\App\Models\AdminUser::query()
|
||||
->whereIn('id', \Illuminate\Support\Facades\DB::table('admin_user_agents')->pluck('admin_user_id'))
|
||||
->each(static function (\App\Models\AdminUser $user): void {
|
||||
$agentNodeId = $user->primaryAgentNodeId();
|
||||
if ($agentNodeId !== null) {
|
||||
$user->syncPrimaryPlatformAgentRole($agentNodeId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('agent_profiles', function (Blueprint $table): void {
|
||||
$table->dropColumn(['can_create_child_agent', 'can_create_player']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 修正代理主账号 admin_users.status 与 agent_nodes.status 语义不一致的历史数据。
|
||||
*
|
||||
* admin_users: 0=可登录, 1=禁用
|
||||
* agent_nodes: 1=启用, 0=停用
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$now = now();
|
||||
|
||||
$enabledUserIds = DB::table('admin_user_agents as aua')
|
||||
->join('agent_nodes as an', 'an.id', '=', 'aua.agent_node_id')
|
||||
->join('admin_users as au', 'au.id', '=', 'aua.admin_user_id')
|
||||
->where('aua.is_primary', true)
|
||||
->where('an.status', 1)
|
||||
->where('au.status', 1)
|
||||
->pluck('au.id');
|
||||
|
||||
if ($enabledUserIds->isNotEmpty()) {
|
||||
DB::table('admin_users')
|
||||
->whereIn('id', $enabledUserIds->all())
|
||||
->update(['status' => 0, 'updated_at' => $now]);
|
||||
}
|
||||
|
||||
$disabledUserIds = DB::table('admin_user_agents as aua')
|
||||
->join('agent_nodes as an', 'an.id', '=', 'aua.agent_node_id')
|
||||
->join('admin_users as au', 'au.id', '=', 'aua.admin_user_id')
|
||||
->where('aua.is_primary', true)
|
||||
->where('an.status', 0)
|
||||
->where('au.status', 0)
|
||||
->pluck('au.id');
|
||||
|
||||
if ($disabledUserIds->isNotEmpty()) {
|
||||
DB::table('admin_users')
|
||||
->whereIn('id', $disabledUserIds->all())
|
||||
->update(['status' => 1, 'updated_at' => $now]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不可逆:无法可靠还原误写前的 admin_users.status
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('ticket_items', function (Blueprint $table): void {
|
||||
$table->foreignId('agent_node_id')->nullable()->after('player_id')->constrained('agent_nodes')->nullOnDelete();
|
||||
$table->json('share_snapshot')->nullable()->after('rule_snapshot_json');
|
||||
$table->decimal('agent_rebate_rate_snapshot', 8, 4)->nullable()->after('share_snapshot');
|
||||
$table->timestamp('agent_settled_at')->nullable()->after('settled_at');
|
||||
$table->foreignId('agent_settlement_reversal_of_id')->nullable()->after('agent_settled_at')
|
||||
->constrained('ticket_items')->nullOnDelete();
|
||||
});
|
||||
|
||||
Schema::create('share_ledger', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('ticket_item_id')->constrained('ticket_items')->cascadeOnDelete();
|
||||
$table->foreignId('player_id')->constrained('players')->cascadeOnDelete();
|
||||
$table->foreignId('agent_node_id')->nullable()->constrained('agent_nodes')->nullOnDelete();
|
||||
$table->json('agent_path')->nullable();
|
||||
$table->json('share_snapshot')->nullable();
|
||||
$table->bigInteger('game_win_loss')->default(0);
|
||||
$table->bigInteger('basic_rebate')->default(0);
|
||||
$table->bigInteger('shared_net_win_loss')->default(0);
|
||||
$table->json('allocations_json')->nullable();
|
||||
$table->foreignId('settlement_period_id')->nullable()->constrained('settlement_periods')->nullOnDelete();
|
||||
$table->unsignedBigInteger('reversal_of_id')->nullable();
|
||||
$table->timestamp('settled_at');
|
||||
$table->timestamps();
|
||||
$table->index(['settled_at', 'player_id']);
|
||||
$table->index(['settlement_period_id']);
|
||||
});
|
||||
|
||||
Schema::table('share_ledger', function (Blueprint $table): void {
|
||||
$table->foreign('reversal_of_id')->references('id')->on('share_ledger')->nullOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('rebate_records', function (Blueprint $table): void {
|
||||
$table->foreignId('ticket_item_id')->nullable()->after('player_id')->constrained('ticket_items')->nullOnDelete();
|
||||
$table->foreignId('reversal_of_id')->nullable()->after('ticket_item_id')->constrained('rebate_records')->nullOnDelete();
|
||||
});
|
||||
|
||||
Schema::table('settlement_bills', function (Blueprint $table): void {
|
||||
$table->timestamp('locked_at')->nullable()->after('confirmed_at');
|
||||
$table->foreignId('reversed_bill_id')->nullable()->after('locked_at')->constrained('settlement_bills')->nullOnDelete();
|
||||
$table->json('meta_json')->nullable()->after('reversed_bill_id');
|
||||
});
|
||||
|
||||
Schema::create('settlement_adjustments', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->foreignId('settlement_period_id')->nullable()->constrained('settlement_periods')->nullOnDelete();
|
||||
$table->foreignId('original_bill_id')->nullable()->constrained('settlement_bills')->nullOnDelete();
|
||||
$table->string('adjustment_type', 32);
|
||||
$table->bigInteger('amount');
|
||||
$table->string('reason', 255)->nullable();
|
||||
$table->foreignId('created_by')->nullable()->constrained('admin_users')->nullOnDelete();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('settlement_adjustments');
|
||||
|
||||
Schema::table('settlement_bills', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('reversed_bill_id');
|
||||
$table->dropColumn(['locked_at', 'meta_json']);
|
||||
});
|
||||
|
||||
Schema::table('rebate_records', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('reversal_of_id');
|
||||
$table->dropConstrainedForeignId('ticket_item_id');
|
||||
});
|
||||
|
||||
Schema::dropIfExists('share_ledger');
|
||||
|
||||
Schema::table('ticket_items', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('agent_settlement_reversal_of_id');
|
||||
$table->dropConstrainedForeignId('agent_node_id');
|
||||
$table->dropColumn(['share_snapshot', 'agent_rebate_rate_snapshot', 'agent_settled_at']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->string('auth_source', 16)->default('main_site_sso')->after('site_player_id');
|
||||
$table->string('funding_mode', 16)->default('wallet')->after('auth_source');
|
||||
$table->string('password_hash', 255)->nullable()->after('username');
|
||||
$table->unsignedSmallInteger('login_failed_count')->default(0)->after('last_login_at');
|
||||
$table->timestamp('login_locked_until')->nullable()->after('login_failed_count');
|
||||
});
|
||||
|
||||
DB::table('players')->update([
|
||||
'auth_source' => 'main_site_sso',
|
||||
'funding_mode' => 'wallet',
|
||||
]);
|
||||
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->index(['site_code', 'auth_source', 'username'], 'idx_players_site_auth_username');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_players_site_auth_username');
|
||||
$table->dropColumn([
|
||||
'auth_source',
|
||||
'funding_mode',
|
||||
'password_hash',
|
||||
'login_failed_count',
|
||||
'login_locked_until',
|
||||
]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('payment_records', function (Blueprint $table): void {
|
||||
$table->text('proof')->nullable()->after('method');
|
||||
$table->string('remark', 255)->nullable()->after('proof');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('payment_records', function (Blueprint $table): void {
|
||||
$table->dropColumn(['proof', 'remark']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use App\Models\AdminRole;
|
||||
use App\Models\AgentNode;
|
||||
use App\Support\AgentDefaultRolePermissions;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
AgentNode::query()->each(static function (AgentNode $node): void {
|
||||
$role = AdminRole::query()
|
||||
->where('owner_agent_id', $node->id)
|
||||
->where('slug', 'agent_owner_'.$node->id)
|
||||
->first();
|
||||
|
||||
if ($role === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$role->syncLegacyPermissionSlugs(AgentDefaultRolePermissions::ownerSlugsForNode($node));
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 权限包为产品策略,回滚不恢复旧 slug 集合。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
use App\Models\AdminRole;
|
||||
use App\Models\AdminUser;
|
||||
use App\Models\AgentNode;
|
||||
use App\Support\AgentDefaultRolePermissions;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$platformRole = AgentDefaultRolePermissions::ensurePlatformAgentRole();
|
||||
|
||||
AgentNode::query()->each(static function (AgentNode $node): void {
|
||||
$ownerRole = AdminRole::query()
|
||||
->where('owner_agent_id', $node->id)
|
||||
->where('slug', 'agent_owner_'.$node->id)
|
||||
->first();
|
||||
|
||||
if ($ownerRole !== null) {
|
||||
$ownerRole->syncLegacyPermissionSlugs(AgentDefaultRolePermissions::ownerSlugsForNode($node));
|
||||
}
|
||||
});
|
||||
|
||||
$bindings = DB::table('admin_user_agents')->get(['admin_user_id', 'agent_node_id']);
|
||||
foreach ($bindings as $binding) {
|
||||
$adminUserId = (int) $binding->admin_user_id;
|
||||
$agentNodeId = (int) $binding->agent_node_id;
|
||||
$user = AdminUser::query()->find($adminUserId);
|
||||
if ($user === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$agentRoleIds = DB::table('admin_user_agent_roles')
|
||||
->where('admin_user_id', $adminUserId)
|
||||
->where('agent_node_id', $agentNodeId)
|
||||
->pluck('role_id')
|
||||
->map(static fn ($id): int => (int) $id)
|
||||
->all();
|
||||
|
||||
if ($agentRoleIds === []) {
|
||||
$ownerId = (int) (AdminRole::query()
|
||||
->where('owner_agent_id', $agentNodeId)
|
||||
->where('slug', 'agent_owner_'.$agentNodeId)
|
||||
->value('id') ?? 0);
|
||||
if ($ownerId > 0) {
|
||||
$agentRoleIds = [$ownerId];
|
||||
}
|
||||
}
|
||||
|
||||
if ($agentRoleIds !== []) {
|
||||
$user->syncAgentRoleIds($agentNodeId, $agentRoleIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不回滚权限与 pivot,避免经营账号失权。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('settlement_bills', function (Blueprint $table): void {
|
||||
$table->bigInteger('platform_rounding_adjustment')->default(0)->after('adjustment_amount');
|
||||
});
|
||||
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->json('risk_tags')->nullable()->after('status');
|
||||
});
|
||||
|
||||
Schema::table('agent_nodes', function (Blueprint $table): void {
|
||||
$table->json('risk_tags')->nullable()->after('status');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('agent_nodes', function (Blueprint $table): void {
|
||||
$table->dropColumn('risk_tags');
|
||||
});
|
||||
|
||||
Schema::table('players', function (Blueprint $table): void {
|
||||
$table->dropColumn('risk_tags');
|
||||
});
|
||||
|
||||
Schema::table('settlement_bills', function (Blueprint $table): void {
|
||||
$table->dropColumn('platform_rounding_adjustment');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use App\Models\AdminRole;
|
||||
use App\Models\AdminUser;
|
||||
use App\Support\AgentDefaultRolePermissions;
|
||||
use App\Support\AgentPlatformRole;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
AgentDefaultRolePermissions::ensurePlatformAgentRole();
|
||||
$platformRoleId = AgentPlatformRole::id();
|
||||
|
||||
foreach (DB::table('admin_user_agents')->get(['admin_user_id', 'agent_node_id']) as $binding) {
|
||||
$user = AdminUser::query()->find((int) $binding->admin_user_id);
|
||||
if ($user === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$user->syncPrimaryPlatformAgentRole((int) $binding->agent_node_id);
|
||||
}
|
||||
|
||||
$ownerRoleIds = AdminRole::query()
|
||||
->where('scope_type', AdminRole::SCOPE_AGENT)
|
||||
->where('slug', 'like', 'agent_owner_%')
|
||||
->pluck('id')
|
||||
->all();
|
||||
|
||||
if ($ownerRoleIds !== []) {
|
||||
DB::table('admin_user_agent_roles')->whereIn('role_id', $ownerRoleIds)->delete();
|
||||
DB::table('admin_user_site_roles')->whereIn('role_id', $ownerRoleIds)->delete();
|
||||
DB::table('admin_role_menu_actions')->whereIn('role_id', $ownerRoleIds)->delete();
|
||||
AdminRole::query()->whereIn('id', $ownerRoleIds)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不回滚:避免经营账号失权。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
use App\Support\PlatformSystemRoles;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
PlatformSystemRoles::ensureAll();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// 不回滚内置角色与权限,避免平台/代理账号失权。
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Support\AdminAuthorizationRegistry;
|
||||
|
||||
/**
|
||||
* 信用流水 API 注册到 admin_api_resources(已有库增量同步,避免 500 api_resource_not_configured)。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const RESOURCE_CODES = [
|
||||
'admin.credit-ledger.index',
|
||||
'admin.settlement-payments.index',
|
||||
'admin.settlement-adjustments.index',
|
||||
'admin.settlement-reports.summary',
|
||||
'admin.settlement-reports.show',
|
||||
];
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
$now = Carbon::now();
|
||||
$menuActionIds = DB::table('admin_menu_actions')->pluck('id', 'permission_code');
|
||||
$byCode = collect(AdminAuthorizationRegistry::resources())->keyBy('code');
|
||||
|
||||
foreach (self::RESOURCE_CODES as $code) {
|
||||
$resource = $byCode->get($code);
|
||||
if (! is_array($resource)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resourceId = DB::table('admin_api_resources')
|
||||
->where('code', $resource['code'])
|
||||
->value('id');
|
||||
|
||||
$payload = [
|
||||
'module_code' => $resource['module_code'],
|
||||
'name' => $resource['name'],
|
||||
'http_method' => $resource['http_method'],
|
||||
'uri_pattern' => $resource['uri_pattern'],
|
||||
'route_name' => $resource['route_name'],
|
||||
'auth_mode' => $resource['auth_mode'],
|
||||
'is_audit_required' => $resource['is_audit_required'],
|
||||
'status' => 1,
|
||||
'meta_json' => null,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
|
||||
if ($resourceId === null) {
|
||||
$resourceId = DB::table('admin_api_resources')->insertGetId($payload + [
|
||||
'code' => $resource['code'],
|
||||
'created_at' => $now,
|
||||
]);
|
||||
} else {
|
||||
DB::table('admin_api_resources')
|
||||
->where('id', (int) $resourceId)
|
||||
->update($payload);
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')
|
||||
->where('api_resource_id', (int) $resourceId)
|
||||
->delete();
|
||||
|
||||
foreach ($resource['permission_codes'] as $permissionCode) {
|
||||
$menuActionId = $menuActionIds[$permissionCode] ?? null;
|
||||
if ($menuActionId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->insert([
|
||||
'api_resource_id' => (int) $resourceId,
|
||||
'menu_action_id' => (int) $menuActionId,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
foreach (self::RESOURCE_CODES as $code) {
|
||||
$resourceId = DB::table('admin_api_resources')->where('code', $code)->value('id');
|
||||
if ($resourceId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_api_resource_bindings')->where('api_resource_id', (int) $resourceId)->delete();
|
||||
DB::table('admin_api_resources')->where('id', (int) $resourceId)->delete();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
@@ -10,33 +9,7 @@ return new class extends Migration
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('player_credit_accounts')) {
|
||||
Schema::create('player_credit_accounts', function (Blueprint $table): void {
|
||||
$table->unsignedBigInteger('player_id')->primary();
|
||||
$table->bigInteger('credit_limit')->default(0);
|
||||
$table->bigInteger('used_credit')->default(0);
|
||||
$table->bigInteger('frozen_credit')->default(0);
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('player_id')
|
||||
->references('id')
|
||||
->on('players')
|
||||
->cascadeOnDelete();
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('credit_ledger')) {
|
||||
Schema::create('credit_ledger', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('owner_type', 16);
|
||||
$table->unsignedBigInteger('owner_id');
|
||||
$table->bigInteger('amount');
|
||||
$table->string('reason', 64);
|
||||
$table->string('ref_type', 32)->nullable();
|
||||
$table->unsignedBigInteger('ref_id')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['owner_type', 'owner_id', 'created_at']);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (Schema::hasTable('players') && Schema::hasColumn('players', 'funding_mode')) {
|
||||
@@ -71,7 +44,6 @@ return new class extends Migration
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('credit_ledger');
|
||||
Schema::dropIfExists('player_credit_accounts');
|
||||
// 兼容回填迁移,不回滚既有表结构。
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! $this->hasIndex('ticket_items', 'idx_ticket_items_order_id')) {
|
||||
Schema::table('ticket_items', function (Blueprint $table): void {
|
||||
$table->index('order_id', 'idx_ticket_items_order_id');
|
||||
});
|
||||
}
|
||||
|
||||
if (! $this->hasIndex('settlement_batches', 'idx_settlement_batches_result_batch_id')) {
|
||||
Schema::table('settlement_batches', function (Blueprint $table): void {
|
||||
$table->index('result_batch_id', 'idx_settlement_batches_result_batch_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if ($this->hasIndex('settlement_batches', 'idx_settlement_batches_result_batch_id')) {
|
||||
Schema::table('settlement_batches', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_settlement_batches_result_batch_id');
|
||||
});
|
||||
}
|
||||
|
||||
if ($this->hasIndex('ticket_items', 'idx_ticket_items_order_id')) {
|
||||
Schema::table('ticket_items', function (Blueprint $table): void {
|
||||
$table->dropIndex('idx_ticket_items_order_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private function hasIndex(string $table, string $indexName): bool
|
||||
{
|
||||
return DB::table('pg_indexes')
|
||||
->where('schemaname', 'public')
|
||||
->where('tablename', $table)
|
||||
->where('indexname', $indexName)
|
||||
->exists();
|
||||
}
|
||||
};
|
||||
@@ -1,19 +1,12 @@
|
||||
# 迁移目录说明
|
||||
|
||||
当前项目已切换为 **schema dump 作为数据库基线** 的维护方式。
|
||||
当前项目使用 **纯 migration 链** 维护 PostgreSQL 结构。
|
||||
|
||||
- 最终版 PostgreSQL 结构:[`../schema/pgsql-schema.sql`](../schema/pgsql-schema.sql)
|
||||
- 新环境初始化:优先加载 schema dump,再执行后续新增 migration
|
||||
- 旧的历史 migration 已清理,不再作为基线结构来源
|
||||
- 新环境初始化:直接执行完整 migration 链
|
||||
- 历史 migration 保留,作为唯一结构来源
|
||||
- 统一初始化入口:`php artisan lottery:db-init`
|
||||
|
||||
后续规则:
|
||||
|
||||
1. 新增数据库结构变更时,继续正常创建新的 migration 文件放在本目录。
|
||||
2. 当结构进入一个新的稳定阶段后,可重新执行:
|
||||
|
||||
```bash
|
||||
php artisan schema:dump --database=pgsql --prune
|
||||
```
|
||||
|
||||
3. 执行 `--prune` 前,确认团队已接受“历史迁移链不再保留”的方式。
|
||||
2. 不再依赖 `schema dump` 作为基线;如果有临时导出文件,也不作为部署前提。
|
||||
|
||||
@@ -1,4889 +0,0 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict rPXEgF1VaYgsz0ptn4X1KcYROWRPYlYb6daN4zAOY961hMNjxCs5gLhsUZO9N0E
|
||||
|
||||
-- Dumped from database version 18.3(ServBay)
|
||||
-- Dumped by pg_dump version 18.3(ServBay)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
SET default_tablespace = '';
|
||||
|
||||
SET default_table_access_method = heap;
|
||||
|
||||
--
|
||||
-- Name: admin_action_catalog; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_action_catalog (
|
||||
id bigint NOT NULL,
|
||||
code character varying(64) NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
sort_order integer DEFAULT 0 NOT NULL,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_action_catalog.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_action_catalog.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_action_catalog_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_action_catalog_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_action_catalog_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_action_catalog_id_seq OWNED BY public.admin_action_catalog.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_api_resource_bindings (
|
||||
id bigint NOT NULL,
|
||||
api_resource_id bigint NOT NULL,
|
||||
menu_action_id bigint NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_api_resource_bindings_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_api_resource_bindings_id_seq OWNED BY public.admin_api_resource_bindings.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resources; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_api_resources (
|
||||
id bigint NOT NULL,
|
||||
code character varying(128) NOT NULL,
|
||||
module_code character varying(64) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
http_method character varying(16) NOT NULL,
|
||||
uri_pattern character varying(255) NOT NULL,
|
||||
route_name character varying(255),
|
||||
auth_mode character varying(24) DEFAULT 'permission_required'::character varying NOT NULL,
|
||||
is_audit_required boolean DEFAULT false NOT NULL,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
meta_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_api_resources.auth_mode; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_api_resources.auth_mode IS 'login_only|permission_required|internal_only';
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_api_resources.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_api_resources.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resources_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_api_resources_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resources_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_api_resources_id_seq OWNED BY public.admin_api_resources.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_menu_actions (
|
||||
id bigint NOT NULL,
|
||||
menu_id bigint NOT NULL,
|
||||
action_id bigint NOT NULL,
|
||||
permission_code character varying(128) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_menu_actions.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_menu_actions.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_menu_actions_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_menu_actions_id_seq OWNED BY public.admin_menu_actions.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_menus (
|
||||
id bigint NOT NULL,
|
||||
parent_id bigint,
|
||||
menu_type character varying(24) NOT NULL,
|
||||
code character varying(128) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
path character varying(255),
|
||||
route_name character varying(255),
|
||||
component character varying(255),
|
||||
icon character varying(128),
|
||||
active_menu_code character varying(128),
|
||||
sort_order integer DEFAULT 0 NOT NULL,
|
||||
is_visible boolean DEFAULT true NOT NULL,
|
||||
is_cache boolean DEFAULT false NOT NULL,
|
||||
is_external boolean DEFAULT false NOT NULL,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
meta_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_menus.menu_type; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_menus.menu_type IS 'directory|menu|page';
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_menus.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_menus.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_menus_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_menus_id_seq OWNED BY public.admin_menus.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_role_menu_actions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_role_menu_actions (
|
||||
role_id bigint NOT NULL,
|
||||
menu_action_id bigint NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_roles (
|
||||
id bigint NOT NULL,
|
||||
slug character varying(64) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
code character varying(64) NOT NULL,
|
||||
description text,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
is_system boolean DEFAULT false NOT NULL,
|
||||
sort_order integer DEFAULT 0 NOT NULL,
|
||||
owner_agent_id bigint,
|
||||
delegated_from_role_id bigint,
|
||||
scope_type character varying(16) DEFAULT 'system'::character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_roles.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_roles.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_roles_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_roles_id_seq OWNED BY public.admin_roles.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_sites; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_sites (
|
||||
id bigint NOT NULL,
|
||||
code character varying(64) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
currency_code character varying(16) DEFAULT 'NPR'::character varying NOT NULL,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
is_default boolean DEFAULT false NOT NULL,
|
||||
extra_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
wallet_api_url character varying(512),
|
||||
wallet_debit_path character varying(128) DEFAULT '/wallet/debit-for-lottery'::character varying NOT NULL,
|
||||
wallet_credit_path character varying(128) DEFAULT '/wallet/credit-from-lottery'::character varying NOT NULL,
|
||||
wallet_balance_path character varying(128) DEFAULT '/wallet/balance'::character varying NOT NULL,
|
||||
wallet_api_key_encrypted text,
|
||||
sso_jwt_secret_encrypted text,
|
||||
wallet_timeout_seconds smallint DEFAULT '10'::smallint NOT NULL,
|
||||
iframe_allowed_origins json,
|
||||
lottery_h5_base_url character varying(512),
|
||||
notes text
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_sites.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_sites.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_sites_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_sites_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_sites_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_sites_id_seq OWNED BY public.admin_sites.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agent_roles; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_user_agent_roles (
|
||||
admin_user_id bigint NOT NULL,
|
||||
agent_node_id bigint NOT NULL,
|
||||
role_id bigint NOT NULL,
|
||||
granted_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agents; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_user_agents (
|
||||
admin_user_id bigint NOT NULL,
|
||||
agent_node_id bigint NOT NULL,
|
||||
is_primary boolean DEFAULT true NOT NULL,
|
||||
granted_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_menu_actions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_user_menu_actions (
|
||||
admin_user_id bigint NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
menu_action_id bigint NOT NULL,
|
||||
granted_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_site_roles; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_user_site_roles (
|
||||
admin_user_id bigint NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
role_id bigint NOT NULL,
|
||||
granted_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_users; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.admin_users (
|
||||
id bigint NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
email character varying(255),
|
||||
email_verified_at timestamp(0) without time zone,
|
||||
password character varying(255) NOT NULL,
|
||||
status smallint DEFAULT '0'::smallint NOT NULL,
|
||||
last_login_at timestamp(0) without time zone,
|
||||
remember_token character varying(100),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
username character varying(64) NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN admin_users.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.admin_users.status IS '0=active,1=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_users_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.admin_users_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.admin_users_id_seq OWNED BY public.admin_users.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.agent_delegation_grants (
|
||||
id bigint NOT NULL,
|
||||
parent_agent_id bigint NOT NULL,
|
||||
child_agent_id bigint NOT NULL,
|
||||
menu_action_id bigint NOT NULL,
|
||||
can_delegate boolean DEFAULT false NOT NULL,
|
||||
granted_by bigint,
|
||||
granted_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.agent_delegation_grants_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.agent_delegation_grants_id_seq OWNED BY public.agent_delegation_grants.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.agent_nodes (
|
||||
id bigint NOT NULL,
|
||||
admin_site_id bigint NOT NULL,
|
||||
parent_id bigint,
|
||||
path character varying(512) NOT NULL,
|
||||
depth smallint DEFAULT '0'::smallint NOT NULL,
|
||||
code character varying(64) NOT NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
status smallint DEFAULT '1'::smallint NOT NULL,
|
||||
created_by bigint,
|
||||
extra_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
risk_tags json
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN agent_nodes.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.agent_nodes.status IS '1=enabled,0=disabled';
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.agent_nodes_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.agent_nodes_id_seq OWNED BY public.agent_nodes.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_profiles; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.agent_profiles (
|
||||
agent_node_id bigint NOT NULL,
|
||||
total_share_rate numeric(5,2) DEFAULT '0'::numeric NOT NULL,
|
||||
credit_limit bigint DEFAULT '0'::bigint NOT NULL,
|
||||
allocated_credit bigint DEFAULT '0'::bigint NOT NULL,
|
||||
used_credit bigint DEFAULT '0'::bigint NOT NULL,
|
||||
rebate_limit numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
default_player_rebate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
settlement_cycle character varying(16) DEFAULT 'weekly'::character varying NOT NULL,
|
||||
can_grant_extra_rebate boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
can_create_child_agent boolean DEFAULT false NOT NULL,
|
||||
can_create_player boolean DEFAULT true NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN agent_profiles.total_share_rate; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.agent_profiles.total_share_rate IS '总占成 0-100';
|
||||
|
||||
|
||||
--
|
||||
-- Name: audit_logs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.audit_logs (
|
||||
id bigint NOT NULL,
|
||||
operator_type character varying(16) NOT NULL,
|
||||
operator_id bigint DEFAULT '0'::bigint NOT NULL,
|
||||
module_code character varying(32),
|
||||
action_code character varying(32),
|
||||
target_type character varying(128),
|
||||
target_id character varying(64),
|
||||
before_json json,
|
||||
after_json json,
|
||||
ip character varying(64),
|
||||
user_agent character varying(255),
|
||||
created_at timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: audit_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.audit_logs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: audit_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.audit_logs_id_seq OWNED BY public.audit_logs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: cache; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.cache (
|
||||
key character varying(255) NOT NULL,
|
||||
value text NOT NULL,
|
||||
expiration bigint NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: cache_locks; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.cache_locks (
|
||||
key character varying(255) NOT NULL,
|
||||
owner character varying(255) NOT NULL,
|
||||
expiration bigint NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: credit_ledger; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.credit_ledger (
|
||||
id bigint NOT NULL,
|
||||
owner_type character varying(16) NOT NULL,
|
||||
owner_id bigint NOT NULL,
|
||||
amount bigint NOT NULL,
|
||||
reason character varying(64) NOT NULL,
|
||||
ref_type character varying(32),
|
||||
ref_id bigint,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: credit_ledger_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.credit_ledger_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: credit_ledger_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.credit_ledger_id_seq OWNED BY public.credit_ledger.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: currencies; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.currencies (
|
||||
id bigint NOT NULL,
|
||||
code character varying(16) NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
decimal_places smallint DEFAULT '2'::smallint NOT NULL,
|
||||
is_enabled boolean DEFAULT true NOT NULL,
|
||||
is_bettable boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: currencies_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.currencies_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: currencies_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.currencies_id_seq OWNED BY public.currencies.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.draw_result_batches (
|
||||
id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
result_version integer NOT NULL,
|
||||
source_type character varying(16) NOT NULL,
|
||||
rng_seed_hash character varying(128),
|
||||
raw_seed_encrypted text,
|
||||
status character varying(32) NOT NULL,
|
||||
created_by bigint,
|
||||
confirmed_by bigint,
|
||||
confirmed_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN draw_result_batches.source_type; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.draw_result_batches.source_type IS 'rng|manual';
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.draw_result_batches_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.draw_result_batches_id_seq OWNED BY public.draw_result_batches.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.draw_result_items (
|
||||
id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
result_batch_id bigint NOT NULL,
|
||||
prize_type character varying(32) NOT NULL,
|
||||
prize_index integer DEFAULT 0 NOT NULL,
|
||||
number_4d character(4) NOT NULL,
|
||||
suffix_3d character(3),
|
||||
suffix_2d character(2),
|
||||
head_digit smallint,
|
||||
tail_digit smallint,
|
||||
created_at timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.draw_result_items_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.draw_result_items_id_seq OWNED BY public.draw_result_items.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draws; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.draws (
|
||||
id bigint NOT NULL,
|
||||
draw_no character varying(32) NOT NULL,
|
||||
business_date date NOT NULL,
|
||||
sequence_no integer NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
start_time timestamp(0) without time zone,
|
||||
close_time timestamp(0) without time zone,
|
||||
draw_time timestamp(0) without time zone,
|
||||
cooling_end_time timestamp(0) without time zone,
|
||||
result_source character varying(16),
|
||||
current_result_version integer DEFAULT 0 NOT NULL,
|
||||
settle_version integer DEFAULT 0 NOT NULL,
|
||||
is_reopened boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN draws.result_source; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.draws.result_source IS 'rng|manual';
|
||||
|
||||
|
||||
--
|
||||
-- Name: draws_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.draws_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draws_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.draws_id_seq OWNED BY public.draws.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: failed_jobs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.failed_jobs (
|
||||
id bigint NOT NULL,
|
||||
uuid character varying(255) NOT NULL,
|
||||
connection text NOT NULL,
|
||||
queue text NOT NULL,
|
||||
payload text NOT NULL,
|
||||
exception text NOT NULL,
|
||||
failed_at timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: failed_jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.failed_jobs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: failed_jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.failed_jobs_id_seq OWNED BY public.failed_jobs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.jackpot_contributions (
|
||||
id bigint NOT NULL,
|
||||
jackpot_pool_id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
ticket_item_id bigint,
|
||||
contribution_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
currency_code character varying(16) NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.jackpot_contributions_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.jackpot_contributions_id_seq OWNED BY public.jackpot_contributions.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.jackpot_payout_logs (
|
||||
id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
jackpot_pool_id bigint NOT NULL,
|
||||
trigger_type character varying(32) NOT NULL,
|
||||
total_payout_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
winner_count integer DEFAULT 0 NOT NULL,
|
||||
trigger_snapshot_json json,
|
||||
created_at timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.jackpot_payout_logs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.jackpot_payout_logs_id_seq OWNED BY public.jackpot_payout_logs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.jackpot_pool_adjustments (
|
||||
id bigint NOT NULL,
|
||||
adjustment_no character varying(32) NOT NULL,
|
||||
jackpot_pool_id bigint NOT NULL,
|
||||
admin_user_id bigint NOT NULL,
|
||||
amount_delta bigint NOT NULL,
|
||||
balance_before bigint NOT NULL,
|
||||
balance_after bigint NOT NULL,
|
||||
reason character varying(500) NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN jackpot_pool_adjustments.amount_delta; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.jackpot_pool_adjustments.amount_delta IS 'signed minor units; + increase pool';
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.jackpot_pool_adjustments_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.jackpot_pool_adjustments_id_seq OWNED BY public.jackpot_pool_adjustments.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.jackpot_pools (
|
||||
id bigint NOT NULL,
|
||||
currency_code character varying(16) NOT NULL,
|
||||
current_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
contribution_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
trigger_threshold bigint DEFAULT '0'::bigint NOT NULL,
|
||||
payout_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
force_trigger_draw_gap integer DEFAULT 0 NOT NULL,
|
||||
min_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
status smallint DEFAULT '0'::smallint NOT NULL,
|
||||
last_trigger_draw_id bigint,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
combo_trigger_play_codes json
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN jackpot_pools.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.jackpot_pools.status IS '0=off,1=on';
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.jackpot_pools_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.jackpot_pools_id_seq OWNED BY public.jackpot_pools.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: job_batches; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.job_batches (
|
||||
id character varying(255) NOT NULL,
|
||||
name character varying(255) NOT NULL,
|
||||
total_jobs integer NOT NULL,
|
||||
pending_jobs integer NOT NULL,
|
||||
failed_jobs integer NOT NULL,
|
||||
failed_job_ids text NOT NULL,
|
||||
options text,
|
||||
cancelled_at integer,
|
||||
created_at integer NOT NULL,
|
||||
finished_at integer
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jobs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.jobs (
|
||||
id bigint NOT NULL,
|
||||
queue character varying(255) NOT NULL,
|
||||
payload text NOT NULL,
|
||||
attempts smallint NOT NULL,
|
||||
reserved_at integer,
|
||||
available_at integer NOT NULL,
|
||||
created_at integer NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.jobs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.jobs_id_seq OWNED BY public.jobs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: lottery_settings; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.lottery_settings (
|
||||
id bigint NOT NULL,
|
||||
setting_key character varying(160) NOT NULL,
|
||||
value_json json NOT NULL,
|
||||
group_name character varying(64) DEFAULT 'general'::character varying NOT NULL,
|
||||
description_zh character varying(255),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN lottery_settings.group_name; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.lottery_settings.group_name IS '控制台分组展示用';
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN lottery_settings.description_zh; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.lottery_settings.description_zh IS '运维说明';
|
||||
|
||||
|
||||
--
|
||||
-- Name: lottery_settings_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.lottery_settings_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: lottery_settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.lottery_settings_id_seq OWNED BY public.lottery_settings.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: migrations; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.migrations (
|
||||
id integer NOT NULL,
|
||||
migration character varying(255) NOT NULL,
|
||||
batch integer NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: migrations_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.migrations_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: migrations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.migrations_id_seq OWNED BY public.migrations.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.odds_items (
|
||||
id bigint NOT NULL,
|
||||
version_id bigint NOT NULL,
|
||||
play_code character varying(32) NOT NULL,
|
||||
prize_scope character varying(32) NOT NULL,
|
||||
odds_value bigint DEFAULT '0'::bigint NOT NULL,
|
||||
rebate_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
commission_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
currency_code character varying(16) NOT NULL,
|
||||
extra_config_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
dimension smallint
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN odds_items.dimension; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.odds_items.dimension IS '2/3/4 维度,佣金按维度配置';
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.odds_items_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.odds_items_id_seq OWNED BY public.odds_items.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.odds_versions (
|
||||
id bigint NOT NULL,
|
||||
version_no integer NOT NULL,
|
||||
status character varying(16) NOT NULL,
|
||||
effective_at timestamp(0) without time zone,
|
||||
updated_by bigint,
|
||||
reason character varying(255),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_versions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.odds_versions_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_versions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.odds_versions_id_seq OWNED BY public.odds_versions.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.payment_records (
|
||||
id bigint NOT NULL,
|
||||
settlement_bill_id bigint NOT NULL,
|
||||
payer_type character varying(16) NOT NULL,
|
||||
payer_id bigint NOT NULL,
|
||||
payee_type character varying(16) NOT NULL,
|
||||
payee_id bigint NOT NULL,
|
||||
amount bigint NOT NULL,
|
||||
method character varying(32),
|
||||
status character varying(16) DEFAULT 'pending'::character varying NOT NULL,
|
||||
created_by bigint,
|
||||
confirmed_by bigint,
|
||||
confirmed_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
proof text,
|
||||
remark character varying(255)
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.payment_records_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.payment_records_id_seq OWNED BY public.payment_records.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.personal_access_tokens (
|
||||
id bigint NOT NULL,
|
||||
tokenable_type character varying(255) NOT NULL,
|
||||
tokenable_id bigint NOT NULL,
|
||||
name text NOT NULL,
|
||||
token character varying(64) NOT NULL,
|
||||
abilities text,
|
||||
last_used_at timestamp(0) without time zone,
|
||||
expires_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.personal_access_tokens_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.personal_access_tokens_id_seq OWNED BY public.personal_access_tokens.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.play_config_items (
|
||||
id bigint NOT NULL,
|
||||
version_id bigint NOT NULL,
|
||||
play_code character varying(32) NOT NULL,
|
||||
is_enabled boolean DEFAULT true NOT NULL,
|
||||
min_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
max_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
display_order integer DEFAULT 0 NOT NULL,
|
||||
rule_text_zh text,
|
||||
rule_text_en text,
|
||||
rule_text_ne text,
|
||||
extra_config_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
category character varying(16),
|
||||
dimension smallint,
|
||||
bet_mode character varying(32),
|
||||
supports_multi_number boolean DEFAULT false NOT NULL,
|
||||
reserved_rule_json json,
|
||||
display_name character varying(64)
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.play_config_items_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.play_config_items_id_seq OWNED BY public.play_config_items.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.play_config_versions (
|
||||
id bigint NOT NULL,
|
||||
version_no integer NOT NULL,
|
||||
status character varying(16) NOT NULL,
|
||||
effective_at timestamp(0) without time zone,
|
||||
updated_by bigint,
|
||||
reason character varying(255),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_versions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.play_config_versions_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_versions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.play_config_versions_id_seq OWNED BY public.play_config_versions.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_types; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.play_types (
|
||||
id bigint NOT NULL,
|
||||
play_code character varying(32) NOT NULL,
|
||||
category character varying(16) NOT NULL,
|
||||
dimension smallint,
|
||||
bet_mode character varying(32),
|
||||
is_enabled boolean DEFAULT true NOT NULL,
|
||||
sort_order integer DEFAULT 0 NOT NULL,
|
||||
supports_multi_number boolean DEFAULT false NOT NULL,
|
||||
reserved_rule_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
display_name character varying(64)
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN play_types.dimension; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.play_types.dimension IS '2/3/4';
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_types_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.play_types_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_types_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.play_types_id_seq OWNED BY public.play_types.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_credit_accounts; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.player_credit_accounts (
|
||||
player_id bigint NOT NULL,
|
||||
credit_limit bigint DEFAULT '0'::bigint NOT NULL,
|
||||
used_credit bigint DEFAULT '0'::bigint NOT NULL,
|
||||
frozen_credit bigint DEFAULT '0'::bigint NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.player_rebate_profiles (
|
||||
id bigint NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
game_type character varying(32) DEFAULT '*'::character varying NOT NULL,
|
||||
inherit_from_agent boolean DEFAULT true NOT NULL,
|
||||
rebate_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
extra_rebate_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.player_rebate_profiles_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.player_rebate_profiles_id_seq OWNED BY public.player_rebate_profiles.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.player_wallets (
|
||||
id bigint NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
wallet_type character varying(32) DEFAULT 'lottery'::character varying NOT NULL,
|
||||
currency_code character varying(16) NOT NULL,
|
||||
balance bigint DEFAULT '0'::bigint NOT NULL,
|
||||
frozen_balance bigint DEFAULT '0'::bigint NOT NULL,
|
||||
status smallint DEFAULT '0'::smallint NOT NULL,
|
||||
version bigint DEFAULT '0'::bigint NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN player_wallets.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.player_wallets.status IS '0=active,1=frozen';
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.player_wallets_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.player_wallets_id_seq OWNED BY public.player_wallets.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: players; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.players (
|
||||
id bigint NOT NULL,
|
||||
site_code character varying(64) NOT NULL,
|
||||
site_player_id character varying(128) NOT NULL,
|
||||
username character varying(128),
|
||||
nickname character varying(128),
|
||||
default_currency character varying(16) DEFAULT 'NPR'::character varying NOT NULL,
|
||||
status smallint DEFAULT '0'::smallint NOT NULL,
|
||||
last_login_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
agent_node_id bigint,
|
||||
auth_source character varying(16) DEFAULT 'main_site_sso'::character varying NOT NULL,
|
||||
funding_mode character varying(16) DEFAULT 'wallet'::character varying NOT NULL,
|
||||
password_hash character varying(255),
|
||||
login_failed_count smallint DEFAULT '0'::smallint NOT NULL,
|
||||
login_locked_until timestamp(0) without time zone,
|
||||
risk_tags json
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN players.status; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.players.status IS '0=active,1=frozen,2=blocked';
|
||||
|
||||
|
||||
--
|
||||
-- Name: players_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.players_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: players_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.players_id_seq OWNED BY public.players.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.rebate_allocations (
|
||||
id bigint NOT NULL,
|
||||
rebate_record_id bigint NOT NULL,
|
||||
settlement_bill_id bigint,
|
||||
participant_type character varying(16) NOT NULL,
|
||||
participant_id bigint DEFAULT '0'::bigint NOT NULL,
|
||||
actual_share_rate numeric(5,2) DEFAULT '0'::numeric NOT NULL,
|
||||
allocated_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
allocation_rule character varying(32) DEFAULT 'share'::character varying NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.rebate_allocations_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.rebate_allocations_id_seq OWNED BY public.rebate_allocations.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.rebate_records (
|
||||
id bigint NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
settlement_period_id bigint,
|
||||
game_type character varying(32) DEFAULT '*'::character varying NOT NULL,
|
||||
valid_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
rebate_rate numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
rebate_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
rebate_type character varying(16) DEFAULT 'basic'::character varying NOT NULL,
|
||||
owner_agent_id bigint,
|
||||
status character varying(16) DEFAULT 'pending'::character varying NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
ticket_item_id bigint,
|
||||
reversal_of_id bigint
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.rebate_records_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.rebate_records_id_seq OWNED BY public.rebate_records.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.reconcile_items (
|
||||
id bigint NOT NULL,
|
||||
reconcile_job_id bigint NOT NULL,
|
||||
side_a_ref character varying(128),
|
||||
side_b_ref character varying(128),
|
||||
difference_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
resolved_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.reconcile_items_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.reconcile_items_id_seq OWNED BY public.reconcile_items.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.reconcile_jobs (
|
||||
id bigint NOT NULL,
|
||||
job_no character varying(64) NOT NULL,
|
||||
reconcile_type character varying(32) NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
period_start timestamp(0) without time zone,
|
||||
period_end timestamp(0) without time zone,
|
||||
summary_json json,
|
||||
finished_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
admin_user_id bigint
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.reconcile_jobs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.reconcile_jobs_id_seq OWNED BY public.reconcile_jobs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.report_jobs (
|
||||
id bigint NOT NULL,
|
||||
job_no character varying(64) NOT NULL,
|
||||
admin_user_id bigint,
|
||||
report_type character varying(64) NOT NULL,
|
||||
export_format character varying(16) DEFAULT 'csv'::character varying NOT NULL,
|
||||
filter_json json,
|
||||
status character varying(32) NOT NULL,
|
||||
output_path character varying(512),
|
||||
error_message text,
|
||||
finished_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.report_jobs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.report_jobs_id_seq OWNED BY public.report_jobs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.risk_cap_items (
|
||||
id bigint NOT NULL,
|
||||
version_id bigint NOT NULL,
|
||||
draw_id bigint,
|
||||
normalized_number character(4) NOT NULL,
|
||||
cap_amount bigint NOT NULL,
|
||||
cap_type character varying(16) NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.risk_cap_items_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.risk_cap_items_id_seq OWNED BY public.risk_cap_items.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_versions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.risk_cap_versions (
|
||||
id bigint NOT NULL,
|
||||
version_no integer NOT NULL,
|
||||
status character varying(16) NOT NULL,
|
||||
effective_at timestamp(0) without time zone,
|
||||
updated_by bigint,
|
||||
reason character varying(255),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_versions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.risk_cap_versions_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_versions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.risk_cap_versions_id_seq OWNED BY public.risk_cap_versions.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.risk_pool_lock_logs (
|
||||
id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
normalized_number character(4) NOT NULL,
|
||||
ticket_item_id bigint,
|
||||
action_type character varying(16) NOT NULL,
|
||||
amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
source_reason character varying(32),
|
||||
created_at timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.risk_pool_lock_logs_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.risk_pool_lock_logs_id_seq OWNED BY public.risk_pool_lock_logs.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.risk_pools (
|
||||
id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
normalized_number character(4) NOT NULL,
|
||||
total_cap_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
locked_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
remaining_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
sold_out_status smallint DEFAULT '0'::smallint NOT NULL,
|
||||
version bigint DEFAULT '0'::bigint NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.risk_pools_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.risk_pools_id_seq OWNED BY public.risk_pools.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: sessions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.sessions (
|
||||
id character varying(255) NOT NULL,
|
||||
user_id bigint,
|
||||
ip_address character varying(45),
|
||||
user_agent text,
|
||||
payload text NOT NULL,
|
||||
last_activity integer NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.settlement_adjustments (
|
||||
id bigint NOT NULL,
|
||||
settlement_period_id bigint,
|
||||
original_bill_id bigint,
|
||||
adjustment_type character varying(32) NOT NULL,
|
||||
amount bigint NOT NULL,
|
||||
reason character varying(255),
|
||||
created_by bigint,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.settlement_adjustments_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.settlement_adjustments_id_seq OWNED BY public.settlement_adjustments.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.settlement_batches (
|
||||
id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
result_batch_id bigint NOT NULL,
|
||||
settle_version integer DEFAULT 1 NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
total_ticket_count integer DEFAULT 0 NOT NULL,
|
||||
total_win_count integer DEFAULT 0 NOT NULL,
|
||||
total_payout_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
total_jackpot_payout_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
review_status character varying(32) DEFAULT 'pending'::character varying NOT NULL,
|
||||
reviewed_by bigint,
|
||||
reviewed_at timestamp(0) without time zone,
|
||||
review_remark character varying(255),
|
||||
paid_at timestamp(0) without time zone,
|
||||
started_at timestamp(0) without time zone,
|
||||
finished_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.settlement_batches_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.settlement_batches_id_seq OWNED BY public.settlement_batches.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.settlement_bills (
|
||||
id bigint NOT NULL,
|
||||
settlement_period_id bigint NOT NULL,
|
||||
bill_type character varying(16) NOT NULL,
|
||||
owner_type character varying(16) NOT NULL,
|
||||
owner_id bigint NOT NULL,
|
||||
counterparty_type character varying(16) NOT NULL,
|
||||
counterparty_id bigint NOT NULL,
|
||||
gross_win_loss bigint DEFAULT '0'::bigint NOT NULL,
|
||||
rebate_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
adjustment_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
net_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
paid_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
unpaid_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
status character varying(16) DEFAULT 'pending'::character varying NOT NULL,
|
||||
confirmed_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
locked_at timestamp(0) without time zone,
|
||||
reversed_bill_id bigint,
|
||||
meta_json json,
|
||||
platform_rounding_adjustment bigint DEFAULT '0'::bigint NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.settlement_bills_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.settlement_bills_id_seq OWNED BY public.settlement_bills.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.settlement_periods (
|
||||
id bigint NOT NULL,
|
||||
admin_site_id bigint NOT NULL,
|
||||
period_start timestamp(0) without time zone NOT NULL,
|
||||
period_end timestamp(0) without time zone NOT NULL,
|
||||
status character varying(16) DEFAULT 'open'::character varying NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.settlement_periods_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.settlement_periods_id_seq OWNED BY public.settlement_periods.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.share_ledger (
|
||||
id bigint NOT NULL,
|
||||
ticket_item_id bigint NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
agent_node_id bigint,
|
||||
agent_path json,
|
||||
share_snapshot json,
|
||||
game_win_loss bigint DEFAULT '0'::bigint NOT NULL,
|
||||
basic_rebate bigint DEFAULT '0'::bigint NOT NULL,
|
||||
shared_net_win_loss bigint DEFAULT '0'::bigint NOT NULL,
|
||||
allocations_json json,
|
||||
settlement_period_id bigint,
|
||||
reversal_of_id bigint,
|
||||
settled_at timestamp(0) without time zone NOT NULL,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.share_ledger_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.share_ledger_id_seq OWNED BY public.share_ledger.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_combinations; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.ticket_combinations (
|
||||
id bigint NOT NULL,
|
||||
ticket_item_id bigint NOT NULL,
|
||||
combination_no integer DEFAULT 0 NOT NULL,
|
||||
number_4d character(4) NOT NULL,
|
||||
bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
estimated_payout bigint DEFAULT '0'::bigint NOT NULL,
|
||||
created_at timestamp(0) without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_combinations_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.ticket_combinations_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_combinations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.ticket_combinations_id_seq OWNED BY public.ticket_combinations.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.ticket_items (
|
||||
id bigint NOT NULL,
|
||||
ticket_no character varying(64) NOT NULL,
|
||||
order_id bigint NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
original_number character varying(32),
|
||||
normalized_number character(4) NOT NULL,
|
||||
play_code character varying(32) NOT NULL,
|
||||
dimension smallint,
|
||||
digit_slot smallint,
|
||||
bet_mode character varying(32),
|
||||
unit_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
total_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
rebate_rate_snapshot numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
commission_rate_snapshot numeric(8,4) DEFAULT '0'::numeric NOT NULL,
|
||||
actual_deduct_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
odds_snapshot_json json,
|
||||
rule_snapshot_json json,
|
||||
combination_count integer DEFAULT 1 NOT NULL,
|
||||
estimated_max_payout bigint DEFAULT '0'::bigint NOT NULL,
|
||||
risk_locked_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
fail_reason_code character varying(32),
|
||||
fail_reason_text character varying(255),
|
||||
win_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
jackpot_win_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
settled_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
agent_node_id bigint,
|
||||
share_snapshot json,
|
||||
agent_rebate_rate_snapshot numeric(8,4),
|
||||
agent_settled_at timestamp(0) without time zone,
|
||||
agent_settlement_reversal_of_id bigint
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN ticket_items.dimension; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.ticket_items.dimension IS '2/3/4';
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN ticket_items.digit_slot; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.ticket_items.digit_slot IS '千百十个位,领域字典';
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.ticket_items_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.ticket_items_id_seq OWNED BY public.ticket_items.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.ticket_orders (
|
||||
id bigint NOT NULL,
|
||||
order_no character varying(64) NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
draw_id bigint NOT NULL,
|
||||
currency_code character varying(16) NOT NULL,
|
||||
total_bet_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
total_rebate_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
total_actual_deduct bigint DEFAULT '0'::bigint NOT NULL,
|
||||
total_estimated_payout bigint DEFAULT '0'::bigint NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
submit_source character varying(16) DEFAULT 'h5'::character varying NOT NULL,
|
||||
client_trace_id character varying(64),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone,
|
||||
play_config_version_no integer DEFAULT 0 NOT NULL,
|
||||
odds_version_no integer DEFAULT 0 NOT NULL,
|
||||
risk_cap_version_no integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.ticket_orders_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.ticket_orders_id_seq OWNED BY public.ticket_orders.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.ticket_settlement_details (
|
||||
id bigint NOT NULL,
|
||||
settlement_batch_id bigint NOT NULL,
|
||||
ticket_item_id bigint NOT NULL,
|
||||
matched_prize_tier character varying(32),
|
||||
win_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
jackpot_allocation_amount bigint DEFAULT '0'::bigint NOT NULL,
|
||||
match_detail_json json,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.ticket_settlement_details_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.ticket_settlement_details_id_seq OWNED BY public.ticket_settlement_details.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.transfer_orders (
|
||||
id bigint NOT NULL,
|
||||
transfer_no character varying(64) NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
direction character varying(16) NOT NULL,
|
||||
currency_code character varying(16) NOT NULL,
|
||||
amount bigint NOT NULL,
|
||||
idempotent_key character varying(64) NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
external_request_payload json,
|
||||
external_response_payload json,
|
||||
external_ref_no character varying(64),
|
||||
fail_reason character varying(255),
|
||||
finished_at timestamp(0) without time zone,
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.transfer_orders_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.transfer_orders_id_seq OWNED BY public.transfer_orders.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.wallet_txns (
|
||||
id bigint NOT NULL,
|
||||
txn_no character varying(64) NOT NULL,
|
||||
player_id bigint NOT NULL,
|
||||
wallet_id bigint NOT NULL,
|
||||
biz_type character varying(32) NOT NULL,
|
||||
biz_no character varying(64),
|
||||
direction smallint NOT NULL,
|
||||
amount bigint NOT NULL,
|
||||
balance_before bigint NOT NULL,
|
||||
balance_after bigint NOT NULL,
|
||||
status character varying(32) NOT NULL,
|
||||
external_ref_no character varying(64),
|
||||
idempotent_key character varying(64),
|
||||
remark character varying(255),
|
||||
created_at timestamp(0) without time zone,
|
||||
updated_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: COLUMN wallet_txns.direction; Type: COMMENT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON COLUMN public.wallet_txns.direction IS '1=in,2=out';
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.wallet_txns_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.wallet_txns_id_seq OWNED BY public.wallet_txns.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_action_catalog id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_action_catalog ALTER COLUMN id SET DEFAULT nextval('public.admin_action_catalog_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resource_bindings ALTER COLUMN id SET DEFAULT nextval('public.admin_api_resource_bindings_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resources id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resources ALTER COLUMN id SET DEFAULT nextval('public.admin_api_resources_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menu_actions ALTER COLUMN id SET DEFAULT nextval('public.admin_menu_actions_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menus ALTER COLUMN id SET DEFAULT nextval('public.admin_menus_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_roles ALTER COLUMN id SET DEFAULT nextval('public.admin_roles_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_sites id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_sites ALTER COLUMN id SET DEFAULT nextval('public.admin_sites_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_users id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_users ALTER COLUMN id SET DEFAULT nextval('public.admin_users_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants ALTER COLUMN id SET DEFAULT nextval('public.agent_delegation_grants_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_nodes ALTER COLUMN id SET DEFAULT nextval('public.agent_nodes_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: audit_logs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.audit_logs ALTER COLUMN id SET DEFAULT nextval('public.audit_logs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: credit_ledger id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.credit_ledger ALTER COLUMN id SET DEFAULT nextval('public.credit_ledger_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: currencies id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.currencies ALTER COLUMN id SET DEFAULT nextval('public.currencies_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_batches ALTER COLUMN id SET DEFAULT nextval('public.draw_result_batches_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_items ALTER COLUMN id SET DEFAULT nextval('public.draw_result_items_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draws id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draws ALTER COLUMN id SET DEFAULT nextval('public.draws_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: failed_jobs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.failed_jobs ALTER COLUMN id SET DEFAULT nextval('public.failed_jobs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions ALTER COLUMN id SET DEFAULT nextval('public.jackpot_contributions_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_payout_logs ALTER COLUMN id SET DEFAULT nextval('public.jackpot_payout_logs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pool_adjustments ALTER COLUMN id SET DEFAULT nextval('public.jackpot_pool_adjustments_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pools ALTER COLUMN id SET DEFAULT nextval('public.jackpot_pools_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jobs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jobs ALTER COLUMN id SET DEFAULT nextval('public.jobs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: lottery_settings id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.lottery_settings ALTER COLUMN id SET DEFAULT nextval('public.lottery_settings_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: migrations id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.migrations ALTER COLUMN id SET DEFAULT nextval('public.migrations_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_items ALTER COLUMN id SET DEFAULT nextval('public.odds_items_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_versions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_versions ALTER COLUMN id SET DEFAULT nextval('public.odds_versions_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_records ALTER COLUMN id SET DEFAULT nextval('public.payment_records_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.personal_access_tokens ALTER COLUMN id SET DEFAULT nextval('public.personal_access_tokens_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_items ALTER COLUMN id SET DEFAULT nextval('public.play_config_items_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_versions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_versions ALTER COLUMN id SET DEFAULT nextval('public.play_config_versions_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_types id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_types ALTER COLUMN id SET DEFAULT nextval('public.play_types_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_rebate_profiles ALTER COLUMN id SET DEFAULT nextval('public.player_rebate_profiles_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_wallets ALTER COLUMN id SET DEFAULT nextval('public.player_wallets_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: players id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.players ALTER COLUMN id SET DEFAULT nextval('public.players_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_allocations ALTER COLUMN id SET DEFAULT nextval('public.rebate_allocations_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records ALTER COLUMN id SET DEFAULT nextval('public.rebate_records_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_items ALTER COLUMN id SET DEFAULT nextval('public.reconcile_items_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_jobs ALTER COLUMN id SET DEFAULT nextval('public.reconcile_jobs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.report_jobs ALTER COLUMN id SET DEFAULT nextval('public.report_jobs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_items ALTER COLUMN id SET DEFAULT nextval('public.risk_cap_items_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_versions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_versions ALTER COLUMN id SET DEFAULT nextval('public.risk_cap_versions_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pool_lock_logs ALTER COLUMN id SET DEFAULT nextval('public.risk_pool_lock_logs_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pools ALTER COLUMN id SET DEFAULT nextval('public.risk_pools_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_adjustments ALTER COLUMN id SET DEFAULT nextval('public.settlement_adjustments_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_batches ALTER COLUMN id SET DEFAULT nextval('public.settlement_batches_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_bills ALTER COLUMN id SET DEFAULT nextval('public.settlement_bills_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_periods ALTER COLUMN id SET DEFAULT nextval('public.settlement_periods_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger ALTER COLUMN id SET DEFAULT nextval('public.share_ledger_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_combinations id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_combinations ALTER COLUMN id SET DEFAULT nextval('public.ticket_combinations_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items ALTER COLUMN id SET DEFAULT nextval('public.ticket_items_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_orders ALTER COLUMN id SET DEFAULT nextval('public.ticket_orders_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_settlement_details ALTER COLUMN id SET DEFAULT nextval('public.ticket_settlement_details_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.transfer_orders ALTER COLUMN id SET DEFAULT nextval('public.transfer_orders_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.wallet_txns ALTER COLUMN id SET DEFAULT nextval('public.wallet_txns_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_action_catalog admin_action_catalog_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_action_catalog
|
||||
ADD CONSTRAINT admin_action_catalog_code_unique UNIQUE (code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_action_catalog admin_action_catalog_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_action_catalog
|
||||
ADD CONSTRAINT admin_action_catalog_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings admin_api_resource_bindings_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resource_bindings
|
||||
ADD CONSTRAINT admin_api_resource_bindings_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resources admin_api_resources_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resources
|
||||
ADD CONSTRAINT admin_api_resources_code_unique UNIQUE (code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resources admin_api_resources_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resources
|
||||
ADD CONSTRAINT admin_api_resources_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions admin_menu_actions_permission_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menu_actions
|
||||
ADD CONSTRAINT admin_menu_actions_permission_code_unique UNIQUE (permission_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions admin_menu_actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menu_actions
|
||||
ADD CONSTRAINT admin_menu_actions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus admin_menus_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menus
|
||||
ADD CONSTRAINT admin_menus_code_unique UNIQUE (code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus admin_menus_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menus
|
||||
ADD CONSTRAINT admin_menus_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_role_menu_actions admin_role_menu_actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_role_menu_actions
|
||||
ADD CONSTRAINT admin_role_menu_actions_pkey PRIMARY KEY (role_id, menu_action_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles admin_roles_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_roles
|
||||
ADD CONSTRAINT admin_roles_code_unique UNIQUE (code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles admin_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_roles
|
||||
ADD CONSTRAINT admin_roles_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles admin_roles_slug_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_roles
|
||||
ADD CONSTRAINT admin_roles_slug_unique UNIQUE (slug);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_sites admin_sites_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_sites
|
||||
ADD CONSTRAINT admin_sites_code_unique UNIQUE (code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_sites admin_sites_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_sites
|
||||
ADD CONSTRAINT admin_sites_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agent_roles admin_user_agent_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agent_roles
|
||||
ADD CONSTRAINT admin_user_agent_roles_pkey PRIMARY KEY (admin_user_id, agent_node_id, role_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agents admin_user_agents_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agents
|
||||
ADD CONSTRAINT admin_user_agents_pkey PRIMARY KEY (admin_user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_menu_actions admin_user_menu_actions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_menu_actions
|
||||
ADD CONSTRAINT admin_user_menu_actions_pkey PRIMARY KEY (admin_user_id, site_id, menu_action_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_site_roles admin_user_site_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_site_roles
|
||||
ADD CONSTRAINT admin_user_site_roles_pkey PRIMARY KEY (admin_user_id, site_id, role_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_users admin_users_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_users
|
||||
ADD CONSTRAINT admin_users_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_users admin_users_username_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_users
|
||||
ADD CONSTRAINT admin_users_username_unique UNIQUE (username);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants agent_delegation_grants_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants
|
||||
ADD CONSTRAINT agent_delegation_grants_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes agent_nodes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_nodes
|
||||
ADD CONSTRAINT agent_nodes_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_profiles agent_profiles_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_profiles
|
||||
ADD CONSTRAINT agent_profiles_pkey PRIMARY KEY (agent_node_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: audit_logs audit_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.audit_logs
|
||||
ADD CONSTRAINT audit_logs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: cache_locks cache_locks_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.cache_locks
|
||||
ADD CONSTRAINT cache_locks_pkey PRIMARY KEY (key);
|
||||
|
||||
|
||||
--
|
||||
-- Name: cache cache_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.cache
|
||||
ADD CONSTRAINT cache_pkey PRIMARY KEY (key);
|
||||
|
||||
|
||||
--
|
||||
-- Name: credit_ledger credit_ledger_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.credit_ledger
|
||||
ADD CONSTRAINT credit_ledger_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: currencies currencies_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.currencies
|
||||
ADD CONSTRAINT currencies_code_unique UNIQUE (code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: currencies currencies_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.currencies
|
||||
ADD CONSTRAINT currencies_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches draw_result_batches_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_batches
|
||||
ADD CONSTRAINT draw_result_batches_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items draw_result_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_items
|
||||
ADD CONSTRAINT draw_result_items_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draws draws_draw_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draws
|
||||
ADD CONSTRAINT draws_draw_no_unique UNIQUE (draw_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draws draws_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draws
|
||||
ADD CONSTRAINT draws_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: failed_jobs failed_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.failed_jobs
|
||||
ADD CONSTRAINT failed_jobs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: failed_jobs failed_jobs_uuid_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.failed_jobs
|
||||
ADD CONSTRAINT failed_jobs_uuid_unique UNIQUE (uuid);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions jackpot_contributions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions
|
||||
ADD CONSTRAINT jackpot_contributions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs jackpot_payout_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_payout_logs
|
||||
ADD CONSTRAINT jackpot_payout_logs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments jackpot_pool_adjustments_adjustment_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pool_adjustments
|
||||
ADD CONSTRAINT jackpot_pool_adjustments_adjustment_no_unique UNIQUE (adjustment_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments jackpot_pool_adjustments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pool_adjustments
|
||||
ADD CONSTRAINT jackpot_pool_adjustments_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools jackpot_pools_currency_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pools
|
||||
ADD CONSTRAINT jackpot_pools_currency_code_unique UNIQUE (currency_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools jackpot_pools_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pools
|
||||
ADD CONSTRAINT jackpot_pools_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: job_batches job_batches_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.job_batches
|
||||
ADD CONSTRAINT job_batches_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jobs jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jobs
|
||||
ADD CONSTRAINT jobs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: lottery_settings lottery_settings_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.lottery_settings
|
||||
ADD CONSTRAINT lottery_settings_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: lottery_settings lottery_settings_setting_key_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.lottery_settings
|
||||
ADD CONSTRAINT lottery_settings_setting_key_unique UNIQUE (setting_key);
|
||||
|
||||
|
||||
--
|
||||
-- Name: migrations migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.migrations
|
||||
ADD CONSTRAINT migrations_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items odds_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_items
|
||||
ADD CONSTRAINT odds_items_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_versions odds_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_versions
|
||||
ADD CONSTRAINT odds_versions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records payment_records_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_records
|
||||
ADD CONSTRAINT payment_records_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens personal_access_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.personal_access_tokens
|
||||
ADD CONSTRAINT personal_access_tokens_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens personal_access_tokens_token_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.personal_access_tokens
|
||||
ADD CONSTRAINT personal_access_tokens_token_unique UNIQUE (token);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items play_config_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_items
|
||||
ADD CONSTRAINT play_config_items_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_versions play_config_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_versions
|
||||
ADD CONSTRAINT play_config_versions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_types play_types_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_types
|
||||
ADD CONSTRAINT play_types_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_types play_types_play_code_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_types
|
||||
ADD CONSTRAINT play_types_play_code_unique UNIQUE (play_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_credit_accounts player_credit_accounts_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_credit_accounts
|
||||
ADD CONSTRAINT player_credit_accounts_pkey PRIMARY KEY (player_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles player_rebate_profiles_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_rebate_profiles
|
||||
ADD CONSTRAINT player_rebate_profiles_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles player_rebate_profiles_player_id_game_type_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_rebate_profiles
|
||||
ADD CONSTRAINT player_rebate_profiles_player_id_game_type_unique UNIQUE (player_id, game_type);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets player_wallets_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_wallets
|
||||
ADD CONSTRAINT player_wallets_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: players players_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.players
|
||||
ADD CONSTRAINT players_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations rebate_allocations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_allocations
|
||||
ADD CONSTRAINT rebate_allocations_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records rebate_records_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records
|
||||
ADD CONSTRAINT rebate_records_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_items reconcile_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_items
|
||||
ADD CONSTRAINT reconcile_items_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs reconcile_jobs_job_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_jobs
|
||||
ADD CONSTRAINT reconcile_jobs_job_no_unique UNIQUE (job_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs reconcile_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_jobs
|
||||
ADD CONSTRAINT reconcile_jobs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs report_jobs_job_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.report_jobs
|
||||
ADD CONSTRAINT report_jobs_job_no_unique UNIQUE (job_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs report_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.report_jobs
|
||||
ADD CONSTRAINT report_jobs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items risk_cap_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_items
|
||||
ADD CONSTRAINT risk_cap_items_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_versions risk_cap_versions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_versions
|
||||
ADD CONSTRAINT risk_cap_versions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs risk_pool_lock_logs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pool_lock_logs
|
||||
ADD CONSTRAINT risk_pool_lock_logs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools risk_pools_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pools
|
||||
ADD CONSTRAINT risk_pools_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: sessions sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.sessions
|
||||
ADD CONSTRAINT sessions_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments settlement_adjustments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_adjustments
|
||||
ADD CONSTRAINT settlement_adjustments_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches settlement_batches_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_batches
|
||||
ADD CONSTRAINT settlement_batches_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills settlement_bills_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_bills
|
||||
ADD CONSTRAINT settlement_bills_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods settlement_periods_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_periods
|
||||
ADD CONSTRAINT settlement_periods_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger share_ledger_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger
|
||||
ADD CONSTRAINT share_ledger_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_combinations ticket_combinations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_combinations
|
||||
ADD CONSTRAINT ticket_combinations_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_ticket_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_ticket_no_unique UNIQUE (ticket_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders ticket_orders_order_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_orders
|
||||
ADD CONSTRAINT ticket_orders_order_no_unique UNIQUE (order_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders ticket_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_orders
|
||||
ADD CONSTRAINT ticket_orders_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details ticket_settlement_details_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_settlement_details
|
||||
ADD CONSTRAINT ticket_settlement_details_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders transfer_orders_idempotent_key_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.transfer_orders
|
||||
ADD CONSTRAINT transfer_orders_idempotent_key_unique UNIQUE (idempotent_key);
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders transfer_orders_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.transfer_orders
|
||||
ADD CONSTRAINT transfer_orders_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders transfer_orders_transfer_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.transfer_orders
|
||||
ADD CONSTRAINT transfer_orders_transfer_no_unique UNIQUE (transfer_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings uk_admin_api_bindings_api_action; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resource_bindings
|
||||
ADD CONSTRAINT uk_admin_api_bindings_api_action UNIQUE (api_resource_id, menu_action_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions uk_admin_menu_actions_menu_action; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menu_actions
|
||||
ADD CONSTRAINT uk_admin_menu_actions_menu_action UNIQUE (menu_id, action_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants uk_agent_delegation_child_action; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants
|
||||
ADD CONSTRAINT uk_agent_delegation_child_action UNIQUE (child_agent_id, menu_action_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes uk_agent_nodes_site_code; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_nodes
|
||||
ADD CONSTRAINT uk_agent_nodes_site_code UNIQUE (admin_site_id, code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches uk_draw_result_batches_draw_version; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_batches
|
||||
ADD CONSTRAINT uk_draw_result_batches_draw_version UNIQUE (draw_id, result_version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions uk_jackpot_contributions_ticket_item; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions
|
||||
ADD CONSTRAINT uk_jackpot_contributions_ticket_item UNIQUE (ticket_item_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items uk_odds_items_version_play_prize_currency_dimension; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_items
|
||||
ADD CONSTRAINT uk_odds_items_version_play_prize_currency_dimension UNIQUE (version_id, play_code, prize_scope, currency_code, dimension);
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items uk_play_config_items_version_play; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_items
|
||||
ADD CONSTRAINT uk_play_config_items_version_play UNIQUE (version_id, play_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets uk_player_wallets_player_type_currency; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_wallets
|
||||
ADD CONSTRAINT uk_player_wallets_player_type_currency UNIQUE (player_id, wallet_type, currency_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: players uk_players_site_player; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.players
|
||||
ADD CONSTRAINT uk_players_site_player UNIQUE (site_code, site_player_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools uk_risk_pools_draw_number; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pools
|
||||
ADD CONSTRAINT uk_risk_pools_draw_number UNIQUE (draw_id, normalized_number);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details uk_ticket_settlement_batch_ticket; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_settlement_details
|
||||
ADD CONSTRAINT uk_ticket_settlement_batch_ticket UNIQUE (settlement_batch_id, ticket_item_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns uk_wallet_txns_idempotent_biz; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.wallet_txns
|
||||
ADD CONSTRAINT uk_wallet_txns_idempotent_biz UNIQUE (idempotent_key, biz_type);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders uniq_ticket_orders_player_draw_trace; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_orders
|
||||
ADD CONSTRAINT uniq_ticket_orders_player_draw_trace UNIQUE (player_id, draw_id, client_trace_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns wallet_txns_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.wallet_txns
|
||||
ADD CONSTRAINT wallet_txns_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns wallet_txns_txn_no_unique; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.wallet_txns
|
||||
ADD CONSTRAINT wallet_txns_txn_no_unique UNIQUE (txn_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: cache_expiration_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX cache_expiration_index ON public.cache USING btree (expiration);
|
||||
|
||||
|
||||
--
|
||||
-- Name: cache_locks_expiration_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX cache_locks_expiration_index ON public.cache_locks USING btree (expiration);
|
||||
|
||||
|
||||
--
|
||||
-- Name: credit_ledger_owner_type_owner_id_created_at_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX credit_ledger_owner_type_owner_id_created_at_index ON public.credit_ledger USING btree (owner_type, owner_id, created_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_admin_api_resources_module_status; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_admin_api_resources_module_status ON public.admin_api_resources USING btree (module_code, status);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_admin_menu_actions_menu_status; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_admin_menu_actions_menu_status ON public.admin_menu_actions USING btree (menu_id, status);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_admin_menus_parent_sort; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_admin_menus_parent_sort ON public.admin_menus USING btree (parent_id, sort_order);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_agent_delegation_parent_child; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_agent_delegation_parent_child ON public.agent_delegation_grants USING btree (parent_agent_id, child_agent_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_agent_nodes_path; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_agent_nodes_path ON public.agent_nodes USING btree (path);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_agent_nodes_site_parent; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_agent_nodes_site_parent ON public.agent_nodes USING btree (admin_site_id, parent_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_audit_logs_module_action; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_audit_logs_module_action ON public.audit_logs USING btree (module_code, action_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_audit_logs_operator_time; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_audit_logs_operator_time ON public.audit_logs USING btree (operator_type, operator_id, created_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_draw_result_items_batch_prize; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_draw_result_items_batch_prize ON public.draw_result_items USING btree (result_batch_id, prize_type, prize_index);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_draw_result_items_draw_number; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_draw_result_items_draw_number ON public.draw_result_items USING btree (draw_id, number_4d);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_draw_result_items_draw_prize; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_draw_result_items_draw_prize ON public.draw_result_items USING btree (draw_id, prize_type, prize_index);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_draws_business_date_draw_time; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_draws_business_date_draw_time ON public.draws USING btree (business_date, draw_time);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_draws_status_draw_time; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_draws_status_draw_time ON public.draws USING btree (status, draw_time);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_jackpot_contrib_draw_player; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_jackpot_contrib_draw_player ON public.jackpot_contributions USING btree (draw_id, player_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_jackpot_pool_adjustments_pool_created; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_jackpot_pool_adjustments_pool_created ON public.jackpot_pool_adjustments USING btree (jackpot_pool_id, created_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_lottery_settings_group; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_lottery_settings_group ON public.lottery_settings USING btree (group_name);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_odds_items_version_play; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_odds_items_version_play ON public.odds_items USING btree (version_id, play_code);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_players_site_agent; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_players_site_agent ON public.players USING btree (site_code, agent_node_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_players_site_auth_username; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_players_site_auth_username ON public.players USING btree (site_code, auth_source, username);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_players_status; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_players_status ON public.players USING btree (status);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_risk_cap_items_lookup; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_risk_cap_items_lookup ON public.risk_cap_items USING btree (version_id, draw_id, normalized_number);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_risk_lock_logs_draw_number; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_risk_lock_logs_draw_number ON public.risk_pool_lock_logs USING btree (draw_id, normalized_number);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_risk_pools_draw_soldout; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_risk_pools_draw_soldout ON public.risk_pools USING btree (draw_id, sold_out_status);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_settlement_batches_draw_version; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_settlement_batches_draw_version ON public.settlement_batches USING btree (draw_id, settle_version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_settlement_batches_result_batch_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_settlement_batches_result_batch_id ON public.settlement_batches USING btree (result_batch_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_combinations_item; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_combinations_item ON public.ticket_combinations USING btree (ticket_item_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_combinations_number; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_combinations_number ON public.ticket_combinations USING btree (number_4d);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_items_draw_number; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_items_draw_number ON public.ticket_items USING btree (draw_id, normalized_number);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_items_draw_status; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_items_draw_status ON public.ticket_items USING btree (draw_id, status);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_items_order_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_items_order_id ON public.ticket_items USING btree (order_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_items_player_draw; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_items_player_draw ON public.ticket_items USING btree (player_id, draw_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_items_player_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_items_player_id ON public.ticket_items USING btree (player_id, id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_orders_draw_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_orders_draw_id ON public.ticket_orders USING btree (draw_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_orders_player_draw; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_orders_player_draw ON public.ticket_orders USING btree (player_id, draw_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_ticket_settlement_details_ticket_item; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_ticket_settlement_details_ticket_item ON public.ticket_settlement_details USING btree (ticket_item_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_wallet_txns_biz; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_wallet_txns_biz ON public.wallet_txns USING btree (biz_type, biz_no);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_wallet_txns_player_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_wallet_txns_player_id ON public.wallet_txns USING btree (player_id, id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: idx_wallet_txns_player_time; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX idx_wallet_txns_player_time ON public.wallet_txns USING btree (player_id, created_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: jobs_queue_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX jobs_queue_index ON public.jobs USING btree (queue);
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens_expires_at_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX personal_access_tokens_expires_at_index ON public.personal_access_tokens USING btree (expires_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: personal_access_tokens_tokenable_type_tokenable_id_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX personal_access_tokens_tokenable_type_tokenable_id_index ON public.personal_access_tokens USING btree (tokenable_type, tokenable_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: sessions_last_activity_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX sessions_last_activity_index ON public.sessions USING btree (last_activity);
|
||||
|
||||
|
||||
--
|
||||
-- Name: sessions_user_id_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX sessions_user_id_index ON public.sessions USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills_settlement_period_id_bill_type_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX settlement_bills_settlement_period_id_bill_type_index ON public.settlement_bills USING btree (settlement_period_id, bill_type);
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods_admin_site_id_status_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX settlement_periods_admin_site_id_status_index ON public.settlement_periods USING btree (admin_site_id, status);
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger_settled_at_player_id_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX share_ledger_settled_at_player_id_index ON public.share_ledger USING btree (settled_at, player_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger_settlement_period_id_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX share_ledger_settlement_period_id_index ON public.share_ledger USING btree (settlement_period_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders_player_id_created_at_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX transfer_orders_player_id_created_at_index ON public.transfer_orders USING btree (player_id, created_at);
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings admin_api_resource_bindings_api_resource_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resource_bindings
|
||||
ADD CONSTRAINT admin_api_resource_bindings_api_resource_id_foreign FOREIGN KEY (api_resource_id) REFERENCES public.admin_api_resources(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_api_resource_bindings admin_api_resource_bindings_menu_action_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_api_resource_bindings
|
||||
ADD CONSTRAINT admin_api_resource_bindings_menu_action_id_foreign FOREIGN KEY (menu_action_id) REFERENCES public.admin_menu_actions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions admin_menu_actions_action_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menu_actions
|
||||
ADD CONSTRAINT admin_menu_actions_action_id_foreign FOREIGN KEY (action_id) REFERENCES public.admin_action_catalog(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menu_actions admin_menu_actions_menu_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menu_actions
|
||||
ADD CONSTRAINT admin_menu_actions_menu_id_foreign FOREIGN KEY (menu_id) REFERENCES public.admin_menus(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_menus admin_menus_parent_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_menus
|
||||
ADD CONSTRAINT admin_menus_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES public.admin_menus(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_role_menu_actions admin_role_menu_actions_menu_action_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_role_menu_actions
|
||||
ADD CONSTRAINT admin_role_menu_actions_menu_action_id_foreign FOREIGN KEY (menu_action_id) REFERENCES public.admin_menu_actions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_role_menu_actions admin_role_menu_actions_role_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_role_menu_actions
|
||||
ADD CONSTRAINT admin_role_menu_actions_role_id_foreign FOREIGN KEY (role_id) REFERENCES public.admin_roles(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles admin_roles_delegated_from_role_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_roles
|
||||
ADD CONSTRAINT admin_roles_delegated_from_role_id_foreign FOREIGN KEY (delegated_from_role_id) REFERENCES public.admin_roles(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_roles admin_roles_owner_agent_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_roles
|
||||
ADD CONSTRAINT admin_roles_owner_agent_id_foreign FOREIGN KEY (owner_agent_id) REFERENCES public.agent_nodes(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agent_roles admin_user_agent_roles_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agent_roles
|
||||
ADD CONSTRAINT admin_user_agent_roles_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agent_roles admin_user_agent_roles_agent_node_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agent_roles
|
||||
ADD CONSTRAINT admin_user_agent_roles_agent_node_id_foreign FOREIGN KEY (agent_node_id) REFERENCES public.agent_nodes(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agent_roles admin_user_agent_roles_role_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agent_roles
|
||||
ADD CONSTRAINT admin_user_agent_roles_role_id_foreign FOREIGN KEY (role_id) REFERENCES public.admin_roles(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agents admin_user_agents_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agents
|
||||
ADD CONSTRAINT admin_user_agents_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_agents admin_user_agents_agent_node_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_agents
|
||||
ADD CONSTRAINT admin_user_agents_agent_node_id_foreign FOREIGN KEY (agent_node_id) REFERENCES public.agent_nodes(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_menu_actions admin_user_menu_actions_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_menu_actions
|
||||
ADD CONSTRAINT admin_user_menu_actions_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_menu_actions admin_user_menu_actions_menu_action_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_menu_actions
|
||||
ADD CONSTRAINT admin_user_menu_actions_menu_action_id_foreign FOREIGN KEY (menu_action_id) REFERENCES public.admin_menu_actions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_menu_actions admin_user_menu_actions_site_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_menu_actions
|
||||
ADD CONSTRAINT admin_user_menu_actions_site_id_foreign FOREIGN KEY (site_id) REFERENCES public.admin_sites(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_site_roles admin_user_site_roles_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_site_roles
|
||||
ADD CONSTRAINT admin_user_site_roles_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_site_roles admin_user_site_roles_role_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_site_roles
|
||||
ADD CONSTRAINT admin_user_site_roles_role_id_foreign FOREIGN KEY (role_id) REFERENCES public.admin_roles(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: admin_user_site_roles admin_user_site_roles_site_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.admin_user_site_roles
|
||||
ADD CONSTRAINT admin_user_site_roles_site_id_foreign FOREIGN KEY (site_id) REFERENCES public.admin_sites(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants agent_delegation_grants_child_agent_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants
|
||||
ADD CONSTRAINT agent_delegation_grants_child_agent_id_foreign FOREIGN KEY (child_agent_id) REFERENCES public.agent_nodes(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants agent_delegation_grants_granted_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants
|
||||
ADD CONSTRAINT agent_delegation_grants_granted_by_foreign FOREIGN KEY (granted_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants agent_delegation_grants_menu_action_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants
|
||||
ADD CONSTRAINT agent_delegation_grants_menu_action_id_foreign FOREIGN KEY (menu_action_id) REFERENCES public.admin_menu_actions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_delegation_grants agent_delegation_grants_parent_agent_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_delegation_grants
|
||||
ADD CONSTRAINT agent_delegation_grants_parent_agent_id_foreign FOREIGN KEY (parent_agent_id) REFERENCES public.agent_nodes(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes agent_nodes_admin_site_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_nodes
|
||||
ADD CONSTRAINT agent_nodes_admin_site_id_foreign FOREIGN KEY (admin_site_id) REFERENCES public.admin_sites(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes agent_nodes_created_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_nodes
|
||||
ADD CONSTRAINT agent_nodes_created_by_foreign FOREIGN KEY (created_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_nodes agent_nodes_parent_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_nodes
|
||||
ADD CONSTRAINT agent_nodes_parent_id_foreign FOREIGN KEY (parent_id) REFERENCES public.agent_nodes(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: agent_profiles agent_profiles_agent_node_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.agent_profiles
|
||||
ADD CONSTRAINT agent_profiles_agent_node_id_foreign FOREIGN KEY (agent_node_id) REFERENCES public.agent_nodes(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches draw_result_batches_confirmed_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_batches
|
||||
ADD CONSTRAINT draw_result_batches_confirmed_by_foreign FOREIGN KEY (confirmed_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches draw_result_batches_created_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_batches
|
||||
ADD CONSTRAINT draw_result_batches_created_by_foreign FOREIGN KEY (created_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_batches draw_result_batches_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_batches
|
||||
ADD CONSTRAINT draw_result_batches_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items draw_result_items_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_items
|
||||
ADD CONSTRAINT draw_result_items_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: draw_result_items draw_result_items_result_batch_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.draw_result_items
|
||||
ADD CONSTRAINT draw_result_items_result_batch_id_foreign FOREIGN KEY (result_batch_id) REFERENCES public.draw_result_batches(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions jackpot_contributions_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions
|
||||
ADD CONSTRAINT jackpot_contributions_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions jackpot_contributions_jackpot_pool_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions
|
||||
ADD CONSTRAINT jackpot_contributions_jackpot_pool_id_foreign FOREIGN KEY (jackpot_pool_id) REFERENCES public.jackpot_pools(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions jackpot_contributions_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions
|
||||
ADD CONSTRAINT jackpot_contributions_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_contributions jackpot_contributions_ticket_item_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_contributions
|
||||
ADD CONSTRAINT jackpot_contributions_ticket_item_id_foreign FOREIGN KEY (ticket_item_id) REFERENCES public.ticket_items(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs jackpot_payout_logs_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_payout_logs
|
||||
ADD CONSTRAINT jackpot_payout_logs_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_payout_logs jackpot_payout_logs_jackpot_pool_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_payout_logs
|
||||
ADD CONSTRAINT jackpot_payout_logs_jackpot_pool_id_foreign FOREIGN KEY (jackpot_pool_id) REFERENCES public.jackpot_pools(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments jackpot_pool_adjustments_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pool_adjustments
|
||||
ADD CONSTRAINT jackpot_pool_adjustments_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pool_adjustments jackpot_pool_adjustments_jackpot_pool_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pool_adjustments
|
||||
ADD CONSTRAINT jackpot_pool_adjustments_jackpot_pool_id_foreign FOREIGN KEY (jackpot_pool_id) REFERENCES public.jackpot_pools(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: jackpot_pools jackpot_pools_last_trigger_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.jackpot_pools
|
||||
ADD CONSTRAINT jackpot_pools_last_trigger_draw_id_foreign FOREIGN KEY (last_trigger_draw_id) REFERENCES public.draws(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_items odds_items_version_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_items
|
||||
ADD CONSTRAINT odds_items_version_id_foreign FOREIGN KEY (version_id) REFERENCES public.odds_versions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: odds_versions odds_versions_updated_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.odds_versions
|
||||
ADD CONSTRAINT odds_versions_updated_by_foreign FOREIGN KEY (updated_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records payment_records_confirmed_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_records
|
||||
ADD CONSTRAINT payment_records_confirmed_by_foreign FOREIGN KEY (confirmed_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records payment_records_created_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_records
|
||||
ADD CONSTRAINT payment_records_created_by_foreign FOREIGN KEY (created_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: payment_records payment_records_settlement_bill_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.payment_records
|
||||
ADD CONSTRAINT payment_records_settlement_bill_id_foreign FOREIGN KEY (settlement_bill_id) REFERENCES public.settlement_bills(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_items play_config_items_version_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_items
|
||||
ADD CONSTRAINT play_config_items_version_id_foreign FOREIGN KEY (version_id) REFERENCES public.play_config_versions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: play_config_versions play_config_versions_updated_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.play_config_versions
|
||||
ADD CONSTRAINT play_config_versions_updated_by_foreign FOREIGN KEY (updated_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_credit_accounts player_credit_accounts_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_credit_accounts
|
||||
ADD CONSTRAINT player_credit_accounts_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_rebate_profiles player_rebate_profiles_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_rebate_profiles
|
||||
ADD CONSTRAINT player_rebate_profiles_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: player_wallets player_wallets_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.player_wallets
|
||||
ADD CONSTRAINT player_wallets_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: players players_agent_node_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.players
|
||||
ADD CONSTRAINT players_agent_node_id_foreign FOREIGN KEY (agent_node_id) REFERENCES public.agent_nodes(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations rebate_allocations_rebate_record_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_allocations
|
||||
ADD CONSTRAINT rebate_allocations_rebate_record_id_foreign FOREIGN KEY (rebate_record_id) REFERENCES public.rebate_records(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_allocations rebate_allocations_settlement_bill_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_allocations
|
||||
ADD CONSTRAINT rebate_allocations_settlement_bill_id_foreign FOREIGN KEY (settlement_bill_id) REFERENCES public.settlement_bills(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records rebate_records_owner_agent_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records
|
||||
ADD CONSTRAINT rebate_records_owner_agent_id_foreign FOREIGN KEY (owner_agent_id) REFERENCES public.agent_nodes(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records rebate_records_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records
|
||||
ADD CONSTRAINT rebate_records_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records rebate_records_reversal_of_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records
|
||||
ADD CONSTRAINT rebate_records_reversal_of_id_foreign FOREIGN KEY (reversal_of_id) REFERENCES public.rebate_records(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records rebate_records_settlement_period_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records
|
||||
ADD CONSTRAINT rebate_records_settlement_period_id_foreign FOREIGN KEY (settlement_period_id) REFERENCES public.settlement_periods(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: rebate_records rebate_records_ticket_item_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.rebate_records
|
||||
ADD CONSTRAINT rebate_records_ticket_item_id_foreign FOREIGN KEY (ticket_item_id) REFERENCES public.ticket_items(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_items reconcile_items_reconcile_job_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_items
|
||||
ADD CONSTRAINT reconcile_items_reconcile_job_id_foreign FOREIGN KEY (reconcile_job_id) REFERENCES public.reconcile_jobs(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: reconcile_jobs reconcile_jobs_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.reconcile_jobs
|
||||
ADD CONSTRAINT reconcile_jobs_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: report_jobs report_jobs_admin_user_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.report_jobs
|
||||
ADD CONSTRAINT report_jobs_admin_user_id_foreign FOREIGN KEY (admin_user_id) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items risk_cap_items_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_items
|
||||
ADD CONSTRAINT risk_cap_items_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_items risk_cap_items_version_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_items
|
||||
ADD CONSTRAINT risk_cap_items_version_id_foreign FOREIGN KEY (version_id) REFERENCES public.risk_cap_versions(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_cap_versions risk_cap_versions_updated_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_cap_versions
|
||||
ADD CONSTRAINT risk_cap_versions_updated_by_foreign FOREIGN KEY (updated_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs risk_pool_lock_logs_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pool_lock_logs
|
||||
ADD CONSTRAINT risk_pool_lock_logs_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pool_lock_logs risk_pool_lock_logs_ticket_item_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pool_lock_logs
|
||||
ADD CONSTRAINT risk_pool_lock_logs_ticket_item_id_foreign FOREIGN KEY (ticket_item_id) REFERENCES public.ticket_items(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: risk_pools risk_pools_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.risk_pools
|
||||
ADD CONSTRAINT risk_pools_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments settlement_adjustments_created_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_adjustments
|
||||
ADD CONSTRAINT settlement_adjustments_created_by_foreign FOREIGN KEY (created_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments settlement_adjustments_original_bill_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_adjustments
|
||||
ADD CONSTRAINT settlement_adjustments_original_bill_id_foreign FOREIGN KEY (original_bill_id) REFERENCES public.settlement_bills(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_adjustments settlement_adjustments_settlement_period_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_adjustments
|
||||
ADD CONSTRAINT settlement_adjustments_settlement_period_id_foreign FOREIGN KEY (settlement_period_id) REFERENCES public.settlement_periods(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches settlement_batches_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_batches
|
||||
ADD CONSTRAINT settlement_batches_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches settlement_batches_result_batch_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_batches
|
||||
ADD CONSTRAINT settlement_batches_result_batch_id_foreign FOREIGN KEY (result_batch_id) REFERENCES public.draw_result_batches(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_batches settlement_batches_reviewed_by_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_batches
|
||||
ADD CONSTRAINT settlement_batches_reviewed_by_foreign FOREIGN KEY (reviewed_by) REFERENCES public.admin_users(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills settlement_bills_reversed_bill_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_bills
|
||||
ADD CONSTRAINT settlement_bills_reversed_bill_id_foreign FOREIGN KEY (reversed_bill_id) REFERENCES public.settlement_bills(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_bills settlement_bills_settlement_period_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_bills
|
||||
ADD CONSTRAINT settlement_bills_settlement_period_id_foreign FOREIGN KEY (settlement_period_id) REFERENCES public.settlement_periods(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: settlement_periods settlement_periods_admin_site_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.settlement_periods
|
||||
ADD CONSTRAINT settlement_periods_admin_site_id_foreign FOREIGN KEY (admin_site_id) REFERENCES public.admin_sites(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger share_ledger_agent_node_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger
|
||||
ADD CONSTRAINT share_ledger_agent_node_id_foreign FOREIGN KEY (agent_node_id) REFERENCES public.agent_nodes(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger share_ledger_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger
|
||||
ADD CONSTRAINT share_ledger_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger share_ledger_reversal_of_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger
|
||||
ADD CONSTRAINT share_ledger_reversal_of_id_foreign FOREIGN KEY (reversal_of_id) REFERENCES public.share_ledger(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger share_ledger_settlement_period_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger
|
||||
ADD CONSTRAINT share_ledger_settlement_period_id_foreign FOREIGN KEY (settlement_period_id) REFERENCES public.settlement_periods(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: share_ledger share_ledger_ticket_item_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.share_ledger
|
||||
ADD CONSTRAINT share_ledger_ticket_item_id_foreign FOREIGN KEY (ticket_item_id) REFERENCES public.ticket_items(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_combinations ticket_combinations_ticket_item_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_combinations
|
||||
ADD CONSTRAINT ticket_combinations_ticket_item_id_foreign FOREIGN KEY (ticket_item_id) REFERENCES public.ticket_items(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_agent_node_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_agent_node_id_foreign FOREIGN KEY (agent_node_id) REFERENCES public.agent_nodes(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_agent_settlement_reversal_of_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_agent_settlement_reversal_of_id_foreign FOREIGN KEY (agent_settlement_reversal_of_id) REFERENCES public.ticket_items(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_order_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_order_id_foreign FOREIGN KEY (order_id) REFERENCES public.ticket_orders(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_items ticket_items_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_items
|
||||
ADD CONSTRAINT ticket_items_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders ticket_orders_draw_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_orders
|
||||
ADD CONSTRAINT ticket_orders_draw_id_foreign FOREIGN KEY (draw_id) REFERENCES public.draws(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_orders ticket_orders_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_orders
|
||||
ADD CONSTRAINT ticket_orders_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details ticket_settlement_details_settlement_batch_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_settlement_details
|
||||
ADD CONSTRAINT ticket_settlement_details_settlement_batch_id_foreign FOREIGN KEY (settlement_batch_id) REFERENCES public.settlement_batches(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: ticket_settlement_details ticket_settlement_details_ticket_item_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.ticket_settlement_details
|
||||
ADD CONSTRAINT ticket_settlement_details_ticket_item_id_foreign FOREIGN KEY (ticket_item_id) REFERENCES public.ticket_items(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: transfer_orders transfer_orders_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.transfer_orders
|
||||
ADD CONSTRAINT transfer_orders_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns wallet_txns_player_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.wallet_txns
|
||||
ADD CONSTRAINT wallet_txns_player_id_foreign FOREIGN KEY (player_id) REFERENCES public.players(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: wallet_txns wallet_txns_wallet_id_foreign; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.wallet_txns
|
||||
ADD CONSTRAINT wallet_txns_wallet_id_foreign FOREIGN KEY (wallet_id) REFERENCES public.player_wallets(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict rPXEgF1VaYgsz0ptn4X1KcYROWRPYlYb6daN4zAOY961hMNjxCs5gLhsUZO9N0E
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict RiLJxG2okqJB0Ghnyl7nmKPp6kFTgq0lQmAb7r3CeeShjxRjgjZVfbJ1VM9V1oB
|
||||
|
||||
-- Dumped from database version 18.3(ServBay)
|
||||
-- Dumped by pg_dump version 18.3(ServBay)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Data for Name: migrations; Type: TABLE DATA; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
COPY public.migrations (id, migration, batch) FROM stdin;
|
||||
1 0001_01_01_000000_create_users_table 1
|
||||
2 0001_01_01_000001_create_cache_table 1
|
||||
3 0001_01_01_000002_create_jobs_table 1
|
||||
4 2026_05_08_100000_create_currencies_table 1
|
||||
5 2026_05_08_100001_create_players_table 1
|
||||
6 2026_05_08_100002_create_admin_users_table 1
|
||||
7 2026_05_08_100003_create_admin_roles_and_permissions_tables 1
|
||||
8 2026_05_08_100004_create_player_wallets_table 1
|
||||
9 2026_05_08_100005_create_wallet_txns_table 1
|
||||
10 2026_05_08_100006_create_transfer_orders_table 1
|
||||
11 2026_05_08_100007_create_draws_table 1
|
||||
12 2026_05_08_100008_create_draw_result_batches_table 1
|
||||
13 2026_05_08_100009_create_draw_result_items_table 1
|
||||
14 2026_05_08_120000_drop_laravel_default_users_and_password_reset_tables 1
|
||||
15 2026_05_08_130000_create_play_types_table 1
|
||||
16 2026_05_08_130001_create_play_config_versions_and_items_tables 1
|
||||
17 2026_05_08_130002_create_odds_versions_and_items_tables 1
|
||||
18 2026_05_08_130003_create_risk_cap_versions_and_items_tables 1
|
||||
19 2026_05_08_130004_create_ticket_orders_table 1
|
||||
20 2026_05_08_130005_create_ticket_items_table 1
|
||||
21 2026_05_08_130006_create_ticket_combinations_table 1
|
||||
22 2026_05_08_130007_create_risk_pools_and_lock_logs_tables 1
|
||||
23 2026_05_08_130008_create_settlement_and_jackpot_tables 1
|
||||
24 2026_05_08_130009_create_report_audit_reconcile_tables 1
|
||||
25 2026_05_08_140000_create_lottery_settings_table 1
|
||||
26 2026_05_09_023835_create_personal_access_tokens_table 1
|
||||
27 2026_05_09_119999_rename_duplicate_migration_filenames_in_table 1
|
||||
28 2026_05_09_120001_add_username_and_nullable_email_to_admin_users 1
|
||||
29 2026_05_09_120002_migrate_draw_status_to_domain_dict 1
|
||||
30 2026_05_11_120000_add_admin_user_id_to_reconcile_jobs_table 1
|
||||
31 2026_05_11_173000_create_admin_user_permissions_table 1
|
||||
32 2026_05_13_100000_rebuild_admin_authorization_system 1
|
||||
33 2026_05_16_000100_add_snapshot_columns_to_play_config_items_table 1
|
||||
34 2026_05_18_000001_add_combo_trigger_to_jackpot_pools_table 1
|
||||
35 2026_05_18_090000_add_config_version_snapshots_to_ticket_orders 1
|
||||
36 2026_05_18_120000_sync_complete_admin_api_resources 1
|
||||
37 2026_05_19_112752_seed_default_jackpot_pools 1
|
||||
38 2026_05_19_120000_create_admin_role_legacy_permissions_table 1
|
||||
39 2026_05_19_121000_sync_admin_role_manage_permission 1
|
||||
40 2026_05_19_122000_sync_player_permission_resource_bindings 1
|
||||
41 2026_05_20_000001_add_admin_ticket_items_api_resource 1
|
||||
42 2026_05_21_000002_add_admin_currency_api_resources 1
|
||||
43 2026_05_21_093141_add_dimension_to_odds_items_table 1
|
||||
44 2026_05_21_150000_add_admin_currency_destroy_api_resource 1
|
||||
45 2026_05_21_160000_add_currency_manage_legacy_permission 1
|
||||
46 2026_05_21_170000_move_currency_menu_to_top_level_route 1
|
||||
47 2026_05_22_100000_add_admin_report_module 1
|
||||
48 2026_05_22_110000_fix_admin_report_authorization 1
|
||||
49 2026_05_22_120000_drop_redundant_admin_and_system_tables 1
|
||||
50 2026_05_22_130000_consolidate_admin_rbac_slugs 1
|
||||
51 2026_05_22_140000_add_frontend_play_rules_html_i18n_settings 1
|
||||
52 2026_05_25_120001_consolidate_play_display_name_columns 1
|
||||
53 2026_05_25_120002_expand_audit_logs_target_type 1
|
||||
54 2026_05_25_120003_refine_admin_permission_granularity 1
|
||||
55 2026_05_25_130000_remove_stale_admin_menu_actions 1
|
||||
56 2026_05_25_140000_add_admin_dashboard_analytics_resource 1
|
||||
57 2026_05_25_180000_add_settlement_batch_review_columns 1
|
||||
58 2026_05_26_100000_expand_admin_permission_granularity 1
|
||||
59 2026_05_27_100000_add_jackpot_manual_burst_permission 1
|
||||
60 2026_05_28_100000_resync_admin_api_resources_after_dashboard_view 2
|
||||
61 2026_05_29_100000_add_unique_ticket_item_id_to_jackpot_contributions 3
|
||||
62 2026_05_30_100000_create_jackpot_pool_adjustments_table 4
|
||||
63 2026_05_30_100001_add_jackpot_pool_adjustment_api_resources 5
|
||||
64 2026_05_26_120000_add_unique_client_trace_to_ticket_orders 6
|
||||
65 2026_05_27_140000_add_integration_fields_to_admin_sites 6
|
||||
66 2026_05_27_140001_seed_integration_menu_actions 7
|
||||
67 2026_05_31_100000_add_query_performance_indexes 8
|
||||
68 2026_06_01_100000_add_admin_settings_batch_update_api_resource 8
|
||||
69 2026_06_02_100000_create_agent_hierarchy_tables 8
|
||||
70 2026_06_02_100001_seed_agent_node_permissions 8
|
||||
71 2026_06_02_110000_agent_scoped_roles_and_player_agent 8
|
||||
72 2026_06_02_110001_seed_agent_role_permissions 8
|
||||
73 2026_06_02_120000_create_agent_delegation_grants 8
|
||||
74 2026_06_02_130000_backfill_players_agent_node_id 9
|
||||
75 2026_06_03_140000_ensure_agent_admin_user_destroy_api_resource 10
|
||||
76 2026_06_03_120000_split_agent_permission_granularity 11
|
||||
77 2026_06_03_150000_align_root_agent_codes 12
|
||||
78 2026_06_03_160000_agent_credit_and_settlement_tables 12
|
||||
79 2026_06_03_170000_seed_agent_settlement_api_resources 13
|
||||
80 2026_06_03_180000_add_agent_profile_capability_flags 14
|
||||
81 2026_06_03_190000_fix_agent_primary_admin_user_status 15
|
||||
82 2026_06_04_100000_agent_game_settlement_ledger 16
|
||||
83 2026_06_04_120000_resync_agent_owner_role_permissions 16
|
||||
84 2026_06_04_130000_seed_platform_agent_role_and_resync_bindings 16
|
||||
85 2026_06_04_140000_bind_agents_to_platform_agent_role 17
|
||||
86 2026_06_04_120000_add_player_auth_and_funding_mode 18
|
||||
87 2026_06_04_120000_agent_settlement_payment_proof 19
|
||||
88 2026_06_04_140000_agent_settlement_reports_and_tags 20
|
||||
89 2026_06_04_150000_ensure_platform_fixed_system_roles 20
|
||||
90 2026_06_05_120000_seed_credit_ledger_admin_api_resource 21
|
||||
\.
|
||||
|
||||
|
||||
--
|
||||
-- Name: migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
SELECT pg_catalog.setval('public.migrations_id_seq', 90, true);
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict RiLJxG2okqJB0Ghnyl7nmKPp6kFTgq0lQmAb7r3CeeShjxRjgjZVfbJ1VM9V1oB
|
||||
|
||||
Reference in New Issue
Block a user