package model import ( "context" "errors" "gorm.io/gorm" "spark-server/internal/module/message/entity" "spark-server/internal/pkg/errs" ) func (m *Repo) ListByConversation(ctx context.Context, conversationID, viewerID, lastMsgID int64, limit int) ([]*entity.Message, error) { if conversationID <= 0 || viewerID <= 0 { return nil, errs.ErrInvalidArgument } if limit <= 0 { limit = 200 } db, err := m.session(ctx) if err != nil { return nil, err } kind, err := m.lookupKind(db, conversationID) if err != nil { return nil, err } table := tableOf(kind) if kind == entity.KindGroup { var rows []GroupMessage err = db.Table(table).Select(table+".*"). Joins("LEFT JOIN t_message_deletes AS d ON d.msg_id = "+table+".id AND d.user_id = ?", viewerID). Where(table+".conversation_id = ? AND "+table+".id > ? AND "+table+".status <> ? AND d.msg_id IS NULL", conversationID, lastMsgID, entity.StatusHidden). Order(table + ".id ASC"). Limit(limit). Find(&rows).Error if err != nil { return nil, mapDBErr(err) } out := make([]*entity.Message, 0, len(rows)) for i := range rows { out = append(out, rows[i].entity()) } return out, nil } var rows []PrivateMessage err = db.Table(table).Select(table+".*"). Joins("LEFT JOIN t_message_deletes AS d ON d.msg_id = "+table+".id AND d.user_id = ?", viewerID). Where(table+".conversation_id = ? AND "+table+".id > ? AND "+table+".status <> ? AND d.msg_id IS NULL", conversationID, lastMsgID, entity.StatusHidden). Order(table + ".id ASC"). Limit(limit). Find(&rows).Error if err != nil { return nil, mapDBErr(err) } out := make([]*entity.Message, 0, len(rows)) for i := range rows { out = append(out, rows[i].entity()) } return out, nil } func (m *Repo) Recall(ctx context.Context, id int64) error { if id <= 0 { return errs.ErrInvalidArgument } db, err := m.session(ctx) if err != nil { return err } if n, err := m.recallTable(db, tablePrivateMessage, id); err != nil { return err } else if n > 0 { return nil } n, err := m.recallTable(db, tableGroupMessage, id) if err != nil { return err } if n == 0 { return errs.ErrNotFound } return nil } func (m *Repo) recallTable(db *gorm.DB, table string, id int64) (int64, error) { res := db.Table(table).Where("id = ? AND status = ?", id, entity.StatusNormal).Update("status", entity.StatusRecalled) if res.Error != nil { return 0, mapDBErr(res.Error) } return res.RowsAffected, nil } func (m *Repo) HideForUser(ctx context.Context, userID int64, msg *entity.Message) error { if userID <= 0 || msg == nil || msg.ID <= 0 { return errs.ErrInvalidArgument } db, err := m.session(ctx) if err != nil { return err } row := MessageDelete{ UserID: userID, MsgID: msg.ID, ConversationID: msg.ConversationID, } if err := db.Create(&row).Error; err != nil { if errors.Is(mapDBErr(err), errs.ErrDuplicate) { return nil } return mapDBErr(err) } return nil } func (m *Repo) PurgeUser(ctx context.Context, userID int64) error { if userID <= 0 { return errs.ErrInvalidArgument } db, err := m.session(ctx) if err != nil { return err } return mapDBErr(db.Where("user_id = ?", userID).Delete(&MessageDelete{}).Error) }