用户管理

This commit is contained in:
wuyanwen
2019-12-07 17:31:38 +08:00
parent fa4837487b
commit 330a19e8c3
35 changed files with 1181 additions and 214 deletions

View File

@@ -5,6 +5,8 @@ use catcher\command\InstallCommand;
use catcher\command\MigrateRunCommand;
use catcher\command\ModelGeneratorCommand;
use catcher\command\ModuleCacheCommand;
use catcher\validates\Sometimes;
use think\facade\Validate;
use think\Service;
class CatchAdminService extends Service
@@ -22,5 +24,26 @@ class CatchAdminService extends Service
MigrateRunCommand::class,
ModelGeneratorCommand::class,
]);
$this->registerValidates();
}
/**
*
* @time 2019年12月07日
* @return void
*/
protected function registerValidates(): void
{
$validates = [
new Sometimes(),
];
Validate::maker(function($validate) use ($validates){
foreach ($validates as $vali) {
$validate->extend($vali->type(), [$vali, 'verify'], $vali->message());
}
});
}
}

View File

@@ -220,8 +220,8 @@
<div class="layui-body"></div>
<!-- 底部 -->
<div class="layui-footer">
copyright © 2019 <a href="http://easyweb.vip" target="_blank">easyweb.vip</a> all rights reserved.
<span class="pull-right">Version 3.1.5</span>
copyright 2017 ~ © {:date('Y', time())} <a href="http://easyweb.vip" target="_blank">catchadmin.com</a> all rights reserved.
<span class="pull-right">Version 2.0</span>
</div>
</div>

View File

@@ -1,6 +1,7 @@
<?php
namespace catchAdmin\user\controller;
use app\Request;
use catchAdmin\user\model\Users;
use catchAdmin\user\request\CreateRequest;
use catchAdmin\user\request\UpdateRequest;
@@ -24,33 +25,48 @@ class User extends BaseController
* @return string
*/
public function index()
{
return $this->fetch();
}
public function list(Request $request)
{
return CatchResponse::paginate($this->user->getList($request->param()));
}
/**
*
* @time 2019年12月06日
* @throws \Exception
* @return string
*/
public function create()
{
$form = new CatchForm();
$form->text('name', '用户名')->id('id')->class('class');
$form->select('names', '性别')->options(['请选择性别', '男', '女'])->default(1);
//$form->select('namess', '用户名');
$form->formId('userForm');
$form->text('username', '用户名')->verify('required')->placeholder('请输入用户名');
$form->text('email', '邮箱')->verify('email')->placeholder('请输入邮箱');
$form->password('password', '密码')->id('pwd')->verify('required|psw')->placeholder('请输入密码');
$form->password('passwordConfirm', '确认密码')->verify('required|equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码');
$form->formBtn('submitUser');
$form->render();
return $this->fetch([
'form' => $form->render()
'form' => $form->render(),
]);
}
/**
*
* @time 2019年12月04日
* @param CreateRequest $request
* @time 2019年12月06日
* @return \think\response\Json
*/
public function create(CreateRequest $request)
public function save(CreateRequest $request)
{
return CatchResponse::success($this->user->storeBy($request->post()));
}
public function save()
{}
/**
*
* @time 2019年12月04日
@@ -62,8 +78,23 @@ class User extends BaseController
return CatchResponse::success($this->user->findBy($id));
}
public function edit()
{}
public function edit($id)
{
$user = $this->user->findBy($id, ['id','username', 'email']);
$form = new CatchForm();
$form->formId('userForm');
$form->text('username', '用户名')->verify('required')->default($user->username)->placeholder('请输入用户名');
$form->text('email', '邮箱')->verify('email')->default($user->email)->placeholder('请输入邮箱');
$form->password('password', '密码')->id('pwd')->placeholder('请输入密码');
$form->password('passwordConfirm', '确认密码')->verify('equalTo', ['pwd', '两次密码输入不一致'])->placeholder('请再次输入密码');
$form->formBtn('submitUser');
return $this->fetch([
'form' => $form->render(),
'uid' => $user->id,
]);
}
/**
*
@@ -88,4 +119,37 @@ class User extends BaseController
return CatchResponse::success($this->user->deleteBy($id));
}
/**
*
* @time 2019年12月07日
* @param $id
* @return \think\response\Json
*/
public function switchStatus($id): \think\response\Json
{
$user = $this->user->findBy($id);
return CatchResponse::success($this->user->updateBy($id, [
'status' => $user->status == Users::ENABLE ? Users::DISABLE : Users::ENABLE,
]));
}
/**
*
* @time 2019年12月07日
* @param $id
* @return \think\response\Json
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DataNotFoundException
*/
public function recover($id): \think\response\Json
{
$trashedUser = $this->user->findBy($id, ['*'], true);
if ($this->user->where('email', $trashedUser->email)->find()) {
return CatchResponse::fail(sprintf('该恢复用户的邮箱 [%s] 已被占用', $trashedUser->email));
}
return CatchResponse::success($this->user->recover($id));
}
}

