package service import ( "context" "fmt" "strings" "oci-portal/internal/oci" ) // RegionSubscriptionView 在云端订阅信息之上补充本地维护的友好名称。 type RegionSubscriptionView struct { oci.RegionSubscription Alias string `json:"alias"` } // RegionSubscriptions 返回租户已订阅的区域列表(订阅 Tab 使用 SDK 实时数据); // 开启多区域支持时与缓存比对,有差异即入库,保持缓存跟随真实状态。 func (s *OciConfigService) RegionSubscriptions(ctx context.Context, id uint) ([]RegionSubscriptionView, error) { cfg, err := s.Get(ctx, id) if err != nil { return nil, err } cred, err := s.credentialsOf(cfg) if err != nil { return nil, err } subs, err := s.client.ListRegionSubscriptions(ctx, cred) if err != nil { return nil, err } if cfg.MultiRegion { s.reconcileRegionCache(ctx, cfg.ID, subs) } return enrichRegionAlias(subs), nil } // SubscribeRegion 为租户订阅新区域并返回最新订阅列表。 // OCI 区域订阅一经创建不可取消。 func (s *OciConfigService) SubscribeRegion(ctx context.Context, id uint, regionKey string) ([]RegionSubscriptionView, error) { regionKey = strings.ToUpper(strings.TrimSpace(regionKey)) if regionKey == "" { return nil, fmt.Errorf("subscribe region: region key is empty") } cfg, err := s.Get(ctx, id) if err != nil { return nil, err } cred, err := s.credentialsOf(cfg) if err != nil { return nil, err } // 订阅请求必须发往 home region;本地表查不到时退回配置默认区域 if err := s.client.SubscribeRegion(ctx, cred, homeRegionOf(cfg), regionKey); err != nil { return nil, err } subs, err := s.client.ListRegionSubscriptions(ctx, cred) if err != nil { return nil, err } // 订阅成功入库(新区域 IN_PROGRESS 状态随缓存读取持续刷新直到 READY) if cfg.MultiRegion { _ = s.saveRegionCache(ctx, cfg.ID, subs) } return enrichRegionAlias(subs), nil } // Limits 查询租户在指定区域、服务下的配额。 func (s *OciConfigService) Limits(ctx context.Context, id uint, q oci.LimitsQuery) ([]oci.LimitValue, error) { if q.Service == "" { return nil, fmt.Errorf("list limits: service is empty") } cfg, err := s.Get(ctx, id) if err != nil { return nil, err } cred, err := s.credentialsOf(cfg) if err != nil { return nil, err } return s.client.ListLimits(ctx, cred, q) } func enrichRegionAlias(subs []oci.RegionSubscription) []RegionSubscriptionView { views := make([]RegionSubscriptionView, 0, len(subs)) for _, sub := range subs { view := RegionSubscriptionView{RegionSubscription: sub} if info, ok := oci.RegionByKey(sub.Key); ok { view.Alias = info.Alias } views = append(views, view) } return views }