spark-server/internal/module/friend/logic/greeting.go
2026-09-18 14:50:41 +08:00

96 lines
2.6 KiB
Go

package logic
import (
"context"
"encoding/json"
"fmt"
"time"
deliverentity "spark-server/internal/module/deliver/entity"
friendentity "spark-server/internal/module/friend/entity"
msgentity "spark-server/internal/module/message/entity"
"spark-server/internal/pkg/reply"
)
const cmdMessage uint16 = 6
// DeliverQueue is Redis deliver:queue Push (C5).
type DeliverQueue interface {
Push(ctx context.Context, job *deliverentity.Job) error
}
// SystemGreeter inserts a type-9 system message into the P2P conversation and enqueues deliver.
type SystemGreeter struct {
chats P2PChats
msgs Messages
ids IDGen
queue DeliverQueue
}
func NewGreeter(chats P2PChats, msgs Messages, ids IDGen, queue DeliverQueue) *SystemGreeter {
return &SystemGreeter{chats: chats, msgs: msgs, ids: ids, queue: queue}
}
func (g *SystemGreeter) BecameFriends(ctx context.Context, userA, userB int64) error {
if g == nil || g.chats == nil || g.msgs == nil || g.ids == nil {
return nil
}
convID, err := g.chats.EnsureP2P(ctx, userA, userB)
if err != nil {
return err
}
msgID, err := g.ids.NextID()
if err != nil {
return err
}
now := time.Now()
content := msgentity.NewSystem(&msgentity.System{Kind: friendentity.SystemKindBecameFriends})
raw, err := content.Marshal()
if err != nil {
return err
}
msg := &msgentity.Message{
ID: msgID,
ConversationID: convID,
SenderID: 0,
ClientMsgID: fmt.Sprintf("sys:friend:%d", msgID),
Type: msgentity.TypeSystem,
Kind: msgentity.KindPrivate,
Content: raw,
Status: msgentity.StatusNormal,
CreatedAtMS: now.UnixMilli(),
}
if err := g.msgs.Create(ctx, msg); err != nil {
return err
}
if err := g.chats.UpdateLastMsg(ctx, convID, msgID, now.UnixMilli()); err != nil {
return err
}
if g.queue == nil {
return nil
}
return g.queue.Push(ctx, &deliverentity.Job{
MsgID: msgID,
Cmd: cmdMessage,
ConversationID: convID,
ToUserIDs: []int64{userA, userB},
Payload: reply.MustMarshal(reply.OK(pushBodyOf(msg))),
})
}
type pushBody struct {
MsgID int64 `json:"msg_id"`
ConversationID int64 `json:"conversation_id"`
SenderID int64 `json:"sender_id"`
MessageType msgentity.Type `json:"message_type"`
Content json.RawMessage `json:"content"`
CreatedAt int64 `json:"created_at"`
}
func pushBodyOf(m *msgentity.Message) pushBody {
return pushBody{
MsgID: m.ID, ConversationID: m.ConversationID, SenderID: m.SenderID,
MessageType: m.Type, Content: m.Content, CreatedAt: m.CreatedAtMS,
}
}