You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.4 KiB

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\AdminRole;
use App\Models\RoleMenuPermission;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class AdminRoleController extends Controller
{
public function index(Request $request): JsonResponse
{
$this->ensureSuperAdmin($request);
$roles = AdminRole::query()->orderBy('sort')->orderBy('id')->get(['id', 'slug', 'name', 'is_system', 'full_access', 'sort']);
return response()->json($roles);
}
public function store(Request $request): JsonResponse
{
$this->ensureSuperAdmin($request);
$data = $request->validate([
'slug' => [
'required',
'string',
'max:50',
'regex:/^[a-z][a-z0-9_]{1,47}$/',
Rule::unique('admin_roles', 'slug'),
Rule::notIn(['super_admin', 'venue_admin']),
],
'name' => ['required', 'string', 'max:100'],
'full_access' => ['sometimes', 'boolean'],
]);
$slug = strtolower(trim($data['slug']));
$role = AdminRole::create([
'slug' => $slug,
'name' => trim($data['name']),
'is_system' => false,
'full_access' => (bool) ($data['full_access'] ?? false),
'sort' => (int) (AdminRole::query()->max('sort') ?? 0) + 1,
]);
return response()->json($role, 201);
}
public function update(Request $request, string $slug): JsonResponse
{
$this->ensureSuperAdmin($request);
$role = AdminRole::query()->where('slug', $slug)->firstOrFail();
$data = $request->validate([
'name' => ['sometimes', 'string', 'max:100'],
'full_access' => ['sometimes', 'boolean'],
]);
if (isset($data['name'])) {
$role->name = trim($data['name']);
}
if (array_key_exists('full_access', $data)) {
if ($role->slug === 'venue_admin') {
abort_if($data['full_access'], 422, '场馆管理员不可设为系统级全权限');
}
if ($role->slug === 'super_admin') {
// 固定为全权限
$role->full_access = true;
} else {
$role->full_access = (bool) $data['full_access'];
}
}
$role->save();
return response()->json($role->fresh());
}
public function destroy(Request $request, string $slug): JsonResponse
{
$this->ensureSuperAdmin($request);
$role = AdminRole::query()->where('slug', $slug)->firstOrFail();
abort_if($role->is_system, 422, '系统内置角色不可删除');
abort_if(
User::query()->where('role', $slug)->exists(),
422,
'仍有管理员使用该角色,无法删除'
);
DB::transaction(function () use ($slug) {
RoleMenuPermission::query()->where('role', $slug)->delete();
AdminRole::query()->where('slug', $slug)->delete();
});
return response()->json(['message' => '角色已删除']);
}
private function ensureSuperAdmin(Request $request): void
{
abort_unless($request->user()?->isSuperAdmin(), 403, '仅超级管理员可操作');
}
}