补上会员价格按平台筛选,并修正广场机器人测试的 Feed 调用,使 go test 能通过。 Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
package model
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
"spark-server/internal/module/conversation/entity"
|
||
"spark-server/internal/pkg/errs"
|
||
)
|
||
|
||
// ConversationMember maps table conversation_members.
|
||
type ConversationMember struct {
|
||
ID int64 `gorm:"column:id;primaryKey;autoIncrement;comment:行 id,表内自增,仅内部用;业务唯一键是 (conversation_id, user_id)"`
|
||
ConversationID int64 `gorm:"column:conversation_id;comment:会话 id"`
|
||
UserID int64 `gorm:"column:user_id;comment:成员 user_id"`
|
||
LastReadMsgID int64 `gorm:"column:last_read_msg_id;comment:该成员已读到的最大消息 id,未读真相;Redis 丢了可从此重建"`
|
||
JoinedAt time.Time `gorm:"column:joined_at;comment:加入会话时间"`
|
||
Muted int `gorm:"column:muted;comment:0=未静音 1=免打扰"`
|
||
}
|
||
|
||
func (ConversationMember) TableName() string { return "t_conversation_members" }
|
||
|
||
func (r *ConversationMember) entity() *entity.Member {
|
||
if r == nil {
|
||
return nil
|
||
}
|
||
m := &entity.Member{
|
||
ConversationID: r.ConversationID, UserID: r.UserID,
|
||
LastReadMsgID: r.LastReadMsgID, JoinedAtMS: r.JoinedAt.UnixMilli(),
|
||
}
|
||
m.Muted = r.Muted != 0
|
||
return m
|
||
}
|
||
|
||
func (m *Repo) ListMemberIDs(ctx context.Context, conversationID int64) ([]int64, error) {
|
||
if conversationID <= 0 {
|
||
return nil, errs.ErrInvalidArgument
|
||
}
|
||
db, err := m.session(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
var rows []ConversationMember
|
||
if err := db.Where("conversation_id = ?", conversationID).Find(&rows).Error; err != nil {
|
||
return nil, mapDBErr(err)
|
||
}
|
||
ids := make([]int64, 0, len(rows))
|
||
for i := range rows {
|
||
ids = append(ids, rows[i].UserID)
|
||
}
|
||
return ids, nil
|
||
}
|
||
|
||
func (m *Repo) UpdateLastRead(ctx context.Context, conversationID, userID, msgID int64) error {
|
||
if conversationID <= 0 || userID <= 0 || msgID <= 0 {
|
||
return errs.ErrInvalidArgument
|
||
}
|
||
db, err := m.session(ctx)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
res := db.Model(&ConversationMember{}).
|
||
Where("conversation_id = ? AND user_id = ? AND last_read_msg_id < ?", conversationID, userID, msgID).
|
||
Update("last_read_msg_id", msgID)
|
||
if res.Error != nil {
|
||
return mapDBErr(res.Error)
|
||
}
|
||
if res.RowsAffected > 0 {
|
||
return nil
|
||
}
|
||
var n int64
|
||
if err := db.Model(&ConversationMember{}).
|
||
Where("conversation_id = ? AND user_id = ?", conversationID, userID).
|
||
Count(&n).Error; err != nil {
|
||
return mapDBErr(err)
|
||
}
|
||
if n == 0 {
|
||
return errs.ErrNotFound
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (m *Repo) GetMember(ctx context.Context, conversationID, userID int64) (*entity.Member, error) {
|
||
if conversationID <= 0 || userID <= 0 {
|
||
return nil, errs.ErrInvalidArgument
|
||
}
|
||
db, err := m.session(ctx)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
var row ConversationMember
|
||
if err := db.Where("conversation_id = ? AND user_id = ?", conversationID, userID).Take(&row).Error; err != nil {
|
||
return nil, mapDBErr(err)
|
||
}
|
||
return row.entity(), nil
|
||
}
|