feat: 升级权限管理模式

This commit is contained in:
augushong
2025-03-20 16:57:05 +08:00
parent 1887733b32
commit d3e85fa552
50 changed files with 330 additions and 1125 deletions

View File

@@ -6,6 +6,7 @@ use app\admin\model\SystemAuth;
use app\admin\model\SystemAuthNode;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnotation;
use app\admin\service\NodeService;
use app\admin\service\TriggerService;
use app\common\controller\AdminController;
use think\App;
@@ -36,11 +37,30 @@ class AuthBase extends AdminController
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isAjax()) {
$list = $this->model->getAuthorizeNodeListByAdminId($id);
$this->success('获取成功', $list);
$checkNodeList = (new SystemAuthNode())
->where('auth_id', $id)
->column('node');
$module_list = (new NodeService())->getNodeTree();
foreach ($module_list as $module_key => $module) {
foreach ($module['children'] as $controllerKey => $controller) {
foreach ($controller['children'] as $actionKey => $action) {
$checked = in_array($action['node'], $checkNodeList);
$checked_string = $checked? 'checked' : '';
$disabled_string = '';
if(!$action['auth']){
$checked_string = 'checked';
$disabled_string = 'disabled';
}
$module_list[$module_key]['children'][$controllerKey]['children'][$actionKey]['checked'] = $checked_string;
$module_list[$module_key]['children'][$controllerKey]['children'][$actionKey]['disabled'] = $disabled_string;
}
}
}
$this->assign('row', $row);
$this->assign('checked_node_list', $checkNodeList);
$this->assign('module_list', $module_list);
return $this->fetch();
}
@@ -52,8 +72,8 @@ class AuthBase extends AdminController
{
$this->checkPostRequest();
$id = $this->request->post('id');
$node = $this->request->post('node', '[]');
$node = json_decode($node, true);
$node = $this->request->post('node', []);
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
try {
@@ -64,7 +84,7 @@ class AuthBase extends AdminController
foreach ($node as $vo) {
$saveAll[] = [
'auth_id' => $id,
'node_id' => $vo,
'node' => $vo,
];
}
$authNode->saveAll($saveAll);

View File

@@ -3,9 +3,9 @@
namespace base\admin\controller\system;
use app\admin\model\SystemMenu;
use app\admin\model\SystemNode;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnotation;
use app\admin\service\NodeService;
use app\admin\service\TriggerService;
use app\common\constants\MenuConstant;
use app\common\controller\AdminController;
@@ -14,7 +14,7 @@ use think\facade\Db;
/**
* Class Menu.
* @ControllerAnnotation(title="菜单管理",auth=true)
* @ControllerAnnotation(title="菜单管理")
*/
class MenuBase extends AdminController
{
@@ -206,10 +206,8 @@ class MenuBase extends AdminController
public function getMenuTips()
{
$node = input('get.keywords');
$list = SystemNode::whereLike('node', "%{$node}%")
->field('node,title')
->limit(10)
->select();
$list = (new NodeService())->getNodeCollection();
$list = $list->whereLike('node', $node);
return json([
'code' => 0,

View File

@@ -2,7 +2,6 @@
namespace base\admin\controller\system;
use app\admin\model\SystemNode;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnotation;
use app\admin\service\NodeService;
@@ -21,7 +20,6 @@ class NodeBase extends AdminController
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new SystemNode();
}
/**
@@ -29,82 +27,8 @@ class NodeBase extends AdminController
*/
public function index()
{
if ($this->request->isAjax()) {
if (input('selectFields')) {
return $this->selectList();
}
$count = $this->model
->count();
$list = $this->model
->getNodeTreeList();
$data = [
'code' => 0,
'msg' => '',
'count' => $count,
'data' => $list,
];
return json($data);
}
$module_list = (new NodeService())->getNodeTree();
$this->assign('module_list', $module_list);
return $this->fetch();
}
/**
* @NodeAnotation(title="系统节点更新")
*/
public function refreshNode($force = 0)
{
$this->checkPostRequest();
$nodeList = (new NodeService())->getNodelist();
empty($nodeList) && $this->error('暂无需要更新的系统节点');
$model = new SystemNode();
try {
if ($force == 1) {
$updateNodeList = $model->whereIn('node', array_column($nodeList, 'node'))->select();
$formatNodeList = array_format_key($nodeList, 'node');
foreach ($updateNodeList as $vo) {
isset($formatNodeList[$vo['node']]) && $model->where('id', $vo['id'])->update([
'title' => $formatNodeList[$vo['node']]['title'],
'is_auth' => $formatNodeList[$vo['node']]['is_auth'],
]);
}
}
$existNodeList = $model->field('node,title,type,is_auth')->select();
foreach ($nodeList as $key => $vo) {
foreach ($existNodeList as $v) {
if ($vo['node'] == $v->node) {
unset($nodeList[$key]);
break;
}
}
}
$model->saveAll($nodeList);
TriggerService::updateNode();
} catch (\Exception $e) {
$this->error('节点更新失败');
}
$this->success('节点更新成功');
}
/**
* @NodeAnotation(title="清除失效节点")
*/
public function clearNode()
{
$this->checkPostRequest();
$nodeList = (new NodeService())->getNodelist();
$model = new SystemNode();
try {
$existNodeList = $model->field('id,node,title,type,is_auth')->select()->toArray();
$formatNodeList = array_format_key($nodeList, 'node');
foreach ($existNodeList as $vo) {
!isset($formatNodeList[$vo['node']]) && $model->where('id', $vo['id'])->delete();
}
TriggerService::updateNode();
} catch (\Exception $e) {
$this->error('节点更新失败');
}
$this->success('节点更新成功');
}
}

View File

@@ -3,7 +3,7 @@
namespace base\admin\model;
use app\admin\model\SystemAuthNode;
use app\admin\model\SystemNode;
use app\admin\service\NodeService;
use app\common\model\TimeModel;
class SystemAuthBase extends TimeModel
@@ -22,13 +22,9 @@ class SystemAuthBase extends TimeModel
{
$checkNodeList = (new SystemAuthNode())
->where('auth_id', $authId)
->column('node_id');
$systemNode = new SystemNode();
$nodelList = $systemNode
->where('is_auth', 1)
->field('id,node,title,type,is_auth')
->select()
->toArray();
->column('node');
$nodelList = (new NodeService())->getNodelist();
$newNodeList = [];
foreach ($nodelList as $vo) {
if ($vo['type'] == 1) {
@@ -39,7 +35,7 @@ class SystemAuthBase extends TimeModel
foreach ($nodelList as $v) {
if ($v['type'] == 2 && strpos($v['node'], $vo['node'] . '/') !== false) {
$v = array_merge($v, ['field' => 'node', 'spread' => true]);
$v['checked'] = in_array($v['id'], $checkNodeList) ? true : false;
$v['checked'] = in_array($v['node'], $checkNodeList) ? true : false;
$v['title'] = "{$v['title']}{$v['node']}";
$children[] = $v;
}

View File

@@ -1,37 +0,0 @@
<?php
namespace base\admin\model;
use app\common\model\TimeModel;
class SystemNodeBase extends TimeModel
{
protected $deleteTime = false;
public function getNodeTreeList()
{
$list = $this->select()->toArray();
$list = $this->buildNodeTree($list);
return $list;
}
protected function buildNodeTree($list)
{
$newList = [];
$repeatString = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
foreach ($list as $vo) {
if ($vo['type'] == 1) {
$newList[] = $vo;
foreach ($list as $v) {
if ($v['type'] == 2 && strpos($v['node'], $vo['node'] . '/') !== false) {
$v['node'] = "{$repeatString}{$repeatString}" . $v['node'];
$newList[] = $v;
}
}
}
}
return $newList;
}
}

View File

@@ -10,7 +10,6 @@ use app\admin\model\SystemAuth;
use app\admin\model\SystemAuthNode;
use app\admin\model\SystemConfig;
use app\admin\model\SystemMenu;
use app\admin\model\SystemNode;
use app\admin\model\SystemQuick;
use app\common\constants\AdminConstant;
@@ -126,11 +125,6 @@ class AdminInitServiceBase
$list_auth_node = $this->requireData('SystemAuthNode');
$this->installData(SystemAuthNode::class, $list_auth_node);
$output->writeln('开始初始化系统节点');
$list_node = $this->requireData('SystemNode');
$this->installData(SystemNode::class, $list_node);
}
protected function installData($model_name, $list)

View File

@@ -22,4 +22,56 @@ class NodeServiceBase
return $nodeList;
}
public function getNodeParis()
{
$node_list = $this->getNodelist();
return array_column($node_list, null, 'node');
}
public function getNodeCollection()
{
$nodeList = $this->getNodelist();
$nodeCollection = collect($nodeList);
return $nodeCollection;
}
/**
* 获取节点服务
* @return array
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \ReflectionException
*/
public function getNodeTree()
{
$nodelList = $this->getNodelist();
$newNodeList = [];
foreach ($nodelList as $vo) {
if ($vo['type'] == 1) {
if (!isset($newNodeList[$vo['module']])) {
$newNodeList[$vo['module']] = [
'title' => $vo['module'],
'children' => [],
];
}
$vo['title'] = "{$vo['title']}";
$children = [];
foreach ($nodelList as $v) {
if ($v['type'] == 2 && strpos($v['node'], $vo['node'] . '/') !== false) {
$v['title'] = "{$v['title']}";
$children[] = $v;
}
}
!empty($children) && $vo['children'] = $children;
$newNodeList[$vo['module']]['children'][] = $vo;
}
}
$newNodeList = array_values($newNodeList);
array_unshift($newNodeList, ['title' => '全部', 'children' => []]);
return $newNodeList;
}
}

View File

@@ -1,726 +0,0 @@
<?php
$ul_system_node = array(
array(
"id" => 1,
"node" => "system.admin",
"title" => "管理员管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 2,
"node" => "system.admin/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 3,
"node" => "system.admin/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 4,
"node" => "system.admin/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 5,
"node" => "system.admin/password",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 6,
"node" => "system.admin/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 7,
"node" => "system.admin/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347263,
"update_time" => 1657347263
),
array(
"id" => 8,
"node" => "system.admin/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 9,
"node" => "system.auth",
"title" => "角色权限管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 10,
"node" => "system.auth/authorize",
"title" => "授权",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 11,
"node" => "system.auth/saveAuthorize",
"title" => "授权保存",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 12,
"node" => "system.auth/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 13,
"node" => "system.auth/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 14,
"node" => "system.auth/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347264,
"update_time" => 1657347264
),
array(
"id" => 15,
"node" => "system.auth/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 16,
"node" => "system.auth/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 17,
"node" => "system.auth/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 18,
"node" => "system.config",
"title" => "系统配置管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 19,
"node" => "system.config/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 20,
"node" => "system.config/save",
"title" => "保存",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 21,
"node" => "system.menu",
"title" => "菜单管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 22,
"node" => "system.menu/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347265,
"update_time" => 1657347265
),
array(
"id" => 23,
"node" => "system.menu/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 24,
"node" => "system.menu/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 25,
"node" => "system.menu/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 26,
"node" => "system.menu/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 27,
"node" => "system.menu/getMenuTips",
"title" => "添加菜单提示",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 28,
"node" => "system.menu/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 29,
"node" => "system.node",
"title" => "系统节点管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 30,
"node" => "system.node/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347266,
"update_time" => 1657347266
),
array(
"id" => 31,
"node" => "system.node/refreshNode",
"title" => "系统节点更新",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 32,
"node" => "system.node/clearNode",
"title" => "清除失效节点",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 33,
"node" => "system.node/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 34,
"node" => "system.node/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 35,
"node" => "system.node/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 36,
"node" => "system.node/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 37,
"node" => "system.node/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347267,
"update_time" => 1657347267
),
array(
"id" => 38,
"node" => "system.uploadfile",
"title" => "上传文件管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 39,
"node" => "system.uploadfile/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 40,
"node" => "system.uploadfile/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 41,
"node" => "system.uploadfile/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 42,
"node" => "system.uploadfile/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 43,
"node" => "system.uploadfile/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 44,
"node" => "system.uploadfile/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 45,
"node" => "mall.cate",
"title" => "商品分类管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347268,
"update_time" => 1657347268
),
array(
"id" => 46,
"node" => "mall.cate/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 47,
"node" => "mall.cate/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 48,
"node" => "mall.cate/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 49,
"node" => "mall.cate/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 50,
"node" => "mall.cate/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 51,
"node" => "mall.cate/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 52,
"node" => "mall.goods",
"title" => "商城商品管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347269,
"update_time" => 1657347269
),
array(
"id" => 53,
"node" => "mall.goods/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 54,
"node" => "mall.goods/stock",
"title" => "入库",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 55,
"node" => "mall.goods/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 56,
"node" => "mall.goods/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 57,
"node" => "mall.goods/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 58,
"node" => "mall.goods/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 59,
"node" => "mall.goods/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 60,
"node" => "system.quick",
"title" => "快捷入口管理",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347270,
"update_time" => 1657347270
),
array(
"id" => 61,
"node" => "system.quick/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 62,
"node" => "system.quick/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 63,
"node" => "system.quick/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 64,
"node" => "system.quick/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 65,
"node" => "system.quick/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 66,
"node" => "system.quick/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 69,
"node" => "debug.log",
"title" => "debug_log",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347271,
"update_time" => 1657347271
),
array(
"id" => 70,
"node" => "debug.log/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347272,
"update_time" => 1657347272
),
array(
"id" => 71,
"node" => "debug.log/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347272,
"update_time" => 1657347272
),
array(
"id" => 72,
"node" => "debug.log/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347272,
"update_time" => 1657347272
),
array(
"id" => 73,
"node" => "debug.log/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347272,
"update_time" => 1657347272
),
array(
"id" => 74,
"node" => "debug.log/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347272,
"update_time" => 1657347272
),
array(
"id" => 75,
"node" => "debug.log/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347272,
"update_time" => 1657347272
),
array(
"id" => 76,
"node" => "mall.tag",
"title" => "mall_tag",
"type" => 1,
"is_auth" => 1,
"create_time" => 1657347614,
"update_time" => 1657347614
),
array(
"id" => 77,
"node" => "mall.tag/index",
"title" => "列表",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347614,
"update_time" => 1657347614
),
array(
"id" => 78,
"node" => "mall.tag/add",
"title" => "添加",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347615,
"update_time" => 1657347615
),
array(
"id" => 79,
"node" => "mall.tag/edit",
"title" => "编辑",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347615,
"update_time" => 1657347615
),
array(
"id" => 80,
"node" => "mall.tag/delete",
"title" => "删除",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347615,
"update_time" => 1657347615
),
array(
"id" => 81,
"node" => "mall.tag/export",
"title" => "导出",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347615,
"update_time" => 1657347615
),
array(
"id" => 82,
"node" => "mall.tag/modify",
"title" => "属性修改",
"type" => 2,
"is_auth" => 1,
"create_time" => 1657347615,
"update_time" => 1657347615
)
);
return $ul_system_node;

View File

@@ -44,4 +44,15 @@ return [
'php think migrate:run',
],
],
[
'version' => 'v2.0.116',
'desc' => [
'本次更新使用了新的权限模式,需要运行以下命令更新表结构:',
'php think migrate:run',
'由于使用了新的权限模式,您需要重新设置角色的权限设置,原来的权限已失效,',
'本次更新弃用了system_node表建议手动删除',
'本次更新弃用了system_auth_node表的node_id字段建议手动删除',
'本版本之后,修改了上述表格结构的安装文件,无需手动处理。',
],
],
];

View File

@@ -39,9 +39,9 @@ class ControllerAnnotationBase
public $title = '';
/**
* 是否开启权限控制.
* @Enum({true,false})
* @var bool
* 功能所属模块.
*
* @var string
*/
public $auth = true;
public $module = '通用';
}

View File

@@ -87,7 +87,7 @@ class NodeBase
$actionList[] = [
'node' => $controllerFormat . '/' . $method_name,
'title' => $actionTitle,
'is_auth' => $actionAuth,
'auth' => $actionAuth,
'type' => 2,
];
}
@@ -100,7 +100,7 @@ class NodeBase
$actionList[] = [
'node' => $controllerFormat . '/' . $nodeAnnotation->name,
'title' => $nodeAnnotation->title,
'is_auth' => $nodeAnnotation->auth,
'auth' => $nodeAnnotation->auth,
'type' => 2,
];
}
@@ -110,12 +110,16 @@ class NodeBase
if (!empty($actionList)) {
// 读取Controller的注解
$controllerAnnotation = $reader->getClassAnnotation($reflectionClass, ControllerAnnotation::class);
$controllerTitle = !empty($controllerAnnotation) && !empty($controllerAnnotation->title) ? $controllerAnnotation->title : null;
$controllerAuth = !empty($controllerAnnotation) && !empty($controllerAnnotation->auth) ? $controllerAnnotation->auth : false;
$controllerTitle = null;
$controllerModule = '通用';
if(!empty($controllerAnnotation)){
$controllerTitle = $controllerAnnotation->title;
$controllerModule = $controllerAnnotation->module;
}
$nodeList[] = [
'node' => $controllerFormat,
'title' => $controllerTitle,
'is_auth' => $controllerAuth,
'module' => $controllerModule,
'type' => 1,
];
$nodeList = array_merge($nodeList, $actionList);

View File

@@ -13,7 +13,7 @@
<!-- 基础js -->
<script src="__STATIC__/plugs/jquery-3.4.1/jquery-3.4.1.min.js?t={:get_site_version_key()}"></script>
<script src="__STATIC__/common/js/app.js?t={:get_site_version_key()}"></script>
<script src="__STATIC__/plugs/layui-v2.9.18/layui.js?t={:get_site_version_key()}" charset="utf-8"></script>
<script src="__STATIC__/plugs/layui-v2.10.1/layui.js?t={:get_site_version_key()}" charset="utf-8"></script>
<script src="__STATIC__/plugs/vue-2.6.10/vue.min.js?t={:get_site_version_key()}"></script>
<script src="__STATIC__/plugs/Sortable.min.js?t={:get_site_version_key()}"></script>

View File

@@ -11,7 +11,39 @@
<div class="layui-form-item">
<label class="layui-form-label required">分配节点</label>
<div class="layui-input-block">
<div id="node_ids" class="demo-tree-more"></div>
<table class="layui-table" lay-size="sm">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th>模块</th>
<th>功能</th>
<th>权限</th>
</tr>
</thead>
<tbody>
{volist name='$module_list' id='module'}
{volist name='$module.children' id='controller_item'}
<tr class="auth-node-tr">
<td style="white-space: nowrap;">{$controller_item.module}</td>
<td title="{$controller_item.node}">
<input lay-filter="controller-checkbox" type="checkbox" title="{$controller_item.title}">
</td>
<td>
{volist name='controller_item.children' id='action'}
<div title="{$action.node}" style="display: inline-block;">
<input type="checkbox" lay-filter="action-checkbox" name="node[]" title="{$action.title}" {$action.checked} {$action.disabled} value="{$action.node}">
</div>
{/volist}
</td>
</tr>
{/volist}
{/volist}
</tbody>
</table>
</div>
</div>

View File

@@ -1,32 +1,50 @@
$(function () {
var tree = layui.tree;
ua.request.get(
{
url: window.location.href,
}, function (res) {
res.data = res.data || [];
tree.render({
elem: '#node_ids',
data: res.data,
showCheckbox: true,
id: 'nodeDataId',
});
}
);
ua.listen(function (data) {
var checkedData = tree.getChecked('nodeDataId');
var ids = [];
$.each(checkedData, function (i, v) {
ids.push(v.id);
if (v.children !== undefined && v.children.length > 0) {
$.each(v.children, function (ii, vv) {
ids.push(vv.id);
});
layui.form.on('checkbox(controller-checkbox)', function (data) {
var elem = data.elem;
var checked = elem.checked;
$(elem).closest('tr').find('input').each(function(i,input){
if(!$(input).prop('disabled')){
$(input).prop('checked', checked);
}
});
data.node = JSON.stringify(ids);
return data;
})
});
layui.form.on('checkbox(action-checkbox)', function (data) {
initCheckedStatus();
});
function initCheckedStatus() {
$('.auth-node-tr').each(function (i, elem) {
var checkedCount = 0;
var totalCount = 0;
$(elem).find('[lay-filter="action-checkbox"]').each(function (j, checkbox) {
totalCount++;
if ($(checkbox).prop('checked')) {
checkedCount++;
}
});
var checkedStatus;
if (checkedCount === totalCount) {
checkedStatus = 1; // 全部选中
} else if (checkedCount === 0) {
checkedStatus = -1; // 全部未选中
} else {
checkedStatus = 0; // 部分选中
}
if (checkedStatus === 0) {
$(elem).find('[lay-filter="controller-checkbox"]').prop('checked', false);
$(elem).find('[lay-filter="controller-checkbox"]').prop('indeterminate', true);
} else if (checkedStatus > 0) {
$(elem).find('[lay-filter="controller-checkbox"]').prop('checked', true);
$(elem).find('[lay-filter="controller-checkbox"]').prop('indeterminate', false);
} else {
$(elem).find('[lay-filter="controller-checkbox"]').prop('checked', false);
$(elem).find('[lay-filter="controller-checkbox"]').prop('indeterminate', false);
}
layui.form.render('checkbox');
});
}
initCheckedStatus();
ua.listen();
});

View File

@@ -22,6 +22,7 @@ $(function () {
method: 'open',
auth: 'authorize',
class: 'layui-btn layui-btn-normal layui-btn-xs',
extend: 'data-full="true"'
}],
'delete'
]

View File

@@ -1,10 +1,61 @@
<div class="layuimini-container">
<div class="layuimini-main">
<table id="currentTable" class="layui-table layui-hide"
data-auth-refresh="{:auth('system.node/refreshNode')}"
data-auth-clear="{:auth('system.node/clearNode')}"
data-auth-modify="{:auth('system.node/modify')}"
lay-filter="currentTable">
</table>
<div class="layui-tabs">
<ul class="layui-tabs-header">
{volist name='module_list' id='vo'}
<li>{$vo.title}</li>
{/volist}
</ul>
<div class="layui-tabs-body">
{volist name='module_list' id='module_tab'}
<div class="layui-tabs-item">
<table class="layui-table" lay-size="sm">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th>模块</th>
<th>功能</th>
<th>权限</th>
</tr>
</thead>
<tbody>
{volist name='$module_list' id='module'}
{volist name='$module.children' id='controller_item'}
{if $module_tab.title == '全部' || $controller_item.module == $module_tab.title }
<tr>
<td style="white-space: nowrap;">{$controller_item.module}</td>
<td title="{$controller_item.node}">{$controller_item.title}</td>
<td>
<div class="layui-btn-container">
{volist name='controller_item.children' id='action'}
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" title="{$action.node}">
{$action.title}
{if $action.auth}
<span class="layui-badge layui-bg-blue" title="已开启权限控制">
开启
</span>
{else/}
<span class="layui-badge" title="已关闭权限控制">
关闭
</span>
{/if}
</button>
{/volist}
</div>
</td>
</tr>
{/if}
{/volist}
{/volist}
</tbody>
</table>
</div>
{/volist}
</div>
</div>
</div>
</div>

View File

@@ -1,47 +1,3 @@
$(function () {
ua.table.render({
init: init,
search: false,
page: false,
toolbar: ['refresh',
[{
text: '更新节点',
title: '确定更新新节点?',
url: 'system.node/refreshNode?force=0',
method: 'request',
auth: 'refresh',
class: 'layui-btn layui-btn-success layui-btn-sm',
icon: 'fa fa-hourglass',
extend: 'data-table="' + init.tableRenderId + '"',
}, {
text: '强制更新节点',
title: '该操作会覆盖已存在的节点信息。<br>确定强制更新节点?',
url: 'system.node/refreshNode?force=1',
method: 'request',
auth: 'refresh',
class: 'layui-btn layui-btn-sm layui-btn-normal',
icon: 'fa fa-hourglass',
extend: 'data-table="' + init.tableRenderId + '"',
}, {
text: '清除失效节点',
title: '确定清除失效节点?',
url: 'system.node/clearNode',
method: 'request',
auth: 'clear',
class: 'layui-btn layui-btn-sm layui-btn-danger',
icon: 'fa fa-trash-o',
extend: 'data-table="' + init.tableRenderId + '"',
}
]],
cols: [[
{ field: 'node', sort: false, minWidth: 200, align: 'left', title: '系统节点' },
{ field: 'title', sort: false, minWidth: 80, title: '节点名称 <i class="table-edit-tips color-red">*</i>', edit: 'text' },
{ field: 'update_time', sort: false, minWidth: 80, title: '更新时间', search: 'range' },
{ field: 'is_auth', sort: false, title: '节点控制', width: 85, search: 'select', selectList: { 0: '禁用', 1: '启用' }, templet: ua.table.switch },
]],
});
ua.listen();
});

View File

@@ -1,64 +0,0 @@
<?php
namespace base\common\command;
use app\admin\model\SystemNode;
use app\admin\service\NodeService;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
class NodeBase extends Command
{
protected function configure()
{
$this->setName('node')
->addOption('force', null, Option::VALUE_REQUIRED, '是否强制刷新', 0)
->setDescription('系统节点刷新服务');
}
protected function execute(Input $input, Output $output)
{
$force = $input->getOption('force');
$output->writeln('========正在刷新节点服务:=====' . date('Y-m-d H:i:s'));
$check = $this->refresh($force);
$check !== true && $output->writeln('节点刷新失败:' . $check);
$output->writeln('刷新完成:' . date('Y-m-d H:i:s'));
}
protected function refresh($force)
{
$nodeList = (new NodeService())->getNodelist();
if (empty($nodeList)) {
return true;
}
$model = new SystemNode();
try {
if ($force == 1) {
$updateNodeList = $model->whereIn('node', array_column($nodeList, 'node'))->select();
$formatNodeList = array_format_key($nodeList, 'node');
foreach ($updateNodeList as $vo) {
isset($formatNodeList[$vo['node']]) && $model->where('id', $vo['id'])->update([
'title' => $formatNodeList[$vo['node']]['title'],
'is_auth' => $formatNodeList[$vo['node']]['is_auth'],
]);
}
}
$existNodeList = $model->field('node,title,type,is_auth')->select();
foreach ($nodeList as $key => $vo) {
foreach ($existNodeList as $v) {
if ($vo['node'] == $v->node) {
unset($nodeList[$key]);
break;
}
}
}
$model->insertAll($nodeList);
} catch (\Exception $e) {
return $e->getMessage();
}
return true;
}
}

View File

@@ -17,7 +17,7 @@ class VersionBase extends Command
public const PRODUCT_VERSION = '';
public const LAYUI_VERSION = '2.9.18';
public const LAYUI_VERSION = 'v2.10.1';
public const COMMENT = [
'版本更新说明:',

View File

@@ -48,7 +48,6 @@ class AdminControllerBase extends BaseController
'sort',
'remark',
'is_delete',
'is_auth',
'title',
];

View File

@@ -2,7 +2,10 @@
namespace base\common\service;
use app\admin\model\SystemAuthNode;
use app\admin\service\NodeService;
use app\common\constants\AdminConstant;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Db;
@@ -26,7 +29,6 @@ class AuthServiceBase
'auth_on' => true, // 权限开关
'system_admin' => 'system_admin', // 用户表
'system_auth' => 'system_auth', // 权限表
'system_node' => 'system_node', // 节点表
'system_auth_node' => 'system_auth_node', // 权限-节点表
];
@@ -48,6 +50,8 @@ class AuthServiceBase
*/
protected $adminNode;
protected $nodeService;
/***
* 构造方法
* AuthService constructor.
@@ -58,6 +62,8 @@ class AuthServiceBase
*/
public function __construct($adminId = null)
{
$this->nodeService = new NodeService();
$this->adminId = $adminId;
$this->adminInfo = $this->getAdminInfo();
$this->nodeList = $this->getNodeList();
@@ -66,7 +72,7 @@ class AuthServiceBase
return $this;
}
public function isSuperAdmin()
public function isSuperAdmin()
{
return $this->adminId == AdminConstant::SUPER_ADMIN_ID;
}
@@ -100,7 +106,7 @@ class AuthServiceBase
return Config::get('admin.default_auth_check');
}
$nodeInfo = $this->nodeList[$node];
if ($nodeInfo['is_auth'] == 0) {
if (!$nodeInfo['auth']) {
return true;
}
// 用户验证,优先获取缓存信息
@@ -143,20 +149,7 @@ class AuthServiceBase
}
if (!empty($adminInfo) && !empty($adminInfo['auth_ids'])) {
$buildAuthSql = Db::name($this->config['system_auth'])
->distinct(true)
->whereIn('id', $adminInfo['auth_ids'])
->field('id')
->buildSql(true);
$buildAuthNodeSql = Db::name($this->config['system_auth_node'])
->distinct(true)
->where("auth_id IN {$buildAuthSql}")
->field('node_id')
->buildSql(true);
$nodeList = Db::name($this->config['system_node'])
->distinct(true)
->where("id IN {$buildAuthNodeSql}")
->column('node');
$nodeList = SystemAuthNode::where('auth_id', 'in', $adminInfo['auth_ids'])->cache(60)->column('node');
}
return $nodeList;
@@ -170,9 +163,15 @@ class AuthServiceBase
*/
public function getNodeList()
{
return Db::name($this->config['system_node'])
->autoCache(null, null, 'table')
->column('id,node,title,type,is_auth', 'node');
$cache_key = 'node_paris';
$node_list = Cache::get($cache_key);
if (!$node_list) {
$node_list = $this->nodeService->getNodeParis();
Cache::set($cache_key, $node_list, 60);
}
return $node_list;
}
/**