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
+332
View File
@@ -0,0 +1,332 @@
package followmod
import (
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"time"
)
var mdb *db.MongoDB
const table = models.Follow
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
// initIndex 初始化索引
func initIndex() {
many := []mongo.IndexModel{
{
Keys: bson.D{{"followUID", -1}},
},
{
Keys: bson.D{{"uid", 1}, {"followUID", 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{"uniq", 1}},
},
{
Keys: bson.D{{"createdAt", -1}},
},
}
_, err := coll(nil).CreateIndex(many)
if err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
return
}
// AddFollow 添加关注
func AddFollow(uid uint64, followUID uint64, isShort bool) (int64, error) {
set := bson.M{"uniq": Unique(uid, followUID), "createdAt": time.Now()}
if isShort {
set["newsType"] = "SHORT"
}
res, err := coll(nil).UpsertOne(
bson.M{"uid": uid, "followUID": followUID},
bson.M{"$set": set})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "AddFollow", table, "UpsertOne", err),
log.Any("uid", uid), log.Any("followUID", followUID),
)
}
if res != nil {
return res.UpsertedCount, err
}
return 0, err
}
// CloseFollow 取消关注
func CloseFollow(uid uint64, followUID uint64) (int64, error) {
res, err := coll(nil).DeleteOne(
bson.M{"uid": uid, "followUID": followUID})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "CloseFollow", table, "DeleteOne", err),
log.Any("uid", uid), log.Any("followUID", followUID),
)
}
if res != nil {
return res.DeletedCount, err
}
return 0, err
}
// IsFollow 是否关注
func IsFollow(uid uint64, followUID uint64) (bool, error) {
f := FollowModel{}
err := coll(nil).FindOne(&f, bson.M{"uid": uid, "followUID": followUID})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsFollow", table, "Count", err), log.Any("uid", uid), log.Any("followUID", followUID))
return false, err
}
if f.FollowUID == 0 {
return false, err
}
return true, nil
}
// IsFollowUsers 是否关注这些用户
func IsFollowUsers(uid uint64, followUIDs []uint64) (map[uint64]bool, error) {
if followUIDs == nil {
followUIDs = []uint64{}
}
m := make(map[uint64]bool)
if uid == 0 || len(followUIDs) == 0 {
return m, nil
}
var infos []FollowModel
err := coll(nil).Find(&infos, bson.M{"uid": uid, "followUID": bson.M{"$in": followUIDs}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsFollowUsers", table, "Find", err),
log.Any("uid", uid), log.Any("followUIDs", followUIDs),
)
return m, err
}
for _, i := range infos {
m[i.FollowUID] = true
}
return m, nil
}
// IsFollowedByUsers 是否被这些用户关注
func IsFollowedByUsers(followUID uint64, uids []uint64) (map[uint64]bool, error) {
if uids == nil {
uids = []uint64{}
}
m := make(map[uint64]bool)
var infos []FollowModel
err := coll(nil).Find(&infos, bson.M{"followUID": followUID, "uid": bson.M{"$in": uids}})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsFollowedByUsers", table, "Find", err),
log.Any("followUID", followUID), log.Any("uids", uids),
)
return m, err
}
for _, i := range infos {
m[i.UID] = true
}
return m, nil
}
// FollowStatueMap 从给定的hash列表中获取like状态映射:hash->Statue
// hash通过Vector.hash()获取
func FollowStatueMap(uniqList []string) (map[string]bool, error) {
filter := bson.M{
"uniq": bson.M{"$in": uniqList},
}
existLikeList := make([]FollowModel, 0, len(uniqList))
err := coll(nil).Find(&existLikeList, filter)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "FollowStatueMap", table, "Find", err),
log.Any("uniqList", uniqList),
)
return nil, err
}
m := make(map[string]bool, len(existLikeList))
//初始化
for _, uniq := range uniqList {
m[uniq] = false
}
//已经关注的
for _, v := range existLikeList {
uniq := v.Uniq
m[uniq] = true
}
return m, nil
}
// GetFollowCount 获取关注总数
func GetFollowCount(uid uint64) (int64, error) {
total, err := coll(nil).Count(bson.M{"uid": uid})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "IsFollowEachOther", table, "Count", err),
log.Any("uid", uid),
)
return 0, err
}
return total, nil
}
// GetFansCount 获取粉丝总数
func GetFansCount(uid uint64) (int64, error) {
total, err := coll(nil).Count(bson.M{"followUID": uid})
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFansCount", table, "Count", err),
log.Any("uid", uid),
)
return 0, err
}
return total, nil
}
// GetFollowList 获取关注列表
func GetFollowList(uid uint64, page int, size int, isShort bool) ([]uint64, map[uint64]FollowModel, bool, error) {
hasNext := false
m := make(map[uint64]FollowModel)
cond := bson.M{"uid": uid}
sort := bson.D{{Key: "createdAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort).SetSkip(int64((page - 1) * size)).SetLimit(int64(size + 1))
if isShort {
cond["newsType"] = "SHORT"
}
var data []*FollowModel
err := coll(nil).Find(&data, cond, &opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFollowList", table, "Find", err),
log.Any("uid", uid), log.Any("page", page), log.Any("size", size),
)
return nil, m, false, err
}
if len(data) > size {
hasNext = true
data = data[:size]
}
var uids []uint64
for _, d := range data {
if d == nil {
continue
}
uids = append(uids, d.FollowUID)
m[d.FollowUID] = *d
}
return uids, m, hasNext, nil
}
// GetFansList 获取粉丝列表
func GetFansList(uid uint64, page int, size int) ([]uint64, map[uint64]FollowModel, bool, error) {
hasNext := false
m := make(map[uint64]FollowModel)
cond := bson.M{"followUID": uid}
sort := bson.D{{Key: "createdAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort).SetSkip(int64((page - 1) * size)).SetLimit(int64(size + 1))
var data []*FollowModel
err := coll(nil).Find(&data, cond, &opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetFansList", table, "Find", err),
log.Any("uid", uid), log.Any("page", page), log.Any("size", size),
)
return nil, m, hasNext, err
}
if len(data) > size {
hasNext = true
data = data[:size]
}
var uids []uint64
for _, d := range data {
if d == nil {
continue
}
uids = append(uids, d.UID)
m[d.UID] = *d
}
return uids, m, hasNext, nil
}
// GetAllFansUid 获取所有粉丝用户id
func GetAllFansUid(uid uint64) ([]uint64, error) {
var data []*FollowModel
cond := bson.M{"followUID": uid}
sort := bson.D{{Key: "createdAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort)
err := coll(nil).Find(&data, cond, &opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetAllFansUid", table, "Find", err),
log.Any("uid", uid),
)
return nil, err
}
var uids []uint64
for _, d := range data {
uids = append(uids, d.UID)
}
return uids, nil
}
// GetTotalFollowList 获取所有关注用户
func GetTotalFollowList(uid uint64) ([]uint64, error) {
var data []*FollowModel
cond := bson.M{"uid": uid}
sort := bson.D{{Key: "createdAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort).SetLimit(5)
err := coll(nil).Find(&data, cond, &opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetTotalFollowList", table, "Find", err),
log.Any("uid", uid),
)
return nil, err
}
var uids []uint64
for _, d := range data {
uids = append(uids, d.FollowUID)
}
return uids, nil
}
// GetTotalFollowListLimit 获取所有关注用户
func GetTotalFollowListLimit(uid uint64, limit int64) ([]uint64, error) {
var data []*FollowModel
cond := bson.M{"uid": uid}
sort := bson.D{{Key: "createdAt", Value: -1}}
opts := options.FindOptions{}
opts.SetSort(sort).SetLimit(limit)
err := coll(nil).Find(&data, cond, &opts)
if err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "GetTotalFollowListLimit", table, "Find", err),
log.Any("uid", uid),
)
return nil, err
}
var uids []uint64
for _, d := range data {
uids = append(uids, d.FollowUID)
}
return uids, nil
}
// WeekFollowLeaderboard 周关注榜单
func WeekFollowLeaderboard(bind interface{}, filter bson.M, limit int) error {
opt := options.Aggregate().SetAllowDiskUse(true)
pip := []bson.M{
{"$match": filter}, // 过滤条件 由外部决定
{"$group": bson.M{"_id": "$followUID", "count": bson.M{"$sum": 1}}}, // 统计用户被关注
{"$sort": bson.M{"count": -1}}, // 按照作品数排序
{"$limit": limit}, // 限制返回条数
}
return coll(nil).Aggregate(bind, pip, opt)
}