Files
web_hghl_server/web/service/srv_playlet/theme.go
T
2026-10-26 16:28:14 +08:00

214 lines
6.6 KiB
Go

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
}