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

235 lines
7.0 KiB
Go

package infmtser
import (
"sort"
"time"
"91porn-server/models/v/noticefmtmod"
"91porn-server/models/v/noticerecdmod"
"91porn-server/models/v/usermod"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// ObjectID
type ObjectID = primitive.ObjectID
type Sender = noticefmtmod.Sender
type NoticeFmt = noticefmtmod.NoticeFmt
type Notice struct {
SendAt time.Time `json:"sendAt"` //消息的发送时间
Sender Sender `json:"sender"` //发送者
Title string `json:"title"` //标题
Content string `json:"content"` //内容
}
// 通知预览
type NoticPreview struct {
NewsCount int64 `json:"newsCount"`
Notice
}
type FMTEnableMatch = noticefmtmod.EnableMatch
func UpdateNoticePreviewList(uid uint64, curTime time.Time) ([]NoticPreview, bool, error) {
enable := true
enableMatch := FMTEnableMatch{Enable: &enable}
noticeFmts, err := noticefmtmod.GetNoticeFmtListByUID(uid, enableMatch.New())
if err != nil {
return nil, false, err
}
noticeFmtsLen := len(noticeFmts)
var (
noticeCodeList = make([]string, noticeFmtsLen)
noticeFmtMap = make(map[string]NoticeFmt)
systemNoticeCodeList = make([]string, 0, noticeFmtsLen)
actAsstNoticeCodeList = make([]string, 0, noticeFmtsLen)
)
for i, n := range noticeFmts {
sender := n.Sender
if sender == noticefmtmod.System {
systemNoticeCodeList = append(systemNoticeCodeList, n.NoticeCode)
} else if sender == noticefmtmod.ActAsst {
actAsstNoticeCodeList = append(actAsstNoticeCodeList, n.NoticeCode)
}
noticeFmtMap[n.NoticeCode] = n
noticeCodeList[i] = n.NoticeCode
}
lastSendAtMap, err := noticerecdmod.GetLastSendAtMap(uid, noticeCodeList)
if err != nil {
return nil, false, err
}
var nextSendAtMap = make(map[string]time.Time) //新通知
for _, fmt := range noticeFmts {
nextSendTimeList := noticefmtmod.TimeSlice{}
switch fmt.NoticeType {
case noticefmtmod.MailNoticeType:
nextSendTimeList = fmt.MailNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode])
case noticefmtmod.RegularNoticeType:
nextSendTimeList = fmt.RegularNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode])
case noticefmtmod.PlanNoticeType:
nextSendTimeList = fmt.PlanNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode])
case noticefmtmod.SpecifyNoticeType:
nextSendTimeList = fmt.SpecifyNotice.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode])
case noticefmtmod.AfterRegistNoticeType:
user, _ := usermod.FindUserByUID(uid)
if user != nil {
afterRegistNoticeEx := noticefmtmod.AfterRegistNoticeEx{AfterRegistNotice: fmt.AfterRegistNotice, CreatedAt: user.CreatedAt}
nextSendTimeList = afterRegistNoticeEx.NextSendTimeList(curTime, lastSendAtMap[fmt.NoticeCode])
}
}
if nextSendTimeList.Len() != 0 {
nextSendAtMap[fmt.NoticeCode] = nextSendTimeList[0]
}
}
if err = noticerecdmod.UpsertLastSendAt(uid, nextSendAtMap); err != nil {
return nil, false, err
}
return getNoticePreview(uid, noticeFmtMap, systemNoticeCodeList, actAsstNoticeCodeList)
}
func getNoticePreview(uid uint64, noticeFmtMap map[string]NoticeFmt, systemNoticeCodeList []string, actAsstNoticeCodeList []string) ([]NoticPreview, bool, error) {
sysRecordSlice, err := noticerecdmod.GetRecordSlice(uid, systemNoticeCodeList)
if err != nil {
return nil, false, err
}
astRecordSlice, err := noticerecdmod.GetRecordSlice(uid, actAsstNoticeCodeList)
if err != nil {
return nil, false, err
}
var noticTalkList []NoticPreview
totalHasNew := false
fill := func(recordSlice noticerecdmod.RecordSlice) {
if recordSlice.Len() == 0 {
return
}
sort.Sort(sort.Reverse(recordSlice)) //发送时间降序
top := recordSlice[0]
noticeFmt, ok := noticeFmtMap[top.NoticeCode]
if !ok {
return
}
notice := Notice{
SendAt: top.LastSendAt,
Sender: noticeFmt.Sender,
Title: noticeFmt.Title,
Content: noticeFmt.Content,
}
newsCount := int64(0)
for _, v := range recordSlice {
if v.LastSendAt.After(v.LastReadAt) {
newsCount++
}
}
totalHasNew = totalHasNew || (newsCount > 0)
noticTalkList = append(noticTalkList, NoticPreview{newsCount, notice})
}
fill(sysRecordSlice)
fill(astRecordSlice)
return noticTalkList, totalHasNew, nil
}
type NoticePage struct {
HasNext bool `json:"hasNext"`
List []Notice `json:"list"`
}
type FMTSenderMatch = noticefmtmod.SenderMatch
type RecdNoticeCodeInMatch = noticerecdmod.NoticeCodeInMatch
type RecdUIDMatch = noticerecdmod.UIDMatch
func NoticePages(sender Sender, uid uint64, skip int64, limit int64) (NoticePage, error) {
enable := true
enableMatch := FMTEnableMatch{Enable: &enable}
senderMatch := FMTSenderMatch{Sender: &sender}
noticeFmts, err := noticefmtmod.GetNoticeFmtListByUID(uid, senderMatch.New(), enableMatch.New())
if err != nil {
return NoticePage{}, err
}
noticeCodeList := make([]string, len(noticeFmts))
fmtMap := make(map[string]NoticeFmt)
for i, fmt := range noticeFmts {
noticeCodeList[i] = fmt.NoticeCode
fmtMap[fmt.NoticeCode] = fmt
}
sort := bson.D{{Key: "lastSendAt", Value: -1}}
recdNoticeCodeInMatch := RecdNoticeCodeInMatch{NoticeCodes: noticeCodeList}
recdUIDMatch := RecdUIDMatch{UID: &uid}
limitEx := limit + 1
list, err := noticerecdmod.List(sort, skip, limitEx, recdUIDMatch.New(), recdNoticeCodeInMatch.New())
if err != nil {
return NoticePage{}, err
}
hasNext := false
if len(list) > int(limit) {
hasNext = true
list = list[:limit]
}
noticeList := make([]Notice, 0, list.Len())
for _, v := range list {
noticeCode := v.NoticeCode
fmt, ok := fmtMap[noticeCode]
if !ok {
continue
}
notice := Notice{
SendAt: v.LastSendAt,
Sender: fmt.Sender,
Title: fmt.Title,
Content: fmt.Content,
}
noticeList = append(noticeList, notice)
}
return NoticePage{
hasNext,
noticeList,
}, nil
}
func UpdateNoticeReadTime(sender Sender, uid uint64, readAt time.Time) error {
senderMatch := FMTSenderMatch{Sender: &sender}
noticeFmts, err := noticefmtmod.GetNoticeFmtListByUID(uid, senderMatch.New())
if err != nil {
return err
}
noticeCodeList := make([]string, len(noticeFmts))
for i, fmt := range noticeFmts {
noticeCodeList[i] = fmt.NoticeCode
}
return noticerecdmod.UpdateReadTime(readAt, uid, noticeCodeList)
}
const (
Fans = noticerecdmod.Fans //粉丝
Like = noticerecdmod.Like //点赞
Cmet = noticerecdmod.Cmet //评论
Itte = noticerecdmod.Itte //互动
)
// 动态预览
type TrendPreview struct {
Count int64 `json:"count"` //数量
}
// 动态预览映射
func TrendPreviewMap(uid uint64) (map[noticerecdmod.TrendType]TrendPreview, bool) {
var (
fensPreviewCount int64 //粉丝预览数
likePreviewCount int64 //点赞预览数
cmetPreviewCount int64 //评论预览数
ittePreviewCount int64 //互动预览数 暂不做
)
hasNews := (fensPreviewCount + likePreviewCount + cmetPreviewCount + ittePreviewCount) > 0
return map[noticerecdmod.TrendType]TrendPreview{
Fans: {fensPreviewCount},
Like: {likePreviewCount},
Cmet: {cmetPreviewCount},
Itte: {ittePreviewCount},
}, hasNews
}