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 }