package system import ( "errors" "strconv" "kra/internal/biz/system" "github.com/casbin/casbin/v2" gormadapter "github.com/casbin/gorm-adapter/v3" "gorm.io/gorm" ) type casbinRepo struct { db *gorm.DB enforcer *casbin.SyncedCachedEnforcer } // NewCasbinRepo 创建Casbin仓储 func NewCasbinRepo(db *gorm.DB, enforcer *casbin.SyncedCachedEnforcer) system.CasbinRepo { return &casbinRepo{db: db, enforcer: enforcer} } // ClearCasbin 清除匹配的权限 func (r *casbinRepo) ClearCasbin(v int, p ...string) bool { success, _ := r.enforcer.RemoveFilteredPolicy(v, p...) return success } // UpdateCasbinApi API更新随动 func (r *casbinRepo) UpdateCasbinApi(oldPath, newPath, oldMethod, newMethod string) error { err := r.db.Model(&gormadapter.CasbinRule{}). Where("v1 = ? AND v2 = ?", oldPath, oldMethod). Updates(map[string]any{"v1": newPath, "v2": newMethod}).Error if err != nil { return err } return r.enforcer.LoadPolicy() } // GetPolicyPathByAuthorityId 获取权限列表 func (r *casbinRepo) GetPolicyPathByAuthorityId(authorityId uint) []system.CasbinRule { authorityIdStr := strconv.FormatUint(uint64(authorityId), 10) list, _ := r.enforcer.GetFilteredPolicy(0, authorityIdStr) pathMaps := make([]system.CasbinRule, len(list)) for i, v := range list { pathMaps[i] = system.CasbinRule{ Path: v[1], Method: v[2], } } return pathMaps } // FreshCasbin 刷新Casbin缓存 func (r *casbinRepo) FreshCasbin() error { return r.enforcer.LoadPolicy() } // AddPolicies 添加策略(使用数据库方法) func (r *casbinRepo) AddPolicies(rules [][]string) error { if len(rules) == 0 { return nil } casbinRules := make([]gormadapter.CasbinRule, len(rules)) for i, rule := range rules { casbinRules[i] = gormadapter.CasbinRule{ Ptype: "p", V0: rule[0], V1: rule[1], V2: rule[2], } } return r.db.Create(&casbinRules).Error } // UpdateCasbin 更新Casbin权限 func (r *casbinRepo) UpdateCasbin(adminAuthorityID, authorityId uint, casbinInfos []system.CasbinRule) error { authorityIdStr := strconv.FormatUint(uint64(authorityId), 10) // 清除旧权限 r.ClearCasbin(0, authorityIdStr) // 去重处理 deduplicateMap := make(map[string]bool) var rules [][]string for _, v := range casbinInfos { key := authorityIdStr + v.Path + v.Method if !deduplicateMap[key] { deduplicateMap[key] = true rules = append(rules, []string{authorityIdStr, v.Path, v.Method}) } } if len(rules) == 0 { return nil } // 使用enforcer添加策略 success, _ := r.enforcer.AddPolicies(rules) if !success { return errors.New("存在相同api,添加失败,请联系管理员") } return nil } // RemoveFilteredPolicy 删除筛选的策略 func (r *casbinRepo) RemoveFilteredPolicy(authorityId string) error { return r.db.Delete(&gormadapter.CasbinRule{}, "v0 = ?", authorityId).Error } // SyncPolicy 同步策略(先删除再添加) func (r *casbinRepo) SyncPolicy(authorityId string, rules [][]string) error { // 先删除旧策略 if err := r.RemoveFilteredPolicy(authorityId); err != nil { return err } // 再添加新策略 return r.AddPolicies(rules) }