package srv_playlet import ( "context" "regexp" "strings" "time" "videoweb/pub/common/response" "videoweb/pub/common/slugx" "videoweb/pub/common/srvdef" "videoweb/pub/common/utils" "videoweb/pub/models/playletmod" "videoweb/pub/models/playletthememod" "videoweb/web/api/proto" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) var playletThemeWebProjection = bson.D{ {Key: playletthememod.FN.PlayletTheme.Id, Value: 1}, {Key: playletthememod.FN.PlayletTheme.Name, Value: 1}, {Key: playletthememod.FN.PlayletTheme.Slug, Value: 1}, {Key: playletthememod.FN.PlayletTheme.Icon, Value: 1}, {Key: playletthememod.FN.PlayletTheme.Status, Value: 1}, {Key: playletthememod.FN.PlayletTheme.Rank, Value: 1}, {Key: playletthememod.FN.PlayletTheme.SeoInfo.Title, Value: 1}, {Key: playletthememod.FN.PlayletTheme.SeoInfo.Description, Value: 1}, {Key: playletthememod.FN.PlayletTheme.SeoInfo.Keyworld, Value: 1}, {Key: playletthememod.FN.PlayletTheme.CreatedAt, Value: 1}, {Key: playletthememod.FN.PlayletTheme.UpdatedAt, Value: 1}, } // ListPlayletTheme 分页查询题材列表 func ListPlayletTheme(ctx context.Context, req *proto.PlayletThemeListReq) (*proto.PlayletThemeListPageResp, *srvdef.SrvErr) { if req == nil { return nil, srvdef.New(srvdef.ErrParamError, "", "") } filter := bson.M{} if req.Id != nil && *req.Id > 0 { filter[playletthememod.FN.PlayletTheme.Id] = *req.Id } if req.Status != nil { filter[playletthememod.FN.PlayletTheme.Status] = *req.Status } if name := strings.TrimSpace(req.Name); name != "" { filter[playletthememod.FN.PlayletTheme.Name] = bson.M{"$regex": regexp.QuoteMeta(name)} } pageNum, pageSize := normalizePage(req.PageNum, req.PageSize) totalCount, err := playletthememod.CountPlayletTheme(ctx, filter) if err != nil { return nil, err } resp := &proto.PlayletThemeListPageResp{ BasePageResp: response.BasePageResp{ TotalCount: totalCount, PageSize: int(pageSize), PageNum: int(pageNum), List: make([]*proto.PlayletThemeListResp, 0), }, } if totalCount == 0 { return resp, nil } list, err := playletthememod.FindManyPlayletTheme(ctx, filter, options.Find(). SetProjection(playletThemeWebProjection). SetSort(bson.D{ {Key: playletthememod.FN.PlayletTheme.Rank, Value: -1}, {Key: playletthememod.FN.PlayletTheme.Id, Value: -1}, }). SetSkip((pageNum-1)*pageSize). SetLimit(pageSize)) if err != nil { return nil, err } items := make([]*proto.PlayletThemeListResp, 0, len(list)) for _, item := range list { if item == nil { continue } items = append(items, &proto.PlayletThemeListResp{ Id: item.Id, Name: item.Name, Slug: item.Slug, Icon: item.Icon, Status: item.Status, Rank: item.Rank, SeoInfo: normalizeSeoValue(item.SeoInfo), CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, }) } resp.List = items return resp, nil } // AddPlayletTheme 新增题材 func AddPlayletTheme(ctx context.Context, req *proto.PlayletThemeAddReq) (*proto.PlayletThemeAddResp, *srvdef.SrvErr) { if req == nil || strings.TrimSpace(req.Name) == "" { return nil, srvdef.New(srvdef.ErrParamError, "题材名称不能为空", "") } doc := &playletthememod.PlayletTheme{ Name: strings.TrimSpace(req.Name), Slug: req.Slug, Icon: strings.TrimSpace(req.Icon), Status: req.Status, Rank: req.Rank, SeoInfo: normalizeSeoValue(req.SeoInfo), } exists := func(s string) bool { item, _ := playletthememod.FindOnePlayletTheme(ctx, slugx.Filter( playletthememod.FN.PlayletTheme.Slug, playletthememod.FN.PlayletTheme.Id, s, 0)) return item != nil } if serr := slugx.Ensure(&doc.Slug, utils.SlugSourceFromKeywordsOrTitle(doc.SeoInfo.Keyworld, doc.Name), exists); serr != nil { return nil, serr } if err := playletthememod.InsertOnePlayletTheme(ctx, doc); err != nil { return nil, err } clearAppPlayletHomeCache() return &proto.PlayletThemeAddResp{Id: doc.Id}, nil } // UpdatePlayletTheme 更新题材 func UpdatePlayletTheme(ctx context.Context, req *proto.PlayletThemeUpdateReq) *srvdef.SrvErr { if req == nil || req.Id <= 0 { return srvdef.New(srvdef.ErrParamError, "题材ID无效", "") } current, err := playletthememod.FindOnePlayletTheme(ctx, bson.M{ playletthememod.FN.PlayletTheme.Id: req.Id, }) if err != nil { return err } setDoc := bson.M{playletthememod.FN.PlayletTheme.UpdatedAt: time.Now()} if req.Name != nil { name := strings.TrimSpace(*req.Name) if name == "" { return srvdef.New(srvdef.ErrParamError, "题材名称不能为空", "") } setDoc[playletthememod.FN.PlayletTheme.Name] = name } if req.Icon != nil { setDoc[playletthememod.FN.PlayletTheme.Icon] = strings.TrimSpace(*req.Icon) } if req.Status != nil { setDoc[playletthememod.FN.PlayletTheme.Status] = *req.Status } if req.Rank != nil { setDoc[playletthememod.FN.PlayletTheme.Rank] = *req.Rank } if req.SeoInfo != nil { setDoc["seoInfo"] = normalizeSeoValue(*req.SeoInfo) } name := current.Name if req.Name != nil { name = strings.TrimSpace(*req.Name) } keywords := current.SeoInfo.Keyworld if req.SeoInfo != nil { keywords = normalizeSeoValue(*req.SeoInfo).Keyworld } exists := func(s string) bool { item, _ := playletthememod.FindOnePlayletTheme(ctx, slugx.Filter( playletthememod.FN.PlayletTheme.Slug, playletthememod.FN.PlayletTheme.Id, s, req.Id)) return item != nil } slug, changed, serr := slugx.PrepareOnUpdate(current.Slug, req.Slug, utils.SlugSourceFromKeywordsOrTitle(keywords, name), exists) if serr != nil { return serr } if changed { setDoc[playletthememod.FN.PlayletTheme.Slug] = slug } if len(setDoc) <= 1 { return srvdef.New(srvdef.ErrParamError, "没有可更新字段", "") } if err := playletthememod.UpdateOnePlayletTheme(ctx, bson.M{playletthememod.FN.PlayletTheme.Id: req.Id}, bson.M{"$set": setDoc}, ); err != nil { return err } clearAppPlayletHomeCache() return nil } // DelPlayletTheme 删除题材,被短剧引用时禁止删除 func DelPlayletTheme(ctx context.Context, id int64) *srvdef.SrvErr { if id <= 0 { return srvdef.New(srvdef.ErrParamError, "题材ID无效", "") } usedCount, err := playletmod.CountPlaylet(ctx, bson.M{ playletmod.FN.Playlet.ThemeIds: bson.M{"$in": []int64{id}}, }) if err != nil { return err } if usedCount > 0 { return srvdef.New(srvdef.ErrParamError, "题材已被短剧引用,无法删除", "") } count, err := playletthememod.DelOnePlayletTheme(ctx, bson.M{playletthememod.FN.PlayletTheme.Id: id}) if err != nil { return err } if count == 0 { return srvdef.New(srvdef.ErrNoData, "", "") } clearAppPlayletHomeCache() return nil }