feat: enhance agent settlement features and improve data access controls

- Added new section in AGENTS.md detailing learned workspace facts for better understanding of settlement processes.
- Updated AgentNodeDestroyController to remove unnecessary checks for admin users.
- Enhanced AgentSettlement controllers to assert permissions for finance adjustments and bill operations.
- Improved query scopes in AgentSettlement services to ensure proper data access based on admin roles.
- Refactored methods in SettlementPartyEnrichment for better bill row enrichment and data handling.
- Introduced new methods in AdminAgentSettlementScope for managing agent node visibility and finance adjustments.
This commit is contained in:
2026-06-12 15:59:05 +08:00
parent e14b7b4569
commit 980f3c9593
47 changed files with 2403 additions and 187 deletions

View File

@@ -0,0 +1,165 @@
<?php
/**
* 一次性清理 default_site 重叠账期脏数据,并补齐可演示的连续账期。
* 用法php scripts/dev-cleanup-settlement-periods.php
*/
use Illuminate\Support\Facades\DB;
require __DIR__.'/../vendor/autoload.php';
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$siteId = 1;
$keepPeriodIds = [5, 8, 9];
$deletePeriodIds = [1, 2, 3, 4, 6, 7];
DB::transaction(function () use ($siteId, $keepPeriodIds, $deletePeriodIds): void {
$deleteBillIds = DB::table('settlement_bills')
->whereIn('settlement_period_id', $deletePeriodIds)
->pluck('id')
->map(static fn ($id): int => (int) $id)
->all();
if ($deleteBillIds !== []) {
DB::table('payment_records')->whereIn('settlement_bill_id', $deleteBillIds)->delete();
DB::table('settlement_adjustments')
->where(function ($query) use ($deletePeriodIds, $deleteBillIds): void {
$query->whereIn('settlement_period_id', $deletePeriodIds)
->orWhereIn('original_bill_id', $deleteBillIds);
})
->delete();
DB::table('settlement_bills')->whereIn('id', $deleteBillIds)->delete();
}
DB::table('settlement_periods')->whereIn('id', $deletePeriodIds)->delete();
// 规范化保留账期UTC 时刻 = 东八区本地自然日边界,与开账 API 一致)
DB::table('settlement_periods')->where('id', 5)->update([
'admin_site_id' => $siteId,
'period_start' => '2026-05-24 16:00:00',
'period_end' => '2026-05-31 15:59:59',
'status' => 'closed',
'updated_at' => now(),
]);
DB::table('settlement_periods')->where('id', 9)->update([
'admin_site_id' => $siteId,
'period_start' => '2026-05-31 16:00:00',
'period_end' => '2026-06-07 15:59:59',
'status' => 'completed',
'updated_at' => now(),
]);
DB::table('settlement_periods')->where('id', 8)->update([
'admin_site_id' => $siteId,
'period_start' => '2026-06-07 16:00:00',
'period_end' => '2026-06-14 15:59:59',
'status' => 'closed',
'updated_at' => now(),
]);
// 6/86/14 流水归属第二周账期
DB::table('share_ledger')
->whereIn('id', [910, 911, 912, 913, 914])
->update([
'settlement_period_id' => 8,
'updated_at' => now(),
]);
// 待入账流水改到 6/15、6/17供下一期开账演示
DB::table('share_ledger')->where('id', 915)->update([
'settlement_period_id' => null,
'settled_at' => '2026-06-15 10:00:00',
'updated_at' => now(),
]);
DB::table('share_ledger')->where('id', 916)->update([
'settlement_period_id' => null,
'settled_at' => '2026-06-17 14:30:00',
'updated_at' => now(),
]);
// 第二周账期账单(待收付,用于日历「未结清」标记)
DB::table('settlement_bills')->where('settlement_period_id', 8)->delete();
$now = now();
DB::table('settlement_bills')->insert([
[
'settlement_period_id' => 8,
'bill_type' => 'player',
'owner_type' => 'player',
'owner_id' => 5,
'counterparty_type' => 'agent',
'counterparty_id' => 4,
'gross_win_loss' => 8000,
'rebate_amount' => 0,
'adjustment_amount' => 0,
'platform_rounding_adjustment' => 0,
'net_amount' => 8000,
'paid_amount' => 0,
'unpaid_amount' => 8000,
'status' => 'confirmed',
'confirmed_at' => $now,
'created_at' => $now,
'updated_at' => $now,
],
[
'settlement_period_id' => 8,
'bill_type' => 'agent',
'owner_type' => 'agent',
'owner_id' => 4,
'counterparty_type' => 'agent',
'counterparty_id' => 1,
'gross_win_loss' => 8000,
'rebate_amount' => 0,
'adjustment_amount' => 0,
'platform_rounding_adjustment' => 0,
'net_amount' => 6400,
'paid_amount' => 0,
'unpaid_amount' => 6400,
'status' => 'confirmed',
'confirmed_at' => $now,
'created_at' => $now,
'updated_at' => $now,
],
[
'settlement_period_id' => 8,
'bill_type' => 'agent',
'owner_type' => 'agent',
'owner_id' => 1,
'counterparty_type' => 'platform',
'counterparty_id' => 0,
'gross_win_loss' => 8000,
'rebate_amount' => 0,
'adjustment_amount' => 0,
'platform_rounding_adjustment' => 0,
'net_amount' => 1600,
'paid_amount' => 0,
'unpaid_amount' => 1600,
'status' => 'pending_confirm',
'confirmed_at' => null,
'created_at' => $now,
'updated_at' => $now,
],
]);
});
$rows = DB::select(
'SELECT id, period_start::date AS ps, period_end::date AS pe, status FROM settlement_periods WHERE admin_site_id = ? ORDER BY period_start',
[$siteId],
);
echo "Settlement periods after cleanup:\n";
foreach ($rows as $row) {
echo sprintf(" #%d %s ~ %s [%s]\n", $row->id, $row->ps, $row->pe, $row->status);
}
$unassigned = (int) DB::table('share_ledger as sl')
->join('players as p', 'p.id', '=', 'sl.player_id')
->where('p.site_code', 'default_site')
->whereNull('sl.settlement_period_id')
->whereNull('sl.reversal_of_id')
->count();
echo "\nUnassigned share_ledger (default_site): {$unassigned}\n";