Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+424
View File
@@ -0,0 +1,424 @@
package commentser
import (
"91porn-server/app/service/taskser"
"91porn-server/common"
"91porn-server/common/log"
"91porn-server/common/stderr"
"91porn-server/models/commod"
"91porn-server/models/v/cmtmod"
"91porn-server/models/v/dailytaskmod"
"91porn-server/models/v/locmod"
"91porn-server/models/v/messagemod"
"91porn-server/models/v/txnmod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/vidmod"
"91porn-server/models/v/walletmod"
"91porn-server/web/service/chat_message_ser"
"91porn-server/web/vidhelp"
"91porn-server/web/webg"
"errors"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// GetCommentList 后台获取评论列表
func GetCommentList(vidID string, cUID uint64, content string, isRobot, isAdvertiser *bool, status *int, page commod.Page) (data interface{}, err error) {
cList, count, err := cmtmod.CmtFindCommentsAndCount(vidID, cUID, content, isRobot, isAdvertiser, status, page)
if err != nil {
log.Error("web service comment GetCommentList FindUserByUID error", log.E(err), log.Any("vidID", vidID), log.Any("cUID", cUID), log.Any("content", content))
return
}
var cmtList []cmtmod.WebCmtRespList
var uids []uint64
for _, v := range cList {
// 获取评论的用户是否已禁言
usr, err := usermod.FindUserByUID(v.UserID)
if err != nil || usr == nil {
log.Error("web service comment GetCommentList FindUserByUID error", log.E(err), log.Any("uid", v.UserID))
continue // 避免测试服脏数据造成无数据返回
}
tmp := cmtmod.WebCmtRespList{
ID: v.ID,
ObjID: v.ObjID,
UserID: v.UserID,
LikeCount: v.LikeCount,
Content: v.Content,
Level: v.Level,
Status: v.Status,
IsDelete: v.IsDelete,
LinkStr: v.LinkStr,
IsBaned: usr.HasBanned,
IsGodComment: v.IsGodComment,
Portrait: usr.Portrait,
Name: usr.Name,
CreatedAt: v.CreatedAt,
IsRobot: v.IsRobot,
HasLocked: usr.HasLocked,
IsAdvertiser: usr.IsAdvertiser,
Image: v.Image,
}
cmtList = append(cmtList, tmp)
uids = append(uids, v.UserID)
}
if cmtList == nil {
cmtList = []cmtmod.WebCmtRespList{}
}
resp := make(map[string]interface{})
resp["list"] = cmtList
resp["total"] = count
resp["uids"] = uids
data = resp
return
}
// 后台评论管理屏蔽评论
func DeleteCommentsByID(ids []primitive.ObjectID, uid uint64, content string) (err error) {
var cmtList []cmtmod.Comment
if uid != 0 {
// 获取评论
if cmtList, err = cmtmod.GetCommentsByUID(uid); err != nil {
return
}
if err = cmtmod.DelCommentsByUID(uid); err != nil {
return
}
} else if content != "" {
if cmtList, err = cmtmod.GetCommentsByContent(content); err != nil {
return
}
if err = cmtmod.DelCommentsByContent(content); err != nil {
return
}
} else {
if ids == nil || len(ids) == 0 {
return
}
if cmtList, err = cmtmod.GetCommentsByIDS(ids); err != nil {
return
}
if err = cmtmod.DelCommentsByIDS(ids); err != nil {
return
}
}
// 评论数更新
for _, v := range cmtList {
// 视频评论数-1
_ = vidhelp.DecCommentCount(v.ObjID)
// 删除子评论
if v.Level == 1 {
var childIDS []primitive.ObjectID
// 获取子评论
childCmtList, _ := cmtmod.GetCommentsByCID(v.ObjID, v.ID)
for _, v1 := range childCmtList {
childIDS = append(childIDS, v1.ID)
// 视频评论数-1
_ = vidhelp.DecCommentCount(v1.ObjID)
}
if childIDS == nil || len(childIDS) == 0 {
continue
}
// 删除评论
_ = cmtmod.DelCommentsByIDS(childIDS)
}
// 评论数-1
if v.Level == 2 && !v.CID.IsZero() {
_ = cmtmod.CmtDecreaseCommentCountByID(v.CID)
}
}
return
}
// 后台获取评论详情
func GetCommentInfo(id primitive.ObjectID) (data interface{}, err error) {
return cmtmod.CmtFindOneByID(id)
}
// AccessComment 后台评论通过审核
func AccessComment(id primitive.ObjectID) (err error) {
cmt, err := cmtmod.CmtFindOneByID(id)
if err != nil || cmt.ID.IsZero() {
log.Error("web service comment AccessComment CmtFindOneByID error", log.E(err), log.Any("id", id))
return
}
err = cmtmod.CmtUpdateCommentStatusByID(id, 1)
if err != nil {
log.Error("web service comment GetCommentList CmtUpdateCommentStatusByID error", log.E(err), log.Any("uid", id))
return
}
// 审核通过增加评论数
err = vidmod.IncCommentCount(cmt.ObjID)
if err != nil {
log.Error("web service comment GetCommentList IncCommentCount error", log.E(err), log.Any("uid", id))
return
}
return
}
// BatchAccessComment 批量后台评论通过审核
func BatchAccessComment(ids []primitive.ObjectID, status int) (err error) {
cmt, err := cmtmod.CmtFindOneByIds(ids)
if err != nil || len(cmt) <= 0 {
log.Error("web service comment AccessComment CmtFindOneByIds error", log.E(err), log.Any("ids", ids))
return
}
err = cmtmod.PassCommentStatusByIds(ids, status)
if err != nil {
log.Error("web service BatchAccessComment PassCommentStatusByIds error", log.E(err))
return
}
return
}
// PublishComment 发表评论 统一以作者身份回复
func PublishComment(param cmtmod.PublishReqInfo) (code stderr.Code, err error) {
videoInfo, err := vidmod.GetVideoInfo(param.ObjID.Hex())
if err != nil || videoInfo.ID.IsZero() {
code = stderr.CommentErrSendFail
code.SetMsg("current video is not exist or find error")
return code, err
}
var cmtMod cmtmod.Comment
isAuthor := false
if videoInfo.PublisherID == param.ToUserID {
isAuthor = true
}
if code, cmtMod, err = getTrackInfo(videoInfo, "", isAuthor, param); code != stderr.Success || err != nil {
return code, err
}
// 保存到数据库
id, err := cmtmod.CmtInsertOne(&cmtMod)
if err != nil {
code = stderr.CommentErrSendFail
return code, err
}
if err = setGid(param.CID, param.RID, id); err != nil {
code = stderr.CommentErrSendFail
return code, err
}
// 增加评论数
incCommentCount(param.CID, param.ObjID)
// 获取该评论
return
}
// 获取相关信息
func getTrackInfo(videoInfo vidmod.VideoModel, ip string, isAuthor bool, param cmtmod.PublishReqInfo) (code stderr.Code, data cmtmod.Comment, err error) {
var cid primitive.ObjectID
var publiserID = videoInfo.PublisherID
if param.CID != "" {
if cid, err = primitive.ObjectIDFromHex(param.CID); err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
}
loc, _ := locmod.GetLocationInfoByID(videoInfo.Location)
now := time.Now()
data = cmtmod.Comment{
ObjID: param.ObjID,
CID: cid,
PublisherID: publiserID,
SortCnt: 0,
ToUserID: param.ToUserID,
Content: param.Content,
OrgContent: param.Content,
UserID: param.ToUserID,
Status: 1,
Level: param.Level,
AuthorMark: isAuthor,
IsAuthor: isAuthor,
IsDelete: false,
CommentCount: 0,
LikeCount: 0,
IPAddr: ip,
City: loc.City,
IsRobot: true,
CreatedAt: now,
}
if param.ToUserID != 0 {
if param.Level == 1 {
user, err := usermod.FindUserByUID(param.ToUserID)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
data.UserID = user.UID
} else {
rCmt, err := cmtmod.CmtFindOneByID(cid)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
user, err := usermod.FindUserByUID(rCmt.UserID)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
data.UserID = param.ToUserID
data.ToUserID = rCmt.UserID
data.ToUserName = user.Name
}
}
if param.RID != "" {
rid, err := primitive.ObjectIDFromHex(param.RID)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
rCmt, err := cmtmod.CmtFindOneByID(rid)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
user, err := usermod.FindUserByUID(rCmt.UserID)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
if rCmt.Level != 1 {
// 如果回复的不是1级,则需要写入rid
data.RID = rid
}
data.GID = rCmt.GID
data.AuthorMark = rCmt.AuthorMark
data.SortCnt = rCmt.SortCnt
data.Type = cmtmod.CmtTypeReply
data.PublisherID = rCmt.UserID
data.ToUserName = user.Name
data.ToUserID = rCmt.UserID
if !rCmt.CID.IsZero() {
data.CID = rCmt.CID
}
} else if param.RID == "" && !cid.IsZero() {
data.Type = cmtmod.CmtTypeComment
cCmt, err := cmtmod.CmtFindOneByID(cid)
if err != nil {
code = stderr.CommentErrSendFail
return code, data, err
}
data.PublisherID = cCmt.UserID
} else {
data.PublisherID = videoInfo.PublisherID
data.Type = cmtmod.CmtTypeVideo
}
code = stderr.Success
return
}
// 设置分组id
func setGid(cid string, rid string, id primitive.ObjectID) (err error) {
if cid != "" && rid == "" {
return cmtmod.SetGid(id)
}
return
}
// 增加评论数
func incCommentCount(cid string, objID primitive.ObjectID) {
if cid != "" {
var objCid primitive.ObjectID
objCid, err := primitive.ObjectIDFromHex(cid)
if err != nil {
return
}
// 根据cid获取评论信息
if toComment, err := cmtmod.CmtFindOneByID(objCid); err != nil || (toComment.Level != 1 && toComment.Level != 2) {
return
}
if err := cmtmod.CmtIncreaseCommentCountByID(objCid); err != nil {
return
}
}
// 增加视频评论数
if err := vidhelp.IncCommentCount(objID); err != nil {
return
}
}
// UpdateComment 后台评论设置
func UpdateComment(in *cmtmod.EditCond) (err error) {
cmt, err := cmtmod.CmtFindOneByID(in.ID)
if err != nil || cmt.ID.IsZero() {
log.Error("web service comment AccessComment CmtFindOneByID error", log.E(err), log.Any("id", in.ID))
return errors.New("comment is err or null")
}
if in.LinkStr == nil && cmt.Level != 1 && in.LikeCount == nil {
return errors.New("comment level is not 1")
}
if in.LinkStr == nil && cmt.IsAuthor && in.LikeCount == nil {
return errors.New("author not allow godComment")
}
if in.LinkStr == nil && in.IsGodComment == nil && in.LikeCount == nil {
return errors.New("update params is null")
}
// 如果设置为神评论
// 判断是否已经发送过该评论的神评论奖励(避免修改为普通评论后又修改为神评论,奖励多次发放的情况)
if in.IsGodComment != nil && *in.IsGodComment == true && !cmt.GodCommentAward {
in.GodCommentAward = true
}
err = cmtmod.Update(in.Filter(), in.Update())
if err != nil {
log.Error("web service comment GetCommentList CmtUpdateCommentStatusByID error", log.E(err), log.Any("id", in.ID))
return
}
/********************* 以下是神评相关逻辑 **********************/
// 完成任务,评论被设置为神评
if in.IsGodComment != nil && *in.IsGodComment == true {
// 完成评论被设置为神评
common.Go(func() {
err = taskser.CompleteDailyTask(nil, cmt.UserID, dailytaskmod.CommentSetGod)
if err != nil {
log.Error("web 设置神评,完成每日任务【评论被设置为神评】失败", log.E(err), log.Any("id", in.ID))
return
}
})
}
// 获取神评论奖励积分配置
if webg.Conf.GodCommentAward <= 0 {
return stderr.Success
}
// 查询出评论的帖子信息
video, err := vidmod.GetVideoByID(cmt.ObjID)
if err != nil || video == nil {
return
}
objName := fmt.Sprintf("[%v]", video.Title)
content := fmt.Sprintf("恭喜您在%v中评论获得神评,获得%v积分", objName, webg.Conf.GodCommentAward)
// 发放积分
walletInfo, err := walletmod.CreditIntegral(nil, webg.Conf.GodCommentAward, cmt.UserID)
if err != nil {
return err
}
log := &txnmod.TransactionLog{
TransNo: primitive.NewObjectID(),
UID: cmt.UserID,
Integral: webg.Conf.GodCommentAward,
ActualIntegral: float64(webg.Conf.GodCommentAward),
TranType: txnmod.GodCommentAward.Key(),
TranTypeInt: int64(txnmod.GodCommentAward),
Desc: fmt.Sprintf("%s-积分[%d个]", txnmod.GodCommentAward.Key(), webg.Conf.GodCommentAward),
RealIntegral: walletInfo.RealIntegral(),
}
txnmod.InsertTransactionLog(nil, log)
// 发放私信告诉用户获得了积分
code := chat_message_ser.AddPrivateLetter(&messagemod.SendMsg{
Sender: 100001,
Receiver: cmt.UserID,
Content: content,
MsgType: messagemod.OfficialPrivateLetterMsg,
ObjId: video.ID,
ObjName: objName,
})
return code
}
+417
View File
@@ -0,0 +1,417 @@
package commentser
import (
"91porn-server/common"
"91porn-server/common/log"
"91porn-server/models/v/cmtmod"
"91porn-server/models/v/mediacontentmod"
"91porn-server/models/v/mediamod"
"91porn-server/models/v/usermod"
"91porn-server/models/v/vidmod"
"fmt"
"strconv"
"strings"
"sync"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// 缓存随机用户列表,避免每次都查询数据库
var (
cachedUsers []*usermod.User
cachedUsersMu sync.RWMutex
cachedUsersTime time.Time
cachedUsersTTL = 10 * time.Minute
)
func getReplyUsers() ([]*usermod.User, error) {
cachedUsersMu.RLock()
if len(cachedUsers) > 0 && time.Since(cachedUsersTime) < cachedUsersTTL {
users := cachedUsers
cachedUsersMu.RUnlock()
return users, nil
}
cachedUsersMu.RUnlock()
cachedUsersMu.Lock()
defer cachedUsersMu.Unlock()
// double check
if len(cachedUsers) > 0 && time.Since(cachedUsersTime) < cachedUsersTTL {
return cachedUsers, nil
}
users, _, err := usermod.FetchList(bson.M{"uid": bson.M{"$lte": 300000}}, options.Find().SetLimit(1000))
if err != nil {
return nil, err
}
cachedUsers = users
cachedUsersTime = time.Now()
return users, nil
}
func PullCommentList(status string, limit int) (cmtmod.PullResp, error) {
var resp cmtmod.PullResp
filter := bson.M{}
if limit <= 0 {
limit = 20
}
if limit > 100 {
limit = 100
}
// 判断评论状态,抓取未审核的评论
if status == "pending" {
filter["status"] = 2
}
// 拉取已经审核成功且无子评论的一级评论
if status == "pending_reply" {
filter["status"] = 1
filter["level"] = 1
}
// 查询评论列表
opts := options.FindOptions{}
opts.SetSort(bson.D{{Key: "createdAt", Value: 1}}).SetLimit(int64(limit))
commentList, err := cmtmod.GetList(filter, &opts)
if err != nil {
log.Error("pull comment list fail", log.E(err))
return resp, err
}
resp = cmtmod.PullResp{
Code: 200,
Msg: "success",
Data: nil,
}
for _, comment := range commentList {
pullComment := cmtmod.PullComment{
Id: comment.ID.Hex(),
UserId: strconv.FormatUint(comment.UserID, 10),
Nickname: "",
Content: comment.Content,
CreatedAt: comment.CreatedAt.Format("2006-01-02 15:04:05"),
Ip: "",
Context: cmtmod.Context{
ContentId: comment.ObjID.Hex(),
ContentTitle: comment.Title,
},
}
switch comment.ObjType {
case cmtmod.OTypeVideo:
pullComment.Context.ContentType = 1
case cmtmod.OTypeCartoon:
pullComment.Context.ContentType = 3
default:
pullComment.Context.ContentType = 2
}
resp.Data = append(resp.Data, pullComment)
}
log.Info("pull comment list success", log.Any("resp", resp))
return resp, nil
}
func CommentApprove(comments cmtmod.ApproveReq) (err error) {
var passCommentIDs []primitive.ObjectID
var reviewCommentIDs []primitive.ObjectID
// 遍历评论列表
for _, comment := range comments.Reviews {
oid, parseErr := primitive.ObjectIDFromHex(comment.CommentId)
if parseErr != nil || oid.IsZero() {
continue
}
reviewCommentIDs = append(reviewCommentIDs, oid)
// 审核通过评论
if comment.Action == "approve" {
passCommentIDs = append(passCommentIDs, oid)
} else if comment.Action == "reject" {
// 评论没有通过,更新评论状态,以及评论没有通过原因
err = cmtmod.Update(bson.M{"_id": oid}, bson.M{"$set": bson.M{"status": 4, "reason": comment.Reason, "desc": "Agent system review reject"}})
if err != nil {
log.Error("web service comment CommentApprove cmtmod.Update fail", log.E(err), log.Any("id", oid))
return
}
}
}
if len(passCommentIDs) > 0 {
err = cmtmod.UpdateMany(bson.M{"_id": bson.M{"$in": passCommentIDs}}, bson.M{"$set": bson.M{"status": 1, "desc": "Agent system review"}})
if err != nil {
log.Error("web service comment CommentApprove cmtmod.UpdateMany fail", log.E(err), log.Any("_id", passCommentIDs))
return
}
}
if len(reviewCommentIDs) == 0 {
return nil
}
commentList, err := cmtmod.GetCommentsByIDS(reviewCommentIDs)
if err != nil {
log.Error("web service comment CommentApprove cmtmod.GetCommentsByIDS fail", log.E(err), log.Any("ids", reviewCommentIDs))
return err
}
go rebuildVideoAndMediaCommentCount(commentList)
return
}
func ReplyComment(comments cmtmod.RepliesReq) (cmtmod.ReplyResp, error) {
now := time.Now()
// 从缓存获取随机用户列表
userInfos, err := getReplyUsers()
if err != nil {
log.Error("web service comment ReplyComment getReplyUsers fail", log.E(err))
return cmtmod.ReplyResp{Code: 0, Msg: "web service comment ReplyComment Error"}, err
}
if len(userInfos) == 0 {
return cmtmod.ReplyResp{Code: 0, Msg: "web service comment ReplyComment Error"}, fmt.Errorf("no available users for auto reply")
}
// 先收集所有有效的评论ID
oidMap := make(map[primitive.ObjectID]string, len(comments.Replies)) // oid -> reply content
oids := make([]primitive.ObjectID, 0, len(comments.Replies))
for _, reply := range comments.Replies {
oid, parseErr := primitive.ObjectIDFromHex(reply.CommentId)
if parseErr != nil || oid.IsZero() {
continue
}
oids = append(oids, oid)
oidMap[oid] = reply.Content
}
// 批量查询评论信息
cmtInfos, err := cmtmod.CmtFindOneByIds(oids)
if err != nil {
log.Error("web service comment ReplyComment cmtmod.CmtFindOneByIds fail", log.E(err))
return cmtmod.ReplyResp{Code: 0, Msg: "web service comment ReplyComment Error"}, err
}
affectedComments := make([]cmtmod.Comment, 0, len(cmtInfos))
insertDocs := make([]cmtmod.Comment, 0, len(cmtInfos))
for _, cmtInfo := range cmtInfos {
if cmtInfo.ID.IsZero() {
continue
}
content, ok := oidMap[cmtInfo.ID]
if !ok {
continue
}
rand := common.RandInt(0, len(userInfos))
insertDocs = append(insertDocs, cmtmod.Comment{
ID: primitive.NewObjectID(),
ObjType: cmtInfo.ObjType,
Title: cmtInfo.Title,
ObjID: cmtInfo.ObjID,
CID: cmtInfo.ID,
RID: cmtmod.ObjectID{},
GID: cmtmod.ObjectID{},
Type: cmtmod.CmtTypeReply,
PublisherID: 0,
AuthorMark: false,
SortCnt: 0,
UserID: userInfos[rand].UID,
ToUserID: 0,
ToUserName: "",
LikeCount: 0,
CommentCount: 0,
IsGodComment: false,
IsAuthor: false,
IsRobot: false,
Content: content,
OrgContent: "",
Level: 2,
IPAddr: "",
Status: 1,
Reason: "",
Desc: "Agent system reply",
Image: "",
City: "",
LinkStr: "",
QuoteType: "",
QuoteID: primitive.ObjectID{},
QuoteImg: "",
QuoteTitle: "",
IsDelete: false,
IsAdvertiser: false,
CreatedAt: now,
DeletedAt: time.Time{},
})
affectedComments = append(affectedComments, cmtInfo)
}
if len(insertDocs) > 0 {
_, err = cmtmod.CmtInsertMany(insertDocs)
if err != nil {
log.Error("web service comment ReplyComment cmtmod.CmtInsertMany fail", log.E(err))
return cmtmod.ReplyResp{Code: 0, Msg: "web service comment ReplyComment Error"}, err
}
}
rebuildVideoAndMediaCommentCount(affectedComments)
return cmtmod.ReplyResp{
Code: 200,
Msg: "success",
}, nil
}
func rebuildVideoAndMediaCommentCount(comments []cmtmod.Comment) {
if len(comments) == 0 {
return
}
type objInfo struct {
objType cmtmod.OType
objID primitive.ObjectID
}
objMap := make(map[string]objInfo)
for _, cmt := range comments {
if cmt.ObjID.IsZero() {
continue
}
if cmt.ObjType != cmtmod.OTypeVideo && cmt.ObjType != cmtmod.OTypeCartoon {
continue
}
key := string(cmt.ObjType) + "_" + cmt.ObjID.Hex()
objMap[key] = objInfo{
objType: cmt.ObjType,
objID: cmt.ObjID,
}
}
var wg sync.WaitGroup
for _, v := range objMap {
obj := v
wg.Add(1)
common.Go(func() {
defer wg.Done()
rebuildSingleObjCommentCount(obj.objType, obj.objID)
})
}
wg.Wait()
}
func rebuildSingleObjCommentCount(objType cmtmod.OType, objID primitive.ObjectID) {
cond := bson.M{
"objType": objType,
"objID": objID,
"status": 1,
"isAdvertiser": false,
"isDelete": false,
}
count, err := cmtmod.CmtFindCountByCond(cond)
if err != nil {
log.Error("web service comment rebuildSingleObjCommentCount cmtmod.CmtFindCountByCond fail",
log.E(err), log.Any("objType", objType), log.Any("objID", objID))
return
}
switch objType {
case cmtmod.OTypeVideo:
fakeDelta := 0
videoInfo, err := vidmod.GetVideoInfo(objID.Hex())
if err == nil && !videoInfo.ID.IsZero() {
fakeDelta = videoInfo.FakeCommentCount - videoInfo.CommentCount
if fakeDelta < 0 {
fakeDelta = 0
}
}
_, err = vidmod.UpdateOneByID(objID, bson.M{
"commentCount": int(count),
"fakeCommentCount": int(count) + fakeDelta,
})
if err != nil {
log.Error("web service comment rebuildSingleObjCommentCount vidmod.UpdateOneByID fail",
log.E(err), log.Any("objID", objID), log.Any("count", count))
}
case cmtmod.OTypeCartoon:
_, err = mediacontentmod.UpdateOneByID(objID, bson.M{"countComment": count})
if err != nil {
log.Error("web service comment rebuildSingleObjCommentCount mediacontentmod.UpdateOneByID fail",
log.E(err), log.Any("objID", objID), log.Any("count", count))
}
_, err = mediamod.UpdateByID(nil, objID, map[string]interface{}{"countComment": count})
if err != nil {
log.Error("web service comment rebuildSingleObjCommentCount mediamod.UpdateByID fail",
log.E(err), log.Any("objID", objID), log.Any("count", count))
}
}
}
func ComicsTranslatePull(req *cmtmod.ComicsTitlePullReq) (cmtmod.ComicsTitlePullResp, error) {
resp := cmtmod.ComicsTitlePullResp{List: make([]cmtmod.ComicsTitleInfo, 0)}
if req == nil {
return resp, nil
}
opts := options.Find()
pageNum := req.PageNum
if pageNum <= 0 {
pageNum = 1
}
pageSize := req.PageSize
if pageSize <= 0 {
pageSize = 20
}
opts.SetSkip((pageNum - 1) * pageSize)
opts.SetLimit(pageSize)
opts.SetSort(bson.D{{Key: "_id", Value: -1}})
filter := bson.M{}
if strings.TrimSpace(req.TagId) != "" {
tagID, err := primitive.ObjectIDFromHex(strings.TrimSpace(req.TagId))
if err != nil {
return resp, err
}
filter["tags"] = tagID
}
list, err := mediamod.QueryAllList(filter, opts)
if err != nil {
return resp, err
}
for _, one := range list {
resp.List = append(resp.List, cmtmod.ComicsTitleInfo{Id: one.ID.Hex(), Title: one.Title})
}
return resp, nil
}
func ComicsTranslatePush(req *cmtmod.ComicsTitlePushReq) (cmtmod.ComicsTitlePushRes, error) {
resp := cmtmod.ComicsTitlePushRes{}
if req == nil {
return resp, nil
}
var tagID primitive.ObjectID
var hasTag bool
if strings.TrimSpace(req.TagId) != "" {
parsedTagID, err := primitive.ObjectIDFromHex(strings.TrimSpace(req.TagId))
if err != nil {
return resp, err
}
tagID = parsedTagID
hasTag = true
}
for _, one := range req.List {
mediaID, err := primitive.ObjectIDFromHex(strings.TrimSpace(one.Id))
if err != nil {
return resp, err
}
update := bson.M{"title": strings.TrimSpace(one.Title), "updateTime": time.Now()}
if hasTag {
mediaInfo, err := mediamod.GetInfo(mediaID)
if err != nil {
return resp, err
}
newTags := make([]primitive.ObjectID, 0, len(mediaInfo.Tags))
for _, tag := range mediaInfo.Tags {
if tag != tagID {
newTags = append(newTags, tag)
}
}
update["tags"] = newTags
}
if _, err = mediamod.UpdateByID(nil, mediaID, update); err != nil {
return resp, err
}
}
return resp, nil
}