优化
This commit is contained in:
+56
-42
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func (r *userRepo) FindUserByUsername(ctx context.Context, username string) (*biz.User, error) {
|
||||
@@ -36,9 +37,20 @@ func (r *userRepo) FindUserByID(ctx context.Context, id uint) (*biz.User, error)
|
||||
return r.loadUser(ctx, &po)
|
||||
}
|
||||
|
||||
func (r *userRepo) FindUserByUUID(ctx context.Context, value string) (*biz.User, error) {
|
||||
var po userPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("uuid = ?", value).First(&po).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, biz.ErrUserNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return r.loadUser(ctx, &po)
|
||||
}
|
||||
|
||||
func (r *userRepo) loadUser(ctx context.Context, po *userPO) (*biz.User, error) {
|
||||
var authority authorityPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&authority, "authority_id = ?", po.AuthorityID).Error; err != nil {
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&authority, "authority_id = ?", po.AuthorityID).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
var authorityPOs []authorityPO
|
||||
@@ -58,13 +70,17 @@ func (r *userRepo) loadUser(ctx context.Context, po *userPO) (*biz.User, error)
|
||||
return nil, err
|
||||
}
|
||||
departments := make([]biz.Department, 0, len(departmentPOs))
|
||||
var primary *biz.Department
|
||||
for _, item := range departmentPOs {
|
||||
value := deptFromPO(item)
|
||||
departments = append(departments, *value)
|
||||
if item.ID == po.DeptID {
|
||||
copy := *value
|
||||
primary = ©
|
||||
}
|
||||
var primary *biz.Department
|
||||
if po.DeptID != 0 {
|
||||
var primaryPO departmentPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&primaryPO, po.DeptID).Error; err == nil {
|
||||
primary = deptFromPO(primaryPO)
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var positionPOs []positionPO
|
||||
@@ -200,12 +216,21 @@ func (r *userRepo) loadUsers(ctx context.Context, pos []userPO) ([]*biz.User, er
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (r *userRepo) HasAuthorityMenu(ctx context.Context, authorityID uint, name string) (bool, error) {
|
||||
var count int64
|
||||
err := r.data.gormDB.WithContext(ctx).Model(&menuPO{}).
|
||||
Joins("JOIN sys_authority_menus ON sys_authority_menus.sys_base_menu_id = sys_base_menus.id").
|
||||
Where("sys_authority_menus.sys_authority_authority_id = ? AND sys_base_menus.name = ?", authorityID, name).
|
||||
Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
func (r *userRepo) MenusByAuthority(ctx context.Context, authorityID uint) ([]*biz.Menu, error) {
|
||||
var pos []menuPO
|
||||
err := r.data.gormDB.WithContext(ctx).Table("sys_base_menus").
|
||||
Joins("JOIN sys_authority_menus ON sys_authority_menus.sys_base_menu_id = sys_base_menus.id").
|
||||
Where("sys_authority_menus.sys_authority_authority_id = ? AND sys_base_menus.deleted_at IS NULL", authorityID).
|
||||
Order("sys_base_menus.sort asc, sys_base_menus.id asc").Scan(&pos).Error
|
||||
Order("sys_base_menus.sort").Scan(&pos).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -214,15 +239,15 @@ func (r *userRepo) MenusByAuthority(ctx context.Context, authorityID uint) ([]*b
|
||||
for _, po := range pos {
|
||||
menu := menuFromPO(po)
|
||||
menu.MenuID = po.ID
|
||||
menu.Children = []*biz.Menu{}
|
||||
menu.Children = nil
|
||||
menu.Parameters = []*biz.MenuParameter{}
|
||||
menu.Buttons = []*biz.MenuButton{}
|
||||
menu.Buttons = nil
|
||||
byID[po.ID] = menu
|
||||
menuIDs = append(menuIDs, po.ID)
|
||||
}
|
||||
if len(menuIDs) > 0 {
|
||||
var parameters []menuParameterPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("sys_base_menu_id IN ?", menuIDs).Order("id").Find(¶meters).Error; err != nil {
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("sys_base_menu_id IN ?", menuIDs).Find(¶meters).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, parameter := range parameters {
|
||||
@@ -240,7 +265,7 @@ func (r *userRepo) MenusByAuthority(ctx context.Context, authorityID uint) ([]*b
|
||||
menu.Buttons = append(menu.Buttons, value)
|
||||
}
|
||||
}
|
||||
roots := make([]*biz.Menu, 0)
|
||||
var roots []*biz.Menu
|
||||
for _, po := range pos {
|
||||
menu := byID[po.ID]
|
||||
if parent := byID[po.ParentID]; parent != nil {
|
||||
@@ -281,7 +306,7 @@ func (r *userRepo) ListUsers(ctx context.Context, page, pageSize int, filter *bi
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []userPO
|
||||
if err := applyPagination(db.Order(order), page, pageSize, 100).Find(&pos).Error; err != nil {
|
||||
if err := applyRequiredPagination(db.Order(order), page, pageSize, 100).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
users, err := r.loadUsers(ctx, pos)
|
||||
@@ -307,9 +332,7 @@ func (r *userRepo) CreateUserWithAuthorities(ctx context.Context, user *biz.User
|
||||
}
|
||||
now := time.Now()
|
||||
po := userPO{UUID: user.UUID, Username: user.Username, Password: user.Password, NickName: user.NickName, HeaderImg: user.HeaderImg, AuthorityID: user.AuthorityID, Phone: user.Phone, Email: user.Email, Enable: user.Enable, PasswordUpdatedAt: &now, MustChangePassword: user.MustChangePassword}
|
||||
if len(authorityIDs) == 0 {
|
||||
authorityIDs = []uint{user.AuthorityID}
|
||||
}
|
||||
var createdAuthorities []biz.Authority
|
||||
if err := r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// The compatible registration rejects an existing non-deleted username before creating the
|
||||
// account. The username column is intentionally not unique for legacy
|
||||
@@ -321,34 +344,36 @@ func (r *userRepo) CreateUserWithAuthorities(ctx context.Context, user *biz.User
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
if err := validateAuthorities(tx, authorityIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if len(authorityIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
links := make([]userAuthorityPO, 0, len(authorityIDs))
|
||||
for _, authorityID := range authorityIDs {
|
||||
// Creating a user through the compatible administration endpoint lets
|
||||
// GORM save the many-to-many authority values supplied by the request.
|
||||
// With an ID-only value this is an upsert: an existing role is left
|
||||
// untouched, while a missing role is materialized with model defaults.
|
||||
associated := authorityPO{AuthorityID: authorityID}
|
||||
if err := tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&associated).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
createdAuthorities = append(createdAuthorities, toBizAuthority(associated))
|
||||
links = append(links, userAuthorityPO{SysUserID: po.ID, SysAuthorityAuthorityID: authorityID})
|
||||
}
|
||||
return tx.Create(&links).Error
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.FindUserByID(ctx, po.ID)
|
||||
}
|
||||
|
||||
func validateAuthorities(tx *gorm.DB, authorityIDs []uint) error {
|
||||
for _, authorityID := range authorityIDs {
|
||||
var count int64
|
||||
if err := tx.Model(&authorityPO{}).Where("authority_id = ?", authorityID).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
return errors.New("角色不存在")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
// Registration returns the just-created entity, not a second hydrated
|
||||
// query. The reference handler returns the request's authority IDs and
|
||||
// leaves related authority/department records at their zero values; keep
|
||||
// that response contract while retaining the persisted timestamps/UUID.
|
||||
created := baseBizUser(&po)
|
||||
created.Authorities = createdAuthorities
|
||||
return created, nil
|
||||
}
|
||||
|
||||
func (r *userRepo) UpdateUser(ctx context.Context, user *biz.User) error {
|
||||
@@ -416,14 +441,6 @@ func (r *userRepo) FillDepartmentNamePaths(ctx context.Context, user *biz.User)
|
||||
parts = append(parts, user.Departments[i].Name)
|
||||
user.Departments[i].NamePath = strings.Join(parts, "/")
|
||||
}
|
||||
if user.Department != nil {
|
||||
for i := range user.Departments {
|
||||
if user.Departments[i].ID == user.Department.ID {
|
||||
user.Department.NamePath = user.Departments[i].NamePath
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -504,9 +521,6 @@ func setUserAuthorities(tx *gorm.DB, id uint, authorityIDs []uint) error {
|
||||
if len(authorityIDs) == 0 {
|
||||
return errors.New("角色不能为空")
|
||||
}
|
||||
if err := validateAuthorities(tx, authorityIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("sys_user_id = ?", id).Delete(&userAuthorityPO{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user