spark-server/internal/module/message/model/query.go
2026-09-20 17:49:09 +08:00

124 lines
3.2 KiB
Go

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 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 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)
}