package model import ( "context" "encoding/json" "fmt" "time" "trading-go/common" "trading-go/response" "trading-go/util" ) type Message struct { MsgType int `json:"msgType"` From uint `json:"from,string"` To uint `json:"to,string"` Time uint `json:"time,string"` Content any `json:"content"` } var fromIndex map[uint]string var toIndex map[uint]string func init() { fromIndex = make(map[uint]string) toIndex = make(map[uint]string) } func (m Message) Save() error { rds := common.Redis jsonData, err := json.Marshal(m) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() key := fmt.Sprintf("%d:%d:%d", m.From, m.To, m.Time) _, err = rds.Set(ctx, key, jsonData, time.Second*60*60*24*30).Result() if err != nil { return err } return err } func (m Message) GetFrom(uid uint, page, pageSize int) (ms response.PageResponse, err error) { var mess []Message if page == 1 { fromIndex[uid] = "0" } rds := common.Redis ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() key := fmt.Sprintf("%d:*", uid) result, err := rds.Do(ctx, "scan", fromIndex[uid], "match", key, "count", pageSize).Result() if err != nil { return } rs := result.([]interface{}) index := rs[0].(string) if index != "0" { fromIndex[uid] = index ms.HNext = true } keys := rs[1].([]interface{}) for i := 0; i < len(keys); i++ { value, err := rds.Get(ctx, keys[i].(string)).Result() if err != nil { break } err = json.Unmarshal([]byte(value), &m) if err != nil { break } mess = append(mess, m) } ms.Data = mess ms.PageSize = pageSize ms.Page = page return } func (m Message) GetMsg(uid, target uint) (ms []Message, err error) { mFrom, err := m.GetFrom(uid, 1, 10000000) if err != nil { return nil, err } mTo, err := m.GetTo(uid, 1, 10000000) if err != nil { return nil, err } s1, s2 := mFrom.Data.([]Message), mTo.Data.([]Message) msgs := append(s1, s2...) for _, msg := range msgs { if msg.To == target || msg.From == target { ms = append(ms, msg) } } return ms, nil } func (m Message) GetTo(uid uint, page, pageSize int) (ms response.PageResponse, err error) { var mess []Message if page == 1 { toIndex[uid] = "0" } rds := common.Redis ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() key := fmt.Sprintf("*:%d:*", uid) result, err := rds.Do(ctx, "scan", toIndex[uid], "match", key, "count", pageSize).Result() if err != nil { return } rs := result.([]interface{}) index := rs[0].(string) if index != "0" { toIndex[uid] = index ms.HNext = true } keys := rs[1].([]interface{}) for i := 0; i < len(keys); i++ { value, err := rds.Get(ctx, keys[i].(string)).Result() if err != nil { break } err = json.Unmarshal([]byte(value), &m) if err != nil { break } mess = append(mess, m) } ms.Data = mess ms.PageSize = pageSize ms.Page = page return } func (m Message) GetLatestMsg(uid, target uint) (msg Message, err error) { mFrom, err := m.GetFrom(uid, 1, 10000000) if err != nil { return Message{}, err } mTo, err := m.GetTo(uid, 1, 10000000) if err != nil { return Message{}, err } s1, s2 := mFrom.Data.([]Message), mTo.Data.([]Message) ms := append(s1, s2...) if len(ms) == 0 { return Message{}, util.NoMessageError } last := -1 for i := range ms { if ms[i].From != target && ms[i].To != target { continue } if last == -1 { last = i } else if ms[i].Time > ms[last].Time { last = i } } if last == -1 { return Message{}, util.NoMessageError } return ms[last], nil }