*/ private const MODULE_LABELS = [ 'agent' => '代理', 'system' => '系统', 'settings' => '系统设置', 'integration' => '对接站点', 'player_manage' => '玩家管理', 'risk_cap' => '风险池', 'odds' => '赔率', 'play_config' => '玩法配置', 'settlement' => '结算', 'report_jobs' => '报表任务', 'reconcile_jobs' => '对账任务', 'draw' => '开奖', 'wallet' => '钱包', 'reconcile' => '对账', 'job' => '任务', 'bootstrap' => '系统', ]; /** @var array */ private const ACTION_LABELS = [ 'agent_role.sync_permissions' => '同步代理角色权限', 'admin_role.sync_permissions' => '同步平台角色权限', 'admin_role.create' => '创建平台角色', 'admin_role.update' => '更新平台角色', 'admin_role.delete' => '删除平台角色', 'agent_role.create' => '创建代理角色', 'agent_role.update' => '更新代理角色', 'agent_role.destroy' => '删除代理角色', 'agent_admin_user.create' => '创建代理账号', 'agent_admin_user.sync_roles' => '同步代理账号角色', 'agent_node.create' => '创建代理节点', 'agent_node.update' => '更新代理节点', 'agent_node.destroy' => '删除代理节点', 'agent.delegation.sync' => '同步代理授权', 'admin_user.create' => '创建管理员', 'admin_user.update' => '更新管理员', 'admin_user.delete' => '删除管理员', 'sync_permissions' => '同步权限', 'batch_update' => '批量更新设置', 'payout_adjustment' => '派彩调整', 'rotate_secrets' => '轮换密钥', 'toggle_active' => '切换启用状态', 'enqueue' => '提交报表任务', ]; /** @var array */ private const TARGET_TYPE_LABELS = [ 'admin_role' => '角色', 'admin_user' => '管理员', 'agent_node' => '代理节点', 'admin_site' => '对接站点', 'player' => '玩家', 'lottery_settings' => '系统设置', 'lottery_setting' => '设置项', 'risk_cap_version' => '风险池版本', 'odds_version' => '赔率版本', 'play_config_item' => '玩法', 'play_config_version' => '玩法配置版本', 'settlement_batch_adjustment' => '结算调整单', 'report_job' => '报表任务', 'reconcile_job' => '对账任务', 'transfer_no' => '转账单', 'draw' => '期次', 'batch' => '批次', ]; /** @var array */ private const VERB_LABELS = [ 'sync' => '同步', 'store' => '创建', 'update' => '更新', 'destroy' => '删除', 'delete' => '删除', 'create' => '创建', 'publish' => '发布', 'reopen' => '重新开奖', 'freeze' => '冻结', 'unfreeze' => '解冻', 'run' => '执行', 'transfer' => '转账', 'start' => '开始', 'test' => '测试', ]; /** * @param LengthAwarePaginator $paginator * @return array{items: list>, meta: array{current_page: int, per_page: int, total: int, last_page: int}} */ public static function listPayload(LengthAwarePaginator $paginator): array { $items = collect($paginator->items()); $resourceNames = self::loadResourceNames($items); return AdminApiList::payload( $paginator, fn (AuditLog $r) => self::row($r, $resourceNames), ); } /** * @param array $resourceNames * @return array */ public static function row(AuditLog $r, array $resourceNames = []): array { return [ 'id' => (int) $r->id, 'operator_type' => $r->operator_type, 'operator_id' => (int) $r->operator_id, 'module_code' => $r->module_code, 'action_code' => $r->action_code, 'target_type' => $r->target_type, 'target_id' => $r->target_id, 'module_label' => self::moduleLabel($r->module_code), 'action_label' => self::actionLabel($r, $resourceNames), 'target_label' => self::targetLabel($r, $resourceNames), 'before_json' => $r->before_json, 'after_json' => $r->after_json, 'ip' => $r->ip, 'user_agent' => $r->user_agent, 'created_at' => $r->created_at?->toIso8601String(), ]; } /** * @param Collection $items * @return array */ private static function loadResourceNames(Collection $items): array { $codes = $items ->pluck('target_type') ->filter(fn (?string $type) => self::isApiResourceCode($type)) ->unique() ->values() ->all(); if ($codes === []) { return []; } /** @var array */ return DB::table('admin_api_resources') ->whereIn('code', $codes) ->pluck('name', 'code') ->all(); } private static function moduleLabel(?string $code): string { if ($code === null || $code === '') { return '—'; } return self::MODULE_LABELS[$code] ?? $code; } /** * @param array $resourceNames */ private static function actionLabel(AuditLog $r, array $resourceNames): string { $action = (string) ($r->action_code ?? ''); if ($action === '') { return '—'; } if (isset(self::ACTION_LABELS[$action])) { return self::ACTION_LABELS[$action]; } $targetType = (string) ($r->target_type ?? ''); if (self::isApiResourceCode($targetType) && isset($resourceNames[$targetType])) { return $resourceNames[$targetType]; } if (isset(self::VERB_LABELS[$action])) { return self::VERB_LABELS[$action]; } return $action; } /** * @param array $resourceNames */ private static function targetLabel(AuditLog $r, array $resourceNames): string { $type = (string) ($r->target_type ?? ''); $id = trim((string) ($r->target_id ?? '')); if ($type === '') { return $id !== '' ? '#'.$id : '—'; } if (self::isApiResourceCode($type)) { $name = $resourceNames[$type] ?? $type; return $id !== '' ? sprintf('%s #%s', $name, $id) : $name; } $typeLabel = self::TARGET_TYPE_LABELS[$type] ?? $type; return $id !== '' ? sprintf('%s #%s', $typeLabel, $id) : $typeLabel; } private static function isApiResourceCode(?string $code): bool { return is_string($code) && str_starts_with($code, 'admin.'); } }