Files
ulthon_admin/extend/base/admin/controller/system/AuthBase.php

220 lines
7.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace base\admin\controller\system;
use app\admin\model\SystemAdmin;
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\constants\AdminConstant;
use app\common\controller\AdminController;
use think\App;
use think\facade\Db;
/**
* @ControllerAnnotation(title="角色权限管理")
* Class Auth
*/
class AuthBase extends AdminController
{
use \app\admin\traits\Curd;
protected $sort = [
'sort' => 'desc',
'id' => 'desc',
];
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new SystemAuth();
}
/**
* @NodeAnotation(title="授权")
*/
public function authorize($id)
{
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
$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();
}
/**
* @NodeAnotation(title="授权保存")
*/
public function saveAuthorize()
{
$this->checkPostRequest();
$id = $this->request->post('id');
$node = $this->request->post('node', []);
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
try {
$authNode = new SystemAuthNode();
$authNode->where('auth_id', $id)->delete();
if (!empty($node)) {
$saveAll = [];
foreach ($node as $vo) {
$saveAll[] = [
'auth_id' => $id,
'node' => $vo,
];
}
$authNode->saveAll($saveAll);
}
TriggerService::updateMenu();
} catch (\Exception $e) {
$this->error('保存失败');
}
$this->success('保存成功');
}
/**
* @NodeAnotation(title="分配用户")
*
* 兼容 layui table 的 filter 传参ua.table 把 where:{id:roleId} 放入
* filter JSONfilter={"id":"xxx"})而非顶层 query 参数。若 $id 无默认值,
* ThinkPHP 方法参数绑定会从顶层 query 找 id 失败报"方法参数错误:id"。
* 这里给默认值 null再从 query / filter 兜底解析Ajax 时从 filter/op
* 移除 id角色ID不是用户搜索条件防 buildTableParames 误用。
*/
public function assignUsers($id = null)
{
if (empty($id)) {
// 优先从顶层 query 取iframe 页面加载时的 ?id=xxx
$id = $this->request->param('id');
// 再从 filter JSON 取table Ajax 请求时的 filter={"id":"xxx"}
if (empty($id) && $this->request->isAjax()) {
$filter = json_decode($this->request->param('filter', '{}'), true) ?: [];
$id = $filter['id'] ?? '';
}
if (empty($id)) {
$this->error('参数错误缺少角色ID');
}
}
// Ajax 时从 filter/op 移除 id它是角色ID不是用户搜索条件
// 防止 buildTableParames 把它当用户 id 的 WHERE 条件。
// 注意Request::withGet 是整体覆盖($this->get = $get而非合并
// 必须先取全量 GET 再写回,否则 page/limit 丢失导致翻页失效。
if ($this->request->isAjax()) {
$get = $this->request->get('', null);
$filter = isset($get['filter']) ? (json_decode($get['filter'], true) ?: []) : [];
unset($filter['id']);
$get['filter'] = json_encode($filter, JSON_UNESCAPED_UNICODE);
$op = isset($get['op']) ? (json_decode($get['op'], true) ?: []) : [];
unset($op['id']);
$get['op'] = json_encode($op, JSON_UNESCAPED_UNICODE);
$this->request->withGet($get);
}
$row = $this->model->find($id);
empty($row) && $this->error('数据不存在');
if ($this->request->isAjax()) {
list($page, $limit, $where) = $this->buildTableParames();
$count = SystemAdmin::where($where)
->where('delete_time', 0)
->count();
$list = SystemAdmin::where($where)
->withoutField('password')
->fieldRaw('FIND_IN_SET(' . intval($id) . ', auth_ids) AS has_role')
->where('delete_time', 0)
->page($page, $limit)
->order('id desc')
->select();
$data = [
'code' => 0,
'msg' => '',
'count' => $count,
'data' => $list,
];
return json($data);
}
$this->assign('row', $row);
return $this->fetch();
}
/**
* @NodeAnotation(title="分配用户切换")
*/
public function toggleUser()
{
$this->checkPostRequest();
$userId = intval($this->request->post('user_id'));
$roleId = intval($this->request->post('role_id'));
if ($userId == AdminConstant::SUPER_ADMIN_ID) {
$this->error('超级管理员不支持此操作');
}
$user = SystemAdmin::find($userId);
if (empty($user)) {
$this->error('用户不存在');
}
$role = SystemAuth::where('id', $roleId)->where('delete_time', 0)->find();
if (empty($role)) {
$this->error('角色不存在');
}
Db::startTrans();
try {
// FOR UPDATE 行锁,防止并发下读-改-写丢失逗号串的其它角色
$userRow = Db::name('system_admin')->where('id', $userId)->lock(true)->find();
$existing = empty($userRow['auth_ids']) ? [] : array_filter(explode(',', $userRow['auth_ids']));
$existing = array_values(array_map('strval', $existing));
$roleIdStr = (string) $roleId;
if (in_array($roleIdStr, $existing)) {
// 撤回:仅移除该角色,保留其它角色
$newArr = array_values(array_diff($existing, [$roleIdStr]));
} else {
// 分配:新增该角色,保留其它角色
$newArr = array_values(array_unique(array_merge($existing, [$roleIdStr])));
}
Db::name('system_admin')->where('id', $userId)->update([
'auth_ids' => empty($newArr) ? '' : implode(',', $newArr),
]);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->error('操作失败:' . $e->getMessage());
}
TriggerService::updateMenu($userId);
$this->success('操作成功');
}
}