feat: 切换 schema dump 基线并增强返点结算与管理校验

This commit is contained in:
2026-06-08 17:41:41 +08:00
parent 2d32f006c5
commit 8d5d7f5b17
130 changed files with 5746 additions and 6723 deletions

View File

@@ -3,6 +3,8 @@
namespace App\Support;
use App\Models\AuditLog;
use App\Models\AdminUser;
use App\Models\Player;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@@ -106,23 +108,29 @@ final class AuditLogApiPresenter
{
$items = collect($paginator->items());
$resourceNames = self::loadResourceNames($items);
$operatorLabels = self::loadOperatorLabels($items);
return AdminApiList::payload(
$paginator,
fn (AuditLog $r) => self::row($r, $resourceNames),
fn (AuditLog $r) => self::row($r, $resourceNames, $operatorLabels),
);
}
/**
* @param array<string, string> $resourceNames
* @param array<string, string> $operatorLabels
* @return array<string, mixed>
*/
public static function row(AuditLog $r, array $resourceNames = []): array
public static function row(AuditLog $r, array $resourceNames = [], array $operatorLabels = []): array
{
$operatorDisplay = self::operatorDisplay($r, $operatorLabels);
return [
'id' => (int) $r->id,
'operator_type' => $r->operator_type,
'operator_id' => (int) $r->operator_id,
'operator_label' => $operatorDisplay['label'],
'operator_subtitle' => $operatorDisplay['subtitle'],
'module_code' => $r->module_code,
'action_code' => $r->action_code,
'target_type' => $r->target_type,
@@ -138,6 +146,57 @@ final class AuditLogApiPresenter
];
}
/**
* @param Collection<int, AuditLog> $items
* @return array<string, string>
*/
private static function loadOperatorLabels(Collection $items): array
{
$labels = [];
$adminIds = $items
->filter(fn (AuditLog $row) => $row->operator_type === 'admin' && (int) $row->operator_id > 0)
->pluck('operator_id')
->map(fn (mixed $id): int => (int) $id)
->unique()
->values()
->all();
if ($adminIds !== []) {
$admins = AdminUser::query()
->whereIn('id', $adminIds)
->get(['id', 'username', 'name']);
foreach ($admins as $admin) {
$labels['admin:'.$admin->id] = self::formatIdentityLabel(
(string) ($admin->name ?? ''),
(string) ($admin->username ?? ''),
);
}
}
$playerIds = $items
->filter(fn (AuditLog $row) => $row->operator_type === 'player' && (int) $row->operator_id > 0)
->pluck('operator_id')
->map(fn (mixed $id): int => (int) $id)
->unique()
->values()
->all();
if ($playerIds !== []) {
$players = Player::query()
->whereIn('id', $playerIds)
->get(['id', 'username', 'nickname']);
foreach ($players as $player) {
$labels['player:'.$player->id] = self::formatIdentityLabel(
(string) ($player->nickname ?? ''),
(string) ($player->username ?? ''),
);
}
}
return $labels;
}
/**
* @param Collection<int, AuditLog> $items
* @return array<string, string>
@@ -171,6 +230,48 @@ final class AuditLogApiPresenter
return self::MODULE_LABELS[$code] ?? $code;
}
/**
* @param array<string, string> $operatorLabels
*/
private static function operatorDisplay(AuditLog $r, array $operatorLabels): array
{
$type = (string) ($r->operator_type ?? '');
$id = (int) ($r->operator_id ?? 0);
if ($type === 'system') {
return ['label' => '系统', 'subtitle' => null];
}
$key = $type.':'.$id;
if (isset($operatorLabels[$key]) && $operatorLabels[$key] !== '') {
return [
'label' => $operatorLabels[$key],
'subtitle' => $id > 0 ? sprintf('%s #%d', $type === 'admin' ? '管理员' : ($type === 'player' ? '玩家' : $type), $id) : null,
];
}
$fallbackLabel = match ($type) {
'admin' => $id > 0 ? '管理员 #'.$id : '管理员',
'player' => $id > 0 ? '玩家 #'.$id : '玩家',
'system' => '系统',
default => $id > 0 ? sprintf('%s #%d', $type !== '' ? $type : '未知', $id) : ($type !== '' ? $type : '未知'),
};
return ['label' => $fallbackLabel, 'subtitle' => null];
}
private static function formatIdentityLabel(string $primary, string $secondary): string
{
$primary = trim($primary);
$secondary = trim($secondary);
if ($primary !== '') {
return $primary;
}
return $secondary;
}
/**
* @param array<string, string> $resourceNames
*/