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
+46
View File
@@ -0,0 +1,46 @@
package noticerecdmod
import (
"91porn-server/common/pageopt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
type RecordSlice []NoticeRecord
func (r RecordSlice) Len() int {
return len(r)
}
func (r RecordSlice) Swap(i, j int) {
r[i], r[j] = r[j], r[i]
}
func (r RecordSlice) Less(i, j int) bool {
return r[i].LastSendAt.Before(r[j].LastSendAt)
}
type Matcher = pageopt.Matcher
type UIDMatch = pageopt.UIDMatch
type NoticeCodeInMatch struct {
NoticeCodes []string
}
func (u *NoticeCodeInMatch) New() Matcher {
return pageopt.NewInMatch("noticeCode", u.NoticeCodes)
}
func List(sort bson.D, skip, limit int64, matchs ...Matcher) (RecordSlice, error) {
filter := pageopt.MergeM(matchs)
opt := (&options.FindOptions{})
if len(sort) != 0 {
opt.SetSort(sort)
}
opt.SetSkip(skip)
opt.SetLimit(limit)
list := make(RecordSlice, 0, limit)
return list, coll(nil).Find(&list, filter, opt)
}
+144
View File
@@ -0,0 +1,144 @@
package noticerecdmod
import (
"fmt"
"time"
"91porn-server/common/db"
"91porn-server/common/log"
"91porn-server/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
const table = models.NoticeRecd
type M = bson.M
var mdb *db.MongoDB
func coll(t *db.MongoTool) *db.MongoTool {
if t == nil {
return mdb.Coll(table)
}
return t.Coll(table)
}
func initIndex() {
many := []mongo.IndexModel{ //batch set indexes //value is the type 1 or -1
{
Keys: bson.D{{Key: "uid", Value: 1}, {Key: "noticeCode", Value: 1}},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{{Key: "createdAt", Value: 1}},
},
{
Keys: bson.D{{Key: "updatedAt", Value: 1}},
},
}
if _, err := coll(nil).CreateIndex(many); err != nil {
panic(fmt.Sprintf("%s model set index err ==>[%+v]", table, err))
}
}
func GetRecordSlice(uid uint64, noticeCodeList []string) (RecordSlice, error) {
if len(noticeCodeList) == 0 {
return RecordSlice{}, nil
}
filter := M{
"uid": uid,
"noticeCode": M{"$in": noticeCodeList},
}
list := make(RecordSlice, 0)
return list, coll(nil).Find(&list, filter)
}
func GetLastSendAtMap(uid uint64, noticeCodeList []string) (map[string]time.Time, error) {
if len(noticeCodeList) == 0 {
return make(map[string]time.Time), nil
}
list, err := GetRecordSlice(uid, noticeCodeList)
if err != nil {
return nil, err
}
m := make(map[string]time.Time)
for _, v := range list {
m[v.NoticeCode] = v.LastSendAt
}
return m, nil
}
func UpsertLastSendAt(uid uint64, lastSendAtMap map[string]time.Time) error {
now := time.Now()
writes := make([]mongo.WriteModel, len(lastSendAtMap))
i := 0
for noticeCode, lastSendAt := range lastSendAtMap {
writes[i] = mongo.NewUpdateOneModel().SetFilter(bson.M{
"uid": uid,
"noticeCode": noticeCode,
"lastSendAt": M{"$lt": lastSendAt},
}).SetUpdate(bson.M{
"$setOnInsert": M{
"uid": uid,
"noticeCode": noticeCode,
"lastReadAt": time.Time{},
"createdAt": now,
},
"$set": M{
"lastSendAt": lastSendAt,
"updatedAt": now,
},
}).SetUpsert(true)
i++
}
if len(writes) == 0 {
return nil
}
opt := (&options.BulkWriteOptions{}).SetOrdered(false) //设为无序,触发并行写,提升写效率
if _, err := coll(nil).Bulk(writes, opt); err != nil {
log.Error(fmt.Sprintf("[METHOD-%s]==> Model %s %s fail error:%+v:", "UpsertLastSendAt", table, "Bulk", err),
log.Any("uid", uid),
log.Any("lastSendAtMap", lastSendAtMap),
)
return err
}
return nil
}
func UpdateReadTime(readAt time.Time, uid uint64, noticeCodeList []string) error {
if len(noticeCodeList) == 0 {
return nil
}
filter := M{
"uid": uid,
"noticeCode": M{"$in": noticeCodeList},
"lastReadAt": M{"$lt": readAt},
}
update := M{
"$set": M{
"lastReadAt": readAt,
"updatedAt": time.Now(),
},
}
_, err := coll(nil).UpdateMany(filter, update)
return err
}
func GetLastReadAtMap(uid uint64, noticeCodeList []string) (map[string]time.Time, error) {
if len(noticeCodeList) == 0 {
return make(map[string]time.Time), nil
}
list, err := GetRecordSlice(uid, noticeCodeList)
if err != nil {
return nil, err
}
m := make(map[string]time.Time)
for _, v := range list {
m[v.NoticeCode] = v.LastReadAt
}
return m, nil
}
+42
View File
@@ -0,0 +1,42 @@
package noticerecdmod
import "time"
// 动态类型
type TrendType string
const (
Fans TrendType = "fans" //粉丝
Like TrendType = "like" //点赞
Cmet TrendType = "cmet" //评论
Itte TrendType = "itte" //互动
)
// UpdateTrendReadTime 更新动态的阅读时间
func UpdateTrendReadTime(trend TrendType, uid uint64, readAt time.Time) error {
filter := M{
"uid": uid,
"noticeCode": trend,
}
noticeRecord := NoticeRecord{}
if err := coll(nil).FindOne(&noticeRecord, filter); err != nil {
return err
}
if noticeRecord.LastReadAt.After(readAt) {
return nil
}
filter["lastReadAt"] = M{"$lt": readAt}
update := M{
"$setOnInsert": M{
"uid": uid,
"noticeCode": trend,
"createdAt": time.Now(),
},
"$set": M{
"lastReadAt": readAt,
"updatedAt": time.Now(),
},
}
_, err := coll(nil).UpsertOne(filter, update)
return err
}
+31
View File
@@ -0,0 +1,31 @@
package noticerecdmod
import (
"time"
"91porn-server/common/db"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// ObjectID
type ObjectID = primitive.ObjectID
type D = bson.D
// 通知记录
type NoticeRecord struct {
ID ObjectID `bson:"_id,omitempty"`
UID uint64 `bson:"uid"`
NoticeCode string `bson:"noticeCode"` //通知码 唯一标记通知内容和计划
LastSendAt time.Time `bson:"lastSendAt"` //发送消息的最后时间
LastReadAt time.Time `bson:"lastReadAt"` //发送消息的最后时间
UpdatedAt time.Time `bson:"updatedAt"` //文档更新时间
CreatedAt time.Time `bson:"createdAt"` //文档创建时间
}
func Init() {
mdb = db.Init(table)
initIndex()
}