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("", err) } if exist { err2.EsxErr() } req.Password = strings.TrimSpace(req.Password) if len(req.Password) < 1 { err2.ParamErr(": password too short") } if cast.ToInt64(req.Role) != 0 { // 检查 role 是否存在 exist, err = dao.NewRole().Exists(cast.ToInt64(req.Role)) if err != nil { err2.DbErr("", err) } if !exist { err2.NotEsxErr(" 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("", 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("", err) } if user == nil { err2.NotEsxErr("") 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("", err) } if !role { err2.NotEsxErr() } } // 不能修改密码 //req.Password = strings.TrimSpace(req.Password) //if len(req.Password) < 1 { // err2.ParamErr(": 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("", 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("", err) } if user == nil { err2.NotEsxErr("") return } if err = dao.NewUser().Delete(user.ID); err != nil { err2.DbErr("", 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("", 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("", err) } if user == nil { err2.NotEsxErr("") return "" } if user.Password != goutil.Md5(req.Password+model.Salt) { err2.PriErr(": 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("", 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("", 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 }