thinkphp-wechat/application/user/admin/Index.php
Wenbin.Wang d49c9fde59 代码
2021-12-24 16:40:05 +08:00

578 lines
22 KiB
PHP
Raw Permalink 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 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]);
}
}