168 lines
5.1 KiB
Go
168 lines
5.1 KiB
Go
package service
|
||
|
||
import (
|
||
"strconv"
|
||
"strings"
|
||
|
||
roomv1 "hyapp.local/api/proto/room/v1"
|
||
"hyapp/services/room-service/internal/room/command"
|
||
"hyapp/services/room-service/internal/room/state"
|
||
)
|
||
|
||
func normalizeGiftTargetUserIDs(targetUserID int64, targetUserIDs []int64) []int64 {
|
||
seen := make(map[int64]bool, len(targetUserIDs)+1)
|
||
ids := make([]int64, 0, len(targetUserIDs)+1)
|
||
for _, userID := range targetUserIDs {
|
||
if userID <= 0 || seen[userID] {
|
||
continue
|
||
}
|
||
seen[userID] = true
|
||
ids = append(ids, userID)
|
||
}
|
||
if len(ids) == 0 && targetUserID > 0 {
|
||
ids = append(ids, targetUserID)
|
||
}
|
||
return ids
|
||
}
|
||
|
||
func giftTargetHostScopesFromProto(scopes []*roomv1.SendGiftTargetHostScope) []command.GiftTargetHostScope {
|
||
result := make([]command.GiftTargetHostScope, 0, len(scopes))
|
||
seen := make(map[int64]bool, len(scopes))
|
||
for _, scope := range scopes {
|
||
targetUserID := scope.GetTargetUserId()
|
||
if targetUserID <= 0 || seen[targetUserID] {
|
||
continue
|
||
}
|
||
seen[targetUserID] = true
|
||
result = append(result, command.GiftTargetHostScope{
|
||
TargetUserID: targetUserID,
|
||
TargetIsHost: scope.GetTargetIsHost(),
|
||
TargetHostRegionID: scope.GetTargetHostRegionId(),
|
||
TargetAgencyOwnerUserID: scope.GetTargetAgencyOwnerUserId(),
|
||
})
|
||
}
|
||
return result
|
||
}
|
||
|
||
func giftDisplayProfileFromProto(item *roomv1.SendGiftDisplayProfile) command.GiftDisplayProfile {
|
||
if item == nil || item.GetUserId() <= 0 {
|
||
return command.GiftDisplayProfile{}
|
||
}
|
||
// 展示快照只裁剪空白字符,不做业务兜底;兜底顺序统一放在 giftDisplayName,避免事件字段互相不一致。
|
||
return command.GiftDisplayProfile{
|
||
UserID: item.GetUserId(),
|
||
Username: strings.TrimSpace(item.GetUsername()),
|
||
Avatar: strings.TrimSpace(item.GetAvatar()),
|
||
DisplayUserID: strings.TrimSpace(item.GetDisplayUserId()),
|
||
PrettyDisplayUserID: strings.TrimSpace(item.GetPrettyDisplayUserId()),
|
||
}
|
||
}
|
||
|
||
func giftDisplayProfilesFromProto(items []*roomv1.SendGiftDisplayProfile) []command.GiftDisplayProfile {
|
||
result := make([]command.GiftDisplayProfile, 0, len(items))
|
||
seen := make(map[int64]bool, len(items))
|
||
for _, item := range items {
|
||
profile := giftDisplayProfileFromProto(item)
|
||
if profile.UserID <= 0 || seen[profile.UserID] {
|
||
continue
|
||
}
|
||
seen[profile.UserID] = true
|
||
result = append(result, profile)
|
||
}
|
||
return result
|
||
}
|
||
|
||
func filterGiftTargetHostScopes(scopes []command.GiftTargetHostScope, targetUserIDs []int64) []command.GiftTargetHostScope {
|
||
if len(scopes) == 0 || len(targetUserIDs) == 0 {
|
||
return nil
|
||
}
|
||
allowed := giftTargetUserIDSet(targetUserIDs)
|
||
result := make([]command.GiftTargetHostScope, 0, len(scopes))
|
||
for _, scope := range scopes {
|
||
if allowed[scope.TargetUserID] {
|
||
result = append(result, scope)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func giftTargetHostScopeForExact(scopes []command.GiftTargetHostScope, targetUserID int64) (command.GiftTargetHostScope, bool) {
|
||
if targetUserID <= 0 {
|
||
return command.GiftTargetHostScope{}, false
|
||
}
|
||
for _, scope := range scopes {
|
||
if scope.TargetUserID == targetUserID {
|
||
return scope, true
|
||
}
|
||
}
|
||
return command.GiftTargetHostScope{}, false
|
||
}
|
||
|
||
func filterGiftDisplayProfiles(profiles []command.GiftDisplayProfile, targetUserIDs []int64) []command.GiftDisplayProfile {
|
||
if len(profiles) == 0 || len(targetUserIDs) == 0 {
|
||
return nil
|
||
}
|
||
allowed := giftTargetUserIDSet(targetUserIDs)
|
||
result := make([]command.GiftDisplayProfile, 0, len(profiles))
|
||
for _, profile := range profiles {
|
||
if allowed[profile.UserID] {
|
||
result = append(result, profile)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func giftTargetUserIDSet(targetUserIDs []int64) map[int64]bool {
|
||
result := make(map[int64]bool, len(targetUserIDs))
|
||
for _, targetUserID := range targetUserIDs {
|
||
if targetUserID > 0 {
|
||
result[targetUserID] = true
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func giftDisplayProfileForUser(profiles []command.GiftDisplayProfile, userID int64) command.GiftDisplayProfile {
|
||
if userID <= 0 {
|
||
return command.GiftDisplayProfile{}
|
||
}
|
||
for _, profile := range profiles {
|
||
if profile.UserID == userID {
|
||
return profile
|
||
}
|
||
}
|
||
return command.GiftDisplayProfile{UserID: userID}
|
||
}
|
||
|
||
func giftDisplayName(profile command.GiftDisplayProfile) string {
|
||
// Flutter 的 IM 解析已支持 sender_name/receiver_nickname;这里按用户昵称、靓号、短号依次兜底,避免跨房飘窗直接落到 User <id>。
|
||
for _, value := range []string{profile.Username, profile.PrettyDisplayUserID, profile.DisplayUserID} {
|
||
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
||
return trimmed
|
||
}
|
||
}
|
||
return ""
|
||
}
|
||
|
||
func giftTargetUserIDsAttribute(targetUserIDs []int64) string {
|
||
if len(targetUserIDs) == 0 {
|
||
return ""
|
||
}
|
||
parts := make([]string, 0, len(targetUserIDs))
|
||
for _, targetUserID := range targetUserIDs {
|
||
parts = append(parts, strconv.FormatInt(targetUserID, 10))
|
||
}
|
||
return strings.Join(parts, ",")
|
||
}
|
||
|
||
func findRankItem(items []state.RankItem, userID int64) state.RankItem {
|
||
// 送礼后通常能找到发送方榜单项;找不到时返回 user_id 占位避免空事件。
|
||
for _, item := range items {
|
||
if item.UserID == userID {
|
||
return item
|
||
}
|
||
}
|
||
|
||
return state.RankItem{UserID: userID}
|
||
}
|