初始化
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$q = trim((string) $request->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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user