ldap-1-backend/service/isql/user_isql.go

335 lines
9.5 KiB
Go

package isql
import (
"errors"
"fmt"
"strings"
"time"
"github.com/eryajf/go-ldap-admin/model"
"github.com/eryajf/go-ldap-admin/public/common"
"github.com/eryajf/go-ldap-admin/public/tools"
"github.com/eryajf/go-ldap-admin/svc/request"
"github.com/gin-gonic/gin"
"github.com/patrickmn/go-cache"
"github.com/thoas/go-funk"
"gorm.io/gorm"
)
type UserService struct{}
// 当前用户信息缓存,避免频繁获取数据库
var userInfoCache = cache.New(24*time.Hour, 48*time.Hour)
// Add 添加资源
func (s UserService) Add(user *model.User) error {
user.Password = tools.NewGenPasswd(user.Password)
//result := common.DB.Create(user)
//return user.ID, result.Error
return common.DB.Create(user).Error
}
// List 获取数据列表
func (s UserService) List(req *request.UserListReq) ([]*model.User, error) {
var list []*model.User
db := common.DB.Model(&model.User{}).Order("id DESC")
username := strings.TrimSpace(req.Username)
if username != "" {
db = db.Where("username LIKE ?", fmt.Sprintf("%%%s%%", username))
}
nickname := strings.TrimSpace(req.Nickname)
if nickname != "" {
db = db.Where("nickname LIKE ?", fmt.Sprintf("%%%s%%", nickname))
}
mobile := strings.TrimSpace(req.Mobile)
if mobile != "" {
db = db.Where("mobile LIKE ?", fmt.Sprintf("%%%s%%", mobile))
}
departmentId := req.DepartmentId
if len(departmentId) > 0 {
db = db.Where("department_id = ?", departmentId)
}
givenName := strings.TrimSpace(req.GivenName)
if givenName != "" {
db = db.Where("given_name LIKE ?", fmt.Sprintf("%%%s%%", givenName))
}
status := req.Status
if status != 0 {
db = db.Where("status = ?", status)
}
pageReq := tools.NewPageOption(req.PageNum, req.PageSize)
err := db.Offset(pageReq.PageNum).Limit(pageReq.PageSize).Preload("Roles").Find(&list).Error
return list, err
}
// ListCout 获取符合条件的数据列表条数
func (s UserService) ListCount(req *request.UserListReq) (int64, error) {
var count int64
db := common.DB.Model(&model.User{}).Order("id DESC")
username := strings.TrimSpace(req.Username)
if username != "" {
db = db.Where("username LIKE ?", fmt.Sprintf("%%%s%%", username))
}
nickname := strings.TrimSpace(req.Nickname)
if nickname != "" {
db = db.Where("nickname LIKE ?", fmt.Sprintf("%%%s%%", nickname))
}
mobile := strings.TrimSpace(req.Mobile)
if mobile != "" {
db = db.Where("mobile LIKE ?", fmt.Sprintf("%%%s%%", mobile))
}
departmentId := req.DepartmentId
if len(departmentId) > 0 {
db = db.Where("department_id = ?", departmentId)
}
givenName := strings.TrimSpace(req.GivenName)
if givenName != "" {
db = db.Where("given_name LIKE ?", fmt.Sprintf("%%%s%%", givenName))
}
status := req.Status
if status != 0 {
db = db.Where("status = ?", status)
}
err := db.Count(&count).Error
return count, err
}
// List 获取数据列表
func (s UserService) ListAll() (list []*model.User, err error) {
err = common.DB.Model(&model.User{}).Order("created_at DESC").Find(&list).Error
return list, err
}
// Count 获取数据总数
func (s UserService) Count() (int64, error) {
var count int64
err := common.DB.Model(&model.User{}).Count(&count).Error
return count, err
}
// Exist 判断资源是否存在
func (s UserService) Exist(filter map[string]interface{}) bool {
var dataObj model.User
err := common.DB.Where(filter).First(&dataObj).Error
return !errors.Is(err, gorm.ErrRecordNotFound)
}
// Find 获取单个资源
func (s UserService) Find(filter map[string]interface{}, data *model.User) error {
return common.DB.Where(filter).Preload("Roles").First(&data).Error
}
// Update 更新资源
func (s UserService) Update(user *model.User) error {
err := common.DB.Model(user).Updates(user).Error
if err != nil {
return err
}
err = common.DB.Model(user).Association("Roles").Replace(user.Roles)
// 如果更新成功就更新用户信息缓存
if err == nil {
userInfoCache.Set(user.Username, *user, cache.DefaultExpiration)
}
return err
}
// GetUserMinRoleSortsByIds 根据用户ID获取用户角色排序最小值
func (s UserService) GetUserMinRoleSortsByIds(ids []uint) ([]int, error) {
// 根据用户ID获取用户信息
var userList []model.User
err := common.DB.Where("id IN (?)", ids).Preload("Roles").Find(&userList).Error
if err != nil {
return []int{}, err
}
if len(userList) == 0 {
return []int{}, errors.New("未获取到任何用户信息")
}
var roleMinSortList []int
for _, user := range userList {
roles := user.Roles
var roleSortList []int
for _, role := range roles {
roleSortList = append(roleSortList, int(role.Sort))
}
roleMinSort := funk.MinInt(roleSortList).(int)
roleMinSortList = append(roleMinSortList, roleMinSort)
}
return roleMinSortList, nil
}
//GetCurrentUserMinRoleSort 获取当前用户角色排序最小值(最高等级角色)以及当前用户信息
func (s UserService) GetCurrentUserMinRoleSort(c *gin.Context) (uint, model.User, error) {
// 获取当前用户
ctxUser, err := s.GetCurrentLoginUser(c)
if err != nil {
return 999, ctxUser, err
}
// 获取当前用户的所有角色
currentRoles := ctxUser.Roles
// 获取当前用户角色的排序,和前端传来的角色排序做比较
var currentRoleSorts []int
for _, role := range currentRoles {
currentRoleSorts = append(currentRoleSorts, int(role.Sort))
}
// 当前用户角色排序最小值(最高等级角色)
currentRoleSortMin := uint(funk.MinInt(currentRoleSorts).(int))
return currentRoleSortMin, ctxUser, nil
}
// Delete 批量删除
func (s UserService) Delete(ids []uint) error {
// 用户和角色存在多对多关联关系
var users []model.User
for _, id := range ids {
// 根据ID获取用户
user := new(model.User)
err := s.Find(map[string]interface{}{"id": id}, user)
if err != nil {
return errors.New(fmt.Sprintf("未获取到ID为%d的用户", id))
}
users = append(users, *user)
}
err := common.DB.Select("Roles").Unscoped().Delete(&users).Error
// 删除用户成功,则删除用户信息缓存
if err == nil {
for _, user := range users {
userInfoCache.Delete(user.Username)
}
}
return err
}
// GetUserByIds 根据用户ID获取用户角色排序最小值
func (s UserService) GetUserByIds(ids []uint) ([]model.User, error) {
// 根据用户ID获取用户信息
var userList []model.User
err := common.DB.Where("id IN (?)", ids).Preload("Roles").Find(&userList).Error
return userList, err
}
// ChangePwd 更新密码
func (s UserService) ChangePwd(username string, hashNewPasswd string) error {
err := common.DB.Model(&model.User{}).Where("username = ?", username).Update("password", hashNewPasswd).Error
// 如果更新密码成功,则更新当前用户信息缓存
// 先获取缓存
cacheUser, found := userInfoCache.Get(username)
if err == nil {
if found {
user := cacheUser.(model.User)
user.Password = hashNewPasswd
userInfoCache.Set(username, user, cache.DefaultExpiration)
} else {
// 没有缓存就获取用户信息缓存
var user model.User
common.DB.Where("username = ?", username).First(&user)
userInfoCache.Set(username, user, cache.DefaultExpiration)
}
}
return err
}
// ChangeStatus 更新状态
func (s UserService) ChangeStatus(id, status int) error {
return common.DB.Model(&model.User{}).Where("id = ?", id).Update("status", status).Error
}
// GetCurrentLoginUser 获取当前登录用户信息
// 需要缓存,减少数据库访问
func (s UserService) GetCurrentLoginUser(c *gin.Context) (model.User, error) {
var newUser model.User
ctxUser, exist := c.Get("user")
if !exist {
return newUser, errors.New("用户未登录")
}
u, _ := ctxUser.(model.User)
// 先获取缓存
cacheUser, found := userInfoCache.Get(u.Username)
var user model.User
var err error
if found {
user = cacheUser.(model.User)
err = nil
} else {
// 缓存中没有就获取数据库
user, err = s.GetUserById(u.ID)
// 获取成功就缓存
if err != nil {
userInfoCache.Delete(u.Username)
} else {
userInfoCache.Set(u.Username, user, cache.DefaultExpiration)
}
}
return user, err
}
// Login 登录
func (s UserService) Login(user *model.User) (*model.User, error) {
// 根据用户名获取用户(正常状态:用户状态正常)
var firstUser model.User
// err := common.DB.
// Where("username = ?", user.Username).
// Preload("Roles").
// First(&firstUser).Error
// if err != nil {
// return nil, errors.New("用户不存在")
// }
err := s.Find(tools.H{"username": user.Username}, &firstUser)
if err != nil {
return nil, errors.New("用户不存在")
}
// 判断用户的状态
userStatus := firstUser.Status
if userStatus != 1 {
return nil, errors.New("用户被禁用")
}
// 判断用户拥有的所有角色的状态,全部角色都被禁用则不能登录
// roles := firstUser.Roles
// isValidate := false
// for _, role := range roles {
// // 有一个正常状态的角色就可以登录
// if role.Status == 1 {
// isValidate = true
// break
// }
// }
// if !isValidate {
// return nil, errors.New("用户角色被禁用")
// }
if tools.NewParPasswd(firstUser.Password) != user.Password {
return nil, errors.New("密码错误")
}
// 校验密码
// err = tools.ComparePasswd(firstUser.Password, user.Password)
// if err != nil {
// return &firstUser, errors.New("密码错误")
// }
return &firstUser, nil
}
// ClearUserInfoCache 清理所有用户信息缓存
func (s UserService) ClearUserInfoCache() {
userInfoCache.Flush()
}
// GetUserById 获取单个用户
func (us UserService) GetUserById(id uint) (model.User, error) {
var user model.User
err := common.DB.Where("id = ?", id).Preload("Roles").First(&user).Error
return user, err
}