package logic import ( "context" "fmt" "strconv" "strings" "time" ) func (s *Service) ImStats(ctx context.Context) (*ImStats, error) { if !s.ready() { return nil, ErrNotReady } return s.repo.ImStats(ctx) } func (s *Service) ListMessages(ctx context.Context, q string, limit int) ([]ImMessageView, error) { if !s.ready() { return nil, ErrNotReady } if limit <= 0 || limit > 500 { limit = 100 } q = strings.TrimSpace(q) rows, err := s.repo.ListRecentMessages(ctx, limit*3) if err != nil { return nil, err } out := make([]ImMessageView, 0, limit) for i := range rows { v := messageView(&rows[i]) if q != "" && !messageMatch(&v, q) { continue } out = append(out, v) if len(out) >= limit { break } } return out, nil } func (s *Service) ListConversations(ctx context.Context, userID int64) (convs []ImConversationView, groups []GroupView, stats *ImStats, err error) { if !s.ready() { return nil, nil, nil, ErrNotReady } if userID <= 0 { stats, err = s.ImStats(ctx) return nil, nil, stats, err } rows, err := s.repo.ListUserConversations(ctx, userID) if err != nil { return nil, nil, nil, err } convs = make([]ImConversationView, 0, len(rows)) groups = make([]GroupView, 0) seenGroup := map[int64]struct{}{} for i := range rows { chatType := "private" r := &rows[i] if r.Type == 2 { chatType = "group" } key := fmt.Sprintf("c:%d", r.ID) if chatType == "private" { key = fmt.Sprintf("p2p:%d_%d", r.UserSmall, r.UserBig) } else if r.GroupID > 0 { key = fmt.Sprintf("group:%d", r.GroupID) } convs = append(convs, ImConversationView{ Key: key, ChatType: chatType, UserA: r.UserSmall, UserB: r.UserBig, GroupID: r.GroupID, LastMsgID: r.LastMsgID, UpdatedAt: r.LastMsgAt.Format(time.RFC3339), }) if r.GroupID > 0 { if _, ok := seenGroup[r.GroupID]; !ok { seenGroup[r.GroupID] = struct{}{} gv, gerr := s.GroupDetail(ctx, strconv.FormatInt(r.GroupID, 10)) if gerr == nil && gv != nil { groups = append(groups, *gv) } } } } return convs, groups, nil, nil }