This commit is contained in:
walkor 2022-12-21 22:22:47 +08:00
parent 83151a50fc
commit d3e82c54f0
7 changed files with 109 additions and 34 deletions

View File

@ -4,6 +4,17 @@ namespace plugin\admin\app\common;
class Tree class Tree
{ {
/**
* 获取完整的树结构,包含祖先节点
*/
const INCLUDE_ANCESTORS = 0;
/**
* 获取部分树,不包含祖先节点
*/
const EXCLUDE_ANCESTORS = 1;
/** /**
* 数据 * 数据
* @var array * @var array
@ -89,10 +100,24 @@ class Tree
/** /**
* 获取树 * 获取树
* @param array $include * @param array $include
* @param int $type
* @return array|null * @return array|null
*/ */
public function getTree(array $include = []): ?array public function getTree(array $include = [], int $type = 0): ?array
{ {
if ($type === static::EXCLUDE_ANCESTORS) {
$items = [];
$include = array_unique($include);
foreach ($include as $id) {
if (!isset($this->hashTree[$id])) {
return [];
}
$items[] = $this->hashTree[$id];
}
return static::arrayValues($items);
}
// $type === static::INCLUDE_ANCESTORS
$hash_tree = $this->hashTree; $hash_tree = $this->hashTree;
$items = []; $items = [];
if ($include) { if ($include) {
@ -120,7 +145,7 @@ class Tree
} }
$formatted_items = []; $formatted_items = [];
foreach ($items as $item) { foreach ($items as $item) {
if (!$item[$this->pidName]) { if (!$item[$this->pidName] || !isset($hash_tree[$item[$this->pidName]])) {
$formatted_items[] = $item; $formatted_items[] = $item;
} }
} }

View File

@ -147,6 +147,7 @@ class Crud extends Base
} }
/** /**
* 格式化数据
* @param $query * @param $query
* @param $format * @param $format
* @param $limit * @param $limit
@ -335,9 +336,11 @@ class Crud extends Base
/** /**
* 格式化树 * 格式化树
* @param $items * @param $items
* @param array $include
* @param int $type
* @return Response * @return Response
*/ */
protected function formatTree($items, array $include = []): Response protected function formatTree($items, array $include = [], int $type = 0): Response
{ {
$items_map = []; $items_map = [];
foreach ($items as $item) { foreach ($items as $item) {
@ -349,7 +352,7 @@ class Crud extends Base
]; ];
} }
$tree = new Tree($items_map); $tree = new Tree($items_map);
return $this->json(0, 'ok', $tree->getTree($include)); return $this->json(0, 'ok', $tree->getTree($include, $type));
} }
/** /**

View File

@ -2,6 +2,7 @@
namespace plugin\admin\app\controller; namespace plugin\admin\app\controller;
use plugin\admin\app\common\Auth;
use plugin\admin\app\common\Tree; use plugin\admin\app\common\Tree;
use plugin\admin\app\model\Role; use plugin\admin\app\model\Role;
use plugin\admin\app\model\Rule; use plugin\admin\app\model\Rule;
@ -36,6 +37,48 @@ class RoleController extends Crud
return view('role/index'); return view('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);
$role_ids = Auth::getDescendantRoleIds(true);
if (!$id) {
$where['id'] = ['in', $role_ids];
} elseif (!in_array($id, $role_ids)) {
throw new BusinessException('无权限');
}
$query = $this->doSelect($where, $field, $order);
return $this->doFormat($query, $format, $limit);
}
/**
* 格式化数据
* @param $query
* @param $format
* @param $limit
* @return Response
*/
protected function doFormat($query, $format, $limit): Response
{
if (in_array($format, ['select', 'tree', 'table_tree'])) {
$items = $query->get();
if ($format == 'select') {
return $this->formatSelect($items);
} elseif ($format == 'tree') {
return $this->formatTree($items);
}
return $this->formatTableTree($items);
}
$paginator = $query->paginate($limit);
return json(['code' => 0, 'msg' => 'ok', 'count' => $paginator->total(), 'data' => $paginator->items()]);
}
/** /**
* 插入 * 插入
* @param Request $request * @param Request $request
@ -46,9 +89,14 @@ class RoleController extends Crud
{ {
if ($request->method() === 'POST') { if ($request->method() === 'POST') {
$data = $this->insertInput($request); $data = $this->insertInput($request);
if (isset($data['pid']) && $data['pid'] == 0) { $pid = $data['pid'] ?? null;
return $this->json(1, '请选择父级权限组'); if ($pid) {
return $this->json(1, '请选择父级角色组');
} }
if (!Auth::isSupperAdmin() && !in_array($pid, Auth::getDescendantRoleIds(true))) {
return $this->json(1, '父级角色组超出权限范围');
}
$id = $this->doInsert($data); $id = $this->doInsert($data);
return $this->json(0, 'ok', ['id' => $id]); return $this->json(0, 'ok', ['id' => $id]);
} }
@ -67,6 +115,11 @@ class RoleController extends Crud
return view('role/update'); return view('role/update');
} }
[$id, $data] = $this->updateInput($request); [$id, $data] = $this->updateInput($request);
$is_supper_admin = Auth::isSupperAdmin();
$descendant_role_ids = Auth::getDescendantRoleIds();
if (!$is_supper_admin && !in_array($id, $descendant_role_ids)) {
return $this->json(1, '无数据权限');
}
// id为1的权限权限固定为* // id为1的权限权限固定为*
if (isset($data['rules']) && $id == 1) { if (isset($data['rules']) && $id == 1) {
$data['rules'] = '*'; $data['rules'] = '*';
@ -75,14 +128,20 @@ class RoleController extends Crud
if (isset($data['pid']) && $id == 1) { if (isset($data['pid']) && $id == 1) {
$data['pid'] = 0; $data['pid'] = 0;
} }
if (isset($data['pid'])) {
if ($data['pid'] == $id) { if (key_exists('pid', $data)) {
$pid = $data['pid'];
if (!$pid) {
return $this->json(1, '请选择父级角色组');
}
if ($pid == $id) {
return $this->json(1, '父级不能是自己'); return $this->json(1, '父级不能是自己');
} }
if ($data['pid'] == 0) { if (!$is_supper_admin && !in_array($pid, Auth::getDescendantRoleIds(true))) {
return $this->json(1, '请选择父级权限组'); return $this->json(1, '父级超出权限范围');
} }
} }
$this->doUpdate($id, $data); $this->doUpdate($id, $data);
return $this->json(0); return $this->json(0);
} }
@ -91,6 +150,7 @@ class RoleController extends Crud
* 删除 * 删除
* @param Request $request * @param Request $request
* @return Response * @return Response
* @throws BusinessException
*/ */
public function delete(Request $request): Response public function delete(Request $request): Response
{ {
@ -98,11 +158,13 @@ class RoleController extends Crud
if (in_array(1, $ids)) { if (in_array(1, $ids)) {
return $this->json(1, '无法删除超级管理员角色'); return $this->json(1, '无法删除超级管理员角色');
} }
if (!Auth::isSupperAdmin() && array_diff($ids, Auth::getDescendantRoleIds())) {
return $this->json(1, '无删除权限');
}
$this->doDelete($ids); $this->doDelete($ids);
return $this->json(0); return $this->json(0);
} }
/** /**
* 获取角色权限 * 获取角色权限
* @param Request $request * @param Request $request
@ -114,6 +176,9 @@ class RoleController extends Crud
if (empty($role_id)) { if (empty($role_id)) {
return $this->json(0, 'ok', []); return $this->json(0, 'ok', []);
} }
if (!Auth::isSupperAdmin() && !in_array($role_id, Auth::getDescendantRoleIds(true))) {
return $this->json(1, '角色组超出权限范围');
}
$rule_id_string = Role::where('id', $role_id)->value('rules'); $rule_id_string = Role::where('id', $role_id)->value('rules');
if ($rule_id_string === '') { if ($rule_id_string === '') {
return $this->json(0, 'ok', []); return $this->json(0, 'ok', []);

View File

@ -308,25 +308,6 @@ class RuleController extends Crud
return false; return false;
} }
/**
* 递归删除某些key
* @param $array
* @param $keys
* @return void
*/
protected function recursiveRemove(&$array, $keys)
{
if (!is_array($array)) {
return;
}
foreach ($keys as $key) {
unset($array[$key]);
}
foreach ($array as &$item) {
$this->recursiveRemove($item, $keys);
}
}
/** /**
* 获取权限规则 * 获取权限规则
* @param $roles * @param $roles

View File

@ -31,7 +31,7 @@
<!-- 表格行工具栏 --> <!-- 表格行工具栏 -->
<script type="text/html" id="table-bar"> <script type="text/html" id="table-bar">
{{# if(d.id!==1){ }} {{# if(d.id!==1&&d.pid&&!d.isRoot){ }}
<button class="pear-btn pear-btn-xs tool-btn" lay-event="edit" permission="app.admin.role.update">编辑</button> <button class="pear-btn pear-btn-xs tool-btn" lay-event="edit" permission="app.admin.role.update">编辑</button>
<button class="pear-btn pear-btn-xs tool-btn" lay-event="remove" permission="app.admin.role.delete">删除</button> <button class="pear-btn pear-btn-xs tool-btn" lay-event="remove" permission="app.admin.role.delete">删除</button>
{{# } }} {{# } }}

View File

@ -87,7 +87,7 @@
// 字段 权限 rules // 字段 权限 rules
layui.use(["jquery", "xmSelect"], function() { layui.use(["jquery", "xmSelect"], function() {
layui.$.ajax({ layui.$.ajax({
url: "/app/admin/role/rules" + location.search, url: "/app/admin/role/rules?id=" + e.data[0].pid,
dataType: "json", dataType: "json",
success: function (e) { success: function (e) {
let value = layui.$("#rules").attr("value"); let value = layui.$("#rules").attr("value");

View File

@ -63,7 +63,7 @@ layui.define(['layer', 'table'], function (exports) {
}; };
sort(param.treeSpid, tNodes);*/ sort(param.treeSpid, tNodes);*/
var map = {}; var map = {}; // 变更
for (var k in data) { for (var k in data) {
map[data[k].id] = data[k]; map[data[k].id] = data[k];
} }
@ -80,6 +80,7 @@ layui.define(['layer', 'table'], function (exports) {
var tree = []; var tree = [];
for (var l in map) { for (var l in map) {
if (!map[l].pid || !map[map[l].pid]) { if (!map[l].pid || !map[map[l].pid]) {
map[l].isRoot = true;
tree.push(map[l]); tree.push(map[l]);
} }
} }
@ -95,7 +96,7 @@ layui.define(['layer', 'table'], function (exports) {
for (var h in tree) { for (var h in tree) {
travel(tree[h]); travel(tree[h]);
} }
param.prevUrl = param.url; param.prevUrl = param.url;
param.url = undefined; param.url = undefined;
param.data = mData; param.data = mData;