325 lines
7.4 KiB
Go
325 lines
7.4 KiB
Go
package user
|
|
|
|
import (
|
|
"busniess-user-center/config"
|
|
"busniess-user-center/internal/models/base"
|
|
"busniess-user-center/internal/models/role"
|
|
userModel "busniess-user-center/internal/models/user"
|
|
"busniess-user-center/internal/repo"
|
|
"busniess-user-center/pkg/redis"
|
|
contextUtil "busniess-user-center/pkg/utils/context"
|
|
stringUtil "busniess-user-center/pkg/utils/string"
|
|
"busniess-user-center/pkg/utils/token"
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/jinzhu/copier"
|
|
"github.com/samber/do"
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
const (
|
|
COOKIE_KEY_TOKEN = "token"
|
|
COOKIE_KEY_ACCOUNT = "account"
|
|
COOKIE_KEY_ID = "id"
|
|
saltLen = 8
|
|
)
|
|
|
|
func init() {
|
|
do.Provide(nil, NewUserService)
|
|
}
|
|
|
|
type userService struct {
|
|
logger *zap.SugaredLogger
|
|
repo repo.UserRepo
|
|
redis *redis.Redis
|
|
conf *config.AppConfig
|
|
tokenRefresher *token.TokenRefresher
|
|
roleRepo repo.RoleRepo
|
|
orgRepo repo.OrganizationRepo
|
|
}
|
|
|
|
func NewUserService(i *do.Injector) (UserService, error) {
|
|
return &userService{
|
|
logger: do.MustInvoke[*zap.SugaredLogger](i),
|
|
repo: do.MustInvoke[repo.UserRepo](i),
|
|
redis: do.MustInvoke[*redis.Redis](i),
|
|
conf: do.MustInvoke[*config.AppConfig](i),
|
|
tokenRefresher: do.MustInvoke[*token.TokenRefresher](i),
|
|
roleRepo: do.MustInvoke[repo.RoleRepo](i),
|
|
orgRepo: do.MustInvoke[repo.OrganizationRepo](i),
|
|
}, nil
|
|
}
|
|
|
|
func (u *userService) Add(ctx context.Context, info *userModel.AddInfo) (id uint, err error) {
|
|
session, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// 判断手机号
|
|
_, err = u.repo.GetUserByAccount(ctx, info.Account)
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return
|
|
}
|
|
|
|
if err == nil {
|
|
err = fmt.Errorf("用户%s已经存在", info.Account)
|
|
return
|
|
}
|
|
|
|
// 判断账号,手机号是否唯一
|
|
mUser, err := u.repo.GetUserByMobile(ctx, info.Mobile)
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return
|
|
}
|
|
|
|
if err == nil {
|
|
err = fmt.Errorf("手机号:%s的用户%s已经存在", info.Mobile, mUser.Account)
|
|
return
|
|
}
|
|
|
|
// 邮箱
|
|
eUser, err := u.repo.GetUserByEmail(ctx, info.Email)
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return
|
|
}
|
|
|
|
if err == nil {
|
|
err = fmt.Errorf("邮箱:%s的用户%s已经存在", info.Mobile, eUser.Account)
|
|
}
|
|
|
|
salt := stringUtil.RandStringRunes(saltLen)
|
|
pwd := u.sha256(info.Pwd, salt)
|
|
user := repo.User{
|
|
Account: info.Account,
|
|
Name: info.Name,
|
|
Mobile: info.Mobile,
|
|
Email: info.Email,
|
|
Pwd: pwd,
|
|
Sex: info.Sex,
|
|
Salt: salt,
|
|
CreatedBy: session.Account,
|
|
}
|
|
|
|
err = u.repo.CreateUser(ctx, &user)
|
|
id = user.ID
|
|
return
|
|
}
|
|
|
|
func (u *userService) Login(ctx context.Context, info userModel.LoginInfo) error {
|
|
// 通过account获取用户信息
|
|
user, err := u.repo.GetUserByAccount(ctx, info.Account)
|
|
if err == gorm.ErrRecordNotFound {
|
|
return fmt.Errorf("%s用户不存在", info.Account)
|
|
}
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
//输入的密码和加盐后sha256的值跟数据库的值比较
|
|
pwd := u.sha256(info.Pwd, user.Salt)
|
|
if user.Pwd != pwd {
|
|
return fmt.Errorf("%s密码错误", info.Account)
|
|
}
|
|
|
|
// 生成token,写入redis
|
|
claims := creteLoginTokenClaims(&user, u.conf.Jwt.Expires)
|
|
return u.setLoginStatus(ctx, user, claims)
|
|
}
|
|
|
|
func (u *userService) Logout(ctx context.Context) error {
|
|
// 获取当前用户信息
|
|
session, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 删除redis缓存
|
|
if err = u.tokenRefresher.DeleteToken(session.ID); err != nil {
|
|
return err
|
|
}
|
|
|
|
// remome cookie
|
|
u.removeCookie(ctx)
|
|
return nil
|
|
}
|
|
|
|
func (u *userService) Modify(ctx context.Context, mInfo *userModel.ModifyInfo) error {
|
|
// 获取当前操作用户
|
|
session, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 判断修改用户是否是同一个人
|
|
user, err := u.repo.GetUserByAccount(ctx, session.Account)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
user.Name = mInfo.Name
|
|
user.Sex = mInfo.Sex
|
|
return u.repo.SaveUser(ctx, user)
|
|
}
|
|
|
|
func (u *userService) Disable(ctx context.Context, req *userModel.Enable) error {
|
|
// 获取操作用户
|
|
_, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// todo 判断是否有权限
|
|
|
|
// 修改对应用户状态
|
|
return u.repo.SetUserStatus(ctx, req.Id, userModel.DisableUserStatus)
|
|
}
|
|
|
|
func (u *userService) Enable(ctx context.Context, req *userModel.Enable) error {
|
|
_, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// todo 判断是否有权限
|
|
|
|
// 修改对应用户状态
|
|
return u.repo.SetUserStatus(ctx, req.Id, userModel.EnableUserStatus)
|
|
}
|
|
|
|
func (u *userService) Search(ctx context.Context, query *base.Query) (*userModel.SearchRsp, error) {
|
|
// 获取操作用户
|
|
_, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 返回用户列表
|
|
users, err := u.repo.Search(ctx, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
total, err := u.repo.SearchCount(ctx, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rsp := &userModel.SearchRsp{
|
|
List: convertUserList(users),
|
|
Page: query.Page,
|
|
PageSize: query.PageSize,
|
|
Total: total,
|
|
}
|
|
|
|
return rsp, err
|
|
}
|
|
|
|
func (u *userService) ResetPwd(ctx context.Context, req *userModel.ResetPwdReq) error {
|
|
// 获取操作用户
|
|
session, err := contextUtil.GetSession(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 判断是否本人操作
|
|
rUser, err := u.repo.GetUserById(ctx, req.Id)
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return err
|
|
}
|
|
|
|
if err == gorm.ErrRecordNotFound {
|
|
return fmt.Errorf("重置用户不存在")
|
|
}
|
|
|
|
if session.ID != rUser.ID {
|
|
// 校验权限
|
|
return fmt.Errorf("没权限")
|
|
}
|
|
|
|
// 判断当前密码是否正确
|
|
oldPwd := u.sha256(req.OldPwd, rUser.Salt)
|
|
if oldPwd != rUser.Pwd {
|
|
return fmt.Errorf("密码错误")
|
|
}
|
|
|
|
rUser.Salt = stringUtil.RandStringRunes(saltLen)
|
|
rUser.Pwd = u.sha256(req.Pwd, rUser.Salt)
|
|
err = u.repo.ResetPwd(ctx, rUser)
|
|
if err != nil {
|
|
return fmt.Errorf("repo reset pwd fail:%s", err.Error())
|
|
}
|
|
|
|
// 生成新的密码并保存
|
|
if err = u.tokenRefresher.DeleteToken(rUser.ID); err != nil {
|
|
return fmt.Errorf("token delete fail:%s", err.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (u *userService) GetUser(ctx context.Context, req *userModel.GetUserReq) (user userModel.User, err error) {
|
|
rUser, err := u.repo.GetUserByAccount(ctx, req.Account)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// 获取组织
|
|
orgIds := make([]uint, 0)
|
|
orgs, err := u.orgRepo.GetUserOrgsById(ctx, rUser.ID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, item := range orgs {
|
|
orgIds = append(orgIds, item.ID)
|
|
}
|
|
|
|
// 获取用户角色
|
|
uRoles, err := u.roleRepo.GetUserRolesByAccount(ctx, rUser.Account)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// 获取组织角色
|
|
oRoles, err := u.roleRepo.GetOrgRolesByIDs(ctx, orgIds)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
user = convertUser(rUser)
|
|
aRoles := removeRepeatRole(uRoles, oRoles)
|
|
|
|
user.Roles = make([]role.Role, 0, len(aRoles))
|
|
copier.Copy(&user.Roles, aRoles)
|
|
|
|
return
|
|
}
|
|
|
|
func (u *userService) ExistUserByAccount(ctx context.Context, account string) (uint, error) {
|
|
user, err := u.repo.GetUserByAccount(ctx, account)
|
|
if err != nil && err != gorm.ErrRecordNotFound {
|
|
return 0, err
|
|
}
|
|
|
|
if err == gorm.ErrRecordNotFound {
|
|
return 0, nil
|
|
}
|
|
|
|
return user.ID, nil
|
|
}
|
|
|
|
func (u *userService) BatchGetUserByIDs(ctx context.Context, ids []uint) ([]userModel.UserInfo, error) {
|
|
list, err := u.repo.BatchGetUserByIDs(ctx, ids)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rList := make([]userModel.UserInfo, 0, len(list))
|
|
copier.Copy(&rList, list)
|
|
return rList, nil
|
|
}
|