package repository import ( "github.com/pkg/errors" "gorm.io/gorm" "sghgogs.com/sghblog/authorization-service/domain/model/base" req "sghgogs.com/sghblog/authorization-service/domain/model/request" pb "sghgogs.com/sghblog/authorization-service/proto" ) func (u *Repository) GetAdminRole(roleId int64) (req.AdminRole, error) { var role req.AdminRole // status := []string{"enabled", "disabled"} // Where("status <> ?", "deleted") return role, u.db.Where("id = ?", roleId). Preload("Users", "status = ?", pb.StatusEnum_ENABLED). Preload("Permissions", "status = ?", pb.StatusEnum_ENABLED). First(&role).Error } // NOT EXISTS ( // SELECT 1 // FROM admin_user_role // WHERE admin_role.id = admin_user_role.admin_role_id // AND admin_user_role.admin_user_id = ? // ) // 这个查询的核心部分是 NOT EXISTS 子查询。让我们一步步解释它的组成部分: // SELECT 1: 子查询选择一个虚拟的常数 1,因为我们只关心是否存在匹配的记录而不关心具体的值。这是一种常见的惯例。 // FROM admin_user_role: 子查询从 admin_user_role 表中选取数据。 // WHERE admin_role.id = admin_user_role.admin_role_id: 子查询中的条件,它将 admin_user_role 表中的记录与外部查询中的 admin_roles 表中的角色进行匹配。 // AND admin_user_role.admin_user_id = ?: 子查询中的另一个条件,它确保与指定用户ID相关联的记录。 // 现在,NOT EXISTS 子查询的含义是:如果在 admin_user_role 表中找不到匹配条件的记录(即不存在这样的记录),那么返回真。这意味着,外部查询将返回那些在 admin_roles 表中存在但在 admin_user_role 表中没有关联用户的角色。 // 你可以将这个查询理解为:“查找在 admin_roles 表中,但在 admin_user_role 表中没有关联用户的角色”。 func (u *Repository) GetUnassignedAdminRoles(userId int64) ([]req.AdminRole, int64, error) { var roles []req.AdminRole var totalCount int64 tx := u.db.Model(req.AdminRole{}). Where("NOT EXISTS (SELECT 1 FROM admin_user_role WHERE admin_role.id = admin_user_role.admin_role_id AND admin_user_role.admin_user_id = ?)", userId) tx.Count(&totalCount) return roles, totalCount, tx.Find(&roles).Error } func (u *Repository) CreateAdminRole(role *req.AdminRole, adminUsers []int64, adminPermissions []int64) error { // 开始事务 tx := u.db.Begin() // 错误处理 defer func() { if r := recover(); r != nil { tx.Rollback() } }() if err := tx.Create(&role).Error; err != nil { tx.Rollback() return err } if len(adminUsers) > 0 { if _, err := u.getAdminUserValidIDs(adminUsers); err != nil { tx.Rollback() return err } users := make([]req.AdminUser, 0) for _, ID := range adminUsers { users = append(users, req.AdminUser{ID: ID}) } if err := tx.Model(&role).Association("Users").Append(&users); err != nil { tx.Rollback() return err } } if len(adminPermissions) > 0 { if _, err := u.getAdminPermissionValidIDs(adminPermissions); err != nil { tx.Rollback() return err } permissions := make([]req.AdminPermission, 0) for _, ID := range adminPermissions { permissions = append(permissions, req.AdminPermission{ID: ID}) } if err := tx.Model(&role).Association("Permissions").Append(&permissions); err != nil { tx.Rollback() return err } } return tx.Commit().Error } func (u *Repository) ListAdminRoles(query *pb.ListAdminRolesRequest) ([]req.AdminRole, int64, error) { var totalCount int64 tx := u.db.Model(&req.AdminRole{}).Order("id desc"). Preload("Users", "status = ?", pb.StatusEnum_ENABLED). Preload("Permissions", "status = ?", pb.StatusEnum_ENABLED) if query.Keyword != "" { tx.Where("name = ?", query.Keyword) } if base.IsStatusEnum(query.Status) { tx.Where("status = ?", query.Status) } tx.Count(&totalCount) roles := make([]req.AdminRole, 0) return roles, totalCount, tx.Limit(int(query.PageSize)).Offset(int((query.Page - 1) * query.PageSize)).Find(&roles).Error } // UpdateAdminRole 更新角色信息 func (u *Repository) UpdateAdminRole(updateRole *pb.UpdateAdminRoleRequest) error { // 开始事务 tx := u.db.Begin() // 错误处理 defer func() { if r := recover(); r != nil { tx.Rollback() } }() var role req.AdminRole if err := tx.First(&role, updateRole.RoleId).Error; err != nil { tx.Rollback() return err } if err := tx.Model(&role).Association("Users").Clear(); err != nil { tx.Rollback() return err } if err := tx.Model(&role).Association("Permissions").Clear(); err != nil { tx.Rollback() return err } if len(updateRole.Users) > 0 { if _, err := u.getAdminUserValidIDs(updateRole.Users); err != nil { tx.Rollback() return err } users := make([]req.AdminUser, 0) for _, ID := range updateRole.Users { users = append(users, req.AdminUser{ID: ID}) } if err := tx.Model(&role).Association("Users").Append(&users); err != nil { tx.Rollback() return err } } if len(updateRole.Permissions) > 0 { if _, err := u.getAdminUserValidIDs(updateRole.Permissions); err != nil { tx.Rollback() return err } permissions := make([]req.AdminPermission, 0) for _, ID := range updateRole.Permissions { permissions = append(permissions, req.AdminPermission{ID: ID}) } if err := tx.Model(&role).Association("Permissions").Append(&permissions); err != nil { tx.Rollback() return err } } if err := tx.Model(&role).Updates(map[string]interface{}{ "description": updateRole.Description, }).Error; err != nil { tx.Rollback() return err } return tx.Commit().Error } // IsAdminRoleExists 假设有一个方法用于检查角色是否存在 func (u *Repository) IsAdminRoleExists(identifier interface{}) (bool, error) { var role req.AdminRole if err := u.db.Where("id = ? OR name = ?", identifier, identifier).First(&role).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return false, nil // 记录不存在,角色不存在 } return false, err // 发生其他错误 } return true, nil } // DeleteAdminRole 彻底删除 func (u *Repository) DeleteAdminRole(roleId int64) error { // 开始事务 tx := u.db.Begin() // 错误处理 defer func() { if r := recover(); r != nil { tx.Rollback() } }() var role req.AdminRole // 1.查询角色 if err := tx.First(&role, roleId).Error; err != nil { tx.Rollback() return err } // 2 删除关联用户 if err := tx.Model(&role).Association("Users").Clear(); err != nil { tx.Rollback() return err } // 3 移除关联权限 if err := tx.Model(&role).Association("Permissions").Clear(); err != nil { tx.Rollback() return err } // 4. 彻底删除 if err := tx.Model(&req.AdminRole{}).Delete(&req.AdminRole{ ID: roleId, }).Error; err != nil { tx.Rollback() return err } return tx.Commit().Error } func (u *Repository) RetrieveEnabledRoles() ([]req.AdminRole, error) { roles := make([]req.AdminRole, 0) return roles, u.db.Model(req.AdminRole{}). Order("id desc"). Select("ID", "Name", "Description"). Where("status = ?", pb.StatusEnum_ENABLED). Find(&roles).Error } func (u *Repository) ToggleAdminRole(adminRole *pb.ToggleAdminRoleRequest) error { // 开始事务 tx := u.db.Begin() // 错误处理 defer func() { if r := recover(); r != nil { tx.Rollback() } }() var role req.AdminRole // 1.查询角色 if err := tx.First(&role, adminRole.RoleId).Error; err != nil { tx.Rollback() return err } if adminRole.Status == pb.StatusEnum_DELETED { // 1.1 删除关联用户 if err := tx.Model(&role).Association("Users").Clear(); err != nil { tx.Rollback() return err } // 1.2 移除关联权限 if err := tx.Model(&role).Association("Permissions").Clear(); err != nil { tx.Rollback() return err } } // 2. 更新状态 if err := tx.Model(&role).Updates(map[string]interface{}{ "status": adminRole.Status, }).Error; err != nil { tx.Rollback() return err } return tx.Commit().Error }