package user import ( "bsm/full/module/base/mgt/internal/libs" "bsm/full/module/base/mgt/internal/models" "bsm/full/module/base/mgt/internal/types" "git.apinb.com/bsm-sdk/core/errcode" "git.apinb.com/bsm-sdk/core/infra" "git.apinb.com/bsm-sdk/core/printer" "github.com/gin-gonic/gin" "gorm.io/gorm" "gorm.io/gorm/clause" ) // SetRole 给用户设置角色 func SetRole(c *gin.Context) { var ( request = types.UserRoleRequest{} role = make([]models.MgtRole, 0) pmnData = make([]models.MgtLinkUserPmn, 0) roleData = make([]models.MgtLinkUserRole, 0) appId = make([]uint, 0) userApp = make([]models.MgtLinkUserApp, 0) ) if err := c.ShouldBindJSON(&request); err != nil { infra.Response.Error(c, errcode.ErrJsonUnmarshal) return } if err := libs.ValidateStruct(&request); err != nil { infra.Response.Error(c, errcode.ErrInvalidArgument) return } if err := models.DBService.Model(&models.MgtRole{}).Where("id in ?", request.RoleId).Preload("Permissions").Find(&role).Error; err != nil { infra.Response.Error(c, errcode.ErrDB) return } for _, v := range role { for _, vv := range v.Permissions { pmnData = append(pmnData, models.MgtLinkUserPmn{ AppId: vv.Appid, PmnId: vv.ID, UserId: request.UserId, }) } roleData = append(roleData, models.MgtLinkUserRole{UserId: request.UserId, RoleId: v.ID}) } if err := models.DBService.Model(&models.MgtLinkRoleApp{}).Select("app_id").Where("role_id in ?", request.RoleId).Find(&appId).Error; err != nil { infra.Response.Error(c, errcode.ErrDB) return } if len(appId) == 0 { printer.Info("角色未关联应用: roleIds=%v", request.RoleId) infra.Response.Error(c, errcode.ErrRecordNotFound) return } for _, v := range appId { userApp = append(userApp, models.MgtLinkUserApp{UserId: request.UserId, AppId: v}) } if err := models.DBService.Transaction(func(tx *gorm.DB) error { if err := tx.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "app_id"}, {Name: "pmn_id"}, {Name: "user_id"}}, DoUpdates: clause.AssignmentColumns([]string{"app_id", "pmn_id", "user_id"}), }).Create(&pmnData).Error; err != nil { printer.Error("创建用户权限关系失败: %v", err) return err } if err := tx.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "app_id"}, {Name: "user_id"}}, DoUpdates: clause.AssignmentColumns([]string{"app_id", "user_id"}), }).Create(&userApp).Error; err != nil { printer.Error("创建用户app关系失败: %v", err) return err } if err := tx.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "user_id"}, {Name: "role_id"}}, DoUpdates: clause.AssignmentColumns([]string{"user_id", "role_id"}), }).Create(&roleData).Error; err != nil { printer.Error("创建用户角色关系失败: %v", err) return err } return nil }); err != nil { infra.Response.Error(c, errcode.ErrDB) return } infra.Response.Success(c, "") } // DelRole 给用户移除角色 func DelRole(c *gin.Context) { var ( request = types.UserRoleRequest{} ) if err := c.ShouldBindJSON(&request); err != nil { infra.Response.Error(c, errcode.ErrJsonUnmarshal) return } if err := libs.ValidateStruct(&request); err != nil { infra.Response.Error(c, errcode.ErrInvalidArgument) return } if err := models.DBService.Transaction(func(tx *gorm.DB) error { var ( removedRolePmns []uint userOtherRoles []uint otherRolePmns []uint toDeletePmns []uint ) if err := tx.Model(&models.MgtLinkRolePmn{}). Select("pmn_id"). Where("role_id in ?", request.RoleId). Find(&removedRolePmns).Error; err != nil { printer.Error("获取被移除角色权限异常: %v", err) return err } if len(removedRolePmns) == 0 { if err := tx.Where("user_id = ? and role_id in ?", request.UserId, request.RoleId). Delete(&models.MgtLinkUserRole{}).Error; err != nil { printer.Error("删除用户角色关联异常: %v", err) return err } return nil } if err := tx.Model(&models.MgtLinkUserRole{}). Select("role_id"). Where("user_id = ? and role_id not in ?", request.UserId, request.RoleId). Find(&userOtherRoles).Error; err != nil { printer.Error("获取用户其他角色异常: %v", err) return err } if len(userOtherRoles) > 0 { if err := tx.Model(&models.MgtLinkRolePmn{}). Select("pmn_id"). Where("role_id in ?", userOtherRoles). Find(&otherRolePmns).Error; err != nil { printer.Error("获取用户其他角色权限异常: %v", err) return err } } otherPmnSet := make(map[uint]struct{}, len(otherRolePmns)) for _, pmnId := range otherRolePmns { otherPmnSet[pmnId] = struct{}{} } toDeletePmns = make([]uint, 0, len(removedRolePmns)) for _, pmnId := range removedRolePmns { if _, ok := otherPmnSet[pmnId]; !ok { toDeletePmns = append(toDeletePmns, pmnId) } } if err := tx.Where("user_id = ? and role_id in ?", request.UserId, request.RoleId). Delete(&models.MgtLinkUserRole{}).Error; err != nil { printer.Error("删除用户角色关联异常: %v", err) return err } if len(toDeletePmns) > 0 { if err := tx.Where("user_id = ? and pmn_id in ?", request.UserId, toDeletePmns). Delete(&models.MgtLinkUserPmn{}).Error; err != nil { printer.Error("删除用户权限关联异常: %v", err) return err } printer.Info("删除用户权限关联: userId=%d, pmnIds=%v", request.UserId, toDeletePmns) } else { printer.Info("用户权限通过其他角色或直接拥有,无需删除: userId=%d", request.UserId) } return nil }); err != nil { infra.Response.Error(c, errcode.ErrDB) return } infra.Response.Success(c, "") }