Files
2026-10-26 16:28:14 +08:00

127 lines
4.6 KiB
Go

package playletser
import (
"context"
"time"
"videoweb/app/api/proto"
"videoweb/app/service/configser"
"videoweb/app/service/moreser"
"videoweb/app/service/reportser"
"videoweb/app/service/translationser"
"videoweb/pub/common/log"
"videoweb/pub/common/response"
"videoweb/pub/common/srvdef"
"videoweb/pub/common/useragent"
"videoweb/pub/models/playletfavoritemod"
"videoweb/pub/models/playletmod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
// FavoritePlaylet 收藏或取消收藏上架短剧,重复请求不重复变更收藏数
func FavoritePlaylet(ctx context.Context, userID int64, ip string, ua useragent.UA, req *proto.FavoritePlayletReq) (*proto.FavoritePlayletResp, *srvdef.SrvErr) {
if req == nil || userID <= 0 || req.Id <= 0 || req.IsFavorite == nil {
return nil, srvdef.New(srvdef.ErrParamError, "", "")
}
playlet, err := playletmod.FindOnePlaylet(ctx, bson.M{
playletmod.FN.Playlet.Id: req.Id, playletmod.FN.Playlet.Status: playletmod.StatusUp,
}, options.FindOne().SetProjection(bson.M{
playletmod.FN.Playlet.Id: 1, playletmod.FN.Playlet.Title: 1,
playletmod.FN.Playlet.TagIds: 1, playletmod.FN.Playlet.ThemeIds: 1,
playletmod.FN.Playlet.CountCollect: 1,
}))
if err != nil {
return nil, err
}
changed := false
flag := int64(1)
if *req.IsFavorite {
changed, err = playletfavoritemod.Upsert(ctx, userID, req.Id, time.Now())
} else {
flag = 2
changed, err = playletfavoritemod.Delete(ctx, bson.M{
playletfavoritemod.FieldUserID: userID, playletfavoritemod.FieldPlayletID: req.Id,
})
}
if err != nil {
return nil, err
}
if changed {
delta := int64(1)
if !*req.IsFavorite {
delta = -1
}
if delta > 0 || playlet.CountCollect > 0 {
if err := playletmod.UpdateOnePlaylet(ctx, bson.M{playletmod.FN.Playlet.Id: req.Id}, bson.M{
"$inc": bson.M{playletmod.FN.Playlet.CountCollect: delta},
}); err != nil {
return nil, err
}
playlet.CountCollect += delta
}
if err := reportser.ReportPlayletCollect(userID, ua, ip, playlet, flag); err != nil {
log.Warn("ReportPlayletCollect failed", log.Any("playletId", req.Id), log.Any("userId", userID), log.E(err))
}
}
return &proto.FavoritePlayletResp{Id: req.Id, IsFavorite: *req.IsFavorite, CountCollect: playlet.CountCollect}, nil
}
// QueryFavoritePlayletList 按收藏时间倒序查询当前用户收藏的上架短剧
func QueryFavoritePlayletList(ctx context.Context, userID int64, req *proto.QueryFavoritePlayletListReq) (*proto.QueryFavoritePlayletListResp, *srvdef.SrvErr) {
if userID <= 0 || req == nil {
return nil, srvdef.New(srvdef.ErrParamError, "", "")
}
pageNum, pageSize := moreser.NormalizePage(req.PageNum, req.PageSize, 20, 100)
pipeline := []bson.M{
{"$match": bson.M{playletfavoritemod.FieldUserID: userID}},
{"$lookup": bson.M{
"from": playletmod.TN.Playlet,
"localField": playletfavoritemod.FieldPlayletID,
"foreignField": playletmod.FN.Playlet.Id,
"as": "playlet",
}},
{"$unwind": "$playlet"},
{"$match": bson.M{"playlet." + playletmod.FN.Playlet.Status: playletmod.StatusUp}},
}
countRows := make([]struct {
Total int64 `bson:"total"`
}, 0)
countPipeline := append(append([]bson.M(nil), pipeline...), bson.M{"$count": "total"})
if err := playletfavoritemod.Aggregate(ctx, &countRows, countPipeline); err != nil {
return nil, err
}
total := int64(0)
if len(countRows) > 0 {
total = countRows[0].Total
}
resp := &proto.QueryFavoritePlayletListResp{BasePageResp: response.BasePageResp{
TotalCount: total, PageNum: int(pageNum), PageSize: int(pageSize), List: make([]*proto.PlayletData, 0),
}, Translations: translationser.GetTranslationData(), BottonTranslations: translationser.GetTranslationBottomList()}
if total == 0 || pageNum > (total-1)/pageSize+1 {
return resp, nil
}
pagePipeline := append(append([]bson.M(nil), pipeline...),
bson.M{"$sort": bson.D{{Key: playletfavoritemod.FieldCreatedAt, Value: -1}, {Key: playletfavoritemod.FieldID, Value: -1}}},
bson.M{"$skip": (pageNum - 1) * pageSize}, bson.M{"$limit": pageSize},
bson.M{"$replaceRoot": bson.M{"newRoot": "$playlet"}},
bson.M{"$project": appPlayletRecommendProjection},
)
list := make(playletmod.PlayletList, 0)
if err := playletfavoritemod.Aggregate(ctx, &list, pagePipeline); err != nil {
return nil, err
}
tagNames, themeNames, err := buildPlayletTagThemeNameMaps(ctx, list)
if err != nil {
return nil, err
}
cdn := configser.GetRequestConfig(ctx).ImgCdn
items := make([]*proto.PlayletData, 0, len(list))
for _, item := range list {
data := playletToAppData(item, cdn, tagNames, themeNames)
items = append(items, &data)
}
resp.List = items
return resp, nil
}