289 lines
8.7 KiB
Go
289 lines
8.7 KiB
Go
package voiceroomrocket
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"chatapp3-golang/internal/model"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func (s *Service) notifyStatusUpdate(ctx context.Context, sysOrigin string, roomID int64, senderUserIDs ...int64) error {
|
|
data := map[string]any{
|
|
"roomId": strconv.FormatInt(roomID, 10),
|
|
}
|
|
if status, err := s.GetStatus(ctx, AuthUser{SysOrigin: sysOrigin}, roomID); err == nil && status != nil {
|
|
payload, _ := json.Marshal(status)
|
|
_ = json.Unmarshal(payload, &data)
|
|
}
|
|
senderUserID := int64(0)
|
|
if len(senderUserIDs) > 0 {
|
|
senderUserID = senderUserIDs[0]
|
|
}
|
|
if senderUserID > 0 {
|
|
data["senderUserId"] = strconv.FormatInt(senderUserID, 10)
|
|
}
|
|
if s.repo.Redis != nil {
|
|
body, _ := json.Marshal(map[string]any{
|
|
"type": imTypeStatusUpdate,
|
|
"sysOrigin": sysOrigin,
|
|
"roomId": strconv.FormatInt(roomID, 10),
|
|
"data": data,
|
|
})
|
|
streamKey := strings.TrimSpace(s.cfg.VoiceRoomRocket.BroadcastStreamKey)
|
|
if streamKey == "" {
|
|
streamKey = "voice_room:rocket:broadcast"
|
|
}
|
|
_ = s.repo.Redis.XAdd(ctx, &redis.XAddArgs{
|
|
Stream: streamKey,
|
|
Values: map[string]any{
|
|
"type": imTypeStatusUpdate,
|
|
"roomId": strconv.FormatInt(roomID, 10),
|
|
"body": string(body),
|
|
},
|
|
}).Err()
|
|
}
|
|
_ = s.notifyRegionStatusUpdate(ctx, sysOrigin, senderUserID, data)
|
|
if s.im == nil {
|
|
return nil
|
|
}
|
|
groupID := s.resolveRoomAccount(ctx, roomID)
|
|
return s.im.SendCustomGroupMessage(ctx, groupID, map[string]any{
|
|
"type": imTypeStatusUpdate,
|
|
"data": data,
|
|
})
|
|
}
|
|
|
|
func (s *Service) notifyRegionStatusUpdate(ctx context.Context, sysOrigin string, senderUserID int64, data map[string]any) error {
|
|
if s.regionBroadcast == nil || s.regionResolver == nil || s.userProfiles == nil || senderUserID <= 0 {
|
|
return nil
|
|
}
|
|
profile, err := s.userProfiles.GetUserProfile(ctx, senderUserID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
countryCode := strings.TrimSpace(profile.CountryCode)
|
|
if countryCode == "" {
|
|
return nil
|
|
}
|
|
regionCode, err := s.regionResolver.ResolveRegionCodeByCountryCode(ctx, sysOrigin, countryCode)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
regionCode = strings.TrimSpace(regionCode)
|
|
if regionCode == "" {
|
|
return nil
|
|
}
|
|
body := map[string]any{
|
|
"type": imTypeStatusUpdate,
|
|
"data": data,
|
|
}
|
|
_, err = s.regionBroadcast.SendRegionCustomMessage(ctx, sysOrigin, regionCode, body)
|
|
return err
|
|
}
|
|
|
|
func (s *Service) notifyLaunch(ctx context.Context, launch model.VoiceRoomRocketLaunch) error {
|
|
triggerUser := map[string]any{}
|
|
if launch.IgniteUserID != nil && s.userProfiles != nil {
|
|
if profile, err := s.userProfiles.GetUserProfile(ctx, *launch.IgniteUserID); err == nil {
|
|
triggerUser = map[string]any{
|
|
"userId": strconv.FormatInt(*launch.IgniteUserID, 10),
|
|
"nickname": profile.UserNickname,
|
|
"avatar": profile.UserAvatar,
|
|
"account": profile.Account,
|
|
"countryCode": profile.CountryCode,
|
|
"countryName": profile.CountryName,
|
|
}
|
|
}
|
|
}
|
|
roomName := ""
|
|
if s.roomProfiles != nil {
|
|
if profiles, err := s.roomProfiles.MapRoomProfiles(ctx, []int64{launch.RoomID}); err == nil {
|
|
if profile, ok := profiles[launch.RoomID]; ok {
|
|
roomName = profile.RoomName
|
|
if strings.TrimSpace(launch.RoomAccount) == "" && strings.TrimSpace(profile.RoomAccount) != "" {
|
|
launch.RoomAccount = strings.TrimSpace(profile.RoomAccount)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
durationSeconds := defaultBroadcastDurationSeconds
|
|
if snapshot, err := s.loadConfig(ctx, launch.SysOrigin); err == nil && snapshot.BroadcastDurationSeconds > 0 {
|
|
durationSeconds = snapshot.BroadcastDurationSeconds
|
|
}
|
|
triggerUserID := ""
|
|
if launch.IgniteUserID != nil {
|
|
triggerUserID = strconv.FormatInt(*launch.IgniteUserID, 10)
|
|
}
|
|
previewRocketURL := ""
|
|
rocketIconURL := ""
|
|
rocketAnimationURL := ""
|
|
if levelConfig, err := s.loadLevelConfig(ctx, launch.SysOrigin, launch.Level); err == nil {
|
|
previewRocketURL = levelConfig.PreviewRocketURL
|
|
rocketIconURL = levelConfig.RocketIconURL
|
|
rocketAnimationURL = levelConfig.RocketAnimationURL
|
|
}
|
|
body := map[string]any{
|
|
"type": imTypeLaunchBroadcast,
|
|
"data": map[string]any{
|
|
"roomId": strconv.FormatInt(launch.RoomID, 10),
|
|
"roomAccount": launch.RoomAccount,
|
|
"roomName": roomName,
|
|
"roundNo": launch.RoundNo,
|
|
"level": launch.Level,
|
|
"durationSeconds": durationSeconds,
|
|
"previewRocketUrl": previewRocketURL,
|
|
"rocketIconUrl": rocketIconURL,
|
|
"rocketAnimationUrl": rocketAnimationURL,
|
|
"triggerUser": triggerUser,
|
|
"triggerUserId": triggerUserID,
|
|
"launchNo": launch.LaunchNo,
|
|
},
|
|
}
|
|
if s.repo.Redis != nil {
|
|
payload, _ := json.Marshal(body)
|
|
streamKey := strings.TrimSpace(s.cfg.VoiceRoomRocket.BroadcastStreamKey)
|
|
if streamKey == "" {
|
|
streamKey = "voice_room:rocket:broadcast"
|
|
}
|
|
_ = s.repo.Redis.XAdd(ctx, &redis.XAddArgs{
|
|
Stream: streamKey,
|
|
Values: map[string]any{
|
|
"type": imTypeLaunchBroadcast,
|
|
"roomId": strconv.FormatInt(launch.RoomID, 10),
|
|
"launchNo": launch.LaunchNo,
|
|
"body": string(payload),
|
|
},
|
|
}).Err()
|
|
}
|
|
if s.im == nil {
|
|
return nil
|
|
}
|
|
groupID := launch.RoomAccount
|
|
if strings.TrimSpace(groupID) == "" {
|
|
groupID = s.resolveRoomAccount(ctx, launch.RoomID)
|
|
}
|
|
return s.im.SendCustomGroupMessage(ctx, groupID, body)
|
|
}
|
|
|
|
func (s *Service) notifyRewardRecords(ctx context.Context, launch model.VoiceRoomRocketLaunch, records []model.VoiceRoomRocketRewardRecord) error {
|
|
if len(records) == 0 {
|
|
return nil
|
|
}
|
|
users := make([]string, 0, len(records))
|
|
seen := map[int64]struct{}{}
|
|
for _, record := range records {
|
|
if record.UserID <= 0 {
|
|
continue
|
|
}
|
|
if _, exists := seen[record.UserID]; exists {
|
|
continue
|
|
}
|
|
seen[record.UserID] = struct{}{}
|
|
users = append(users, strconv.FormatInt(record.UserID, 10))
|
|
}
|
|
if len(users) == 0 {
|
|
return nil
|
|
}
|
|
body := map[string]any{
|
|
"type": imTypeRewardPopup,
|
|
"data": map[string]any{
|
|
"roomId": strconv.FormatInt(launch.RoomID, 10),
|
|
"launchNo": launch.LaunchNo,
|
|
"level": launch.Level,
|
|
"userIds": users,
|
|
},
|
|
}
|
|
s.publishRewardMessage(ctx, launch.RoomID, launch.LaunchNo, body)
|
|
if s.im == nil {
|
|
return nil
|
|
}
|
|
groupID := launch.RoomAccount
|
|
if strings.TrimSpace(groupID) == "" {
|
|
groupID = s.resolveRoomAccount(ctx, launch.RoomID)
|
|
}
|
|
return s.im.SendCustomGroupMessage(ctx, groupID, body)
|
|
}
|
|
|
|
func (s *Service) notifyRewardRecord(ctx context.Context, record model.VoiceRoomRocketRewardRecord) error {
|
|
profile := s.mapUserProfiles(ctx, []int64{record.UserID})[record.UserID]
|
|
body := map[string]any{
|
|
"type": imTypeRewardUser,
|
|
"data": map[string]any{
|
|
"roomId": strconv.FormatInt(record.RoomID, 10),
|
|
"launchNo": record.LaunchNo,
|
|
"level": record.Level,
|
|
"userId": strconv.FormatInt(record.UserID, 10),
|
|
"userAvatar": profile.UserAvatar,
|
|
"userNickname": profile.UserNickname,
|
|
"account": profile.Account,
|
|
"rewardScene": record.RewardScene,
|
|
"rewardType": record.RewardType,
|
|
"rewardName": record.RewardName,
|
|
"rewardAmount": record.RewardAmount,
|
|
"rewardRecordId": strconv.FormatInt(record.ID, 10),
|
|
},
|
|
}
|
|
s.publishRewardMessage(ctx, record.RoomID, record.LaunchNo, body)
|
|
if s.im == nil {
|
|
return nil
|
|
}
|
|
return s.im.SendCustomGroupMessage(ctx, s.resolveRoomAccount(ctx, record.RoomID), body)
|
|
}
|
|
|
|
func (s *Service) publishRewardMessage(ctx context.Context, roomID int64, launchNo string, body map[string]any) {
|
|
if s.repo.Redis == nil {
|
|
return
|
|
}
|
|
payload, _ := json.Marshal(body)
|
|
streamKey := strings.TrimSpace(s.cfg.VoiceRoomRocket.BroadcastStreamKey)
|
|
if streamKey == "" {
|
|
streamKey = "voice_room:rocket:broadcast"
|
|
}
|
|
_ = s.repo.Redis.XAdd(ctx, &redis.XAddArgs{
|
|
Stream: streamKey,
|
|
Values: map[string]any{
|
|
"type": body["type"],
|
|
"roomId": strconv.FormatInt(roomID, 10),
|
|
"launchNo": launchNo,
|
|
"body": string(payload),
|
|
},
|
|
}).Err()
|
|
}
|
|
|
|
func (s *Service) resolveRoomAccount(ctx context.Context, roomID int64) string {
|
|
if roomID <= 0 {
|
|
return ""
|
|
}
|
|
if s.roomProfiles != nil {
|
|
profiles, err := s.roomProfiles.MapRoomProfiles(ctx, []int64{roomID})
|
|
if err == nil {
|
|
if profile, ok := profiles[roomID]; ok && strings.TrimSpace(profile.RoomAccount) != "" {
|
|
return strings.TrimSpace(profile.RoomAccount)
|
|
}
|
|
for _, profile := range profiles {
|
|
if int64(profile.ID) == roomID && strings.TrimSpace(profile.RoomAccount) != "" {
|
|
return strings.TrimSpace(profile.RoomAccount)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var room model.RoomLiveBroadcastVIP
|
|
err := s.repo.DB.WithContext(ctx).
|
|
Where("room_id = ? OR id = ?", roomID, roomID).
|
|
Order("update_time DESC").
|
|
First(&room).Error
|
|
if err == nil && room.RoomAccount > 0 {
|
|
return strconv.FormatInt(room.RoomAccount, 10)
|
|
}
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return strconv.FormatInt(roomID, 10)
|
|
}
|
|
return strconv.FormatInt(roomID, 10)
|
|
}
|