@@ -0,0 +1,168 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user