package reportser import ( "context" "encoding/json" "fmt" "strconv" "strings" "time" "videoweb/pub/common/srvdef" "videoweb/pub/common/useragent" "videoweb/pub/dataReport" "videoweb/pub/models/contenttagmod" "videoweb/pub/models/eventmod" "videoweb/pub/models/playletchaptermod" "videoweb/pub/models/playletmod" "videoweb/pub/models/playletthememod" "videoweb/pub/models/videocategorymod" "videoweb/pub/models/videoinformationmod" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo/options" ) func ReportVideoComment(userId int64, ua useragent.UA, ip string, media *videoinformationmod.VideoInformation, content string) error { if media == nil { return srvdef.New(srvdef.Failure, "invalid user or media") } typeID, typeName := resolveMediaType(media) event := dataReport.NewCommonField(dataReport.EventTypeVideoComment, "", ua, ip, userId) event.Payload = dataReport.JsonRawMessage(&dataReport.VideoCommentEvent{ VideoEventPub: dataReport.VideoEventPub{ MediaId: "", VideoID: fmt.Sprintf("%v", media.Id), VideoTitle: media.Title, VideoTypeID: typeID, VideoTypeName: typeName, VideoContentType: videoContentType(media), RecommendTraceId: "", }, CommentContent: content, }) return insertEvent(event) } func ReportVideoCollect(userId int64, ua useragent.UA, ip string, media *videoinformationmod.VideoInformation, flag int64) error { if media == nil { return srvdef.New(srvdef.Failure, "invalid user or media") } typeID, typeName := resolveMediaType(media) event := dataReport.NewCommonField(dataReport.EventTypeVideoCollect, "", ua, ip, userId) event.Payload = dataReport.JsonRawMessage(&dataReport.VideoCollectEvent{ VideoEventPub: dataReport.VideoEventPub{ MediaId: "", VideoID: fmt.Sprintf("%v", media.Id), VideoTitle: media.Title, VideoTypeID: typeID, VideoTypeName: typeName, VideoContentType: videoContentType(media), RecommendTraceId: "", }, Flag: dataReport.JsonNumber(flag), }) return insertEvent(event) } func ReportVideoLike(userId int64, ua useragent.UA, ip string, media *videoinformationmod.VideoInformation, flag int64) error { if media == nil { return srvdef.New(srvdef.Failure, "invalid user or media") } typeID, typeName := resolveMediaType(media) event := dataReport.NewCommonField(dataReport.EventTypeVideoLike, "", ua, ip, userId) event.Payload = dataReport.JsonRawMessage(&dataReport.VideoLikeEvent{ VideoEventPub: dataReport.VideoEventPub{ MediaId: "", VideoID: fmt.Sprintf("%v", media.Id), VideoTitle: media.Title, VideoTypeID: typeID, VideoTypeName: typeName, VideoContentType: videoContentType(media), RecommendTraceId: "", }, Flag: dataReport.JsonNumber(flag), }) return insertEvent(event) } func ReportPlayletLike(userId int64, ua useragent.UA, ip string, playlet *playletmod.Playlet, flag int64) error { if playlet == nil { return srvdef.New(srvdef.Failure, "invalid user or playlet") } pub := playletToDramaPub(context.Background(), playlet, 0) if pub.DramaID == "" { return nil } event := dataReport.NewCommonField(dataReport.EventTypeDramaLike, "", ua, ip, userId) event.Payload = dataReport.JsonRawMessage(&dataReport.DramaLikeEvent{ DramaEventPub: pub, Flag: dataReport.JsonNumber(flag), }) return insertEvent(event) } // ReportPlayletCollect 上报短剧收藏状态变化 func ReportPlayletCollect(userId int64, ua useragent.UA, ip string, playlet *playletmod.Playlet, flag int64) error { if playlet == nil { return srvdef.New(srvdef.Failure, "invalid user or playlet") } pub := playletToDramaPub(context.Background(), playlet, 0) if pub.DramaID == "" { return nil } event := dataReport.NewCommonField(dataReport.EventTypeDramaCollect, "", ua, ip, userId) event.Payload = dataReport.JsonRawMessage(&dataReport.DramaCollectEvent{ DramaEventPub: pub, Flag: dataReport.JsonNumber(flag), }) return insertEvent(event) } func playletToDramaPub(ctx context.Context, playlet *playletmod.Playlet, chapterEpisode int64) dataReport.DramaEventPub { if playlet == nil { return dataReport.DramaEventPub{} } return playletChapterToDramaPub(ctx, playlet, findDramaReportChapter(ctx, playlet.Id, chapterEpisode)) } func playletChapterToDramaPub(ctx context.Context, playlet *playletmod.Playlet, chapter *playletchaptermod.PlayletChapter) dataReport.DramaEventPub { if playlet == nil { return dataReport.DramaEventPub{} } typeID, typeName := resolvePlayletType(ctx, playlet) tagKey, tagName := resolvePlayletTags(ctx, playlet.TagIds) episode := int64(1) dramaID := "" videoID := "" if chapter != nil && chapter.Id > 0 { if chapter.CurrentEpisode > 0 { episode = chapter.CurrentEpisode } dramaID = strconv.FormatInt(chapter.Id, 10) if chapter.MediaContentId > 0 { videoID = strconv.FormatUint(uint64(chapter.MediaContentId), 10) } } return dataReport.DramaEventPub{ DramaID: dramaID, DramaTitle: playlet.Title, Episode: dataReport.JsonNumber(episode), VideoID: videoID, TotalEpisode: dataReport.JsonNumber(playlet.TotalEpisode), DramaTypeID: typeID, DramaTypeName: typeName, DramaContentType: dataReport.DramaContentTypeShortDrama, DramaTagKey: tagKey, DramaTagName: tagName, } } // findDramaReportChapter 取上报用剧集。指定集数就用该集,未指定时用第一集。 func findDramaReportChapter(ctx context.Context, playletId, chapterEpisode int64) *playletchaptermod.PlayletChapter { if playletId <= 0 { return nil } projection := options.FindOne().SetProjection(bson.D{ {Key: playletchaptermod.FN.PlayletChapter.Id, Value: 1}, {Key: playletchaptermod.FN.PlayletChapter.MediaContentId, Value: 1}, {Key: playletchaptermod.FN.PlayletChapter.CurrentEpisode, Value: 1}, }) filter := bson.M{playletchaptermod.FN.PlayletChapter.PlayletId: playletId} if chapterEpisode > 0 { filter[playletchaptermod.FN.PlayletChapter.CurrentEpisode] = chapterEpisode chapter, _ := playletchaptermod.FindOnePlayletChapter(ctx, filter, projection) return chapter } chapter, _ := playletchaptermod.FindOnePlayletChapter(ctx, filter, projection.SetSort(bson.D{ {Key: playletchaptermod.FN.PlayletChapter.CurrentEpisode, Value: 1}, {Key: playletchaptermod.FN.PlayletChapter.Id, Value: 1}, })) return chapter } func resolvePlayletType(ctx context.Context, playlet *playletmod.Playlet) (string, string) { if playlet == nil || len(playlet.ThemeIds) == 0 { return "default", "默认分类" } id := playlet.ThemeIds[0] if id <= 0 { return "default", "默认分类" } name := "默认分类" queryCtx, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() themes, err := playletthememod.FindManyPlayletTheme(queryCtx, bson.M{ playletthememod.FN.PlayletTheme.Id: id, }, options.Find().SetProjection(bson.M{ playletthememod.FN.PlayletTheme.Id: 1, playletthememod.FN.PlayletTheme.Name: 1, })) if err == nil { for _, theme := range themes { if theme != nil && theme.Id == id && strings.TrimSpace(theme.Name) != "" { name = strings.TrimSpace(theme.Name) break } } } return strconv.FormatInt(id, 10), name } func resolvePlayletTags(ctx context.Context, ids []int64) (string, string) { keys := make([]string, 0, len(ids)) validIDs := make([]int64, 0, len(ids)) for _, id := range ids { if id > 0 { keys = append(keys, strconv.FormatInt(id, 10)) validIDs = append(validIDs, id) } } if len(keys) == 0 { return "default", "默认标签" } nameMap := map[int64]string{} queryCtx, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() if tags, err := contenttagmod.GetMapTags(queryCtx, validIDs); err == nil { for _, tag := range tags { if tag != nil { nameMap[tag.Id] = tag.Name } } } names := make([]string, 0, len(keys)) for _, id := range validIDs { name := strings.TrimSpace(nameMap[id]) if name == "" { name = strconv.FormatInt(id, 10) } names = append(names, name) } return strings.Join(keys, ","), strings.Join(names, ",") } func insertEvent(event dataReport.CommonField) error { b, _ := json.Marshal(event) return eventmod.InsertOneEvent(context.Background(), &eventmod.Event{ EventId: event.EventID, EventType: event.Event, Data: string(b), Status: eventmod.Default, CreatedAt: time.Now(), UpdatedAt: time.Now(), }) } func resolveMediaType(media *videoinformationmod.VideoInformation) (string, string) { var videoTypeID = "default" var videoTypeName = "默认分类" if media.CategoryId > 0 { // 复用 reportser 中的分类解析逻辑 ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) defer cancel() category, _ := videocategorymod.FindOneVideoCategory(ctx, bson.M{ videocategorymod.FN.VideoCategory.Id: media.CategoryId, }) if category != nil { videoTypeID = fmt.Sprintf("%v", category.Id) videoTypeName = category.Name } } return videoTypeID, videoTypeName } func videoContentType(media *videoinformationmod.VideoInformation) string { //if media != nil && media.ContentType == pubdef.ContentTypeVideoDsp { // return "short_video" //} return "video" }