Initial commit: web_hghl_server

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 16:28:14 +08:00
co-authored by Claude Opus 4.7
commit 65fca60622
653 changed files with 135901 additions and 0 deletions
+279
View File
@@ -0,0 +1,279 @@
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"
}