287 lines
8.9 KiB
PHP
287 lines
8.9 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace plugin\admin\app\controller;
|
||
|
|
|
||
|
|
use plugin\admin\app\common\Auth;
|
||
|
|
use plugin\admin\app\common\Tree;
|
||
|
|
use app\model\UserRole as UserRoleModel;
|
||
|
|
use app\model\UserRule as UserRuleModel;
|
||
|
|
use support\exception\BusinessException;
|
||
|
|
use support\Request;
|
||
|
|
use support\Response;
|
||
|
|
use Throwable;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 角色管理
|
||
|
|
*/
|
||
|
|
class UserRoleController extends Crud
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 不需要鉴权的方法
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $noNeedAuth = ['select'];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @var UserRoleModel
|
||
|
|
*/
|
||
|
|
protected $model = null;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 构造函数
|
||
|
|
*/
|
||
|
|
function __construct()
|
||
|
|
{
|
||
|
|
$this->model = new UserRoleModel;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 浏览
|
||
|
|
* @return Response
|
||
|
|
* @throws Throwable
|
||
|
|
*/
|
||
|
|
public function index(Request $request): Response
|
||
|
|
{
|
||
|
|
return view('user_role/index');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 查询
|
||
|
|
* @param Request $request
|
||
|
|
* @return Response
|
||
|
|
* @throws BusinessException
|
||
|
|
*/
|
||
|
|
public function select(Request $request): Response
|
||
|
|
{
|
||
|
|
[$where, $format, $limit, $field, $order] = $this->selectInput($request);
|
||
|
|
$limit = 100000;
|
||
|
|
$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'] ?? null;
|
||
|
|
// 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('user_role/update',[
|
||
|
|
'rolelist'=> $this->model->select()
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 更新
|
||
|
|
* @param Request $request
|
||
|
|
* @return Response
|
||
|
|
* @throws BusinessException|Throwable
|
||
|
|
*/
|
||
|
|
public function update(Request $request): Response
|
||
|
|
{
|
||
|
|
if ($request->method() === 'GET') {
|
||
|
|
return view('user_role/update',[
|
||
|
|
'rolelist'=> $this->model->select(),
|
||
|
|
'row' => $this->model->whereIn('id',Request()->get('ids'))->findOrEmpty()
|
||
|
|
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
[$id, $data] = $this->updateInput($request);
|
||
|
|
$is_supper_admin = Auth::isSuperAdmin();
|
||
|
|
$descendant_role_ids = Auth::getScopeRoleIds();
|
||
|
|
$role = UserRoleModel::find($id);
|
||
|
|
if (!$role) {
|
||
|
|
return $this->fail('数据不存在');
|
||
|
|
}
|
||
|
|
|
||
|
|
if (key_exists('pid', $data) && $data['pid']) {
|
||
|
|
$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;
|
||
|
|
}
|
||
|
|
$this->checkRules($pid, $data['rules'] ?? '');
|
||
|
|
$this->doUpdate($id, $data);
|
||
|
|
|
||
|
|
// 删除所有子角色组中已经不存在的权限
|
||
|
|
$tree = new Tree(UserRoleModel::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 = UserRoleModel::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(UserRoleModel::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 = UserRoleModel::where('id', $role_id)->value('rules');
|
||
|
|
if ($rule_id_string === '') {
|
||
|
|
return $this->success("操作成功", []);
|
||
|
|
}
|
||
|
|
$rules = UserRuleModel::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 = UserRuleModel::whereIn('id', $rule_ids)->column('id');
|
||
|
|
if (count($rule_exists) != count($rule_ids)) {
|
||
|
|
throw new BusinessException('权限不存在');
|
||
|
|
}
|
||
|
|
$rule_id_string = UserRoleModel::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');
|
||
|
|
$parent_rules = '*';
|
||
|
|
if($pid){
|
||
|
|
$parent_rules = UserRoleModel::where('id', $pid)->value('rules') ?: '';
|
||
|
|
}
|
||
|
|
if($parent_rules == '*'){
|
||
|
|
$rules = UserRuleModel::where('status',1)->Field('id,title as text,pid as parent,"menu" as type')->select();
|
||
|
|
}else{
|
||
|
|
$rules = UserRuleModel::whereIn('id', $parent_rules)->where('status',1)->Field('id,title as text,pid as parent,"menu" as type')->select();
|
||
|
|
}
|
||
|
|
$selected_ids = '';
|
||
|
|
if($id){
|
||
|
|
$selected_ids = UserRoleModel::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){
|
||
|
|
$state = ['selected'=>false];
|
||
|
|
if(in_array($item->id, $selected_ids)){
|
||
|
|
$state['selected'] = true;
|
||
|
|
}
|
||
|
|
$item->state = $state;
|
||
|
|
// if($item->parent == 0){
|
||
|
|
// $item->parent = '#';
|
||
|
|
// }
|
||
|
|
return $item;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
$rules->push([
|
||
|
|
'id' => 0,
|
||
|
|
'parent' => '#',
|
||
|
|
'text' => '全部',
|
||
|
|
'type' => 'menu',
|
||
|
|
]);
|
||
|
|
|
||
|
|
return $this->success('ok',$rules);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|