topfans/backend/gateway/dto/user_converter.go
2026-04-08 10:59:46 +08:00

245 lines
6.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dto
import (
pb "github.com/topfans/backend/pkg/proto/user"
)
// ========== 基础转换函数 ==========
// ToFanIdentityDTO 转换为粉丝身份信息
func ToFanIdentityDTO(star *pb.Star) FanIdentityDTO {
return FanIdentityDTO{
StarID: star.StarId,
IdentityID: star.IdentityId, // "wyb"
Name: star.Name, // "王一博"(原始名称)
Tag: star.Tag, // "小摩托"(昵称标签)
}
}
// ToCurrentIdentityDTO 转换为当前身份详情
func ToCurrentIdentityDTO(profile *pb.FanProfile, star *pb.Star) CurrentIdentityDTO {
return CurrentIdentityDTO{
StarId: star.StarId,
IdentityID: star.IdentityId, // "wyb"
IdentityName: star.Name, // "王一博"
Tag: star.Tag, // "小摩托"
Level: profile.Level,
CrystalBalance: profile.CrystalBalance,
}
}
// ToUserWithIdentityDTO 转换为用户信息(含身份)
func ToUserWithIdentityDTO(user *pb.User, profile *pb.FanProfile, star *pb.Star) UserWithIdentityDTO {
dto := UserWithIdentityDTO{
UID: user.Id, // uid 使用数据库ID
Nickname: profile.Nickname,
FanLevel: profile.Level,
StarbookLimit: profile.StarbookLimit,
SlotLimit: profile.SlotLimit,
AssetsNum: profile.AssetsCount, // assets_count → assets_num
CrystalBalance: profile.CrystalBalance,
}
// 头像URL优先使用粉丝档案中的头像没有则使用用户头像
if profile.AvatarUrl != "" {
dto.AvatarURL = profile.AvatarUrl
} else if user.AvatarUrl != "" {
dto.AvatarURL = user.AvatarUrl
}
// 链地址
if profile.ChainAddress != "" {
dto.ChainAddress = profile.ChainAddress
}
// 粉丝身份
if star != nil {
dto.FanIdentity = ToFanIdentityDTO(star)
}
// 脱敏手机号139****0001
if user.Mobile != "" && len(user.Mobile) == 11 {
dto.MobileMasked = user.Mobile[:3] + "****" + user.Mobile[7:]
}
return dto
}
// ========== 认证相关转换 ==========
// ToRegisterResponseDTO 转换为注册响应
func ToRegisterResponseDTO(
accessToken string,
expiresIn int64,
user *pb.User,
profile *pb.FanProfile,
star *pb.Star,
) RegisterResponseDTO {
return RegisterResponseDTO{
AccessToken: accessToken,
ExpiresIn: expiresIn,
User: ToUserWithIdentityDTO(user, profile, star),
}
}
// ToLoginResponseDTO 转换为登录响应
func ToLoginResponseDTO(
accessToken string,
expiresIn int64,
refreshToken string,
user *pb.User,
profile *pb.FanProfile,
star *pb.Star,
) LoginResponseDTO {
return LoginResponseDTO{
AccessToken: accessToken,
ExpiresIn: expiresIn,
RefreshToken: refreshToken,
User: ToUserWithIdentityDTO(user, profile, star),
}
}
// ToGetMeResponseDTO 转换为 GetMe 响应
func ToGetMeResponseDTO(user *pb.User, profile *pb.FanProfile, star *pb.Star) GetMeResponseDTO {
dto := GetMeResponseDTO{
UID: user.Id,
Nickname: profile.Nickname,
CurrentIdentity: ToCurrentIdentityDTO(profile, star),
}
// 头像URL优先使用粉丝档案中的头像没有则使用用户头像
if profile.AvatarUrl != "" {
dto.AvatarURL = profile.AvatarUrl
} else if user.AvatarUrl != "" {
dto.AvatarURL = user.AvatarUrl
}
if profile.ChainAddress != "" {
dto.ChainAddress = profile.ChainAddress
}
return dto
}
// ========== 个人信息相关转换 ==========
// ToProfileResponseDTO 转换为个人信息响应
func ToProfileResponseDTO(user *pb.User, profile *pb.FanProfile, star *pb.Star) ProfileResponseDTO {
dto := ProfileResponseDTO{
UID: user.Id,
Nickname: profile.Nickname,
FanLevel: profile.Level,
StarbookLimit: profile.StarbookLimit,
SlotLimit: profile.SlotLimit,
AssetsNum: profile.AssetsCount,
CrystalBalance: profile.CrystalBalance,
}
if profile.ChainAddress != "" {
dto.ChainAddress = profile.ChainAddress
}
if star != nil {
dto.FanIdentity = ToFanIdentityDTO(star)
}
return dto
}
// ToUpdateNicknameResponseDTO 转换为更新昵称响应
func ToUpdateNicknameResponseDTO(nickname string) UpdateNicknameResponseDTO {
return UpdateNicknameResponseDTO{
Nickname: nickname,
}
}
// ========== 粉丝身份相关转换 ==========
// ToFanIdentityListItemDTO 转换为粉丝身份列表项
func ToFanIdentityListItemDTO(star *pb.Star) FanIdentityListItemDTO {
dto := FanIdentityListItemDTO{
StarID: star.StarId, // 88star 的主键 ID
IdentityID: star.IdentityId, // "wyb"
Name: star.Name, // "王一博"(原始名称)
Tag: star.Tag, // "小摩托"(昵称标签)
}
if star.PicUrl != "" {
dto.PicURL = star.PicUrl
}
return dto
}
// ToFanIdentityListResponseDTO 转换为粉丝身份列表响应(所有可用明星)
func ToFanIdentityListResponseDTO(stars []*pb.Star) FanIdentityListResponseDTO {
items := make([]FanIdentityListItemDTO, 0, len(stars))
for _, star := range stars {
items = append(items, ToFanIdentityListItemDTO(star))
}
return FanIdentityListResponseDTO{
Items: items,
Total: len(items),
}
}
// ToMyFanIdentitiesResponseDTO 转换为我的粉丝身份列表响应
func ToMyFanIdentitiesResponseDTO(items []*pb.MyFanIdentityItem, currentStarID int64) MyFanIdentitiesResponseDTO {
dtoItems := make([]MyFanIdentityItemDTO, 0, len(items))
for _, item := range items {
profile := item.FanProfile
star := item.Star
dtoItems = append(dtoItems, MyFanIdentityItemDTO{
StarID: profile.StarId,
IdentityID: star.IdentityId,
StarName: star.Name,
StarTag: star.Tag,
Nickname: profile.Nickname,
Level: profile.Level,
Experience: profile.Experience,
CrystalBalance: profile.CrystalBalance,
IsActive: profile.StarId == currentStarID,
})
}
return MyFanIdentitiesResponseDTO{
Items: dtoItems,
Total: len(dtoItems),
CurrentStarID: currentStarID,
}
}
// ToAddIdentityResponseDTO 转换为添加身份响应
func ToAddIdentityResponseDTO(identityID string) AddIdentityResponseDTO {
return AddIdentityResponseDTO{
Bound: true,
IdentityID: identityID,
}
}
// ToSwitchIdentityResponseDTO 转换为切换身份响应
func ToSwitchIdentityResponseDTO(
accessToken string,
expiresIn int64,
profile *pb.FanProfile,
star *pb.Star,
) SwitchIdentityResponseDTO {
return SwitchIdentityResponseDTO{
AccessToken: accessToken,
ExpiresIn: expiresIn,
CurrentIdentity: ToCurrentIdentityDTO(profile, star),
}
}
// ========== 辅助函数 ==========
// getStarDisplayName 获取明星显示名称(优先使用 tag
func getStarDisplayName(star *pb.Star) string {
if star.Tag != "" {
return star.Tag
}
return star.Name
}