package repository import ( "context" "permission/reborn/domain/entity" "permission/reborn/domain/errors" "permission/reborn/domain/repository" "gorm.io/gorm" ) type permissionRepository struct { db *gorm.DB cache repository.CacheRepository } // NewPermissionRepository 建立權限 Repository func NewPermissionRepository(db *gorm.DB, cache repository.CacheRepository) repository.PermissionRepository { return &permissionRepository{ db: db, cache: cache, } } func (r *permissionRepository) Get(ctx context.Context, id int64) (*entity.Permission, error) { var perm entity.Permission err := r.db.WithContext(ctx). Where("id = ? AND status != ?", id, entity.StatusDeleted). First(&perm).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.ErrPermissionNotFound } return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permission", err) } return &perm, nil } func (r *permissionRepository) GetByName(ctx context.Context, name string) (*entity.Permission, error) { var perm entity.Permission err := r.db.WithContext(ctx). Where("name = ? AND status != ?", name, entity.StatusDeleted). First(&perm).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.ErrPermissionNotFound } return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permission by name", err) } return &perm, nil } func (r *permissionRepository) GetByNames(ctx context.Context, names []string) ([]*entity.Permission, error) { if len(names) == 0 { return []*entity.Permission{}, nil } var perms []*entity.Permission err := r.db.WithContext(ctx). Where("name IN ? AND status != ?", names, entity.StatusDeleted). Find(&perms).Error if err != nil { return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permissions by names", err) } return perms, nil } func (r *permissionRepository) GetByHTTP(ctx context.Context, path, method string) (*entity.Permission, error) { var perm entity.Permission err := r.db.WithContext(ctx). Where("http_path = ? AND http_method = ? AND status != ?", path, method, entity.StatusDeleted). First(&perm).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.ErrPermissionNotFound } return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get permission by http", err) } return &perm, nil } func (r *permissionRepository) List(ctx context.Context, filter repository.PermissionFilter) ([]*entity.Permission, error) { query := r.buildQuery(ctx, filter) var perms []*entity.Permission if err := query.Find(&perms).Error; err != nil { return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to list permissions", err) } return perms, nil } func (r *permissionRepository) ListActive(ctx context.Context) ([]*entity.Permission, error) { // 嘗試從快取取得 if r.cache != nil { var perms []*entity.Permission err := r.cache.GetObject(ctx, repository.CacheKeyPermissionList, &perms) if err == nil && len(perms) > 0 { return perms, nil } } // 從資料庫查詢 var perms []*entity.Permission err := r.db.WithContext(ctx). Where("status = ?", entity.StatusActive). Order("parent_id, id"). Find(&perms).Error if err != nil { return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to list active permissions", err) } // 存入快取 if r.cache != nil { _ = r.cache.SetObject(ctx, repository.CacheKeyPermissionList, perms, 0) // 使用預設 TTL } return perms, nil } func (r *permissionRepository) GetChildren(ctx context.Context, parentID int64) ([]*entity.Permission, error) { var perms []*entity.Permission err := r.db.WithContext(ctx). Where("parent_id = ? AND status != ?", parentID, entity.StatusDeleted). Find(&perms).Error if err != nil { return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get children permissions", err) } return perms, nil } func (r *permissionRepository) buildQuery(ctx context.Context, filter repository.PermissionFilter) *gorm.DB { query := r.db.WithContext(ctx). Model(&entity.Permission{}). Where("status != ?", entity.StatusDeleted) if filter.Type != nil { query = query.Where("type = ?", *filter.Type) } if filter.Status != nil { query = query.Where("status = ?", *filter.Status) } if filter.ParentID != nil { query = query.Where("parent_id = ?", *filter.ParentID) } return query.Order("parent_id, id") }