busniess-user-center/internal/service/user/user.go

341 lines
8.0 KiB
Go

package user
import (
"busniess-user-center/config"
appModel "busniess-user-center/internal/models/application"
"busniess-user-center/internal/models/base"
orgModel "busniess-user-center/internal/models/organization"
"busniess-user-center/internal/models/role"
userModel "busniess-user-center/internal/models/user"
"busniess-user-center/internal/repo"
"busniess-user-center/internal/service/application"
"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
appService application.ApplicationService
}
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),
appService: do.MustInvoke[application.ApplicationService](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)
user.Orgs = make([]orgModel.Organization, 0, len(orgs))
copier.Copy(&user.Orgs, orgs)
appInfo, err := u.appService.GetApp(ctx, &appModel.GetAppReq{Code: req.AppCode})
if err != nil {
return
}
user.Menus = appInfo.Menus
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
}