1、实现管理员编辑用户信息

2、禁止管理员更改自己的权限和状态
This commit is contained in:
Minho 2017-05-25 18:18:43 +08:00
parent 36708f3171
commit 89b59ab1e1
8 changed files with 284 additions and 4 deletions

View File

@ -57,6 +57,9 @@ func (c *AccountController) Login() {
//如果没有数据
if err == nil {
member.LastLoginTime = time.Now()
member.Update()
c.SetMember(*member)
if strings.EqualFold(is_remember,"yes") {
remember.MemberId = member.MemberId
@ -68,6 +71,7 @@ func (c *AccountController) Login() {
}
}
c.JsonResult(0,"ok")
}else{
logs.Error("用户登录 =>",err)

View File

@ -18,6 +18,14 @@ type ManagerController struct {
BaseController
}
func (c *ManagerController) Prepare (){
c.BaseController.Prepare()
if !c.Member.IsAdministrator() {
c.Abort("403")
}
}
func (c *ManagerController) Index() {
c.TplName = "manager/index.tpl"
if !c.Member.IsAdministrator() {
@ -141,6 +149,9 @@ func (c *ManagerController) UpdateMemberStatus() {
if _, err := member.Find(member_id); err != nil {
c.JsonResult(6002, "用户不存在")
}
if member.MemberId == c.Member.MemberId {
c.JsonResult(6004,"不能变更自己的状态")
}
member.Status = status
if err := member.Update(); err != nil {
@ -171,6 +182,9 @@ func (c *ManagerController) ChangeMemberRole() {
if _, err := member.Find(member_id); err != nil {
c.JsonResult(6002, "用户不存在")
}
if member.MemberId == c.Member.MemberId {
c.JsonResult(6004,"不能变更自己的权限")
}
member.Role = role
if err := member.Update(); err != nil {
@ -181,6 +195,60 @@ func (c *ManagerController) ChangeMemberRole() {
c.JsonResult(0, "ok", member)
}
func (c *ManagerController) EditMember() {
c.Prepare()
c.TplName = "manager/edit_users.tpl"
if !c.Member.IsAdministrator() {
c.Abort("403")
}
member_id,_ := c.GetInt(":id",0)
if member_id <= 0 {
c.Abort("404")
}
member ,err := models.NewMember().Find(member_id)
if err != nil {
beego.Error(err)
c.Abort("404")
}
if c.Ctx.Input.IsPost() {
password1 := c.GetString("password1")
password2 := c.GetString("password2")
email := c.GetString("email")
phone := c.GetString("phone")
description := c.GetString("description")
member.Email = email
member.Phone = phone
member.Description = description
if password1 != "" && password2 != password1 {
c.JsonResult(6001,"确认密码不正确")
}
if password1 != "" {
member.Password = password1
}
if err := member.Valid(password1 == "");err != nil {
c.JsonResult(6002,err.Error())
}
if password1 != "" {
password,err := utils.PasswordHash(password1)
if err != nil {
beego.Error(err)
c.JsonResult(6003,"对用户密码加密时出错")
}
member.Password = password
}
if err := member.Update();err != nil {
beego.Error(err)
c.JsonResult(6004,"保存失败")
}
c.JsonResult(0,"ok")
}
c.Data["Model"] = member
}
func (c *ManagerController) Books() {
c.Prepare()
c.TplName = "manager/books.tpl"
@ -207,6 +275,9 @@ func (c *ManagerController) Books() {
//编辑项目
func (c *ManagerController) EditBook() {
c.TplName = "manager/edit_book.tpl"
if !c.Member.IsAdministrator() {
c.Abort("403")
}
identify := c.GetString(":key")
if identify == "" {

View File

@ -6,7 +6,14 @@ import "errors"
var (
// ErrMemberNoExist 用户不存在.
ErrMemberNoExist = errors.New("用户不存在")
ErrMemberExist = errors.New("用户已存在")
ErrMemberDisabled = errors.New("用户被禁用")
ErrMemberEmailEmpty = errors.New("用户邮箱不能为空")
ErrMemberEmailExist = errors.New("用户邮箱已被使用")
ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字")
ErrMemberEmailFormatError = errors.New("邮箱格式不正确")
ErrMemberPasswordFormatError = errors.New("密码必须在6-50个字符之间")
ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成且在3-50个字符")
// ErrorMemberPasswordError 密码错误.
ErrorMemberPasswordError = errors.New("用户密码错误")
//ErrorMemberAuthMethodInvalid 不支持此认证方式

View File

@ -22,7 +22,7 @@ type Member struct {
Account string `orm:"size(100);unique;column(account)" json:"account"`
Password string `orm:"size(1000);column(password)" json:"-"`
//认证方式: local 本地数据库 /ldap LDAP
AuthMethod string `orm:"column(auth_method);default(local);size(50);" json:"auth_method)"`
AuthMethod string `orm:"column(auth_method);default(local);size(50);" json:"auth_method"`
Description string `orm:"column(description);size(2000)" json:"description"`
Email string `orm:"size(100);column(email);unique" json:"email"`
Phone string `orm:"size(255);column(phone);null;default(null)" json:"phone"`
@ -73,6 +73,7 @@ func (m *Member) Login(account string, password string) (*Member, error) {
}
switch member.AuthMethod {
case "":
case "local":
ok, err := utils.PasswordVerify(member.Password, password)
if ok && err == nil {
@ -169,7 +170,9 @@ func (m *Member) Add() error {
}
m.Password = hash
if m.AuthMethod == "" {
m.AuthMethod = "local"
}
_, err = o.Insert(m)
if err != nil {
@ -263,3 +266,66 @@ func (m *Member) FindByFieldFirst(field string, value interface{}) (*Member, err
return m, err
}
func (m *Member) Valid(is_hash_password bool) error {
//邮箱不能为空
if m.Email == "" {
return ErrMemberEmailEmpty
}
//用户描述必须小于500字
if strings.Count(m.Description,"") > 500 {
return ErrMemberDescriptionTooLong
}
//邮箱格式校验
if ok,err := regexp.MatchString(conf.RegexpEmail,m.Email); !ok || err != nil || m.Email == "" {
return ErrMemberEmailFormatError
}
//如果是未加密密码,需要校验密码格式
if !is_hash_password {
if l := strings.Count(m.Password,"") ; m.Password == "" || l > 50 || l < 6{
return ErrMemberPasswordFormatError
}
}
//校验邮箱是否呗使用
if member,err := NewMember().FindByFieldFirst("email",m.Account); err == nil && member.MemberId > 0 {
if m.MemberId > 0 && m.MemberId != member.MemberId {
return ErrMemberEmailExist
}
if m.MemberId <= 0{
return ErrMemberEmailExist
}
}
if m.MemberId > 0{
//校验用户是否存在
if _,err := NewMember().Find(m.MemberId);err != nil {
return err
}
}else{
//校验账号格式是否正确
if ok,err := regexp.MatchString(conf.RegexpAccount,m.Account); m.Account == "" || !ok || err != nil {
return ErrMemberAccountFormatError
}
//校验账号是否被使用
if member,err := NewMember().FindByAccount(m.Account); err == nil && member.MemberId > 0 {
return ErrMemberExist
}
}
return nil
}

View File

@ -17,6 +17,7 @@ func init() {
beego.Router("/manager", &controllers.ManagerController{},"*:Index")
beego.Router("/manager/users", &controllers.ManagerController{},"*:Users")
beego.Router("/manager/users/edit/:id", &controllers.ManagerController{},"*:EditMember")
beego.Router("/manager/member/create", &controllers.ManagerController{},"post:CreateMember")
beego.Router("/manager/member/update-member-status",&controllers.ManagerController{},"post:UpdateMemberStatus")
beego.Router("/manager/member/change-member-role", &controllers.ManagerController{},"post:ChangeMemberRole")

View File

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>编辑用户 - Powered by MinDoc</title>
<!-- Bootstrap -->
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
<link href="/static/css/main.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="/static/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="/static/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="manual-reader">
{{template "widgets/header.tpl" .}}
<div class="container manual-body">
<div class="row">
<div class="page-left">
<ul class="menu">
<li><a href="{{urlfor "ManagerController.Index"}}" class="item"><i class="fa fa-dashboard" aria-hidden="true"></i> 仪表盘</a> </li>
<li class="active"><a href="{{urlfor "ManagerController.Users" }}" class="item"><i class="fa fa-users" aria-hidden="true"></i> 用户管理</a> </li>
<li><a href="{{urlfor "ManagerController.Books" }}" class="item"><i class="fa fa-book" aria-hidden="true"></i> 项目管理</a> </li>
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
</ul>
</div>
<div class="page-right">
<div class="m-box">
<div class="box-head">
<strong class="box-title"> 编辑用户</strong>
</div>
</div>
<div class="box-body col-lg-6 col-sm-12">
<form method="post" id="saveMemberInfoForm">
<div class="form-group">
<label>用户账号</label>
<input type="text" class="form-control" name="account" disabled placeholder="用户账号" value="{{.Model.Account}}">
</div>
<div class="form-group">
<label>用户密码</label>
<input type="password" class="form-control" name="password1" placeholder="用户密码" maxlength="50">
<p style="color: #999;font-size: 12px;">不修改密码请留空</p>
</div>
<div class="form-group">
<label>确认密码</label>
<input type="password" class="form-control" name="password2" placeholder="确认密码" maxlength="50">
</div>
<div class="form-group">
<label>用户邮箱 <strong class="text-danger">*</strong></label>
<input type="email" class="form-control" name="email" placeholder="用户邮箱" value="{{.Model.Email}}" maxlength="50">
</div>
<div class="form-group">
<label>手机号码</label>
<input type="text" class="form-control" name="phone" placeholder="手机号码" maxlength="50" value="{{.Model.Phone}}">
</div>
<div class="form-group">
<label class="description">描述</label>
<textarea class="form-control" rows="3" title="描述" name="description" id="description" maxlength="500" >{{.Model.Description}}</textarea>
<p style="color: #999;font-size: 12px;">描述不能超过500字</p>
</div>
<div class="form-group">
<button type="submit" id="btnMemberInfo" class="btn btn-success" data-loading-text="保存中...">保存修改</button>
<span id="form-error-message" class="error-message"></span>
</div>
</form>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
{{template "widgets/footer.tpl" .}}
</div>
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
<script src="/static/js/main.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#saveMemberInfoForm").ajaxForm({
beforeSubmit : function () {
var $then = $("#saveMemberInfoForm");
var email = $.trim($then.find("input[name='email']").val());
var password1 = $.trim($then.find("input[name='password1']").val());
var password2 = $.trim($then.find("input[name='password2']").val());
if (email === ""){
return showError("用户邮箱不能为空!");
}
if (password1 !== "" && password1 !== password2){
return showError("确认密码不正确!");
}
$("#btnMemberInfo").button("loading");
},success : function (res) {
if(res.errcode === 0) {
showSuccess("保存成功")
}else{
showError(res.message);
}
$("#btnMemberInfo").button("reset");
}
});
});
</script>
</body>
</html>

View File

@ -56,6 +56,7 @@
<th width="80">头像</th>
<th>账号</th>
<th>角色</th>
<th>类型</th>
<th>状态</th>
<th>操作</th>
</tr>
@ -69,6 +70,9 @@
<template v-if="item.role == 0">
超级管理员
</template>
<template v-else-if="item.member_id == {{.Member.MemberId}}">
${item.role_name}
</template>
<template v-else>
<div class="btn-group">
<button type="button" class="btn btn-default btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@ -81,6 +85,9 @@
</div>
</template>
</td>
<td>
${item.auth_method}
</td>
<td>
<template v-if="item.status == 0">
<span class="label label-success">正常</span>
@ -89,8 +96,15 @@
<span class="label label-danger">禁用</span>
</template>
</td>
<td>
<template v-if="item.role != 0">
<template v-if="item.member_id == {{.Member.MemberId}}">
</template>
<template v-else-if="item.role != 0">
<a :href="'{{urlfor "ManagerController.EditMember" ":id" ""}}' + item.member_id" class="btn btn-sm btn-default" @click="editMember(item.member_id)">
编辑
</a>
<template v-if="item.status == 0">
<button type="button" class="btn btn-danger btn-sm" @click="setMemberStatus(item.member_id,1,$event)" data-loading-text="启用中...">禁用</button>
</template>

View File

@ -62,7 +62,7 @@
<li>
<a href="{{urlfor "BookController.Index"}}" title="我的项目"><i class="fa fa-book" aria-hidden="true"></i> 我的项目</a>
</li>
{{if eq .Member.Role 0 }}
{{if eq .Member.Role 0 1}}
<li>
<a href="{{urlfor "ManagerController.Index"}}" title="管理后台"><i class="fa fa-university" aria-hidden="true"></i> 管理后台</a>
</li>