Files

313 lines
9.8 KiB
PHP
Raw Permalink Normal View History

2025-11-07 09:56:20 +08:00
<?php
namespace plugin\admin\app\controller;
use plugin\admin\app\common\Auth;
use plugin\admin\app\common\Tree;
use plugin\admin\app\model\AdminRole;
use plugin\admin\app\model\AdminRule;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use Throwable;
/**
* 角色管理
*/
class AdminRoleController extends Crud
{
/**
* 不需要鉴权的方法
* @var array
*/
protected $noNeedAuth = ['select'];
/**
* @var AdminRole
*/
protected $model = null;
/**
* 构造函数
*/
function __construct()
{
$this->model = new AdminRole;
}
/**
* 浏览
* @return Response
* @throws Throwable
*/
public function index(Request $request): Response
{
return view('admin_role/index');
}
/**
* 查询
* @param Request $request
* @return Response
* @throws BusinessException
*/
public function select(Request $request): Response
{
$id = $request->get('id');
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
$limit = 100000;
$role_ids = Auth::getScopeRoleIds(true);
if (!$id) {
$where['id'] = ['symbol'=>'in', 'value1'=>$role_ids];
} elseif (!in_array($id, $role_ids)) {
throw new BusinessException('无权限');
}
$query = $this->doSelect($where, $field, $order);
return $this->doFormat($query, $format, $limit);
}
/**
* 插入
* @param Request $request
* @return Response
* @throws BusinessException
* @throws Throwable
*/
public function insert(Request $request): Response
{
if ($request->method() === 'POST') {
$data = $this->insertInput($request);
$pid = $data['pid'] ?? "";
// if (!$pid) {
// return $this->fail('请选择父级角色组');
// }
if($pid){
if (!Auth::isSuperAdmin() && !in_array($pid, Auth::getScopeRoleIds(true))) {
return $this->fail('父级角色组超出权限范围');
}
$this->checkRules($pid, $data['rules'] ?? '');
}
$id = $this->doInsert($data);
return $this->success("操作成功", ['id' => $id]);
}
return view('admin_role/update',[
'rolelist'=> $this->model->select()
]);
}
/**
* 更新
* @param Request $request
* @return Response
* @throws BusinessException|Throwable
*/
public function update(Request $request): Response
{
if ($request->method() === 'GET') {
$ids = Request()->get('ids');
return view('admin_role/update',[
'rolelist'=> $this->model->where('id','<>',$ids)->select(),
'row' => $this->model->whereIn('id',$ids)->findOrEmpty()
]);
}
[$id, $data] = $this->updateInput($request);
$is_supper_admin = Auth::isSuperAdmin();
$descendant_role_ids = Auth::getScopeRoleIds();
if (!$is_supper_admin && !in_array($id, $descendant_role_ids)) {
return $this->fail('无数据权限');
}
$role = AdminRole::find($id);
if (!$role) {
return $this->fail('数据不存在');
}
$is_supper_role = $role->rules === '*';
// 超级角色组不允许更改rules pid 字段
if ($is_supper_role) {
unset($data['rules'], $data['pid']);
}
if (key_exists('pid', $data) && $data['pid']>0) {
$pid = $data['pid'];
if (!$pid) {
return $this->fail('请选择父级角色组');
}
if ($pid == $id) {
return $this->fail('父级不能是自己');
}
if (!$is_supper_admin && !in_array($pid, Auth::getScopeRoleIds(true))) {
return $this->fail('父级超出权限范围');
}
} else {
$pid = $role->pid;
}
$data['rules'] = explode(',',$data['rules']);
sort($data['rules']);
if(count($data['rules'])>0 && $data['rules'][0] == 0){
array_shift($data['rules']);
}
$data['rules'] = implode(',',$data['rules']);
if (!$is_supper_role) {
$this->checkRules($pid, $data['rules'] ?? '');
}
$this->doUpdate($id, $data);
// 删除所有子角色组中已经不存在的权限
if (!$is_supper_role) {
$tree = new Tree(AdminRole::Field(['id', 'pid'])->select());
$descendant_roles = $tree->getDescendant([$id]);
$descendant_role_ids = array_column($descendant_roles, 'id');
$rule_ids = $data['rules'] ? explode(',', $data['rules']) : [];
foreach ($descendant_role_ids as $role_id) {
$tmp_role = AdminRole::find($role_id);
$tmp_rule_ids = $role->getRuleIds();
$tmp_rule_ids = array_intersect(explode(',',$tmp_role->rules), $tmp_rule_ids);
$tmp_role->rules = implode(',', $tmp_rule_ids);
$tmp_role->save();
}
}
return $this->success("操作成功");
}
/**
* 删除
* @param Request $request
* @return Response
* @throws BusinessException
*/
public function delete(Request $request): Response
{
$ids = $this->deleteInput($request);
if (in_array(1, $ids)) {
return $this->fail('无法删除超级管理员角色');
}
if (!Auth::isSuperAdmin() && array_diff($ids, Auth::getScopeRoleIds())) {
return $this->fail('无删除权限');
}
$tree = new Tree(AdminRole::select());
$descendants = $tree->getDescendant($ids);
if ($descendants) {
$ids = array_merge($ids, array_column($descendants, 'id'));
}
$this->doDelete($ids);
return $this->success("操作成功");
}
/**
* 获取角色权限
* @param Request $request
* @return Response
*/
public function rules(Request $request): Response
{
$role_id = $request->get('id');
if (empty($role_id)) {
return $this->success("操作成功", []);
}
if (!Auth::isSuperAdmin() && !in_array($role_id, Auth::getScopeRoleIds(true))) {
return $this->fail('角色组超出权限范围');
}
$rule_id_string = AdminRole::where('id', $role_id)->value('rules');
if ($rule_id_string === '') {
return $this->success("操作成功", []);
}
$rules = AdminRule::select();
$include = [];
if ($rule_id_string !== '*') {
$include = explode(',', $rule_id_string);
}
$items = [];
foreach ($rules as $item) {
$items[] = [
'name' => $item->title ?? $item->name ?? $item->id,
'value' => (string)$item->id,
'id' => $item->id,
'pid' => $item->pid,
];
}
$tree = new Tree($items);
return $this->success("操作成功", $tree->getTree($include));
}
/**
* 检查权限字典是否合法
* @param int $role_id
* @param $rule_ids
* @return void
* @throws BusinessException
*/
protected function checkRules(int|string|null $role_id, $rule_ids)
{
if ($rule_ids && $role_id>0) {
$rule_ids = explode(',', $rule_ids);
if (in_array('*', $rule_ids)) {
throw new BusinessException('非法数据');
}
$rule_exists = AdminRule::whereIn('id', $rule_ids)->column('id');
$rule_ids = $rule_exists;
// if (count($rule_exists) != count($rule_ids)) {
// throw new BusinessException('权限不存在');
// }
$rule_id_string = AdminRole::where('id', $role_id)->value('rules');
if ($rule_id_string === '') {
throw new BusinessException('数据超出权限范围');
}
if ($rule_id_string === '*') {
return;
}
$legal_rule_ids = explode(',', $rule_id_string);
if (array_diff($rule_ids, $legal_rule_ids)) {
throw new BusinessException('数据超出权限范围');
}
}
}
public function tree(Request $request): Response
{
$id = $request->post('id');
$pid = $request->post('pid');
//$is_supper_admin = Auth::isSuperAdmin();
$parent_rules = '*';
if($pid){
$parent_rules = AdminRole::where('id', $pid)->value('rules') ?:'*';
}
$m = AdminRule::where('status',1)
->Field('id,title as text,pid as parent,"menu" as type')
->order('parent asc ,id asc');
if($parent_rules == '*'){
$rules = $m->select();
}else{
$rules = $m->whereIn('id', $parent_rules)->select();
}
$selected_ids = '';
if($id){
$selected_ids = AdminRole::where('id', $id)->value('rules');
}
if($selected_ids == '*'){
$rules->each(function($item){
$item->state = ['selected'=>false];
return $item;
});
}else{
$selected_ids = explode(',',$selected_ids);
$rules->each(function($item)use($selected_ids){
$item->state = [
'selected'=>in_array($item->id, $selected_ids)
];
return $item;
});
}
$rules->push([
'id' => 0,
'parent' => '#',
'text' => '全部',
'type' => 'menu',
]);
return $this->success('ok',$rules);
}
}