package appconfig import ( "encoding/json" "errors" "fmt" "hyapp-admin-server/internal/appctx" "hyapp-admin-server/internal/model" "gorm.io/gorm" ) const ( giftConfigGroup = "room-gift" giftQuantityPresetsKey = "quantity-presets" giftQuantityPresetMaxCount = 8 giftQuantityPresetMaxValue = 9_999 giftQuantityPresetsDescription = "语音房送礼数量档位,严格递增且每档为 1-9999" ) var defaultGiftQuantityPresets = []int32{1, 9, 99, 999} type giftConfigRequest struct { QuantityPresets []int32 `json:"quantityPresets"` } // GiftConfig 是当前 App 的语音房送礼配置;缺少持久化行时仍返回兼容旧客户端的默认档位。 type GiftConfig struct { AppCode string `json:"appCode"` QuantityPresets []int32 `json:"quantityPresets"` UpdatedAtMS int64 `json:"updatedAtMs"` } func (s *AppConfigService) GetGiftConfig(appCode string) (GiftConfig, error) { appCode = appctx.Normalize(appCode) item, err := s.store.GetOwnedAppConfig(appCode, giftConfigGroup, giftQuantityPresetsKey) if errors.Is(err, gorm.ErrRecordNotFound) { return GiftConfig{ AppCode: appCode, QuantityPresets: cloneGiftQuantityPresets(defaultGiftQuantityPresets), }, nil } if err != nil { return GiftConfig{}, err } return giftConfigFromModel(item) } func (s *AppConfigService) UpdateGiftConfig(appCode string, request giftConfigRequest) (GiftConfig, error) { appCode = appctx.Normalize(appCode) presets, err := normalizeGiftQuantityPresets(request.QuantityPresets) if err != nil { return GiftConfig{}, err } raw, err := json.Marshal(presets) if err != nil { return GiftConfig{}, err } // App 作用域只取鉴权上下文;请求体没有 app_code,保存 Lalu 时不会覆盖 Fami 或其他 App。 if err := s.store.UpsertScopedAppConfigs(appCode, []model.AppConfig{{ AppCode: appCode, Group: giftConfigGroup, Key: giftQuantityPresetsKey, Value: string(raw), Description: giftQuantityPresetsDescription, }}); err != nil { return GiftConfig{}, err } return s.GetGiftConfig(appCode) } func giftConfigFromModel(item model.AppConfig) (GiftConfig, error) { var presets []int32 if err := json.Unmarshal([]byte(item.Value), &presets); err != nil { return GiftConfig{}, fmt.Errorf("送礼数量档位配置格式不正确: %w", err) } presets, err := normalizeGiftQuantityPresets(presets) if err != nil { return GiftConfig{}, err } return GiftConfig{ AppCode: appctx.Normalize(item.AppCode), QuantityPresets: presets, UpdatedAtMS: item.UpdatedAtMS, }, nil } func normalizeGiftQuantityPresets(values []int32) ([]int32, error) { if len(values) == 0 || len(values) > giftQuantityPresetMaxCount { return nil, fmt.Errorf("送礼数量档位必须配置 1-%d 个", giftQuantityPresetMaxCount) } normalized := make([]int32, len(values)) var previous int32 for index, value := range values { if value < 1 || value > giftQuantityPresetMaxValue { return nil, fmt.Errorf("送礼数量档位必须在 1-%d 之间", giftQuantityPresetMaxValue) } if index > 0 && value <= previous { return nil, errors.New("送礼数量档位必须严格递增且不能重复") } normalized[index] = value previous = value } return normalized, nil } func cloneGiftQuantityPresets(values []int32) []int32 { return append([]int32(nil), values...) }