用户管理

This commit is contained in:
wuyanwen
2019-12-11 20:59:59 +08:00
parent ae7fd47a5d
commit 22064c6178
26 changed files with 1306 additions and 274 deletions

View File

@@ -0,0 +1 @@
<?php

View File

@@ -0,0 +1,26 @@
{$form|raw}
<script>
layui.use(['layer', 'form', 'admin', 'formX'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var mUser = admin.getLayerData('#role'); // 列表页面传递的数据,#modelUserForm这个只要写弹窗内任意一个元素的id即可
// 回显数据
form.val('role', mUser);
// 表单提交事件
form.on('submit(submitRole)', function (data) {
admin.req('{:url("role")}', data.field, function (response) {
layer.closeAll('loading');
if (response.code === 10000) {
layer.msg(response.msg, {icon: 1});
admin.putLayerData('formOk', true, '#role'); // 设置操作成功的标识,#modelUserForm这个只要写弹窗内任意一个元素的id即可
admin.closeDialog('#role'); // 关闭页面层弹窗
} else {
layer.msg(response.msg, {icon: 2});
}
}, 'post');
return false;
});
});
</script>

View File

@@ -0,0 +1,25 @@
{$form|raw}
<script>
layui.use(['layer', 'form', 'admin', 'formX'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var mUser = admin.getLayerData('#role'); // 列表页面传递的数据,#modelUserForm这个只要写弹窗内任意一个元素的id即可
// 回显数据
form.val('role', mUser);
// 表单提交事件
form.on('submit(submitRole)', function (data) {
admin.req('role/'+ "{$role_id}", data.field, function (response) {
if (response.code === 10000) {
layer.msg(response.msg, {icon: 1});
admin.putLayerData('formOk', true, '#role'); // 设置操作成功的标识,#modelUserForm这个只要写弹窗内任意一个元素的id即可
admin.closeDialog('#role'); // 关闭页面层弹窗
} else {
layer.msg(response.msg, {icon: 2});
}
}, 'put');
return false;
});
});
</script>

View File

@@ -0,0 +1,178 @@
{extend name="../../../view/layout"}
{block name="title"}角色管理{/block}
{block name="search"}
<div class="layui-form toolbar">
<div class="layui-form-item">
<!--<div class="layui-inline">
<div class="layui-input-inline mr0">
<input id="edtSearchAuth" class="layui-input" type="text" placeholder="输入角色名称"/>
</div>
</div>
<div class="layui-inline">
<button id="btnSearchAuth" class="layui-btn icon-btn"><i class="layui-icon">&#xe615;</i>搜索
</button>-->
<button id="btnAddAuth" class="layui-btn icon-btn"><i class="layui-icon">&#xe654;</i>添加</button>
<!--</div>-->
</div>
</div>
{/block}
{block name="table"}
<table class="layui-table" id="tableRole"></table>
<!-- 表格操作列 -->
<script type="text/html" id="tableBarAuth">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="add">新增子角色</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
</script>
{/block}
{block name="script"}
<script>
layui.use(['layer', 'form', 'table', 'admin', 'util', 'treeTable'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var table = layui.table;
var util = layui.util;
var admin = layui.admin;
var treeTable = layui.treeTable;
var treeTb = treeTable.render({
tree: {
arrowType: 'arrow2',
iconIndex: 1, // 折叠图标显示在第几列
idName: 'id', // 自定义id字段的名称
childName: 'children', // 自定义标识是否还有子节点的字段名称
pidName: 'parent_id',
isPidData: true,
getIcon: function(d) { // 自定义图标
// d是当前行的数据
if (d.children.length) { // 判断是否有子集
return '<i class="ew-tree-icon ew-tree-icon-folder"></i>';
} else {
return '<i class="ew-tree-icon ew-tree-icon-file"></i>';
}
}
},
elem: '#tableRole',
cellMinWidth: 100,
cols: [
{type: 'numbers', title: '#'},
{field: 'role_name', title: '角色名称', minWidth: 100},
{field: 'description', title: '角色描述'},
{
field: 'created_at', sort: true, templet: function (d) {
return util.toDateString(d.created_at);
}, title: '创建时间', maxWidth: 100
},
{templet: '#tableBarAuth', title: '操作', align: 'center', minWidth: 120}
],
reqData: function(data, callback) {
// 在这里写ajax请求通过callback方法回调数据
$.get('{:url("roles")}', function (res) {
callback(res.data); // 参数是数组类型
});
}
});
// 添加按钮点击事件
$('#btnAddAuth').click(function () {
showEditModel();
});
// 工具条点击事件
treeTable.on('tool(tableRole)', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') { // 修改
showEditModel(data);
} else if (layEvent === 'del') { // 删除
doDel(obj);
} else {
showEditModel(data, true);
}
});
// 删除
function doDel(obj) {
layer.confirm('确定要删除“' + obj.data.role_name + '”吗?', {
skin: 'layui-layer-admin',
shade: .1
}, function (index) {
layer.close(index);
admin.req('/role/'+ obj.data.id, {}, function (response) {
if (response.code === 10000) {
layer.msg(response.msg, {icon: 1});
obj.del()
} else {
layer.msg(response.msg, {icon: 2});
}
}, 'delete');
});
}
// 显示表单弹窗
// 显示表单弹窗
function showEditModel(mRole, addRole = false) {
var layIndex = admin.open({
title: addRole ? '新增子角色' : ((mRole ? '修改' : '添加') + '角色'),
url: addRole ? '/role/create' + '?id='+mRole.id : (mRole ? '/role/'+mRole.id + '/edit': '/role/create'),
data: addRole ? '' : mRole, // 传递数据到表单页面
end: function () {
if (admin.getLayerData(layIndex, 'formOk')) { // 判断表单操作成功标识
if (addRole) {
treeTb.reload();
setTimeout(function () {
treeTb.expand(mRole.id)
}, 200)
} else {
if (mRole) {
treeTb.reload();
setTimeout(function () {
treeTb.expand(mRole.id)
}, 200)
} else {
treeTb.reload(); // 成功刷新表格
}
}
}
},
success: function (layero, dIndex) {
// 弹窗超出范围不出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
});
}
// 搜索按钮点击事件
$('#btnSearchAuth').click(function () {
$('#edtSearchAuth').removeClass('layui-form-danger');
var keyword = $('#edtSearchAuth').val();
var $tds = $('#tableAuth').next('.treeTable').find('.layui-table-body tbody tr td');
$tds.css('background-color', 'transparent');
if (!keyword) {
layer.tips('请输入关键字', '#edtSearchAuth', {tips: [1, '#ff4c4c']});
$('#edtSearchAuth').addClass('layui-form-danger');
$('#edtSearchAuth').focus();
return;
}
var searchCount = 0;
$tds.each(function () {
if ($(this).text().indexOf(keyword) >= 0) {
$(this).css('background-color', '#FAE6A0');
if (searchCount == 0) {
$('body,html').stop(true);
$('body,html').animate({scrollTop: $(this).offset().top - 150}, 500);
}
searchCount++;
}
});
if (searchCount == 0) {
layer.msg("没有匹配结果", {icon: 5, anim: 6});
} else {
treetable.expandAll('#tableAuth');
}
});
});
</script>
{/block}

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>

