package paymentguideser import ( "context" "fmt" "strings" "time" "91porn-server/models/cache/sysconfdata" "91porn-server/models/v/paymentguidemod" "go.mongodb.org/mongo-driver/bson/primitive" ) type ListReq struct { Scene string `form:"scene"` PageNumber int64 `form:"pageNumber,default=1" binding:"min=1"` PageSize int64 `form:"pageSize,default=20" binding:"min=1,max=100"` } type ListResp struct { Total int64 `json:"total"` HasNext bool `json:"hasNext"` List []paymentguidemod.PaymentGuide `json:"list"` SceneOptions []SceneOption `json:"sceneOptions"` } type SceneOption struct { Label string `json:"label"` Value string `json:"value"` TotalWatchCount *uint64 `json:"totalWatchCount,omitempty"` } // AddReq keeps the existing flat single-scene request compatible and adds an // optional batch envelope for applying one configuration to multiple scenes. type AddReq struct { paymentguidemod.PaymentGuide Scenes []string `json:"scenes,omitempty"` Config *paymentguidemod.PaymentGuide `json:"config,omitempty"` } type BatchAddReq struct { Scenes []string `json:"scenes"` Config paymentguidemod.PaymentGuide `json:"config"` } type BatchAddItem struct { Scene string `json:"scene"` ID string `json:"id"` } type BatchAddResp struct { List []BatchAddItem `json:"list"` } func (p AddReq) IsBatch() bool { return p.Config != nil || p.Scenes != nil } func (p *ListReq) List() (ListResp, error) { p.Scene = strings.ToUpper(strings.TrimSpace(p.Scene)) if p.Scene != "" && !paymentguidemod.ConfigurableScene(p.Scene) { return ListResp{}, fmt.Errorf("unsupported scene: %s", p.Scene) } list, total, hasNext, err := paymentguidemod.List( p.Scene, (p.PageNumber-1)*p.PageSize, p.PageSize, ) if list == nil { list = []paymentguidemod.PaymentGuide{} } normalizeVideoLimits(list) return ListResp{ Total: total, HasNext: hasNext, List: list, SceneOptions: sceneOptions(sysconfdata.GetTotalWatchCount()), }, err } func sceneOptions(totalWatchCount uint64) []SceneOption { return []SceneOption{ {Label: fmt.Sprintf("首页新用户免费%d次试看", totalWatchCount), Value: paymentguidemod.SceneHomeNewUserFreeTrial, TotalWatchCount: &totalWatchCount}, {Label: "首页老用户", Value: paymentguidemod.SceneHomeOldUser}, {Label: "视频试看3秒", Value: paymentguidemod.SceneVideoPreviewEnd}, {Label: "优惠倒计时", Value: paymentguidemod.SceneDiscountCountdown}, {Label: "视频返回", Value: paymentguidemod.SceneVideoBack}, {Label: "VIP中心", Value: paymentguidemod.SceneVIPCenter}, {Label: "VIP内容更新", Value: paymentguidemod.SceneVIPContentUpdate}, } } func normalizeVideoLimits(list []paymentguidemod.PaymentGuide) { for i := range list { if list[i].Scene == paymentguidemod.SceneVIPContentUpdate { list[i].VideoLimit = list[i].EffectiveVideoLimit() } } } func Add(config *paymentguidemod.PaymentGuide) error { config.Normalize() if !paymentguidemod.ConfigurableScene(config.Scene) { return fmt.Errorf("unsupported scene: %s", config.Scene) } return paymentguidemod.Insert(config) } func (p BatchAddReq) Configs() ([]paymentguidemod.PaymentGuide, error) { if len(p.Scenes) == 0 { return nil, fmt.Errorf("scenes are required") } if len(p.Scenes) > paymentguidemod.MaxBatchSceneCount { return nil, fmt.Errorf("scenes cannot contain more than %d entries", paymentguidemod.MaxBatchSceneCount) } seen := make(map[string]struct{}, len(p.Scenes)) configs := make([]paymentguidemod.PaymentGuide, 0, len(p.Scenes)) for _, rawScene := range p.Scenes { scene := strings.ToUpper(strings.TrimSpace(rawScene)) if !paymentguidemod.ConfigurableScene(scene) { return nil, fmt.Errorf("unsupported scene: %s", scene) } if _, ok := seen[scene]; ok { return nil, fmt.Errorf("duplicate scene: %s", scene) } seen[scene] = struct{}{} config := p.Config config.ID = primitive.NilObjectID config.Scene = scene config.Segments = append([]string(nil), p.Config.Segments...) config.VideoIDs = append([]string(nil), p.Config.VideoIDs...) if config.VideoLimit == 0 { config.VideoLimit = paymentguidemod.DefaultVIPContentVideoLimit } config.CreatedAt = time.Time{} config.UpdatedAt = time.Time{} config.Normalize() if err := config.Validate(); err != nil { return nil, fmt.Errorf("scene %s: %w", scene, err) } configs = append(configs, config) } return configs, nil } func BatchAdd(ctx context.Context, configs []paymentguidemod.PaymentGuide) (BatchAddResp, error) { if err := paymentguidemod.InsertMany(ctx, configs); err != nil { return BatchAddResp{}, err } items := make([]BatchAddItem, 0, len(configs)) for i := range configs { items = append(items, BatchAddItem{Scene: configs[i].Scene, ID: configs[i].ID.Hex()}) } return BatchAddResp{List: items}, nil } func Edit(config *paymentguidemod.PaymentGuide) error { config.Normalize() if !paymentguidemod.ConfigurableScene(config.Scene) { return fmt.Errorf("unsupported scene: %s", config.Scene) } return paymentguidemod.Update(config) } func Delete(id primitive.ObjectID) error { return paymentguidemod.Delete(id) }