578 lines
22 KiB
PHP
578 lines
22 KiB
PHP
<?php
|
||
namespace app\user\admin;
|
||
|
||
use app\admin\controller\Admin;
|
||
use app\common\builder\ZBuilder;
|
||
use app\user\model\User as UserModel;
|
||
use app\user\model\Role as RoleModel;
|
||
use app\admin\model\Module as ModuleModel;
|
||
use app\admin\model\Access as AccessModel;
|
||
use util\Tree;
|
||
use think\Db;
|
||
use think\facade\Hook;
|
||
|
||
/**
|
||
* 用户默认控制器
|
||
* @package app\user\admin
|
||
*/
|
||
class Index extends Admin
|
||
{
|
||
/**
|
||
* 用户首页
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @return mixed
|
||
* @throws \think\Exception
|
||
* @throws \think\exception\DbException
|
||
*/
|
||
public function index()
|
||
{
|
||
cookie('__forward__', $_SERVER['REQUEST_URI']);
|
||
|
||
// 获取查询条件
|
||
$map = $this->getMap();
|
||
// 非超级管理员检查可管理角色
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
$map[] = ['role', 'in', $role_list];
|
||
}
|
||
|
||
// 数据列表
|
||
$data_list = UserModel::where($map)->order('sort,role,id desc')->paginate();
|
||
|
||
// 授权按钮
|
||
$btn_access = [
|
||
'title' => '授权',
|
||
'icon' => 'fa fa-fw fa-key',
|
||
'href' => url('access', ['uid' => '__id__'])
|
||
];
|
||
|
||
// 角色列表
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getTree(null, false, session('user_auth.role'));
|
||
} else {
|
||
$role_list = RoleModel::getTree();
|
||
}
|
||
|
||
// 使用ZBuilder快速创建数据表格
|
||
return ZBuilder::make('table')
|
||
->setPageTitle('用户管理') // 设置页面标题
|
||
->setTableName('admin_user') // 设置数据表名
|
||
->setSearch(['id' => 'ID', 'username' => '用户名', 'email' => '邮箱']) // 设置搜索参数
|
||
->addColumns([ // 批量添加列
|
||
['id', 'ID'],
|
||
['username', '用户名'],
|
||
['nickname', '昵称'],
|
||
['role', '角色', $role_list],
|
||
['email', '邮箱'],
|
||
['mobile', '手机号'],
|
||
['create_time', '创建时间', 'datetime'],
|
||
['status', '状态', 'switch'],
|
||
['right_button', '操作', 'btn']
|
||
])
|
||
->addTopButtons('add,enable,disable,delete') // 批量添加顶部按钮
|
||
->addRightButton('custom', $btn_access) // 添加授权按钮
|
||
->addRightButtons('edit,delete') // 批量添加右侧按钮
|
||
->setRowList($data_list) // 设置表格数据
|
||
->fetch(); // 渲染页面
|
||
}
|
||
|
||
/**
|
||
* 新增
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @return mixed
|
||
* @throws \think\Exception
|
||
*/
|
||
public function add()
|
||
{
|
||
// 保存数据
|
||
if ($this->request->isPost()) {
|
||
$data = $this->request->post();
|
||
// 验证
|
||
$result = $this->validate($data, 'User');
|
||
// 验证失败 输出错误信息
|
||
if(true !== $result) $this->error($result);
|
||
|
||
// 非超级管理需要验证可选择角色
|
||
if (session('user_auth.role') != 1) {
|
||
if ($data['role'] == session('user_auth.role')) {
|
||
$this->error('禁止创建与当前角色同级的用户');
|
||
}
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
if (!in_array($data['role'], $role_list)) {
|
||
$this->error('权限不足,禁止创建非法角色的用户');
|
||
}
|
||
}
|
||
|
||
if ($user = UserModel::create($data)) {
|
||
Hook::listen('user_add', $user);
|
||
// 记录行为
|
||
action_log('user_add', 'admin_user', $user['id'], UID);
|
||
$this->success('新增成功', url('index'));
|
||
} else {
|
||
$this->error('新增失败');
|
||
}
|
||
}
|
||
|
||
// 角色列表
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getTree(null, false, session('user_auth.role'));
|
||
} else {
|
||
$role_list = RoleModel::getTree(null, false);
|
||
}
|
||
|
||
// 使用ZBuilder快速创建表单
|
||
return ZBuilder::make('form')
|
||
->setPageTitle('新增') // 设置页面标题
|
||
->addFormItems([ // 批量添加表单项
|
||
['text', 'username', '用户名', '必填,可由英文字母、数字组成'],
|
||
['text', 'nickname', '昵称', '可以是中文'],
|
||
['select', 'role', '角色', '非超级管理员,禁止创建与当前角色同级的用户', $role_list],
|
||
['text', 'email', '邮箱', ''],
|
||
['password', 'password', '密码', '必填,6-20位'],
|
||
['text', 'mobile', '手机号'],
|
||
['image', 'avatar', '头像'],
|
||
['radio', 'status', '状态', '', ['禁用', '启用'], 1]
|
||
])
|
||
->fetch();
|
||
}
|
||
|
||
/**
|
||
* 编辑
|
||
* @param null $id 用户id
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @return mixed
|
||
* @throws \think\Exception
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @throws \think\exception\DbException
|
||
*/
|
||
public function edit($id = null)
|
||
{
|
||
if ($id === null) $this->error('缺少参数');
|
||
|
||
// 非超级管理员检查可编辑用户
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
$user_list = UserModel::where('role', 'in', $role_list)->column('id');
|
||
if (!in_array($id, $user_list)) {
|
||
$this->error('权限不足,没有可操作的用户');
|
||
}
|
||
}
|
||
|
||
// 保存数据
|
||
if ($this->request->isPost()) {
|
||
$data = $this->request->post();
|
||
|
||
// 禁止修改超级管理员的角色和状态
|
||
if ($data['id'] == 1 && $data['role'] != 1) {
|
||
$this->error('禁止修改超级管理员角色');
|
||
}
|
||
|
||
// 禁止修改超级管理员的状态
|
||
if ($data['id'] == 1 && $data['status'] != 1) {
|
||
$this->error('禁止修改超级管理员状态');
|
||
}
|
||
|
||
// 验证
|
||
$result = $this->validate($data, 'User.update');
|
||
// 验证失败 输出错误信息
|
||
if(true !== $result) $this->error($result);
|
||
|
||
// 如果没有填写密码,则不更新密码
|
||
if ($data['password'] == '') {
|
||
unset($data['password']);
|
||
}
|
||
|
||
// 非超级管理需要验证可选择角色
|
||
if (session('user_auth.role') != 1) {
|
||
if ($data['role'] == session('user_auth.role')) {
|
||
$this->error('禁止修改为当前角色同级的用户');
|
||
}
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
if (!in_array($data['role'], $role_list)) {
|
||
$this->error('权限不足,禁止修改为非法角色的用户');
|
||
}
|
||
}
|
||
|
||
if (UserModel::update($data)) {
|
||
$user = UserModel::get($data['id']);
|
||
Hook::listen('user_edit', $user);
|
||
// 记录行为
|
||
action_log('user_edit', 'admin_user', $user['id'], UID, get_nickname($user['id']));
|
||
$this->success('编辑成功', cookie('__forward__'));
|
||
} else {
|
||
$this->error('编辑失败');
|
||
}
|
||
}
|
||
|
||
// 获取数据
|
||
$info = UserModel::where('id', $id)->field('password', true)->find();
|
||
|
||
// 角色列表
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getTree(null, false, session('user_auth.role'));
|
||
} else {
|
||
$role_list = RoleModel::getTree(null, false);
|
||
}
|
||
|
||
// 使用ZBuilder快速创建表单
|
||
return ZBuilder::make('form')
|
||
->setPageTitle('编辑') // 设置页面标题
|
||
->addFormItems([ // 批量添加表单项
|
||
['hidden', 'id'],
|
||
['static', 'username', '用户名', '不可更改'],
|
||
['text', 'nickname', '昵称', '可以是中文'],
|
||
['select', 'role', '角色', '非超级管理员,禁止创建与当前角色同级的用户', $role_list],
|
||
['text', 'email', '邮箱', ''],
|
||
['password', 'password', '密码', '必填,6-20位'],
|
||
['text', 'mobile', '手机号'],
|
||
['image', 'avatar', '头像'],
|
||
['radio', 'status', '状态', '', ['禁用', '启用']]
|
||
])
|
||
->setFormData($info) // 设置表单数据
|
||
->fetch();
|
||
}
|
||
|
||
/**
|
||
* 授权
|
||
* @param string $module 模块名
|
||
* @param int $uid 用户id
|
||
* @param string $tab 分组tab
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @return mixed
|
||
* @throws \think\Exception
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @throws \think\exception\DbException
|
||
* @throws \think\exception\PDOException
|
||
*/
|
||
public function access($module = '', $uid = 0, $tab = '')
|
||
{
|
||
if ($uid === 0) $this->error('缺少参数');
|
||
|
||
// 非超级管理员检查可编辑用户
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
$user_list = UserModel::where('role', 'in', $role_list)->column('id');
|
||
if (!in_array($uid, $user_list)) {
|
||
$this->error('权限不足,没有可操作的用户');
|
||
}
|
||
}
|
||
|
||
// 获取所有授权配置信息
|
||
$list_module = ModuleModel::where('access', 'neq', '')
|
||
->where('access', 'neq', '')
|
||
->where('status', 1)
|
||
->column('name,title,access');
|
||
|
||
if ($list_module) {
|
||
// tab分组信息
|
||
$tab_list = [];
|
||
foreach ($list_module as $key => $value) {
|
||
$list_module[$key]['access'] = json_decode($value['access'], true);
|
||
// 配置分组信息
|
||
$tab_list[$value['name']] = [
|
||
'title' => $value['title'],
|
||
'url' => url('access', [
|
||
'module' => $value['name'],
|
||
'uid' => $uid
|
||
])
|
||
];
|
||
}
|
||
$module = $module == '' ? current(array_keys($list_module)) : $module;
|
||
$this->assign('tab_nav', [
|
||
'tab_list' => $tab_list,
|
||
'curr_tab' => $module
|
||
]);
|
||
|
||
// 读取授权内容
|
||
$access = $list_module[$module]['access'];
|
||
foreach ($access as $key => $value) {
|
||
$access[$key]['url'] = url('access', [
|
||
'module' => $module,
|
||
'uid' => $uid,
|
||
'tab' => $key
|
||
]);
|
||
}
|
||
|
||
// 当前分组
|
||
$tab = $tab == '' ? current(array_keys($access)) : $tab;
|
||
// 当前授权
|
||
$curr_access = $access[$tab];
|
||
if (!isset($curr_access['nodes'])) {
|
||
$this->error('模块:'.$module.' 数据授权配置缺少nodes信息');
|
||
}
|
||
$curr_access_nodes = $curr_access['nodes'];
|
||
|
||
$this->assign('tab', $tab);
|
||
$this->assign('access', $access);
|
||
|
||
if ($this->request->isPost()) {
|
||
$post = $this->request->param();
|
||
if (isset($post['nodes'])) {
|
||
$data_node = [];
|
||
foreach ($post['nodes'] as $node) {
|
||
list($group, $nid) = explode('|', $node);
|
||
$data_node[] = [
|
||
'module' => $module,
|
||
'group' => $group,
|
||
'uid' => $uid,
|
||
'nid' => $nid,
|
||
'tag' => $post['tag']
|
||
];
|
||
}
|
||
|
||
// 先删除原有授权
|
||
$map['module'] = $post['module'];
|
||
$map['tag'] = $post['tag'];
|
||
$map['uid'] = $post['uid'];
|
||
if (false === AccessModel::where($map)->delete()) {
|
||
$this->error('清除旧授权失败');
|
||
}
|
||
|
||
// 添加新的授权
|
||
$AccessModel = new AccessModel;
|
||
if (!$AccessModel->saveAll($data_node)) {
|
||
$this->error('操作失败');
|
||
}
|
||
|
||
// 调用后置方法
|
||
if (isset($curr_access_nodes['model_name']) && $curr_access_nodes['model_name'] != '') {
|
||
if (strpos($curr_access_nodes['model_name'], '/')) {
|
||
list($module, $model_name) = explode('/', $curr_access_nodes['model_name']);
|
||
} else {
|
||
$model_name = $curr_access_nodes['model_name'];
|
||
}
|
||
$class = "app\\{$module}\\model\\".$model_name;
|
||
$model = new $class;
|
||
try{
|
||
$model->afterAccessUpdate($post);
|
||
}catch(\Exception $e){}
|
||
}
|
||
|
||
// 记录行为
|
||
$nids = implode(',', $post['nodes']);
|
||
$details = "模块($module),分组(".$post['tag']."),授权节点ID($nids)";
|
||
action_log('user_access', 'admin_user', $uid, UID, $details);
|
||
$this->success('操作成功', url('access', ['uid' => $post['uid'], 'module' => $module, 'tab' => $tab]));
|
||
} else {
|
||
// 清除所有数据授权
|
||
$map['module'] = $post['module'];
|
||
$map['tag'] = $post['tag'];
|
||
$map['uid'] = $post['uid'];
|
||
if (false === AccessModel::where($map)->delete()) {
|
||
$this->error('清除旧授权失败');
|
||
} else {
|
||
$this->success('操作成功');
|
||
}
|
||
}
|
||
} else {
|
||
$nodes = [];
|
||
if (isset($curr_access_nodes['model_name']) && $curr_access_nodes['model_name'] != '') {
|
||
if (strpos($curr_access_nodes['model_name'], '/')) {
|
||
list($module, $model_name) = explode('/', $curr_access_nodes['model_name']);
|
||
} else {
|
||
$model_name = $curr_access_nodes['model_name'];
|
||
}
|
||
$class = "app\\{$module}\\model\\".$model_name;
|
||
$model = new $class;
|
||
|
||
try{
|
||
$nodes = $model->access();
|
||
}catch(\Exception $e){
|
||
$this->error('模型:'.$class."缺少“access”方法");
|
||
}
|
||
} else {
|
||
// 没有设置模型名,则按表名获取数据
|
||
$fields = [
|
||
$curr_access_nodes['primary_key'],
|
||
$curr_access_nodes['parent_id'],
|
||
$curr_access_nodes['node_name']
|
||
];
|
||
|
||
$nodes = Db::name($curr_access_nodes['table_name'])->order($curr_access_nodes['primary_key'])->field($fields)->select();
|
||
$tree_config = [
|
||
'title' => $curr_access_nodes['node_name'],
|
||
'id' => $curr_access_nodes['primary_key'],
|
||
'pid' => $curr_access_nodes['parent_id']
|
||
];
|
||
$nodes = Tree::config($tree_config)->toLayer($nodes);
|
||
}
|
||
|
||
// 查询当前用户的权限
|
||
$map = [
|
||
'module' => $module,
|
||
'tag' => $tab,
|
||
'uid' => $uid
|
||
];
|
||
$node_access = AccessModel::where($map)->select();
|
||
$user_access = [];
|
||
foreach ($node_access as $item) {
|
||
$user_access[$item['group'].'|'.$item['nid']] = 1;
|
||
}
|
||
|
||
$nodes = $this->buildJsTree($nodes, $curr_access_nodes, $user_access);
|
||
$this->assign('nodes', $nodes);
|
||
}
|
||
|
||
$page_tips = isset($curr_access['page_tips']) ? $curr_access['page_tips'] : '';
|
||
$tips_type = isset($curr_access['tips_type']) ? $curr_access['tips_type'] : 'info';
|
||
$this->assign('page_tips', $page_tips);
|
||
$this->assign('tips_type', $tips_type);
|
||
}
|
||
|
||
$this->assign('module', $module);
|
||
$this->assign('uid', $uid);
|
||
$this->assign('tab', $tab);
|
||
$this->assign('page_title', '数据授权');
|
||
return $this->fetch();
|
||
}
|
||
|
||
/**
|
||
* 构建jstree代码
|
||
* @param array $nodes 节点
|
||
* @param array $curr_access 当前授权信息
|
||
* @param array $user_access 用户授权信息
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @return string
|
||
*/
|
||
private function buildJsTree($nodes = [], $curr_access = [], $user_access = [])
|
||
{
|
||
$result = '';
|
||
if (!empty($nodes)) {
|
||
$option = [
|
||
'opened' => true,
|
||
'selected' => false
|
||
];
|
||
foreach ($nodes as $node) {
|
||
$key = $curr_access['group'].'|'.$node[$curr_access['primary_key']];
|
||
$option['selected'] = isset($user_access[$key]) ? true : false;
|
||
if (isset($node['child'])) {
|
||
$curr_access_child = isset($curr_access['child']) ? $curr_access['child'] : $curr_access;
|
||
$result .= '<li id="'.$key.'" data-jstree=\''.json_encode($option).'\'>'.$node[$curr_access['node_name']].$this->buildJsTree($node['child'], $curr_access_child, $user_access).'</li>';
|
||
} else {
|
||
$result .= '<li id="'.$key.'" data-jstree=\''.json_encode($option).'\'>'.$node[$curr_access['node_name']].'</li>';
|
||
}
|
||
}
|
||
}
|
||
|
||
return '<ul>'.$result.'</ul>';
|
||
}
|
||
|
||
/**
|
||
* 删除用户
|
||
* @param array $ids 用户id
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @throws \think\Exception
|
||
* @throws \think\exception\PDOException
|
||
*/
|
||
public function delete($ids = [])
|
||
{
|
||
Hook::listen('user_delete', $ids);
|
||
return $this->setStatus('delete');
|
||
}
|
||
|
||
/**
|
||
* 启用用户
|
||
* @param array $ids 用户id
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @throws \think\Exception
|
||
* @throws \think\exception\PDOException
|
||
*/
|
||
public function enable($ids = [])
|
||
{
|
||
Hook::listen('user_enable', $ids);
|
||
return $this->setStatus('enable');
|
||
}
|
||
|
||
/**
|
||
* 禁用用户
|
||
* @param array $ids 用户id
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @throws \think\Exception
|
||
* @throws \think\exception\PDOException
|
||
*/
|
||
public function disable($ids = [])
|
||
{
|
||
Hook::listen('user_disable', $ids);
|
||
return $this->setStatus('disable');
|
||
}
|
||
|
||
/**
|
||
* 设置用户状态:删除、禁用、启用
|
||
* @param string $type 类型:delete/enable/disable
|
||
* @param array $record
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @throws \think\Exception
|
||
* @throws \think\exception\PDOException
|
||
*/
|
||
public function setStatus($type = '', $record = [])
|
||
{
|
||
$ids = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
|
||
$ids = (array)$ids;
|
||
|
||
// 当前用户所能操作的用户
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
$user_list = UserModel::where('role', 'in', $role_list)->column('id');
|
||
if (session('user_auth.role') != 1 && !$user_list) {
|
||
$this->error('权限不足,没有可操作的用户');
|
||
}
|
||
|
||
$ids = array_intersect($user_list, $ids);
|
||
if (!$ids) {
|
||
$this->error('权限不足,没有可操作的用户');
|
||
}
|
||
|
||
switch ($type) {
|
||
case 'enable':
|
||
if (false === UserModel::where('id', 'in', $ids)->setField('status', 1)) {
|
||
$this->error('启用失败');
|
||
}
|
||
break;
|
||
case 'disable':
|
||
if (false === UserModel::where('id', 'in', $ids)->setField('status', 0)) {
|
||
$this->error('禁用失败');
|
||
}
|
||
break;
|
||
case 'delete':
|
||
if (false === UserModel::where('id', 'in', $ids)->delete()) {
|
||
$this->error('删除失败');
|
||
}
|
||
break;
|
||
default:
|
||
$this->error('非法操作');
|
||
}
|
||
|
||
action_log('user_'.$type, 'admin_user', '', UID);
|
||
|
||
$this->success('操作成功');
|
||
}
|
||
|
||
/**
|
||
* 快速编辑
|
||
* @param array $record 行为日志
|
||
* @author 蔡伟明 <314013107@qq.com>
|
||
* @return mixed
|
||
*/
|
||
public function quickEdit($record = [])
|
||
{
|
||
$id = input('post.pk', '');
|
||
$id == UID && $this->error('禁止操作当前账号');
|
||
$field = input('post.name', '');
|
||
$value = input('post.value', '');
|
||
|
||
// 非超级管理员检查可操作的用户
|
||
if (session('user_auth.role') != 1) {
|
||
$role_list = RoleModel::getChildsId(session('user_auth.role'));
|
||
$user_list = UserModel::where('role', 'in', $role_list)->column('id');
|
||
if (!in_array($id, $user_list)) {
|
||
$this->error('权限不足,没有可操作的用户');
|
||
}
|
||
}
|
||
|
||
$config = UserModel::where('id', $id)->value($field);
|
||
$details = '字段(' . $field . '),原值(' . $config . '),新值:(' . $value . ')';
|
||
return parent::quickEdit(['user_edit', 'admin_user', $id, UID, $details]);
|
||
}
|
||
}
|