query('q', '')); $users = User::query() ->when($q, fn ($query) => $query->where(function ($sub) use ($q) { $sub->where('name', 'like', "%{$q}%")->orWhere('email', 'like', "%{$q}%"); })) ->orderByDesc('created_at') ->paginate(20) ->withQueryString(); return view('admin.users.index', compact('users', 'q')); } /** * 新建用户表单(角色 + 权限分配)。 */ public function create(): View { $roles = config('permissions.roles'); $groups = config('permissions.groups'); $permissions = config('permissions.permissions'); return view('admin.users.create', compact('roles', 'groups', 'permissions')); } /** * 新建用户,受层级约束:不能创建权限高于或等于自身角色的用户。 */ public function store(Request $request): RedirectResponse { $current = $request->user(); $allPermKeys = implode(',', array_keys(config('permissions.permissions'))); $data = $request->validate([ 'name' => ['required', 'string', 'max:60'], 'email' => ['required', 'email', 'unique:users,email'], 'password' => ['required', 'string', 'min:8'], 'role' => ['required', 'in:super_admin,admin,forum_admin,staff,user'], 'permissions' => ['nullable', 'array'], 'permissions.*' => ['string', "in:{$allPermKeys}"], ]); // 层级防护:不能创建高于或等于自身权限的角色 if (! $current->isSuperAdmin() && $current->roleLevel() <= $this->roleLevelOf($data['role'])) { return back()->withErrors(['role' => '您只能创建权限低于自身的用户'])->withInput(); } if ($data['role'] === 'super_admin' && ! $current->isSuperAdmin()) { return back()->withErrors(['role' => '只有超级管理员可以创建超级管理员'])->withInput(); } $permissions = $data['role'] === 'staff' ? array_values(array_unique($data['permissions'] ?? [])) : null; $user = User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'role' => $data['role'], 'is_admin' => $data['role'] !== 'user', 'permissions' => $permissions, 'points' => 0, ]); return redirect()->route('admin.users.index') ->with('success', "已创建用户 {$user->name}"); } /** * 编辑用户角色与权限(内部员工可勾选细粒度权限)。 */ public function edit(User $user) { $roles = config('permissions.roles'); $groups = config('permissions.groups'); $permissions = config('permissions.permissions'); $userPerms = is_array($user->permissions) ? $user->permissions : []; $canManage = $this->canManage($user); return view('admin.users.edit', compact('user', 'roles', 'groups', 'permissions', 'userPerms', 'canManage')); } /** * 更新用户角色与权限,受层级约束。 */ public function update(Request $request, User $user): RedirectResponse { $current = $request->user(); // 防锁死:禁止改动自己 if ($user->id === $current->id) { return back()->withErrors(['role' => '不能修改当前登录账号的角色/权限']); } // 层级防护:非超管不能触碰同级或更高权限用户 if (! $current->isSuperAdmin() && $current->roleLevel() <= $user->roleLevel()) { return back()->withErrors(['role' => '您只能修改权限低于自身的用户']); } if ($user->isSuperAdmin() && ! $current->isSuperAdmin()) { return back()->withErrors(['role' => '只有超级管理员可以调整超级管理员']); } $allPermKeys = implode(',', array_keys(config('permissions.permissions'))); $data = $request->validate([ 'role' => ['required', 'in:super_admin,admin,forum_admin,staff,user'], 'permissions' => ['nullable', 'array'], 'permissions.*' => ['string', "in:{$allPermKeys}"], ]); // 越权防护:不能分配高于或等于自身权限的角色 if ($data['role'] === 'super_admin' && ! $current->isSuperAdmin()) { return back()->withErrors(['role' => '只有超级管理员可以分配超级管理员角色']); } if (! $current->isSuperAdmin() && $current->roleLevel() <= $this->roleLevelOf($data['role'])) { return back()->withErrors(['role' => '您只能分配权限低于自身的角色']); } $permissions = $data['role'] === 'staff' ? array_values(array_unique($data['permissions'] ?? [])) : null; $user->update([ 'role' => $data['role'], 'is_admin' => $data['role'] !== 'user', 'permissions' => $permissions, ]); return redirect()->route('admin.users.index') ->with('success', "已更新 {$user->name} 的角色与权限"); } /** * 重置指定用户密码(管理员代操作):可指定新密码,留空则生成随机密码并回显。 * 受层级约束,且禁止重置当前登录账号(请用「修改密码」)。 */ public function resetPassword(Request $request, User $user): RedirectResponse { $current = $request->user(); if ($user->id === $current->id) { return back()->withErrors(['password' => '不能重置当前登录账号的密码,请到「修改密码」操作']); } if (! $current->isSuperAdmin() && $current->roleLevel() <= $user->roleLevel()) { return back()->withErrors(['password' => '您只能重置权限低于自身的用户密码']); } if ($user->isSuperAdmin() && ! $current->isSuperAdmin()) { return back()->withErrors(['password' => '只有超级管理员可以重置超级管理员密码']); } $data = $request->validate([ 'password' => ['nullable', 'string', 'min:8', 'confirmed'], ]); if (! empty($data['password'])) { $new = $data['password']; $msg = '密码已重置'; } else { $new = $this->generatePassword(12); $msg = '密码已重置为随机密码:' . $new . '(请妥善告知用户,并建议其尽快修改)'; } $user->update(['password' => Hash::make($new)]); return redirect()->route('admin.users.edit', $user)->with('success', $msg); } public function destroy(User $user): RedirectResponse { $current = request()->user(); if ($user->id === $current->id) { return back()->withErrors(['name' => '不能删除当前登录账号']); } if (! $current->isSuperAdmin() && $current->roleLevel() <= $user->roleLevel()) { return back()->withErrors(['name' => '您只能删除权限低于自身的用户']); } if ($user->isSuperAdmin() && ! $current->isSuperAdmin()) { return back()->withErrors(['name' => '只有超级管理员可以删除超级管理员']); } $user->delete(); return redirect()->route('admin.users.index')->with('success', '用户已删除'); } /** * 当前用户是否可管理目标用户(用于视图显隐操作按钮)。 */ protected function canManage(User $user): bool { $current = request()->user(); if ($current->isSuperAdmin()) { return true; } return $current->roleLevel() > $user->roleLevel(); } protected function roleLevelOf(string $role): int { return (int) config("permissions.roles.{$role}.level", 1); } protected function generatePassword(int $len): string { $pool = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'; $out = ''; for ($i = 0; $i < $len; $i++) { $out .= $pool[random_int(0, strlen($pool) - 1)]; } return $out; } }