75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
|
|
roomv1 "hyapp.local/api/proto/room/v1"
|
|
"hyapp/pkg/appcode"
|
|
"hyapp/pkg/usermq"
|
|
"hyapp/services/room-service/internal/room/state"
|
|
)
|
|
|
|
type userRegionChangedPayload struct {
|
|
UserID int64 `json:"user_id"`
|
|
OldCountry string `json:"old_country"`
|
|
NewCountry string `json:"new_country"`
|
|
OldRegionID int64 `json:"old_region_id"`
|
|
NewRegionID int64 `json:"new_region_id"`
|
|
Source string `json:"source"`
|
|
RequestID string `json:"request_id"`
|
|
ChangedAtMS int64 `json:"changed_at_ms"`
|
|
}
|
|
|
|
// HandleUserOutboxMessage 只消费 user-service 的当前区域迁移事实;历史注册、邀请或麦位事实不是 room-service 的状态输入。
|
|
func (s *Service) HandleUserOutboxMessage(ctx context.Context, message usermq.UserOutboxMessage) error {
|
|
if strings.TrimSpace(message.EventType) != "UserRegionChanged" {
|
|
return nil
|
|
}
|
|
var payload userRegionChangedPayload
|
|
if err := json.Unmarshal([]byte(message.PayloadJSON), &payload); err != nil {
|
|
return err
|
|
}
|
|
if payload.UserID <= 0 || payload.NewRegionID < 0 {
|
|
// user_outbox 已经是 owner service 提交后的事实;结构错误交给 MQ 重试和告警,不在本地猜测修复。
|
|
return errors.New("user region changed payload is invalid")
|
|
}
|
|
if payload.UserID != message.AggregateID {
|
|
// aggregate_id 是 outbox 幂等和审计键,必须和 payload 指向同一个用户,避免错误事件迁移别人的房间。
|
|
return errors.New("user region changed aggregate_id mismatch")
|
|
}
|
|
|
|
ctx = appcode.WithContext(ctx, message.AppCode)
|
|
meta, exists, err := s.repository.GetRoomMetaByOwner(ctx, payload.UserID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !exists || meta.Status == state.RoomStatusDeleted || meta.VisibleRegionID == payload.NewRegionID {
|
|
return nil
|
|
}
|
|
|
|
requestID := strings.TrimSpace(payload.RequestID)
|
|
if requestID == "" {
|
|
requestID = message.EventID
|
|
}
|
|
sentAtMS := payload.ChangedAtMS
|
|
if sentAtMS <= 0 {
|
|
sentAtMS = message.OccurredAtMS
|
|
}
|
|
_, err = s.AdminUpdateRoom(ctx, &roomv1.AdminUpdateRoomRequest{
|
|
Meta: &roomv1.RequestMeta{
|
|
AppCode: message.AppCode,
|
|
RequestId: requestID,
|
|
CommandId: message.EventID,
|
|
ActorUserId: payload.UserID,
|
|
RoomId: meta.RoomID,
|
|
SentAtMs: sentAtMS,
|
|
},
|
|
VisibleRegionId: &payload.NewRegionID,
|
|
AdminName: "user-region-sync",
|
|
})
|
|
return err
|
|
}
|