View File

@@ -37,8 +37,7 @@ class Users extends Migrator
->addColumn('last_login_time', 'integer',array('default'=>0,'comment'=>'最后登录时间', 'signed' => false))
->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false ))
->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false))
->addColumn('delete_at', 'integer', array('null'=>true,'comment'=>'删除状态0未删除 >0 已删除', 'signed' => false))
->addIndex(array('email'), array('unique' => true))
->addColumn('deleted_at', 'integer', array('null'=>true,'comment'=>'删除状态0未删除 >0 已删除', 'signed' => false))
->create();
}
}

View File

@@ -6,7 +6,7 @@ use catcher\base\BaseModel;
class Users extends BaseModel
{
protected $name = 'users';
protected $field = [
'id', //
'username', // 用户名
@@ -17,7 +17,32 @@ class Users extends BaseModel
'last_login_time', // 最后登录时间
'created_at', // 创建时间
'updated_at', // 更新时间
'delete_at', // 删除状态0未删除 >0 已删除
'deleted_at', // 删除状态0未删除 >0 已删除
];
];
/**
* set password
*
* @time 2019年12月07日
* @param $value
* @return false|string
*/
public function setPasswordAttr($value)
{
return password_hash($value, PASSWORD_DEFAULT);
}
public function getList($search)
{
return (($search['trash'] ?? false) ? static::onlyTrashed() : $this)->when($search['username'] ?? false, function ($query) use ($search){
return $query->whereLike('username', $search['username']);
})
->when($search['email'] ?? false, function ($query) use ($search){
return $query->whereLike('email', $search['email']);
})
->when($search['status'] ?? false, function ($query) use ($search){
return $query->where('status', $search['status']);
})->paginate($search['limit'] ?? $this->limit);
}
}

View File

@@ -1,15 +1,24 @@
<?php
namespace catchAdmin\user\request;
use catchAdmin\user\validate\CreateValidate;
use catchAdmin\user\model\Users;
use catcher\base\BaseRequest;
class CreateRequest extends BaseRequest
{
protected function getValidate()
protected function rules(): array
{
// TODO: Implement getValidate() method.
return new CreateValidate();
// TODO: Implement rules() method.
return [
'username|用户名' => 'require|max:20',
'password|密码' => 'require|min:5|max:12',
'email|邮箱' => 'require|email|unique:'.Users::class,
];
}
protected function message(): array
{
// TODO: Implement message() method.
}
}

View File

@@ -1,14 +1,24 @@
<?php
namespace catchAdmin\user\request;
use catchAdmin\user\validate\UpdateValidate;
use catchAdmin\user\model\Users;
use catcher\base\BaseRequest;
class UpdateRequest extends BaseRequest
{
protected function getValidate()
protected function rules(): array
{
// TODO: Implement getValidate() method.
return new UpdateValidate();
// TODO: Implement rules() method.
return [
'username|用户名' => 'require|max:20',
'password|密码' => 'sometimes|min:5|max:12',
'passwordConfirm|密码' => 'sometimes|confirm:password',
'email|邮箱' => 'require|email|unique:'.Users::class,
];
}
protected function message(): array
{
// TODO: Implement message() method.
}
}

