yintai2/app/admin/service/user.go

264 lines
5.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"fmt"
"strings"
"time"
"yintai-api/app/admin/request"
"yintai-api/app/common/cache"
"yintai-api/app/common/dao"
err2 "yintai-api/app/common/err"
"yintai-api/app/common/model"
"yintai-api/base/global"
"github.com/smbrave/goutil"
"github.com/spf13/cast"
"gorm.io/gorm"
)
type User struct {
user *model.UserWithRole
}
func NewUser(u *model.UserWithRole) *User {
return &User{user: u}
}
func (a *User) Create(req request.UserCreate) int64 {
// 通过 account 判断用户是否存在
exist, err := dao.NewUser().AccountExists(req.Account)
if err != nil {
err2.DbErr("<admin service create>", err)
}
if exist {
err2.EsxErr()
}
req.Password = strings.TrimSpace(req.Password)
if len(req.Password) < 1 {
err2.ParamErr("<admin service create>: password too short")
}
if cast.ToInt64(req.Role) != 0 {
// 检查 role 是否存在
exist, err = dao.NewRole().Exists(cast.ToInt64(req.Role))
if err != nil {
err2.DbErr("<admin service create>", err)
}
if !exist {
err2.NotEsxErr("<admin service create> check role")
}
}
// 通过事务来创建账号以及分配用户角色
m := new(model.User)
m.Username = req.Username
m.Account = req.Account
m.Password = goutil.Md5(req.Password + model.Salt)
m.CreateTime = time.Now().Unix()
m.Status = model.UserStatusNormal
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewUser(tx).Create(m); err != nil {
return err
}
if cast.ToInt64(req.Role) != 0 {
var role *model.Role
// 获取这个角色的页面和路由的所有权限
role, err = dao.NewRole(tx).Get(cast.ToInt64(req.Role))
if err != nil {
return err
}
m := new(model.UserRole)
m.UserID = cast.ToInt64(role.ID)
m.RoleID = cast.ToInt64(role.ID)
if err = dao.NewUserRole(tx).Create(m); err != nil {
return err
}
}
return nil
})
if err != nil {
err2.DbErr("<admin service create>", err)
}
return m.ID
}
func (a *User) Update(req request.UserUpdate) {
var user *model.User
var err error
user, err = dao.NewUser().AccountGet(a.user.Account)
if err != nil {
err2.DbErr("<user service update>", err)
}
if user == nil {
err2.NotEsxErr("<user service update>")
return
}
if req.Username != "" {
user.Username = req.Username
}
if cast.ToInt64(req.Status) != 0 {
user.Status = cast.ToInt64(req.Status)
}
if cast.ToInt64(req.Role) != 0 {
role, err := dao.NewRole().Exists(cast.ToInt64(req.Role))
if err != nil {
err2.DbErr("<user service update>", err)
}
if !role {
err2.NotEsxErr()
}
}
// 不能修改密码
//req.Password = strings.TrimSpace(req.Password)
//if len(req.Password) < 1 {
// err2.ParamErr("<user service update>: password too short")
//}
//
//user.Password = goutil.Md5(req.Password + Salt)
err = global.GetDB().Transaction(func(tx *gorm.DB) error {
if err = dao.NewUser(tx).Update(user); err != nil {
return err
}
if cast.ToInt64(req.Role) != 0 {
if err = dao.NewUserRole(tx).Delete(user.ID); err != nil {
return err
}
if err = dao.NewUserRole(tx).Create(&model.UserRole{UserID: user.ID, RoleID: cast.ToInt64(req.Role)}); err != nil {
return err
}
}
// 禁用即下线
if user.Status == model.UserStatusBaned {
a.expireByAccount(user.Account)
}
return nil
})
if err != nil {
err2.DbErr("<user service update>", err)
}
}
func (a *User) Delete(req request.UserDelete) {
var user *model.User
var err error
user, err = dao.NewUser().Get(cast.ToInt64(req.ID))
if err != nil {
err2.DbErr("<user service update>", err)
}
if user == nil {
err2.NotEsxErr("<user service update>")
return
}
if err = dao.NewUser().Delete(user.ID); err != nil {
err2.DbErr("<user service update>", err)
}
a.expireByAccount(user.Account)
return
}
func (a *User) List(req request.UserList) (any, int64) {
req.Pagination()
users, count, err := dao.NewUser().List(req.Username, req.Account, cast.ToInt64(req.Role), req.Page, req.Size, req.Sort)
if err != nil {
err2.DbErr("<users service list>", err)
}
res := make([]map[string]any, 0)
for _, m := range users {
res = append(res, m.Format())
}
return res, count
}
func (a *User) Login(req request.UserLogin) any {
user, err := dao.NewUser().GetWithRole(req.Account)
if err != nil {
err2.DbErr("<user service login>", err)
}
if user == nil {
err2.NotEsxErr("<user service login>")
return ""
}
if user.Password != goutil.Md5(req.Password+model.Salt) {
err2.PriErr("<user service login>: wrong password")
}
token := fmt.Sprintf("%s", goutil.RandomStr(64))
expire := time.Hour * 24 * 30
redix := cache.GetRedis()
key := cache.NewKeys().User() + token
if err = redix.Set(key, goutil.EncodeJSON(user), expire).Err(); err != nil {
err2.DbErr("<user service login>", err)
}
// 保存用户的user_id 到token
// 通过用户的account来创建一个 k-v account是key,其他的是value
if oldToken := redix.Get(cache.NewKeys().User2Token() + user.Account).Val(); oldToken != "" {
a.expire(oldToken)
}
redix.Set(cache.NewKeys().User2Token()+user.Account, token, expire)
resource, err := dao.NewResource().RoleGet(user.RoleID)
if err != nil {
err2.DbErr("<user service login>", err)
}
userResource := make([]map[string]any, 0)
for _, v := range resource {
if v.Type != "page" {
continue
}
userResource = append(userResource, v.Format())
}
res := make(map[string]any)
res["resource"] = userResource
res["token"] = token
return res
}
func (a *User) Logout(req request.UserLogout) {
a.expire(req.Token)
return
}
func (a *User) expireByAccount(account string) {
key := cache.NewKeys().User2Token() + account
token := cache.GetRedis().Get(key).Val()
if token == "" {
return
}
a.expire(token)
}
func (a *User) expire(token string) {
redix := cache.GetRedis()
key := cache.NewKeys().User() + token
redix.Del(key)
return
}