Files
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

356 lines
12 KiB
Go

package commentser
import (
"91porn-server/app/service/messageser"
"91porn-server/app/service/taskser"
"91porn-server/common"
"91porn-server/common/log"
"91porn-server/common/stderr"
"91porn-server/common/truthutil"
"91porn-server/middleware/ua"
"91porn-server/models/commod"
"91porn-server/models/v/cmtmod"
"91porn-server/models/v/dailytaskmod"
"91porn-server/models/v/mediamod"
"91porn-server/models/v/messagemod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/vidmod"
"errors"
"fmt"
"time"
"unicode/utf8"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// GetVideoTotalComments 获取视频的评论数
func GetVideoTotalComments(objID primitive.ObjectID) (code stderr.Code, data int64, err error) {
return GetTotalComments(objID, cmtmod.OTypeVideo)
}
func GetTotalComments(objID primitive.ObjectID, objType cmtmod.OType) (code stderr.Code, data int64, err error) {
if objType == "" {
objType = cmtmod.OTypeVideo
}
params := bson.M{
"objID": objID,
"objType": objType,
"level": 1,
"status": 1,
"isDelete": false,
"isAdvertiser": bson.M{"$in": []any{nil, false}},
}
data, err = cmtmod.GetCount(params)
if err != nil {
code = stderr.ErrNetWorkBusy
return code, 0, err
}
code = stderr.Success
return code, data, err
}
// 获取二级评论列表
func GetSndCommentsList(uid uint64, objID primitive.ObjectID, cid primitive.ObjectID, fstID primitive.ObjectID, curTime time.Time, page commod.Page) (code stderr.Code, data []cmtmod.ChildRespList, err error) {
// 获取评论信息
stdQuery := commod.StdQuery{Page: &commod.PageBy{Num: page.PageNumber, Size: page.PageSize, CheckNext: true}, Order: &[]commod.OrderBy{}}
modList, err := cmtmod.CmtFindSecondLevelComments(objID, cid, fstID, curTime, stdQuery)
if err != nil {
code = stderr.ErrNetWorkBusy
log.Error("app service comment GetSndCommentsList CmtFindSecondLevelComments err", log.E(err))
return
}
// 空值直接返回
if modList == nil || len(modList) <= 0 {
code = stderr.Success
data = []cmtmod.ChildRespList{}
return
}
// 获取评论附加信息
cList, err := getChildCommentTackInfo(uid, modList)
if err != nil {
code = stderr.ErrNetWorkBusy
log.Error("app service comment GetSndCommentsList getSndCommentTackInfo err", log.E(err))
return
}
code = stderr.Success
data = cList
return
}
// PublishComment 发表评论
func PublishComment(uid uint64, ua ua.UA, ip string, param cmtmod.PublishReqInfo) (code stderr.Code, data interface{}, err error) {
// 获取用户状态
var user, publisher *usermod.User
if code, user, err = checkUserStatus(uid); err != nil || code != stderr.Success || user == nil {
return code, data, err
}
// 评论限制
if isCan, err := canPublishComment(uid); err != nil {
code = stderr.CommentErrSendFail
return code, data, err
} else if !isCan {
code = stderr.CommentPublishTooFrequent
return code, data, err
}
//检测评论是否包含网址,包含网址则发布不予处理
if uid > 200000 && !truthutil.CheckIsValid(param.Content, 1) {
log.Warn("comment send CheckIsValid fail", log.Any("uid", uid), log.Any("content", param.Content))
return stderr.Success, stderr.Success.Msg(), nil
}
// 校验视频是否通过审核
var videoInfo vidmod.VideoModel
var mediaInfo mediamod.Media
var isAuthor bool
var isOneself bool
if param.ObjType == "" || param.ObjType == cmtmod.OTypeVideo {
if code, videoInfo, err = checkVideoStatus(param.ObjID.Hex()); err != nil || code != stderr.Success || videoInfo.ID.IsZero() {
return code, data, err
}
// 获取视频作者信息
if publisher, err = usermod.FindUserByUID(videoInfo.PublisherID); err != nil {
log.Error("获取评论视频作者信息", log.Any("uid", uid), log.Any("ip", ip), log.Any("param", param), log.E(err))
return stderr.CommentErrSendFail, nil, err
}
if publisher == nil || publisher.ID.IsZero() {
return stderr.UserIsNotExists, nil, err
}
if uid == videoInfo.PublisherID {
isAuthor = true
}
}
if param.ObjType == cmtmod.OTypeCartoon || param.ObjType == cmtmod.OTypeDrama {
mediaInfo, err = mediamod.GetInfo(param.ObjID)
if err != nil || mediaInfo.ID.IsZero() || mediaInfo.IsDelete || mediaInfo.Status != 1 {
return stderr.CommentErrVideoIsInvalid, nil, err
}
if param.ObjType == cmtmod.OTypeDrama && mediaInfo.MediaType != mediamod.MediaTypeDrama {
return stderr.CommentErrVideoIsInvalid, nil, errors.New("invalid drama")
}
}
var cmtMod cmtmod.Comment
if code, cmtMod, err = getTrackInfo(uid, videoInfo.PublisherID, isAuthor, ip, param, cmtmod.CmtTypeVideo); code != stderr.Success || err != nil {
return code, data, err
}
cmtMod.IsAdvertiser = user.IsAdvertiser
if !mediaInfo.ID.IsZero() {
cmtMod.Title = mediaInfo.Title
}
var sUid uint64
if param.CID != "" {
// 根据回复ID获取用户信息
oid, _ := primitive.ObjectIDFromHex(param.CID)
cmt, err := cmtmod.CmtFindOneByID(oid)
if err != nil {
code = stderr.ErrDbQueryError
return code, data, err
}
// 校验是否是回复自己的评论
if cmt.UserID != uid {
sUid = cmt.UserID
}
if cmt.UserID == uid {
isOneself = true
}
}
// 保存到数据库
id, err := cmtmod.CmtInsertOne(&cmtMod)
fmt.Println(id.Hex())
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
if err = setGid(param.CID, param.RID, id); err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
// 推荐互动不按用户/账号身份过滤;运营后台直接配置的 fake* 展示值
// 不经过该真实评论落库链路,因此仍不会进入推荐累计分。
if param.ObjType == "" || param.ObjType == cmtmod.OTypeVideo {
if incErr := vidmod.IncrementRecommendInteraction(param.ObjID, vidmod.RecommendInteractionComment); incErr != nil {
// 评论已落库,推荐累计失败只记录,不能向客户端返回发布失败。
log.Error("increment recommend comment failed", log.E(incErr), log.Any("objID", param.ObjID))
}
}
if param.ObjType == cmtmod.OTypeDrama {
if incErr := mediamod.IncrCommentCountByID(param.ObjID, 1); incErr != nil {
log.Error("increment drama comment count failed", log.E(incErr), log.Any("objID", param.ObjID))
}
}
// 增加评论数(审核只统计已审核通过的评论)
//if code, err = incCommentCount(param.CID, param.ObjType, param.ObjID); code != stderr.Success || err != nil {
// return code, data, err
//}
//存动态
common.Go(func() {
if param.Content != "" && utf8.RuneCountInString(param.Content) >= 10 {
_ = taskser.CompleteDailyTask(nil, uid, dailytaskmod.DailyComment)
}
if !isAuthor && videoInfo.Title != "" {
dynamicContent := fmt.Sprintf("%s 于 %s 评论了你的作品", user.Name, time.Now().Format("15:04:05"))
messageser.PublicAddMsg(messagemod.PublicAddMsg{
SendUid: uid,
TakeUid: videoInfo.PublisherID,
MsgType: messagemod.CommentMsg,
ObjId: videoInfo.ID,
ObjName: videoInfo.Title,
ObjCover: videoInfo.Cover,
Content: dynamicContent, //param.Content,
})
}
if !isOneself && videoInfo.Title != "" && param.CID != "" && sUid != 0 {
dynamicContent := fmt.Sprintf("%s 于 %s 回复了你的评论", user.Name, time.Now().Format("15:04:05"))
messageser.PublicAddMsg(messagemod.PublicAddMsg{
SendUid: uid,
TakeUid: sUid,
MsgType: messagemod.ReplyCommentMsg,
ObjId: videoInfo.ID,
ObjName: videoInfo.Title,
ObjCover: videoInfo.Cover,
Content: dynamicContent, //param.Content,
})
}
})
//if (user.VipLevel == 0 || user.VipExpireDate.Before(now)) && !user.GetSuperUser(now) {
// if err = appg.Redis.Set(redisconst.CommentCacheKey(uid), data, 1*time.Minute); err != nil {
// log.Warn(fmt.Sprintf("用户ID:%d;IP:%s;保存缓存数据异常:%v", uid, ip, err))
// }
//}
// 获取该评论
return getRespInfoAfterPublish(uid, id, param.Level)
}
//func DailyComment(uid uint64) {
// key := redisconst.DailyTaskCacheKey(uid, dailytaskmod.DailyComment, timeutil.BeginOfToday())
// if appg.Redis.Exists(key) {
// return
// }
// tasks, err := dailytaskmod.GetUserDailyTaskByType(nil, dailytaskmod.DailyComment)
// if err != nil {
// return
// }
//
// if tasks == nil || tasks.ID.IsZero() {
// return
// }
//
// // 获取任务记录
// today := timeutil.BeginningOfDay(time.Now())
// item, err := taskrecordmod.GetUserRecordByTime(uid, tasks.ID, today)
// if item == nil || item.ID.IsZero() {
// now := time.Now()
// // 更新今日登录记录
// filter := bson.M{"uid": uid, "recordTime": today, "taskId": tasks.ID}
// cond := bson.M{
// "uid": uid,
// "recordTime": today,
// "taskId": tasks.ID,
// "type": taskrecordmod.DailyTask,
// "taskType": taskrecordmod.DailyComment,
// "status": taskrecordmod.UnReceived,
// "count": 1,
// "updateTime": now,
// "createTime": now,
// }
// if err := taskrecordmod.InsertTask(nil, filter, cond); err != nil {
// return
// }
// }
// // 判断每日评论只可三次
// if item != nil && !item.ID.IsZero() && item.Count < 3 {
// filter := bson.M{"uid": uid, "recordTime": today, "taskId": tasks.ID}
// if err := taskrecordmod.CurrentCountUpdate(nil, filter); err != nil {
// return
// }
// }
// // 每日超过三次评论放入缓存
// if item != nil && !item.ID.IsZero() && item.Count > 2 {
// err = appg.Redis.Set(key, "_", time.Hour*24)
// if err != nil {
// return
// }
// }
// return
//}
// NoVidPublishComment 非视频帖子发表评论
func NoVidPublishComment(uid uint64, ip, cmtType string, param cmtmod.PublishReqInfo) (code stderr.Code, data interface{}, err error) {
var publisherID uint64
// 获取用户状态
var user *usermod.User
if code, user, err = checkUserStatus(uid); err != nil || code != stderr.Success || user == nil {
return code, data, err
}
// 评论限制
if isCan, err := canPublishComment(uid); err != nil {
code = stderr.CommentErrSendFail
return code, data, err
} else if !isCan {
code = stderr.CommentPublishTooFrequent
return code, data, err
}
//检测评论是否包含网址,包含网址则发布不予处理
if uid > 200000 && !truthutil.CheckIsValid(param.Content, 1) {
log.Warn("comment send CheckIsValid fail", log.Any("uid", uid), log.Any("content", param.Content))
return stderr.Success, stderr.Success.Msg(), nil
}
var isAuthor bool
if uid == publisherID {
isAuthor = true
}
var cmtMod cmtmod.Comment
if code, cmtMod, err = getTrackInfo(uid, publisherID, isAuthor, ip, param, cmtmod.CmtNoVideo); code != stderr.Success || err != nil {
return code, data, err
}
cmtMod.IsAdvertiser = user.IsAdvertiser
// 保存到数据库
id, err := cmtmod.CmtInsertOne(&cmtMod)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
if err = setGid(param.CID, param.RID, id); err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
common.Go(func() {
// 增加评论数
if param.Level == 2 {
_id, err := primitive.ObjectIDFromHex(param.CID)
if err != nil {
log.Warn("NoVidPublishComment primitive.ObjectIDFromHex err,", log.Any("CID", param.CID), log.Any("ToUserID", param.ToUserID))
}
if err = cmtmod.CmtIncreaseCommentCountByID(_id); err != nil {
log.Warn("NoVidPublishComment cmtmod.CmtIncreaseCommentCountByID err,", log.Any("err", err.Error()), log.Any("CID", param.CID), log.Any("ToUserID", param.ToUserID))
}
}
})
//存动态
//common.Go(func() {
// if objName != "" {
//messageser.PublicAddMsg(messagemod.PublicAddMsg{
// SendUid: uid,
// TakeUid: publisherID,
// MsgType: messagemod.DesireMsg,
// ObjId: objID,
// ObjName: objName,
//})
// }
//})
// 获取该评论
return getRespInfoAfterPublish(uid, id, param.Level)
}