138 lines
4.9 KiB
PHP

<?php
namespace App\Http\Controllers\SystemSettings;
use App\Models\Auth\User;
use App\Models\Auth\UserAccessGroup;
use App\Utilities\SystemAccess;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class UserGroups extends Controller
{
public function __construct()
{
$this->middleware(function ($request, $next) {
abort_unless(SystemAccess::isSuperAdmin(), 403);
return $next($request);
});
}
public function index()
{
return view('system_settings.groups.index', ['groups' => UserAccessGroup::forCompany()->withCount('users')->orderBy('name')->get()]);
}
public function create()
{
return $this->form();
}
public function edit(int $group)
{
return $this->form(UserAccessGroup::forCompany()->findOrFail($group));
}
public function editMembership(int $user)
{
$member = $this->memberForCompany($user);
$groups = UserAccessGroup::forCompany()->orderBy('name')->get();
return view('system_settings.groups.membership', [
'member' => $member,
'groups' => $groups,
'selected' => UserAccessGroup::forUser($member)->pluck('id')->all(),
]);
}
public function updateMembership(int $user, Request $request)
{
$member = $this->memberForCompany($user);
$availableGroupIds = UserAccessGroup::forCompany()->pluck('id')->all();
$data = $request->validate([
'groups' => ['nullable', 'array'],
'groups.*' => ['integer', 'distinct', Rule::in($availableGroupIds)],
], [], ['groups' => '用户分组', 'groups.*' => '用户分组']);
$selected = array_values($data['groups'] ?? []);
DB::transaction(function () use ($member, $availableGroupIds, $selected) {
DB::table('user_access_group_members')
->where('user_id', $member->id)
->whereIn('group_id', $availableGroupIds)
->delete();
if ($selected !== []) {
DB::table('user_access_group_members')->insert(array_map(
fn ($groupId) => ['group_id' => $groupId, 'user_id' => $member->id],
$selected
));
}
});
flash('用户分组已更新。')->success();
return redirect()->route('system-settings.users.index');
}
private function form(?UserAccessGroup $group = null)
{
return view('system_settings.groups.form', ['group' => $group, 'members' => $this->members(), 'selected' => $group?->users()->pluck('users.id')->all() ?? []]);
}
public function store(Request $request)
{
$group = new UserAccessGroup;
$group->company_id = company_id();
$group->page_permissions = [];
return $this->save($request, $group);
}
public function update(Request $request, int $group)
{
return $this->save($request, UserAccessGroup::forCompany()->findOrFail($group));
}
private function save(Request $request, UserAccessGroup $group)
{
$data = $request->validate([
'name' => ['required', 'string', 'max:80', Rule::unique('user_access_groups', 'name')->where('company_id', company_id())->ignore($group->id)],
'members' => ['nullable', 'array'],
'members.*' => ['integer', 'distinct', Rule::in($this->members()->pluck('id')->all())],
], [], ['name' => '分组名称', 'members' => '成员', 'members.*' => '成员']);
DB::transaction(function () use ($group, $data) {
$group->name = $data['name'];
$group->save();
$group->users()->sync($data['members'] ?? []);
});
flash('分组与成员已保存。页面权限在权限管理中设置。')->success();
return redirect()->route('system-settings.groups.index');
}
public function destroy(int $group)
{
$group = UserAccessGroup::forCompany()->findOrFail($group);
if ($group->users()->exists()) {
return back()->withErrors(['group' => '请先移出分组成员,再删除空分组。移出最后一个分组的用户将恢复角色或系统默认权限。']);
}
$group->delete();
flash('空分组已删除。')->success();
return redirect()->route('system-settings.groups.index');
}
private function members()
{
return User::whereHas('companies', fn ($query) => $query->where('companies.id', company_id()))
->whereHas('roles', fn ($query) => $query->whereIn('name', ['admin', 'user']))
->whereDoesntHave('roles', fn ($query) => $query->where('name', 'super_admin'))->orderBy('name')->get();
}
private function memberForCompany(int $user): User
{
$member = $this->members()->firstWhere('id', $user);
abort_unless($member, 404);
return $member;
}
}