feat: 更新玩法配置管理,简化字段并增强功能
- 将玩法相关的显示名称字段统一为 `display_name`,移除多语言字段。 - 在 `PlayTypePatchController` 中新增即时切换玩法开关的功能,并推送大厅更新。 - 优化多个控制器和服务中的权限检查与数据处理逻辑,提升代码可读性与维护性。
This commit is contained in:
143
app/Http/Middleware/RecordAdminApiAudit.php
Normal file
143
app/Http/Middleware/RecordAdminApiAudit.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use App\Models\AdminUser;
|
||||
use App\Services\AuditLogger;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* 对 admin_api_resources.is_audit_required=true 的变更类请求,在成功响应后写入审计日志。
|
||||
*
|
||||
* 若请求已设置 {@see Request::ATTRIBUTE_AUDIT_RECORDED}(业务层已写更细快照),则跳过。
|
||||
*/
|
||||
final class RecordAdminApiAudit
|
||||
{
|
||||
public const ATTRIBUTE_AUDIT_RECORDED = 'admin_audit_recorded';
|
||||
|
||||
private const MUTATING_METHODS = ['POST', 'PUT', 'PATCH', 'DELETE'];
|
||||
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
if (! $this->shouldRecord($request, $response)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$admin = $request->user();
|
||||
if (! $admin instanceof AdminUser) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$resource = $this->resolveResource($request);
|
||||
if ($resource === null || ! (bool) $resource->is_audit_required) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$targetId = $this->resolveTargetId($request);
|
||||
$actionCode = $this->resolveActionCode((string) $resource->code);
|
||||
|
||||
AuditLogger::recordForAdmin(
|
||||
$admin,
|
||||
$request,
|
||||
moduleCode: (string) $resource->module_code,
|
||||
actionCode: $actionCode,
|
||||
targetType: (string) $resource->code,
|
||||
targetId: $targetId,
|
||||
beforeJson: null,
|
||||
afterJson: [
|
||||
'http_method' => $request->method(),
|
||||
'route_name' => $this->normalizeRouteName((string) ($request->route()?->getName() ?? '')),
|
||||
'status' => $response->getStatusCode(),
|
||||
'payload' => $this->sanitizedPayload($request),
|
||||
],
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function shouldRecord(Request $request, Response $response): bool
|
||||
{
|
||||
if ($request->attributes->get(self::ATTRIBUTE_AUDIT_RECORDED) === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! in_array(strtoupper($request->method()), self::MUTATING_METHODS, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$status = $response->getStatusCode();
|
||||
|
||||
return $status >= 200 && $status < 300;
|
||||
}
|
||||
|
||||
private function resolveResource(Request $request): ?object
|
||||
{
|
||||
$routeName = $request->route()?->getName();
|
||||
if (! is_string($routeName) || $routeName === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return DB::table('admin_api_resources')
|
||||
->where('route_name', $this->normalizeRouteName($routeName))
|
||||
->where('status', 1)
|
||||
->first(['code', 'module_code', 'is_audit_required']);
|
||||
}
|
||||
|
||||
private function normalizeRouteName(string $routeName): string
|
||||
{
|
||||
return preg_replace('/^(api\.v1\.admin\.)+/', 'api.v1.admin.', $routeName) ?? $routeName;
|
||||
}
|
||||
|
||||
private function resolveActionCode(string $resourceCode): string
|
||||
{
|
||||
$pos = strrpos($resourceCode, '.');
|
||||
if ($pos === false) {
|
||||
return $resourceCode;
|
||||
}
|
||||
|
||||
return substr($resourceCode, $pos + 1);
|
||||
}
|
||||
|
||||
private function resolveTargetId(Request $request): ?string
|
||||
{
|
||||
$route = $request->route();
|
||||
if ($route === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (['batch', 'draw', 'transfer_no', 'player', 'admin_user', 'admin_role', 'id', 'play_code', 'number_4d', 'key'] as $key) {
|
||||
$value = $route->parameter($key);
|
||||
if ($value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_object($value) && method_exists($value, 'getKey')) {
|
||||
return (string) $value->getKey();
|
||||
}
|
||||
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function sanitizedPayload(Request $request): ?array
|
||||
{
|
||||
$data = $request->except([
|
||||
'password',
|
||||
'password_confirmation',
|
||||
'current_password',
|
||||
'token',
|
||||
]);
|
||||
|
||||
return $data === [] ? null : $data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user