feat: 增强奖池与钱包管理功能
更新 AdminJackpotPoolUpdateController 校验规则,禁止传入 current_amount。 优化 AdminRiskPoolManualStatusController:更新奖池状态后同步 Redis 状态。 在 TransferOrderReconcileController 中新增 completeCredit 方法,用于处理卡住的转账订单对账。 调整 TransferOrderListController:优化转账订单处理条件。 在 TicketItemsIndexController 中实现支持时区的日期筛选,提升日期处理准确性。 扩展 JackpotPool 模型,新增 adjustments 关联关系。 改进票据与钱包相关服务中的错误处理和事务管理。
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user