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

1054 lines
34 KiB
Go

package cmtmod
import (
"91porn-server/common/constant"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"91porn-server/models/commod"
"encoding/json"
"fmt"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var mdb *db.MongoDB
const table = models.Comment
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initCommentIndex 设置index
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{"objID", 1}, {"cid", 1}, {"sortCnt", -1}, {"gid", -1}, {"createdAt", 1}},
},
{
Keys: bson.D{{"objID", 1}, {"level", 1}, {"userID", 1}, {"createdAt", -1}},
},
{
Keys: bson.D{{"objID", 1}, {"level", 1}, {"likeCount", -1}, {"createdAt", -1}},
},
{
Keys: bson.D{{"objID", 1}, {"level", 1}, {"commentCount", -1}, {"createdAt", -1}},
},
{
Keys: bson.D{{"objID", 1}, {"cid", 1}, {"gid", -1}, {"createdAt", 1}},
},
{ // SKD 统计热度统计查询
Keys: bson.D{{"objType", 1}, {"status", 1}, {"isAdvertiser", 1}, {"createdAt", -1}},
},
{
Keys: bson.D{{"createdAt", 1}, {"toUserID", 1}},
},
{
Keys: bson.D{{"publisherID", 1}, {"createdAt", 1}},
},
{
Keys: bson.D{{"userID", 1}, {"createdAt", 1}},
},
{
Keys: bson.D{{"content", 1}},
},
{
Keys: bson.D{{"isGodComment", 1}},
},
// 后台筛选使用
{
Keys: bson.D{{"status", 1}},
},
{
Keys: bson.D{{"isAdvertiser", 1}},
},
}
_, err := coll(nil).CreateIndex(many)
if err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
// InsertManyBulket 插入多条
func InsertManyBulket(docs []*Comment) (insertCount int64, err error) {
opts := options.BulkWriteOptions{}
opts.SetOrdered(false)
models := make([]mongo.WriteModel, 0)
for _, v := range docs {
models = append(models, mongo.NewInsertOneModel().SetDocument(v))
}
res, err := coll(nil).Bulk(models, &opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "InsertManyBulket", table, "Bulk", err))
return
}
insertCount = res.InsertedCount
return
}
// CmtInsertOne 插入一条评论
func CmtInsertOne(c *Comment) (id ObjectID, err error) {
res, err := coll(nil).InsertOne(c)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtInsertOne", table, "InsertOne", err))
return
}
byteID, err := json.Marshal(res.InsertedID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtInsertOne", table, "Marshal", err))
return
}
err = id.UnmarshalJSON(byteID)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtInsertOne", table, "UnmarshalJSON", err))
return
}
return
}
// CmtInsertMany 插入多条评论
func CmtInsertMany(c []Comment) (count int, err error) {
res, err := coll(nil).InsertMany(c)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtInsertMany", table, "InsertMany", err))
return
}
count = len(res.InsertedIDs)
return
}
// CmtFindOneByID 获取评论信息
func CmtFindOneByID(id ObjectID) (data Comment, err error) {
err = coll(nil).FindOne(&data, bson.M{"_id": id}, options.FindOne())
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindOneByID", table, "FindOne", err), log.Any("id", id))
return
}
return
}
// CmtFindOneByIds 获取评论信息
func CmtFindOneByIds(ids []ObjectID) (data []Comment, err error) {
err = coll(nil).Find(&data, bson.M{"_id": bson.M{"$in": ids}}, options.Find())
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindOneByIds", table, "Find", err), log.Any("ids", ids))
return
}
return
}
// CmtFindCommentsAndCount 后台根据条件获取评论
func CmtFindCommentsAndCount(vid string, uid uint64, content string, isRobot, isAdvertiser *bool, status *int, page commod.Page) (data []Comment, total int64, err error) {
vidObjID := ObjectID{}
query := bson.M{"isDelete": false}
if vid != "" {
if vidObjID, err = primitive.ObjectIDFromHex(vid); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindCommentsAndCount", table, "ObjectIDFromHex", err),
log.Any("vid", vid),
log.Any("uid", uid),
log.Any("content", content),
)
return nil, 0, err
}
query["objID"] = vidObjID
}
if content != "" {
//query["content"] = primitive.Regex{Pattern: content, Options: "i"}
query["content"] = content // 完全匹配内容
}
if isRobot != nil && *isRobot == true {
query["userID"] = bson.M{"$lte": constant.RobotUIDLimit}
} else if isRobot != nil && *isRobot == false {
query["userID"] = bson.M{"$gt": constant.RobotUIDLimit}
}
if uid != 0 {
query["userID"] = uid
}
if status != nil {
query["status"] = status
}
if isAdvertiser != nil {
query["isAdvertiser"] = isAdvertiser
}
stdQuery := commod.StdQuery{
Page: &commod.PageBy{Num: page.PageNumber, Size: page.PageSize},
Order: &[]commod.OrderBy{{Key: "createdAt", Desc: true}},
}
err = coll(nil).Find(&data, query, commod.ConvertToListQuery(stdQuery))
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindCommentsAndCount", table, "Find", err),
log.Any("vid", vid),
log.Any("uid", uid),
log.Any("content", content),
)
return
}
total, err = coll(nil).Count(query)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindCommentsAndCount", table, "Count", err),
log.Any("vid", vid),
log.Any("uid", uid),
log.Any("content", content),
)
return
}
return
}
// GetVideosFirstComment 获取视频第一条评论
func GetVideosFirstComment(videoIDs []ObjectID) (map[ObjectID]Comment, error) {
m := make(map[ObjectID]Comment)
var infos []Comment
opts := options.Find()
opts.SetSort(bson.D{{Key: "isGodComment", Value: -1}, {Key: "likeCount", Value: -1}, {Key: "createdAt", Value: -1}})
err := coll(nil).Find(&infos, bson.M{"objID": bson.M{"$in": videoIDs}, "level": 1, "isDelete": false}, opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetVideosFirstComment", table, "Find", err), log.Any("videoIDs", videoIDs))
return m, err
}
for _, i := range infos {
m[i.ObjID] = i
}
return m, nil
}
// CmtFindCountByObjID 根据对象id获取评论数
func CmtFindCountByObjID(objID ObjectID, curTime time.Time, level *int) (count int64, err error) {
query := bson.M{"objID": objID, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
if level != nil {
query = bson.M{"objID": objID, "level": *level, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
}
count, err = coll(nil).Count(query)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindCountByObjID", table, "Count", err),
log.Any("objID", objID),
log.Any("curTime", curTime),
)
return
}
return
}
// CmtFindFirstLevelComments 获取一级评论列表
func CmtFindFirstLevelComments(objID ObjectID, curTime time.Time, stdQuery commod.StdQuery) (total int64, err error, data []Comment) {
*stdQuery.Order = append(*stdQuery.Order, commod.OrderBy{Key: "createdAt", Desc: true})
query := bson.M{"objID": objID, "level": 1, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
if err = coll(nil).Find(&data, query, commod.ConvertToListQuery(stdQuery)); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindFirstLevelComments", table, "Find", err),
log.Any("objID", objID),
log.Any("curTime", curTime),
)
return
}
if total, err = coll(nil).Count(query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindFirstLevelComments", table, "Count", err),
log.Any("objID", objID),
log.Any("curTime", curTime),
)
return
}
return
}
// CmtFindSecondLevelComments 获取二级评论列表
func CmtFindSecondLevelComments(objID ObjectID, cid ObjectID, fstID ObjectID, curTime time.Time, stdQuery commod.StdQuery) (data []Comment, err error) {
*stdQuery.Order = append(*stdQuery.Order, commod.OrderBy{Key: "createdAt", Desc: true})
var query = bson.M{"_id": bson.M{"$ne": fstID}, "objID": objID, "cid": cid, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
if err = coll(nil).Find(&data, query, commod.ConvertToListQuery(stdQuery)); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindSecondLevelComments", table, "Find", err),
log.Any("objID", objID),
log.Any("cid", cid),
log.Any("fstID", fstID),
log.Any("curTime", curTime),
)
return
}
return
}
// CmtIncreaseLikeCountByID 更新评论点赞数
func CmtIncreaseLikeCountByID(value int, ids ...ObjectID) (err error) {
if len(ids) == 0 {
return nil
}
var query = bson.M{}
if len(ids) == 1 {
query["_id"] = ids[0]
} else {
query["_id"] = bson.M{"$in": ids}
}
if _, err = coll(nil).UpdateOne(query, bson.M{"$inc": bson.M{"likeCount": value}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtIncreaseLikeCountByID", table, "UpdateOne", err),
log.Any("ids", ids),
log.Any("value", value),
)
return
}
return
}
// CmtUpdateCommentStatusByID 修改评论状态
func CmtUpdateCommentStatusByID(id ObjectID, status int) (err error) {
if _, err = coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$set": bson.M{"status": status}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtUpdateCommentStatusByID", table, "UpdateOne", err),
log.Any("id", id),
log.Any("status", status),
)
return
}
return
}
// PassCommentStatusByIds 修改评论
func PassCommentStatusByIds(ids []ObjectID, status int) (err error) {
if _, err = coll(nil).UpdateMany(bson.M{"_id": bson.M{"$in": ids}}, bson.M{"$set": bson.M{"status": status}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "PassCommentStatusByIds", table, "UpdateMany", err),
log.Any("ids", ids),
log.Any("status", status),
)
return
}
return
}
// CmtUpdateCommentStatusByUID 修改评论状态
func CmtUpdateCommentStatusByUID(uid uint64) (err error) {
if _, err = coll(nil).UpdateMany(bson.M{"userID": uid}, bson.M{"$set": bson.M{"isDelete": true}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtUpdateCommentStatusByUID", table, "UpdateMany", err), log.Any("uid", uid))
return
}
return
}
// CmtUpdateCommentStatusByIDS 修改评论状态
func CmtUpdateCommentStatusByIDS(ids []ObjectID) (err error) {
if _, err = coll(nil).UpdateMany(bson.M{"_id": bson.M{"$in": ids}}, bson.M{"$set": bson.M{"isDelete": true}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtUpdateCommentStatusByIDS", table, "UpdateMany", err), log.Any("ids", ids))
return
}
return
}
// CmtIncreaseCommentCountByID 增加一级评论的评论数
func CmtIncreaseCommentCountByID(id ObjectID) (err error) {
query := bson.M{"_id": id}
update := bson.M{"$inc": bson.M{"commentCount": 1}}
if _, err = coll(nil).UpdateOne(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtIncreaseCommentCountByID", table, "UpdateOne", err), log.Any("id", id))
return
}
return
}
// CmtIncreaseCommentCountByID 减少一级评论的评论数
func CmtDecreaseCommentCountByID(id ...ObjectID) (err error) {
if len(id) == 0 {
return nil
}
query := bson.M{"_id": id[0], "commentCount": bson.M{"$gte": 1}}
if len(id) > 1 {
query["_id"] = bson.M{"$in": id}
}
update := bson.M{"$inc": bson.M{"commentCount": -1}}
if _, err = coll(nil).UpdateOne(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtDecreaseCommentCountByID", table, "UpdateOne", err), log.Any("id", id))
return
}
return
}
// CmtFIndFirstCommentOfComment 获取一级评论的第一条评论
func CmtFIndFirstCommentOfComment(objID ObjectID, CIDs []ObjectID, curTime time.Time) (data []Comment, err error) {
var cmtInfos []FstCmt
pipeline := []bson.M{
{"$match": bson.M{"objID": objID, "cid": bson.M{"$in": CIDs}, "level": 2, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}},
{"$sort": bson.D{{Key: "createdAt", Value: -1}}},
{"$group": bson.M{"_id": "$cid", "data": bson.M{"$first": "$$ROOT"}}},
}
var opts = options.Aggregate()
opts.SetHint(bson.D{{"objID", 1}, {"cid", 1}, {"sortCnt", -1}, {"gid", -1}, {"createdAt", 1}})
if err = coll(nil).Aggregate(&cmtInfos, pipeline, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFIndFirstCommentOfComment", table, "Aggregate", err),
log.Any("objID", objID),
log.Any("CIDs", CIDs),
log.Any("curTime", curTime),
)
return
}
if cmtInfos == nil {
data = []Comment{}
return
}
for _, value := range cmtInfos {
data = append(data, value.Data)
}
return
}
func GetCommentMap(cidList []ObjectID) (map[ObjectID]Comment, error) {
if len(cidList) == 0 {
return make(map[ObjectID]Comment), nil
}
filter := bson.M{
"_id": bson.M{"$in": cidList},
}
cmtlist := make([]Comment, 0, len(cidList))
if err := coll(nil).Find(&cmtlist, filter); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCommentMap", table, "Find", err), log.Any("cidList", cidList))
return nil, err
}
m := make(map[ObjectID]Comment, len(cmtlist))
for _, cmt := range cmtlist {
m[cmt.ID] = cmt
}
return m, nil
}
func GetCommentsByUID(uid uint64) (data []Comment, err error) {
var query = bson.M{"userID": uid, "isDelete": false}
if err = coll(nil).Find(&data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCommentsByUID", table, "Find", err), log.Any("uid", uid))
return
}
return
}
func GetCommentsByContent(content string) (data []Comment, err error) {
var query = bson.M{"content": content, "isDelete": false}
if err = coll(nil).Find(&data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCommentsByContent", table, "Find", err), log.Any("content", content))
return
}
return
}
func GetCommentsByIDS(ids []ObjectID) (data []Comment, err error) {
var query = bson.M{"_id": bson.M{"$in": ids}, "isDelete": false}
if err = coll(nil).Find(&data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCommentsByIDS", table, "Find", err), log.Any("ids", ids))
return
}
return
}
// 根据评论id获取子评论
func GetCommentsByCID(objID ObjectID, cid ObjectID) (data []Comment, err error) {
var query = bson.M{"objID": objID, "cid": cid, "isDelete": false}
if err = coll(nil).Find(&data, query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCommentsByCID", table, "Find", err),
log.Any("objID", objID),
log.Any("cid", cid),
)
return
}
return
}
// 设置分组id
func SetGid(id ObjectID) (err error) {
if _, err = coll(nil).UpdateOne(bson.M{"_id": id}, bson.M{"$set": bson.M{"gid": id}}); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "SetGid", table, "UpdateOne", err), log.Any("id", id))
return
}
return
}
// 增加回复的排序值
func IncSortKey(objId ObjectID, gid ObjectID) {
var query = bson.M{"objID": objId, "gid": gid}
var update = bson.M{"$inc": bson.M{"sortCnt": 1}}
if _, err := coll(nil).UpdateMany(query, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IncSortKey", table, "UpdateMany", err),
log.Any("objId", objId),
log.Any("gid", gid),
)
return
}
}
// GetAuthorParentCmt 获取作者的所有评论
func GetAuthorParentCmt(isAdvertiser bool, objId ObjectID, author uint64, curTime time.Time) (data []Comment, err error) {
var query = bson.M{"objID": objId, "userID": author, "cid": nil, "level": 1, "status": 1, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
var opts = options.Find()
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
opts.SetSort(bson.D{{"isGodComment", -1}, {"createdAt", -1}})
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAuthorParentCmt", table, "Find", err),
log.Any("objId", objId),
log.Any("author", author),
log.Any("curTime", curTime),
)
return
}
return
}
// GetIsGodCommentParentCmt 获取作者的所有神评论
func GetIsGodCommentParentCmt(isAdvertiser bool, objId ObjectID, curTime time.Time) (data []Comment, err error) {
var query = bson.M{"objID": objId, "isAuthor": false, "isGodComment": true, "level": 1, "status": 1, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
var opts = options.Find()
opts.SetSort(bson.D{{"isGodComment", -1}, {"createdAt", -1}})
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAuthorParentCmt", table, "Find", err),
log.Any("objId", objId),
log.Any("curTime", curTime),
)
return
}
return
}
// GetHotParentCmtList 获取热门的父评论及其条数
func GetHotParentCmtList(uid uint64, isAdvertiser bool, noIds []primitive.ObjectID, objId ObjectID, skip int64, limit int64, curTime time.Time) (data []Comment, err error) {
var query = bson.M{
"objID": objId,
"level": 1,
"status": 1,
"$or": []bson.M{
{"status": 1},
{"userID": uid},
},
"isGodComment": false,
"isDelete": false,
"likeCount": bson.M{"$gt": 0},
"createdAt": bson.M{"$lte": curTime},
}
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
if len(noIds) > 0 {
query["_id"] = bson.M{"$nin": noIds}
}
var opts = options.Find()
opts.SetSort(bson.D{{"likeCount", -1}, {"createdAt", -1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetHotParentCmtList", table, "Find", err),
log.Any("objId", objId),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
return
}
// GetHotReplyParentCmtList 获取热门的父评论及其条数(回复数)
func GetHotReplyParentCmtList(uid uint64, isAdvertiser bool, objId ObjectID, skip int64, limit int64, curTime time.Time) (data []Comment, err error) {
var query = bson.M{
"objID": objId,
"level": 1,
"status": 1,
"$or": []bson.M{
{"status": 1},
{"userID": uid},
},
"isGodComment": false, "isDelete": false, "likeCount": bson.M{"$gt": 0}, "createdAt": bson.M{"$lte": curTime}}
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
var opts = options.Find()
opts.SetSort(bson.D{{"commentCount", -1}, {"createdAt", -1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetHotReplyParentCmtList", table, "Find", err),
log.Any("objId", objId),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
return
}
// GetParentCmtList 获取普通父评论
func GetParentCmtList(isAdvertiser bool, objId ObjectID, ids []ObjectID, skip int64, limit int64, curTime time.Time) (data []Comment, err error) {
var query = bson.M{
"_id": bson.M{"$nin": ids},
"objID": objId,
"level": 1,
"status": 1,
"isGodComment": false,
"isDelete": false,
"createdAt": bson.M{"$lte": curTime},
}
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
var opts = options.Find()
opts.SetSort(bson.D{{"createdAt", -1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetParentCmtList", table, "Find", err),
log.Any("objId", objId),
log.Any("ids", ids),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
return
}
// GetFstAuthorCmtOfParentCmt 获取父评论的首条作者的评论
func GetFstAuthorCmtOfParentCmt(isAdvertiser bool, objID ObjectID, CIDs []ObjectID, author uint64, curTime time.Time) (data []Comment, err error) {
var cmtInfos []FstCmt
var query = bson.M{"objID": objID, "cid": bson.M{"$in": CIDs}, "level": 2, "status": 1, "userID": author, "rid": nil, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
pipeline := []bson.M{
{"$match": query},
{"$sort": bson.D{{"isGodComment", -1}, {Key: "createdAt", Value: -1}}},
{"$group": bson.M{"_id": "$cid", "data": bson.M{"$first": "$$ROOT"}}},
}
if err = coll(nil).Aggregate(&cmtInfos, pipeline); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFstAuthorCmtOfParentCmt", table, "Aggregate", err),
log.Any("objID", objID),
log.Any("CIDs", CIDs),
log.Any("author", author),
log.Any("curTime", curTime),
)
return
}
if cmtInfos == nil {
data = []Comment{}
return
}
for _, value := range cmtInfos {
data = append(data, value.Data)
}
return
}
// 获取父评论的首条作者的评论
func GetFstCmtOfParentCmt(isAdvertiser bool, objID ObjectID, CIDs []ObjectID, curTime time.Time) (data []Comment, err error) {
var cmtInfos []FstCmt
var query = bson.M{"objID": objID, "cid": bson.M{"$in": CIDs}, "level": 2, "status": 1, "rid": nil, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
if !isAdvertiser {
query["isAdvertiser"] = bson.M{"$in": []any{nil, false}}
}
pipeline := []bson.M{
{"$match": query},
{"$sort": bson.D{{"isGodComment", -1}, {Key: "sortCnt", Value: -1}, {Key: "createdAt", Value: -1}}},
{"$group": bson.M{"_id": "$cid", "data": bson.M{"$first": "$$ROOT"}}},
}
if err = coll(nil).Aggregate(&cmtInfos, pipeline); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFstCmtOfParentCmt", table, "Aggregate", err),
log.Any("objID", objID),
log.Any("CIDs", CIDs),
log.Any("curTime", curTime),
)
return
}
if cmtInfos == nil {
data = []Comment{}
return
}
for _, value := range cmtInfos {
data = append(data, value.Data)
}
return
}
// 获取作者的子评论及其回复和数量
func GetAuthorChildCmtList(objID ObjectID, cid ObjectID, fstId ObjectID, skip int64, limit int64, curTime time.Time) (total int64, data []Comment, err error) {
var query = bson.M{"_id": bson.M{"$ne": fstId}, "objID": objID, "cid": cid, "authorMark": true, "status": 1, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
var opts = options.Find()
opts.SetSort(bson.D{{"isGodComment", -1}, {"gid", -1}, {"createdAt", 1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAuthorChildCmtList", table, "Find", err),
log.Any("objID", objID),
log.Any("cid", cid),
log.Any("fstId", fstId),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
if total, err = coll(nil).Count(query); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAuthorChildCmtList", table, "Count", err),
log.Any("objID", objID),
log.Any("cid", cid),
log.Any("fstId", fstId),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
return
}
// 获取热门的子评论及其回复
func GetHotChildCmtList(objID ObjectID, cid ObjectID, fstId ObjectID, skip int64, limit int64, curTime time.Time) (total int64, data []Comment, err error) {
var query = bson.M{"_id": bson.M{"$ne": fstId}, "objID": objID, "cid": cid, "authorMark": false, "level": 2, "status": 1, "isDelete": false, "createdAt": bson.M{"$lte": curTime}}
var opts = options.Find()
opts.SetSort(bson.D{{"isGodComment", -1}, {"sortCnt", -1}, {"gid", -1}, {"createdAt", 1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetHotChildCmtList", table, "Find", err),
log.Any("objID", objID),
log.Any("cid", cid),
log.Any("fstId", fstId),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
return
}
// 获取普通的评论和回复
func GetChildCmtList(objID ObjectID, cid ObjectID, fstId ObjectID, skip int64, limit int64, curTime time.Time) (data []Comment, err error) {
var query = bson.M{"_id": bson.M{"$ne": fstId}, "objID": objID, "cid": cid, "idDelete": false, "level": 2, "status": 1, "createdAt": bson.M{"$lte": curTime}}
var opts = options.Find()
opts.SetSort(bson.D{{"isGodComment", -1}, {"gid", -1}, {"createdAt", 1}}).SetSkip(skip).SetLimit(limit)
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetChildCmtList", table, "Find", err),
log.Any("objID", objID),
log.Any("cid", cid),
log.Any("fstId", fstId),
log.Any("skip", skip),
log.Any("limit", limit),
log.Any("curTime", curTime),
)
return
}
return
}
func ListByPublisherID(skip, limit int64, publisherID uint64) ([]Comment, error) {
sort := bson.D{{"createdAt", -1}}
publisherIDMatch := PublisherIDMatch{&publisherID}
return List(sort, skip, limit, publisherIDMatch.New())
}
// DelCommentsByUID 删除评论通过uid
func DelCommentsByUID(uid uint64) (err error) {
if _, err = coll(nil).DeleteMany(bson.M{"userID": uid}); err != nil {
log.Error("models comment DelCommentsByUID error", log.E(err), log.Any("uid", uid))
return
}
return
}
// DelCommentsByUIDs 批量删除评论通过uid
func DelCommentsByUIDs(uids []uint64) (err error) {
if uids == nil {
uids = []uint64{}
}
if _, err = coll(nil).DeleteMany(bson.M{"userID": bson.M{"$in": uids}}); err != nil {
log.Error("models comment DelCommentsByUIDs error", log.E(err), log.Any("uids", uids))
return
}
return
}
// 删除评论通过_id
func DelCommentsByIDS(ids []ObjectID) (err error) {
if _, err = coll(nil).DeleteMany(bson.M{"_id": bson.M{"$in": ids}}); err != nil {
log.Error("models comment DelCommentsByIDS error", log.E(err), log.Any("ids", ids))
return
}
return
}
// 删除评论通过评论内容精确匹配
func DelCommentsByContent(content string) (err error) {
if _, err = coll(nil).DeleteMany(bson.M{"content": content}); err != nil {
log.Error("models comment DelCommentsByContent error", log.E(err), log.Any("content", content))
return
}
return
}
// 获取评论
func GetCmtList(objID, adoptionCmtId ObjectID, skip int64, limit int64) (data []CmtRespList, hasNext bool, err error) {
hasNext = false
var query = bson.M{"objID": objID, "isDelete": false, "level": 1}
if !adoptionCmtId.IsZero() {
query["_id"] = bson.M{"$ne": adoptionCmtId}
}
opts := options.Find().SetSkip(limit * (skip - 1)).SetLimit(limit + 1).SetSort(bson.D{{"createdAt", -1}})
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCmtList", table, "Find", err),
log.Any("objID", objID),
log.Any("skip", skip),
log.Any("limit", limit),
)
return
}
if int64(len(data)) > limit {
hasNext = true
data = data[:limit]
}
return
}
// 根据objIds获取子评论
func GetCmtListByIds(objIDs []ObjectID) (data []CmtRespList, err error) {
var query = bson.M{"cid": bson.M{"$in": objIDs}, "isDelete": false, "level": 2}
opts := options.Find().SetSort(bson.D{{"createdAt", -1}})
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCmtListByIds", table, "Find", err),
log.Any("objID", objIDs),
)
return
}
return
}
// CmtFindByID 根据_id获取评论
func CmtFindByID(id ObjectID) (data CmtRespList, err error) {
err = coll(nil).FindOne(&data, bson.M{"_id": id}, options.FindOne())
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindByID", table, "FindOne", err), log.Any("id", id))
return
}
return
}
// Update 修改评论状态
func Update(filter, update bson.M) (err error) {
if _, err = coll(nil).UpdateOne(filter, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err),
log.Any("filter", filter),
log.Any("update", update),
)
return
}
return
}
// UpdateMany 修改评论状态
func UpdateMany(filter, update bson.M) (err error) {
if _, err = coll(nil).UpsertMany(filter, update); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "Update", table, "UpdateOne", err),
log.Any("filter", filter),
log.Any("update", update),
)
return
}
return
}
// GetCmtListByCond 根据条件获取评论
func GetCmtListByCond(filter bson.M) (data []CmtRespList, err error) {
opts := options.Find().SetSort(bson.D{{"createdAt", -1}})
if err = coll(nil).Find(&data, filter, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCmtListByCond", table, "Find", err),
log.Any("filter", filter),
)
return
}
return
}
// FindList 根据条件获取评论
func FindList(filter bson.M, opt ...*options.FindOptions) (data []*Comment, err error) {
if err = coll(nil).Find(&data, filter, opt...); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetCmtListByCond", table, "Find", err),
log.Any("filter", filter),
)
return
}
return
}
// Count
func GetCount(m bson.M) (int64, error) {
count, err := coll(nil).Count(m)
if err != nil {
return 0, err
}
return count, nil
}
// GetMyCmtList 获取我的评论
func GetMyCmtList(userID uint64, skip int64, limit int64) (data []MyCmt, hasNext bool, err error) {
var query = bson.M{"userID": userID, "isDelete": false, "level": 1}
opts := options.Find().SetSkip(skip).SetSort(bson.D{{"createdAt", -1}})
if err = coll(nil).Find(&data, query, opts); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetMyCmtList", table, "Find", err),
log.Any("userID", userID),
log.Any("skip", skip),
log.Any("limit", limit),
)
return
}
if int64(len(data)) > limit {
hasNext = true
data = data[:limit]
}
return
}
func GetList(filter bson.M, findOptions *options.FindOptions) (data []Comment, err error) {
if err = coll(nil).Find(&data, filter, findOptions); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetList", table, "Find", err),
log.Any("filter", filter),
log.Any("findOptions", findOptions),
)
return
}
return
}
// CmtFindCountByCond 根据过滤条件获取评论数
func CmtFindCountByCond(cond bson.M) (count int64, err error) {
count, err = coll(nil).Count(cond)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CmtFindCountByCond", table, "Count", err),
log.Any("cond", cond),
)
return
}
return
}
type ObjIdsData struct {
Id primitive.ObjectID `bson:"_id"`
}
type ObjCommentCountData struct {
Id primitive.ObjectID `bson:"_id"`
Count int64 `bson:"count"`
}
// CmtFindParentCountByObjIDs 批量获取对象的一级评论数量(审核通过、未删除、非广告)
func CmtFindParentCountByObjIDs(cmtType CmtType, objIDs []primitive.ObjectID) (map[primitive.ObjectID]int64, error) {
res := make(map[primitive.ObjectID]int64, len(objIDs))
if len(objIDs) == 0 {
return res, nil
}
data := make([]ObjCommentCountData, 0, len(objIDs))
pipeline := []bson.M{
{
"$match": bson.M{
"type": cmtType,
"objID": bson.M{"$in": objIDs},
"level": 1,
"status": 1,
"isDelete": false,
"isAdvertiser": bson.M{"$in": []any{nil, false}},
},
},
{
"$group": bson.M{
"_id": "$objID",
"count": bson.M{"$sum": 1},
},
},
}
if err := coll(nil).Aggregate(&data, pipeline); err != nil {
log.Error("Comment CmtFindParentCountByObjIDs fail", log.E(err), log.Any("cmtType", cmtType), log.Any("objIDs", objIDs))
return nil, err
}
for _, item := range data {
res[item.Id] = item.Count
}
return res, nil
}
// GetObjIdsBetweenTime 按照一段时间内被评论的对象id
func GetObjIdsBetweenTime(objType string, start, end time.Time, skip, limit int) (objIds []primitive.ObjectID, hasNext bool, err error) {
list := []ObjIdsData{}
pipeline := []bson.M{
bson.M{
"$match": bson.M{
"objType": objType,
"status": 1,
"isAdvertiser": false,
"createdAt": bson.M{
"$gte": start,
"$lt": end,
},
},
},
bson.M{
"$group": bson.M{
"_id": "$objID",
"createdAt": bson.M{"$first": "$createdAt"}, // 获取第一个发布的时间
},
},
bson.M{
"$sort": bson.D{{"createdAt", 1}}, // 按照第一个发布时间从晚到早
},
bson.M{
"$skip": skip,
},
bson.M{
"$limit": limit + 1,
},
}
err = coll(nil).Aggregate(&list, pipeline)
if err != nil {
log.Error("Comment GetObjIdsBetweenTime fail", log.E(err))
return
}
if len(list) > limit {
hasNext = true
list = list[:limit]
}
for _, v := range list {
objIds = append(objIds, v.Id)
}
return
}
type CommentCountGroupByDay struct {
Count int64 `json:"count" bson:"count"`
Time string `json:"_id" bson:"_id"`
}
// GetCountGroupByDay 按天分组,获取一段时间内某个对象的评论数量
func GetCountGroupByDay(objId primitive.ObjectID, start, end time.Time) (res []CommentCountGroupByDay, err error) {
pipeline := []bson.M{
bson.M{
"$match": bson.M{
"objID": objId,
"status": 1,
"isAdvertiser": false,
"createdAt": bson.M{
"$gte": start,
"$lt": end,
},
},
},
bson.M{
"$group": bson.M{
"_id": bson.M{
"$dateToString": bson.M{
"format": "%Y-%m-%d",
"date": "$createdAt",
},
},
"count": bson.M{"$sum": 1},
},
},
}
err = coll(nil).Aggregate(&res, pipeline)
if err != nil {
log.Error("Comment GetCountGroupByDay fail", log.E(err))
return
}
return
}