View File

@@ -1,3 +1,8 @@
<?php
$router->resource('user', '\catchAdmin\user\controller\User');
$router->resource('user', '\catchAdmin\user\controller\User');
// 用户列表
$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');

View File

@@ -1,10 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
{$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('#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) {
layer.closeAll('loading');
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');
return false;
});
});
</script>

View File

@@ -1,10 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
</html>
{$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('#userForm'); // 列表页面传递的数据,#modelUserForm这个只要写弹窗内任意一个元素的id即可
// 回显数据
form.val('userForm', mUser);
var uid = "{$uid}";
// 表单提交事件
form.on('submit(submitUser)', function (data) {
admin.req('/user/' + uid, data.field, function (response) {
layer.closeAll('loading');
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});
}
}, 'put');
return false;
});
});
</script>

View File

@@ -3,26 +3,34 @@
{block name="search"}
<div class="layui-form toolbar">
<div class="layui-form-item">
{php}echo $form{/php}
<div class="layui-inline">
<label class="layui-form-label w-auto">&emsp;号:</label>
<div class="layui-input-inline mr0">
<input name="username" class="layui-input" type="text" placeholder="输入账号"/>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label w-auto">用户名:</label>
<div class="layui-input-inline mr0">
<input name="nickName" class="layui-input" type="text" placeholder="输入用户名"/>
<div class="layui-input-inline">
<input name="username" class="layui-input" type="text" placeholder="输入用户名"/>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label w-auto">&emsp;</label>
<label class="layui-form-label w-auto">邮箱</label>
<div class="layui-input-inline mr0">
<select name="sex">
<option value="">选择性别</option>
<option value="男"></option>
<option value="女"></option>
<input name="email" class="layui-input" type="text" placeholder="输入邮箱"/>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label w-auto">状态:</label>
<div class="layui-input-inline mr0">
<select name="status">
<option value="">选择状态</option>
<option value="1">正常</option>
<option value="2">禁用</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label w-auto">回收站:</label>
<div class="layui-input-inline mr0">
<select name="trash">
<option value="">选择</option>
<option value="1">恢复数据</option>
</select>
</div>
</div>
@@ -36,7 +44,17 @@
</div>
{/block}
{block name="table"}
<table class="layui-table" id="tableUser" lay-filter="tableUser"></table>
<table class="layui-table" id="tableUser" lay-filter="tableUser"></table>
<!-- 表格操作列 -->
<script type="text/html" id="tableBarUser">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="{{d.deleted_at ? 'recover' : 'del'}}">{{d.deleted_at ? '恢复' : '删除'}}</a>
</script>
<!-- 表格状态列 -->
<script type="text/html" id="tableStateUser">
<input type="checkbox" lay-filter="ckStateUser" value="{{d.id}}" lay-skin="switch"
lay-text="正常|禁用" {{d.status==1?'checked':''}}/>
</script>
{/block}
{block name="script"}
<script>
@@ -51,23 +69,30 @@
// 渲染表格
var insTb = table.render({
elem: '#tableUser',
url: '../../json/user.json',
url: '{:url("users")}',
page: true,
response: {
statusCode: 10000,
},
toolbar: true,
cellMinWidth: 100,
cols: [[
{type: 'numbers', title: '#'},
{field: 'username', sort: true, title: '账号'},
{field: 'nickName', sort: true, title: '用户名'},
{field: 'sex', sort: true, title: '性别'},
{type: 'id', title: '#', field: 'id'},
{field: 'username', sort: true, title: '用户名'},
{field: 'email', sort: true, title: '邮箱'},
{field: 'status', sort: true, title: '状态', templet: '#tableStateUser'},
{
field: 'createTime', sort: true, templet: function (d) {
return util.toDateString(d.createTime);
field: 'created_at', sort: true, templet: function (d) {
return util.toDateString(d.created_at);
}, title: '创建时间'
},
{field: 'state', sort: true, templet: '#tableStateUser', title: '状态'},
{
field: 'updated_at', sort: true, templet: function (d) {
return util.toDateString(d.updated_at);
}, title: '更新时间'
},
{align: 'center', toolbar: '#tableBarUser', title: '操作', minWidth: 200}
]]
]],
});
// 添加
@@ -87,39 +112,47 @@
if (layEvent === 'edit') { // 修改
showEditModel(data);
} else if (layEvent === 'del') { // 删除
doDel(data.userId, data.nickName);
doDel(data.id, data.username);
} else if (layEvent === 'reset') { // 重置密码
resetPsw(data.userId, data.nickName);
resetPsw(data.id, data.username);
} else if (layEvent === 'recover') {
recover(data.id, data.username);
}
});
function recover(uid, username) {
console.log(username)
layer.confirm('确定要恢复“' + username + '”吗?', {
skin: 'layui-layer-admin',
shade: .1
}, function (i) {
layer.close(i);
admin.req('/user/recover/'+ uid,{}, function(res){
layer.closeAll('loading');
if (res.code == 10000) {
layer.msg(res.msg, {icon: 1});
insTb.reload({}, 'data');
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'put');
});
}
// 显示表单弹窗
function showEditModel(mUser) {
admin.open({
type: 1,
var layIndex = admin.open({
title: (mUser ? '修改' : '添加') + '用户',
content: $('#modelUser').html(),
url: mUser ? '/user/'+mUser.id + '/edit':'/user/create',
data: mUser, // 传递数据到表单页面
end: function () {
if (admin.getLayerData(layIndex, 'formOk')) { // 判断表单操作成功标识
insTb.reload(); // 成功刷新表格
}
},
success: function (layero, dIndex) {
// 弹窗超出范围不出现滚动条
$(layero).children('.layui-layer-content').css('overflow', 'visible');
var url = mUser ? '../../json/ok.json' : '../../json/ok.json';
mUser && (mUser.roleId = mUser.roles[0].roleId);
// 回显数据
form.val('modelUserForm', mUser);
// 表单提交事件
form.on('submit(modelSubmitUser)', function (data) {
layer.load(2);
$.get(url, data.field, function (res) {
layer.closeAll('loading');
if (res.code == 200) {
layer.close(dIndex);
layer.msg(res.msg, {icon: 1});
insTb.reload({}, 'data');
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'json');
return false;
});
}
});
}
@@ -131,60 +164,31 @@
shade: .1
}, function (i) {
layer.close(i);
layer.load(2);
$.get('../../json/ok.json', {
userId: userId
}, function (res) {
admin.req('/user/'+ userId,{}, function(res){
layer.closeAll('loading');
if (res.code == 200) {
if (res.code == 10000) {
layer.msg(res.msg, {icon: 1});
insTb.reload({}, 'data');
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'json');
}, 'delete');
});
}
// 修改用户状态
form.on('switch(ckStateUser)', function (obj) {
layer.load(2);
$.get('../../json/ok.json', {
userId: obj.elem.value,
state: obj.elem.checked ? 0 : 1
}, function (res) {
admin.req('/user/switch/status/'+obj.value,{}, function(res){
layer.closeAll('loading');
if (res.code == 200) {
if (res.code == 10000) {
layer.msg(res.msg, {icon: 1});
} else {
layer.msg(res.msg, {icon: 2});
$(obj.elem).prop('checked', !obj.elem.checked);
form.render('checkbox');
}
}, 'json');
}, 'put');
});
// 重置密码
function resetPsw(userId, nickName) {
layer.confirm('确定要重置“' + nickName + '”的登录密码吗?', {
skin: 'layui-layer-admin',
shade: .1
}, function (i) {
layer.close(i);
layer.load(2);
$.get('../../json/ok.json', {
userId: userId
}, function (res) {
layer.closeAll('loading');
if (res.code == 200) {
layer.msg(res.msg, {icon: 1});
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'json');
});
}
});
</script>
{/block}