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 }