Browse Source

feature(用户):
1、增加登录5次失败账号锁定功能
2、强制用户登录修改初始密码。

ZZH-wl 2 years ago
parent
commit
b71c347368

+ 81 - 75
opms_admin/app/dao/internal/sys_user.go

@@ -28,31 +28,33 @@ type SysUserDao struct {
 
 // SysUserColumns defines and stores column names for table sys_user.
 type sysUserColumns struct {
-	Id          string // 用户ID
-	DeptId      string // 部门ID
-	UserName    string // 用户账号
-	NickName    string // 用户昵称
-	UserType    string // 用户类型(00系统用户)
-	Email       string // 用户邮箱
-	Phone       string // 手机号码
-	Sex         string // 用户性别(10男20女30未知)
-	Avatar      string // 头像地址
-	Password    string // 密码
-	LoginIp     string // 最后登录IP
-	LoginDate   string // 最后登录时间
-	WechatId    string // 微信open_id
-	DingtalkId  string // 钉钉union_id
-	DingtalkUid string // 钉钉用户ID
-	Remark      string // 备注
-	CreatedBy   string // 创建者
-	CreatedName string // 创建人
-	CreatedTime string // 创建时间
-	UpdatedBy   string // 更新者
-	UpdatedName string // 更新人
-	UpdatedTime string // 更新时间
-	DeletedTime string // 删除时间
-	Status      string // 帐号状态(10正常20停用)
-	UserSalt    string // 加密盐
+	Id            string // 用户ID
+	DeptId        string // 部门ID
+	UserName      string // 用户账号
+	NickName      string // 用户昵称
+	UserType      string // 用户类型(00系统用户)
+	Email         string // 用户邮箱
+	Phone         string // 手机号码
+	Sex           string // 用户性别(10男20女30未知)
+	Avatar        string // 头像地址
+	Status        string // 帐号状态(10正常20停用)
+	UserSalt      string // 加密盐
+	Password      string // 密码
+	LoginIp       string // 最后登录IP
+	LoginDate     string // 最后登录时间
+	WechatId      string // 微信open_id
+	DingtalkId    string // 钉钉union_id
+	DingtalkUid   string // 钉钉用户ID
+	IsFirstLogin  string // 首次登录(10是20否)
+	AllowErrorNum string // 允许登录错误次数
+	Remark        string // 备注
+	CreatedBy     string // 创建者
+	CreatedName   string // 创建人
+	CreatedTime   string // 创建时间
+	UpdatedBy     string // 更新者
+	UpdatedName   string // 更新人
+	UpdatedTime   string // 更新时间
+	DeletedTime   string // 删除时间
 }
 
 var (
@@ -62,31 +64,33 @@ var (
 		DB:    g.DB("default"),
 		Table: "sys_user",
 		C: sysUserColumns{
-			Id:          "id",
-			DeptId:      "dept_id",
-			UserName:    "user_name",
-			NickName:    "nick_name",
-			UserType:    "user_type",
-			Email:       "email",
-			Phone:       "phone",
-			Sex:         "sex",
-			Avatar:      "avatar",
-			Password:    "password",
-			LoginIp:     "login_ip",
-			LoginDate:   "login_date",
-			WechatId:    "wechat_id",
-			DingtalkId:  "dingtalk_id",
-			DingtalkUid: "dingtalk_uid",
-			Remark:      "remark",
-			CreatedBy:   "created_by",
-			CreatedName: "created_name",
-			CreatedTime: "created_time",
-			UpdatedBy:   "updated_by",
-			UpdatedName: "updated_name",
-			UpdatedTime: "updated_time",
-			DeletedTime: "deleted_time",
-			Status:      "status",
-			UserSalt:    "user_salt",
+			Id:            "id",
+			DeptId:        "dept_id",
+			UserName:      "user_name",
+			NickName:      "nick_name",
+			UserType:      "user_type",
+			Email:         "email",
+			Phone:         "phone",
+			Sex:           "sex",
+			Avatar:        "avatar",
+			Status:        "status",
+			UserSalt:      "user_salt",
+			Password:      "password",
+			LoginIp:       "login_ip",
+			LoginDate:     "login_date",
+			WechatId:      "wechat_id",
+			DingtalkId:    "dingtalk_id",
+			DingtalkUid:   "dingtalk_uid",
+			IsFirstLogin:  "is_first_login",
+			AllowErrorNum: "allow_error_num",
+			Remark:        "remark",
+			CreatedBy:     "created_by",
+			CreatedName:   "created_name",
+			CreatedTime:   "created_time",
+			UpdatedBy:     "updated_by",
+			UpdatedName:   "updated_name",
+			UpdatedTime:   "updated_time",
+			DeletedTime:   "deleted_time",
 		},
 	}
 )
@@ -98,31 +102,33 @@ func NewSysUserDao(tenant string) SysUserDao {
 		DB:    g.DB(tenant),
 		Table: "sys_user",
 		C: sysUserColumns{
-			Id:          "id",
-			DeptId:      "dept_id",
-			UserName:    "user_name",
-			NickName:    "nick_name",
-			UserType:    "user_type",
-			Email:       "email",
-			Phone:       "phone",
-			Sex:         "sex",
-			Avatar:      "avatar",
-			Password:    "password",
-			LoginIp:     "login_ip",
-			LoginDate:   "login_date",
-			WechatId:    "wechat_id",
-			DingtalkId:  "dingtalk_id",
-			DingtalkUid: "dingtalk_uid",
-			Remark:      "remark",
-			CreatedBy:   "created_by",
-			CreatedName: "created_name",
-			CreatedTime: "created_time",
-			UpdatedBy:   "updated_by",
-			UpdatedName: "updated_name",
-			UpdatedTime: "updated_time",
-			DeletedTime: "deleted_time",
-			Status:      "status",
-			UserSalt:    "user_salt",
+			Id:            "id",
+			DeptId:        "dept_id",
+			UserName:      "user_name",
+			NickName:      "nick_name",
+			UserType:      "user_type",
+			Email:         "email",
+			Phone:         "phone",
+			Sex:           "sex",
+			Avatar:        "avatar",
+			Status:        "status",
+			UserSalt:      "user_salt",
+			Password:      "password",
+			LoginIp:       "login_ip",
+			LoginDate:     "login_date",
+			WechatId:      "wechat_id",
+			DingtalkId:    "dingtalk_id",
+			DingtalkUid:   "dingtalk_uid",
+			IsFirstLogin:  "is_first_login",
+			AllowErrorNum: "allow_error_num",
+			Remark:        "remark",
+			CreatedBy:     "created_by",
+			CreatedName:   "created_name",
+			CreatedTime:   "created_time",
+			UpdatedBy:     "updated_by",
+			UpdatedName:   "updated_name",
+			UpdatedTime:   "updated_time",
+			DeletedTime:   "deleted_time",
 		},
 	}
 	return dao

+ 4 - 1
opms_admin/app/handler/auth.go

@@ -48,7 +48,10 @@ func (h *AuthHandler) Login(ctx context.Context, req *user_def.LoginReq, rsp *co
 	tenant, _ := micro_srv.GetTenant(ctx)
 	tokenResp := gtoken.GFToken.GetOrGenToken(tenant, userInfo.UserName, userInfo.Uuid, userInfo)
 	rsp.Msg = tokenResp.Msg
-	rsp.Data = tokenResp.Data
+
+	tokenData := gconv.Map(tokenResp.Data)
+	tokenData["isFirstLogin"] = userInfo.IsFirstLogin
+	rsp.Data = tokenData
 	return nil
 }
 

+ 7 - 9
opms_admin/app/handler/user.go

@@ -5,7 +5,6 @@ import (
 	"dashoo.cn/opms_libary/myerrors"
 
 	"dashoo.cn/common_definition/admin/user_def"
-	"dashoo.cn/opms_libary/micro_srv"
 	"github.com/gogf/gf/util/gvalid"
 
 	"dashoo.cn/micro/app/model"
@@ -155,15 +154,18 @@ func (h *UserHandler) DeleteByIds(ctx context.Context, req *comm_def.IdsReq, rsp
 }
 
 // ResetPassword 密码重置(管理员进行操作)
-func (e *UserHandler) ResetPassword(ctx context.Context, req *model.SysUserResetPwdReq, rsp *comm_def.CommonMsg) error {
+func (e *UserHandler) ResetPassword(ctx context.Context, req *model.SysResetPwdReq, rsp *comm_def.CommonMsg) error {
 	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
 		return err
 	}
-	// todo:校验用户是否有修改权限
 	userService, err := service.NewUserService(ctx)
 	if err != nil {
 		return err
 	}
+	// todo:校验用户是否有修改权限
+	if userService.GetCxtUserId() != 1000 {
+		return myerrors.TipsError("权限不足")
+	}
 	err = userService.ResetUserPwd(req)
 	if err != nil {
 		return err
@@ -381,7 +383,7 @@ func (e *UserHandler) GetUserByRole(ctx context.Context, req *model.SysUserRoleR
 //}
 
 // ChangePassword 用户修改密码
-func (e *UserHandler) ChangePassword(ctx context.Context, req *user_def.PWDReq, rsp *comm_def.CommonMsg) error {
+func (e *UserHandler) ChangePassword(ctx context.Context, req *model.SysUserResetPwdReq, rsp *comm_def.CommonMsg) error {
 	if err := gvalid.CheckStruct(ctx, req, nil); err != nil {
 		return err
 	}
@@ -389,12 +391,8 @@ func (e *UserHandler) ChangePassword(ctx context.Context, req *user_def.PWDReq,
 	if err != nil {
 		return err
 	}
-	userInfo, err := micro_srv.GetUserInfo(ctx)
-	if err != nil {
-		return err
-	}
 	err = userService.ProfileUpdatePwd(&model.ProfileUpdatePwdReq{
-		UserId:      userInfo.Id,
+		UserId:      userService.GetCxtUserId(),
 		OldPassword: req.OldPassword,
 		NewPassword: req.NewPassword,
 	})

+ 27 - 25
opms_admin/app/model/internal/sys_user.go

@@ -10,29 +10,31 @@ import (
 
 // SysUser is the golang structure for table sys_user.
 type SysUser struct {
-	Id          int         `orm:"id,primary"   json:"id"`          // 用户ID
-	DeptId      int         `orm:"dept_id"      json:"deptId"`      // 部门ID
-	UserName    string      `orm:"user_name"    json:"userName"`    // 用户账号
-	NickName    string      `orm:"nick_name"    json:"nickName"`    // 用户昵称
-	UserType    string      `orm:"user_type"    json:"userType"`    // 用户类型(00系统用户)
-	Email       string      `orm:"email"        json:"email"`       // 用户邮箱
-	Phone       string      `orm:"phone"        json:"phone"`       // 手机号码
-	Sex         string      `orm:"sex"          json:"sex"`         // 用户性别(10男20女30未知)
-	Avatar      string      `orm:"avatar"       json:"avatar"`      // 头像地址
-	Password    string      `orm:"password"     json:"password"`    // 密码
-	LoginIp     string      `orm:"login_ip"     json:"loginIp"`     // 最后登录IP
-	LoginDate   *gtime.Time `orm:"login_date"   json:"loginDate"`   // 最后登录时间
-	WechatId    string      `orm:"wechat_id"    json:"wechatId"`    // 微信open_id
-	DingtalkId  string      `orm:"dingtalk_id"  json:"dingtalkId"`  // 钉钉union_id
-	DingtalkUid string      `orm:"dingtalk_uid" json:"dingtalkUid"` // 钉钉用户ID
-	Remark      string      `orm:"remark"       json:"remark"`      // 备注
-	CreatedBy   int         `orm:"created_by"   json:"createdBy"`   // 创建者
-	CreatedName string      `orm:"created_name" json:"createdName"` // 创建人
-	CreatedTime *gtime.Time `orm:"created_time" json:"createdTime"` // 创建时间
-	UpdatedBy   int         `orm:"updated_by"   json:"updatedBy"`   // 更新者
-	UpdatedName string      `orm:"updated_name" json:"updatedName"` // 更新人
-	UpdatedTime *gtime.Time `orm:"updated_time" json:"updatedTime"` // 更新时间
-	DeletedTime *gtime.Time `orm:"deleted_time" json:"deletedTime"` // 删除时间
-	Status      string      `orm:"status"       json:"status"`      // 帐号状态(10正常20停用)
-	UserSalt    string      `orm:"user_salt"    json:"userSalt"`    // 加密盐
+	Id            int         `orm:"id,primary"      json:"id"`            // 用户ID
+	DeptId        int         `orm:"dept_id"         json:"deptId"`        // 部门ID
+	UserName      string      `orm:"user_name"       json:"userName"`      // 用户账号
+	NickName      string      `orm:"nick_name"       json:"nickName"`      // 用户昵称
+	UserType      string      `orm:"user_type"       json:"userType"`      // 用户类型(00系统用户)
+	Email         string      `orm:"email"           json:"email"`         // 用户邮箱
+	Phone         string      `orm:"phone"           json:"phone"`         // 手机号码
+	Sex           string      `orm:"sex"             json:"sex"`           // 用户性别(10男20女30未知)
+	Avatar        string      `orm:"avatar"          json:"avatar"`        // 头像地址
+	Status        string      `orm:"status"          json:"status"`        // 帐号状态(10正常20停用)
+	UserSalt      string      `orm:"user_salt"       json:"userSalt"`      // 加密盐
+	Password      string      `orm:"password"        json:"password"`      // 密码
+	LoginIp       string      `orm:"login_ip"        json:"loginIp"`       // 最后登录IP
+	LoginDate     *gtime.Time `orm:"login_date"      json:"loginDate"`     // 最后登录时间
+	WechatId      string      `orm:"wechat_id"       json:"wechatId"`      // 微信open_id
+	DingtalkId    string      `orm:"dingtalk_id"     json:"dingtalkId"`    // 钉钉union_id
+	DingtalkUid   string      `orm:"dingtalk_uid"    json:"dingtalkUid"`   // 钉钉用户ID
+	IsFirstLogin  string      `orm:"is_first_login"  json:"isFirstLogin"`  // 首次登录(10是20否)
+	AllowErrorNum int         `orm:"allow_error_num" json:"allowErrorNum"` // 允许登录错误次数
+	Remark        string      `orm:"remark"          json:"remark"`        // 备注
+	CreatedBy     int         `orm:"created_by"      json:"createdBy"`     // 创建者
+	CreatedName   string      `orm:"created_name"    json:"createdName"`   // 创建人
+	CreatedTime   *gtime.Time `orm:"created_time"    json:"createdTime"`   // 创建时间
+	UpdatedBy     int         `orm:"updated_by"      json:"updatedBy"`     // 更新者
+	UpdatedName   string      `orm:"updated_name"    json:"updatedName"`   // 更新人
+	UpdatedTime   *gtime.Time `orm:"updated_time"    json:"updatedTime"`   // 更新时间
+	DeletedTime   *gtime.Time `orm:"deleted_time"    json:"deletedTime"`   // 删除时间
 }

+ 9 - 3
opms_admin/app/model/sys_user.go

@@ -92,10 +92,16 @@ type SysUserRoleDeptRes struct {
 	} `json:"post"`
 }
 
-// SysUserResetPwdReq 重置用户密码状态参数
+// SysResetPwdReq 系统重置用户密码状态参数
+type SysResetPwdReq struct {
+	Id       int    `p:"id" v:"required#用户id不能为空"`
+	Password string `p:"password" v:"required|password#密码不能为空|密码需要以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+}
+
+// SysUserResetPwdReq 用户重置密码状态参数
 type SysUserResetPwdReq struct {
-	Id       int    `p:"userId" v:"required#用户id不能为空"`
-	Password string `p:"password" v:"required|password#密码不能为空|密码以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
+	OldPassword string `json:"oldPassword" v:"required|password#旧密码不能为空|旧密码需要只能包含字母、数字和下划线,长度在6~18之间"`
+	NewPassword string `json:"newPassword" v:"required|passport#新密码不能为空|新密码需要以字母开头,只能包含字母、数字和下划线,长度在6~18之间"`
 }
 
 // SysUserStatusReq 设置用户状态参数

+ 11 - 11
opms_admin/app/service/sys_dept.go

@@ -142,12 +142,12 @@ func (s *DeptService) Create(req *model.SysDeptReq) (err error) {
 	SetCreatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
 
 	//开启事务管理
-	err = dao.SysDept.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) (err error) {
+	err = s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) (err error) {
 		lastId, err := s.Dao.Ctx(ctx).Data(data).InsertAndGetId()
 		if err != nil {
 			return err
 		}
-		err = setAncestors(ctx, req.ParentId, lastId)
+		err = s.setAncestors(ctx, req.ParentId, lastId)
 		return err
 	})
 	return
@@ -166,24 +166,24 @@ func (s *DeptService) UpdateById(req *model.UpdateSysDeptReq) error {
 	data.Ancestors = dept.Ancestors + "," + gconv.String(dept.Id)
 	SetUpdatedInfo(data, s.GetCxtUserId(), s.GetCxtUserName())
 	//开启事务管理
-	err = dao.SysDept.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) (err error) {
+	err = s.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) (err error) {
 		_, err = s.Dao.Ctx(ctx).FieldsEx(UpdateFieldEx...).Data(data).WherePri(data.Id).Update()
 		if err != nil {
 			return myerrors.TipsError("修改失败")
 		}
 		//修改祖籍字段
 		if dept.ParentId != req.ParentId {
-			err := setAncestors(ctx, req.ParentId, req.Id)
+			err := s.setAncestors(ctx, req.ParentId, req.Id)
 			if err != nil {
 				return err
 			}
 			lId := strconv.FormatInt(req.Id, 10)
-			value, _ := dao.SysDept.Ctx(ctx).Fields(dao.SysDept.C.Ancestors).WhereLike(dao.SysDept.C.Ancestors, "%"+lId+"%").Array()
+			value, _ := s.Dao.Ctx(ctx).Fields(dao.SysDept.C.Ancestors).WhereLike(dao.SysDept.C.Ancestors, "%"+lId+"%").Array()
 			if req.ParentId == -1 {
 				for _, v := range value {
 					newAncestors := strings.Replace(v.String(), dept.Ancestors, lId, -1)
 					//修改相关祖籍字段
-					_, err := dao.SysDept.Ctx(ctx).
+					_, err := s.Dao.Ctx(ctx).
 						Data(dao.SysDept.C.Ancestors, newAncestors).
 						Where(dao.SysDept.C.Ancestors, v.String()).Update()
 					if err != nil {
@@ -197,7 +197,7 @@ func (s *DeptService) UpdateById(req *model.UpdateSysDeptReq) error {
 					newAncestors := strings.Replace(dept.Ancestors, lId, "", -1)
 					newAncestor := newAncestors + v.String()
 					//修改相关祖籍字段
-					_, err := dao.SysDept.Ctx(ctx).
+					_, err := s.Dao.Ctx(ctx).
 						Data(dao.SysDept.C.Ancestors, newAncestor).
 						Where(dao.SysDept.C.Ancestors, v.String()).
 						WhereNot(dao.SysDept.C.Id, req.Id).
@@ -224,22 +224,22 @@ func (s *DeptService) DeleteByIds(id int) error {
 }
 
 // 修改祖籍字段
-func setAncestors(ctx context.Context, ParentId int, lastId int64) (err error) {
+func (s *DeptService) setAncestors(ctx context.Context, ParentId int, lastId int64) (err error) {
 	lId := strconv.FormatInt(lastId, 10)
 	if ParentId == -1 { //根级别,修改祖籍为自己
-		_, err := dao.SysDept.Ctx(ctx).Data(dao.SysDept.C.Ancestors, lId).WherePri(lastId).Update()
+		_, err := s.Dao.Ctx(ctx).Data(dao.SysDept.C.Ancestors, lId).WherePri(lastId).Update()
 		if err != nil {
 			g.Log().Error(err)
 			return myerrors.TipsError("祖籍修改失败")
 		}
 	} else {
 		var oldDept *model.SysDept
-		err = dao.SysDept.Ctx(ctx).WherePri(ParentId).Scan(&oldDept)
+		err = s.Dao.Ctx(ctx).WherePri(ParentId).Scan(&oldDept)
 		if err != nil {
 			g.Log().Error(err)
 			return myerrors.TipsError("查询祖籍失败")
 		}
-		_, err := dao.SysDept.Ctx(ctx).Data(dao.SysDept.C.Ancestors, oldDept.Ancestors+","+lId).WherePri(lastId).Update()
+		_, err := s.Dao.Ctx(ctx).Data(dao.SysDept.C.Ancestors, oldDept.Ancestors+","+lId).WherePri(lastId).Update()
 		if err != nil {
 			g.Log().Error(err)
 			return myerrors.TipsError("祖籍修改失败")

+ 1 - 1
opms_admin/app/service/sys_role.go

@@ -41,7 +41,7 @@ func (s *RoleService) GetRoleList() (list []*model.SysRole, err error) {
 }
 
 func (s *RoleService) GetRoleListSearch(req *model.SelectPageReq) (total int, list []*model.SysRole, err error) {
-	db := dao.SysRole.M
+	db := s.Dao.M
 	if req.RoleName != "" {
 		db = db.Where("role_name like ?", "%"+req.RoleName+"%")
 	}

+ 39 - 19
opms_admin/app/service/sys_user.go

@@ -31,34 +31,36 @@ func NewUserService(ctx context.Context) (svc *UserService, err error) {
 		return nil, err
 	}
 	svc.Dao = dao.NewSysUserDao(svc.Tenant)
-	//svc.userRoleDao = dao.NewSysUserRoleDao(svc.Tenant)
-	//svc.userPostDao = dao.NewSysUserPostDao(svc.Tenant)
-	//svc.userGroupDao = dao.NewSysUserGroupDao(svc.Tenant)
+	svc.userRoleDao = dao.NewSysUserRoleDao(svc.Tenant)
+	svc.userPostDao = dao.NewSysUserPostDao(svc.Tenant)
+	svc.userGroupDao = dao.NewSysUserGroupDao(svc.Tenant)
 	return svc, nil
 }
 
 // Login 用户登录,成功返回用户UUID,否则返回空字符串;
 func (s *UserService) Login(username, password string) (*request.UserInfo, error) {
-	record, err := s.Dao.Where("user_name", username).Where("status='10'").FindOne()
+	sysUserInfo, err := s.Dao.Where(s.Dao.C.UserName, username).Where(s.Dao.C.Status, "10").WhereGT(s.Dao.C.AllowErrorNum, 0).FindOne()
 	if err != nil {
 		return nil, myerrors.TipsError("系统异常")
 	}
-	if record == nil {
-		return nil, myerrors.TipsError("账号或密码错误,或限制登录")
+	if sysUserInfo == nil {
+		return nil, myerrors.TipsError("账号或密码错误,或限制登录")
 	}
 	// 验证密码
-	if utils.EncryptPassword(password, record.UserSalt) != record.Password {
+	if utils.EncryptPassword(password, sysUserInfo.UserSalt) != sysUserInfo.Password {
+		s.Dao.WherePri(sysUserInfo.Id).Decrement(s.Dao.C.AllowErrorNum, 1)
 		return nil, myerrors.TipsError("账号密码错误")
 	}
 	//账号状态
-	if record.Status == "20" {
+	if sysUserInfo.Status == "20" {
 		return nil, myerrors.TipsError("账号已被冻结")
 	}
 
 	userInfo := new(request.UserInfo)
-	if err = gconv.Struct(record, userInfo); err != nil {
+	if err = gconv.Struct(sysUserInfo, userInfo); err != nil {
 		return nil, err
 	}
+	userInfo.IsFirstLogin = sysUserInfo.IsFirstLogin == "10"
 	// 权限
 	userInfo.Roles, userInfo.Posts, userInfo.Groups, err = s.GetUserPermission(userInfo.Id)
 	if err != nil {
@@ -71,6 +73,15 @@ func (s *UserService) Login(username, password string) (*request.UserInfo, error
 		g.Log().Error(err)
 		return nil, myerrors.TipsError("获取用户数据权限失败")
 	}
+
+	// 更新允许登录错误次数和是否首次登录
+	if sysUserInfo.AllowErrorNum != 5 {
+		data := g.Map{
+			s.Dao.C.AllowErrorNum: 5,
+		}
+		s.Dao.WherePri(sysUserInfo.Id).Data(data).Update()
+	}
+
 	return userInfo, nil
 }
 
@@ -279,9 +290,10 @@ func (s *UserService) CreateUser(req *model.AddUserReq) (err error) {
 		tx.Rollback()
 		return
 	}
+	userData.IsFirstLogin = "10"
+	userData.AllowErrorNum = 5
 	userData.UserSalt = grand.S(10)
 	userData.Password = utils.EncryptPassword(userData.Password, userData.UserSalt)
-	g.Log("xxxxpassword", userData.Password)
 	SetCreatedInfo(userData, s.GetCxtUserId(), s.GetCxtUserName())
 	res, err := Model.Insert(userData)
 	if err != nil {
@@ -449,15 +461,17 @@ func (s *UserService) UpdateUser(req *model.EditUserReq) (err error) {
 }
 
 // ResetUserPwd 重置用户密码
-func (s *UserService) ResetUserPwd(req *model.SysUserResetPwdReq) error {
+func (s *UserService) ResetUserPwd(req *model.SysResetPwdReq) error {
 	salt := grand.S(10)
 	password := utils.EncryptPassword(req.Password, salt)
 	data := g.Map{
-		s.Dao.C.UserSalt: salt,
-		s.Dao.C.Password: password,
+		s.Dao.C.UserSalt:      salt,
+		s.Dao.C.Password:      password,
+		s.Dao.C.IsFirstLogin:  "10",
+		s.Dao.C.AllowErrorNum: 5,
 	}
 	SetCurrentUpdatedInfo(data, s.CxtUser)
-	_, err := s.Dao.WherePri(req.Id).Update()
+	_, err := s.Dao.WherePri(req.Id).Data(data).Update()
 	return err
 }
 
@@ -466,7 +480,7 @@ func (s *UserService) ChangeUserStatus(req *model.SysUserStatusReq) error {
 		s.Dao.C.Status: req.UserStatus,
 	}
 	SetCurrentUpdatedInfo(data, s.CxtUser)
-	_, err := s.Dao.WherePri(req.Id).Update()
+	_, err := s.Dao.WherePri(req.Id).Data(data).Update()
 	return err
 }
 
@@ -475,7 +489,7 @@ func (s *UserService) DeleteUserByIds(ctx context.Context, ids []int64) error {
 	return g.DB().Transaction(ctx, func(ctx context.Context, tx *gdb.TX) error {
 		_, err := s.Dao.Ctx(ctx).TX(tx).Where(s.Dao.C.Id+" in(?)", ids).Delete()
 		//删除用户对应的岗位
-		_, err = dao.SysUserPost.Ctx(ctx).TX(tx).Delete(dao.SysUserPost.C.UserId+" in (?)", ids)
+		//_, err = dao.SysUserPost.Ctx(ctx).TX(tx).Delete(dao.SysUserPost.C.UserId+" in (?)", ids)
 		return err
 	})
 }
@@ -502,14 +516,20 @@ func (s *UserService) ProfileUpdatePwd(req *model.ProfileUpdatePwdReq) error {
 	}
 	oldPassword := utils.EncryptPassword(req.OldPassword, userInfo.UserSalt)
 	if oldPassword != userInfo.Password {
-		return errors.New("原始密码错误!")
+		return myerrors.TipsError("原始密码错误!")
 	}
 	salt := grand.S(10)
 	newPassword := utils.EncryptPassword(req.NewPassword, salt)
 	data := g.Map{
-		s.Dao.C.UserSalt: salt,
-		s.Dao.C.Password: newPassword,
+		s.Dao.C.UserSalt:      salt,
+		s.Dao.C.Password:      newPassword,
+		s.Dao.C.AllowErrorNum: 5,
+	}
+	// 更新是否首次登录
+	if userInfo.IsFirstLogin == "10" {
+		data[s.Dao.C.IsFirstLogin] = "20"
 	}
+
 	SetCurrentUpdatedInfo(data, s.CxtUser)
 	_, err = s.Dao.WherePri(req.UserId).Unscoped().Update(data)
 	return err

+ 13 - 12
opms_libary/request/request.go

@@ -30,18 +30,19 @@ func (p *PageReq) GetPage() (int, int) {
 
 // UserInfo 登录用户信息
 type UserInfo struct {
-	Id          int      `json:"id"`
-	Uuid        string   `json:"uuid"`
-	UserName    string   `json:"userName"`
-	NickName    string   `json:"nickName"`
-	WechatId    string   `json:"wechatId"`
-	DingtalkId  string   `json:"dingtalkId"`
-	DingtalkUid string   `json:"dingtalkUid"`
-	DeptId      int      `json:"deptId"`    // 所属部门
-	Roles       []string `json:"roles"`     // 所属角色
-	Posts       []string `json:"posts"`     // 所属岗位
-	Groups      []string `json:"groups"`    // 所属用户组
-	DataScope   g.Map    `json:"dataScope"` // 数据权限
+	Id           int      `json:"id"`
+	Uuid         string   `json:"uuid"`
+	UserName     string   `json:"userName"`
+	NickName     string   `json:"nickName"`
+	WechatId     string   `json:"wechatId"`
+	DingtalkId   string   `json:"dingtalkId"`
+	DingtalkUid  string   `json:"dingtalkUid"`
+	DeptId       int      `json:"deptId"`       // 所属部门
+	Roles        []string `json:"roles"`        // 所属角色
+	Posts        []string `json:"posts"`        // 所属岗位
+	Groups       []string `json:"groups"`       // 所属用户组
+	DataScope    g.Map    `json:"dataScope"`    // 数据权限
+	IsFirstLogin bool     `json:"isFirstLogin"` // 是否首次登录
 }
 
 // 设置当前登录用户信息