package db import ( "errors" cherryApp "f1-game/internal/cherry_app" dbFacade "f1-game/internal/component/db/facade" "f1-game/internal/data" nameDB "f1-game/internal/name/db" "f1-game/internal/types" dbMail "f1-game/nodes/game/internal/db/data/mail" "slices" ctime "github.com/cherry-game/cherry/extend/time" clog "github.com/cherry-game/cherry/logger" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" ) // MailTable 邮件表 type MailTable struct { PlayerID int64 `bson:"PlayerID,omitempty"` NodeID string `bson:"NodeID,omitempty"` AutoID int64 `bson:"AutoID,omitempty"` // 邮件自增ID BulkIDList types.List[int64] `bson:"BulkIDList,omitempty"` // 已发放群发邮件Id列表 群发邮件表ID dbMail.Data `bson:"Data,omitempty"` dbFacade.TableBase `bson:",inline"` } func (p *MailTable) TableName() string { return nameDB.Table_Mail } func (p *MailTable) PrimaryValue() any { return p.PlayerID } func (p *MailTable) CheckField() { } func (p *MailTable) Save2Queue() { save2Queue(p) } func (p *MailTable) Add(mail *dbMail.Mail, autoSave bool) ([]*dbMail.Mail, bool) { var ( isChange bool // 是否修改数据 delMailList []*dbMail.Mail // 已删除的邮件id列表 mailCount = int32(len(p.Data)) //当前邮件数量 ) remain := mailCount - data.Const.MailLimitNum + 1 for remain > 0 { delMail := p.Data[0] delMailList = append(delMailList, delMail) p.Data.RemoveIndex(0) remain-- } isChange = p.Data.Add(mail) if isChange && autoSave { p.Save2Queue() } return delMailList, isChange } // CheckExpire 清理过期邮件 func (p *MailTable) CheckExpire(now *ctime.CherryTime) []*dbMail.Mail { var ( curTime = ctime.Now().ToSecond() delMailList = []*dbMail.Mail{} ) for _, mailEntity := range p.Data { if mailEntity.ExpireTime <= curTime { delMailList = append(delMailList, mailEntity) } } if len(delMailList) > 0 { for _, mailEntity := range delMailList { p.Data.Remove(mailEntity.MailID) } p.Save2Queue() } return delMailList } func (p *MailTable) InBulk(bulkID int64) bool { return slices.Contains(p.BulkIDList, bulkID) } func (p *MailTable) AddBulkID(bulkID int64) { p.BulkIDList.Add(bulkID) p.Save2Queue() } func (p *MailTable) NewMailID() int64 { p.AutoID++ p.Save2Queue() return p.AutoID } func GetMailTable(playerID int64) *MailTable { if val, ok := mailTableCache.GetIfPresent(playerID); ok { return val.(*MailTable) } mailTable := GetMailTableFromDB(playerID) mailTableCache.Put(playerID, mailTable) return mailTable } func GetMailTableFromDB(playerID int64) *MailTable { table := newMailTable(playerID) filter := bson.M{ nameDB.Field_NodeID: table.NodeID, nameDB.Field_PlayerID: table.PlayerID, } err := dbComponent.FindOne(table, filter) if err != nil { if errors.Is(err, mongo.ErrNoDocuments) { clog.Warnf("[playerID = %d] not found, create new one", playerID) return table } clog.Errorf("[playerID = %d] db error = %v", playerID, err) return table } table.CheckField() return table } func newMailTable(playerID int64) *MailTable { return &MailTable{ PlayerID: playerID, NodeID: cherryApp.NodeID(), AutoID: 0, BulkIDList: types.NewList[int64](), Data: []*dbMail.Mail{}, } }