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 }