View File

@@ -2,14 +2,16 @@
namespace catchAdmin\user\controller;
use app\Request;
use catchAdmin\permissions\model\Roles;
use catchAdmin\user\model\Users;
use catchAdmin\user\request\CreateRequest;
use catchAdmin\user\request\UpdateRequest;
use catcher\base\BaseController;
use catcher\base\CatchController;
use catcher\CatchForm;
use catcher\CatchResponse;
use catcher\Tree;
class User extends BaseController
class User extends CatchController
{
protected $user;
@@ -49,6 +51,7 @@ class User extends BaseController
$form->text('email', '邮箱')->verify('email')->placeholder('请输入邮箱');
$form->password('password', '密码')->id('pwd')->verify('required|psw')->placeholder('请输入密码');
$form->password('passwordConfirm', '确认密码')->verify('required|equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码');
$form->dom('<div id="roles"></div>', '角色');
$form->formBtn('submitUser');
return $this->fetch([
@@ -64,7 +67,12 @@ class User extends BaseController
*/
public function save(CreateRequest $request)
{
return CatchResponse::success($this->user->storeBy($request->post()));
$uid = $this->user->storeBy($request->post());
if (!empty($request->param('roleids'))) {
$this->user->attach($request->param('roleids'));
}
return CatchResponse::success();
}
/**
@@ -88,6 +96,7 @@ class User extends BaseController
$form->text('email', '邮箱')->verify('email')->default($user->email)->placeholder('请输入邮箱');
$form->password('password', '密码')->id('pwd')->placeholder('请输入密码');
$form->password('passwordConfirm', '确认密码')->verify('equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码');
$form->dom('<div id="roles"></div>', '角色');
$form->formBtn('submitUser');
return $this->fetch([
@@ -152,4 +161,29 @@ class User extends BaseController
return CatchResponse::success($this->user->recover($id));
}
/**
*
* @time 2019年12月11日
* @param Request $request
* @param Roles $roles
* @return \think\response\Json
*/
public function getRoles(Request $request, Roles $roles): \think\response\Json
{
$roles = Tree::done($roles->getList());
$roleIds = [];
if ($request->param('uid')) {
$userHasRoles = $this->user->findBy($request->param('uid'))->getRoles();
foreach ($userHasRoles as $role) {
$roleIds[] = $role->pivot->role_id;
}
}
return CatchResponse::success([
'roles' => $roles,
'hasRoles' => $roleIds,
]);
}
}

View File

@@ -2,9 +2,9 @@
namespace catchAdmin\user\model;
use catchAdmin\permissions\model\HasRolesTrait;
use catcher\base\BaseModel;
use catcher\base\CatchModel;
class Users extends BaseModel
class Users extends CatchModel
{
use HasRolesTrait;
@@ -46,7 +46,9 @@ class Users extends BaseModel
*/
public function getList($search): \think\Paginator
{
return (($search['trash'] ?? false) ? static::onlyTrashed() : $this)->when($search['username'] ?? false, function ($query) use ($search){
return (($search['trash'] ?? false) ? static::onlyTrashed() : $this)
->field(['id', 'username', 'email', 'status','last_login_time','last_login_ip', 'created_at', 'updated_at'])
->when($search['username'] ?? false, function ($query) use ($search){
return $query->whereLike('username', $search['username']);
})
->when($search['email'] ?? false, function ($query) use ($search){

View File

@@ -2,9 +2,9 @@
namespace catchAdmin\user\request;
use catchAdmin\user\model\Users;
use catcher\base\BaseRequest;
use catcher\base\CatchRequest;
class CreateRequest extends BaseRequest
class CreateRequest extends CatchRequest
{
protected function rules(): array

View File

@@ -2,9 +2,9 @@
namespace catchAdmin\user\request;
use catchAdmin\user\model\Users;
use catcher\base\BaseRequest;
use catcher\base\CatchRequest;
class UpdateRequest extends BaseRequest
class UpdateRequest extends CatchRequest
{
protected function rules(): array
{

View File

@@ -6,3 +6,4 @@ $router->get('users', '\catchAdmin\user\controller\User/list');
// 切换状态
$router->put('user/switch/status/<id>', '\catchAdmin\user\controller\User/switchStatus');
$router->put('user/recover/<id>', '\catchAdmin\user\controller\User/recover');
$router->get('user/get/roles', '\catchAdmin\user\controller\User/getRoles');

View File

@@ -1,17 +0,0 @@
<?php
namespace catchAdmin\user\validate;
use catcher\base\BaseValidate;
class CreateValidate extends BaseValidate
{
protected function getRules(): array
{
// TODO: Implement getRules() method.
return [
'username|用户名' => 'require|max:20',
'password|密码' => 'require|max:20',
'email|邮箱' => 'require|email'
];
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace catchAdmin\user\validate;
use catchAdmin\user\model\Users;
use catcher\base\BaseValidate;
class UpdateValidate extends BaseValidate
{
protected function getRules(): array
{
// TODO: Implement getRules() method.
return [
'username|用户名' => 'require|max:20',
'password|密码' => 'require|max:20',
'email|邮箱' => 'require|email|unique:'.Users::class.',email,'.request()->route('user').',id',
];
}
}

View File

@@ -1,28 +1,42 @@
{$form|raw}
<script>
layui.use(['layer', 'form', 'admin', 'formX'], function () {
layui.use(['layer', 'form', 'admin', 'formX','authtree'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var authtree = layui.authtree;
var mUser = admin.getLayerData('#userForm'); // 列表页面传递的数据,#modelUserForm这个只要写弹窗内任意一个元素的id即可
// 回显数据
form.val('userForm', mUser);
// 表单提交事件
form.on('submit(submitUser)', function (data) {
layer.load(2);
var url = mUser ? '{:url("user")}' : '{:url("user")}';
$.post(url, data.field, function (response) {
admin.req(url, data.field, function (response) {
layer.closeAll('loading');
if (response.code == 10000) {
if (response.code === 10000) {
layer.msg(response.msg, {icon: 1});
admin.putLayerData('formOk', true, '#userForm'); // 设置操作成功的标识,#modelUserForm这个只要写弹窗内任意一个元素的id即可
admin.closeDialog('#userForm'); // 关闭页面层弹窗
} else {
layer.msg(response.msg, {icon: 2});
}
}, 'json');
}, 'post');
return false;
});
admin.req('{:url("/user/get/roles")}',{}, function (response) {
authtree.render('#roles', response.data.roles,{
inputname: 'roleids[]',
layfilter: 'lay-check-auth',
autowidth: true,
nameKey: 'role_name',
valueKey: 'id',
childKey: 'children',
collapseLeafNode: true,
theme: 'auth-skin-default',
});
});
});
</script>

View File

@@ -1,14 +1,30 @@
{$form|raw}
<script>
layui.use(['layer', 'form', 'admin', 'formX'], function () {
layui.use(['layer', 'form', 'admin', 'formX', 'authtree'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var authtree = layui.authtree;
var mUser = admin.getLayerData('#userForm'); // 列表页面传递的数据,#modelUserForm这个只要写弹窗内任意一个元素的id即可
// 回显数据
form.val('userForm', mUser);
var uid = "{$uid}";
admin.req('{:url("/user/get/roles")}',{uid:uid}, function (response) {
authtree.render('#roles', response.data.roles, {
inputname: 'roleids[]',
primaryKey: 'id',
parentKey: 'parent_id',
layfilter: 'lay-check-auth',
autowidth: true,
nameKey: 'role_name',
valueKey: 'id',
childKey: 'children',
collapseLeafNode: true,
theme: 'auth-skin-default',
checkedKey: response.data.hasRoles
});
});
// 表单提交事件
form.on('submit(submitUser)', function (data) {
admin.req('/user/' + uid, data.field, function (response) {