138 lines
5.4 KiB
Go
138 lines
5.4 KiB
Go
// Package grpc 将 user-service 认证、用户和短号用例适配成 protobuf gRPC 服务。
|
||
package grpc
|
||
|
||
import (
|
||
userv1 "hyapp/api/proto/user/v1"
|
||
authdomain "hyapp/services/user-service/internal/domain/auth"
|
||
userdomain "hyapp/services/user-service/internal/domain/user"
|
||
authservice "hyapp/services/user-service/internal/service/auth"
|
||
)
|
||
|
||
// toProtoToken 把领域令牌转换为 protobuf 响应。
|
||
func toProtoToken(token authdomain.Token) *userv1.AuthToken {
|
||
// Token 中包含 refresh token 原文,只能出现在登录/刷新响应路径。
|
||
return &userv1.AuthToken{
|
||
UserId: token.UserID,
|
||
DisplayUserId: token.DisplayUserID,
|
||
DefaultDisplayUserId: token.DefaultDisplayUserID,
|
||
DisplayUserIdKind: token.DisplayUserIDKind,
|
||
DisplayUserIdExpiresAtMs: token.DisplayUserIDExpiresAtMs,
|
||
ProfileCompleted: token.ProfileCompleted,
|
||
OnboardingStatus: token.OnboardingStatus,
|
||
SessionId: token.SessionID,
|
||
AccessToken: token.AccessToken,
|
||
RefreshToken: token.RefreshToken,
|
||
ExpiresInSec: token.ExpiresInSec,
|
||
TokenType: token.TokenType,
|
||
}
|
||
}
|
||
|
||
// toProtoUser 把领域用户转换为 protobuf 用户投影。
|
||
func toProtoUser(user userdomain.User) *userv1.User {
|
||
// User proto 只暴露用户主状态和当前展示短号,不包含密码、三方身份或房间状态。
|
||
return &userv1.User{
|
||
UserId: user.UserID,
|
||
Status: toProtoStatus(user.Status),
|
||
CreatedAtMs: user.CreatedAtMs,
|
||
UpdatedAtMs: user.UpdatedAtMs,
|
||
DisplayUserId: user.CurrentDisplayUserID,
|
||
DefaultDisplayUserId: user.DefaultDisplayUserID,
|
||
DisplayUserIdKind: string(user.CurrentDisplayUserIDKind),
|
||
DisplayUserIdExpiresAtMs: user.CurrentDisplayUserIDExpiresAtMs,
|
||
Username: user.Username,
|
||
Gender: user.Gender,
|
||
Country: user.Country,
|
||
Avatar: user.Avatar,
|
||
Birth: user.BirthDate,
|
||
Language: user.Language,
|
||
CountryId: user.CountryID,
|
||
CountryName: user.CountryName,
|
||
CountryDisplayName: user.CountryDisplayName,
|
||
RegionId: user.RegionID,
|
||
RegionCode: user.RegionCode,
|
||
RegionName: user.RegionName,
|
||
ProfileCompleted: user.ProfileCompleted,
|
||
ProfileCompletedAtMs: user.ProfileCompletedAtMs,
|
||
OnboardingStatus: string(user.OnboardingStatus),
|
||
IsoNumeric: user.ISONumeric,
|
||
PhoneCountryCode: user.PhoneCountryCode,
|
||
CountryEnabled: user.CountryEnabled,
|
||
}
|
||
}
|
||
|
||
// toProtoCountry 把国家领域对象转换为管理 RPC 响应。
|
||
func toProtoCountry(country userdomain.Country) *userv1.Country {
|
||
return &userv1.Country{
|
||
CountryId: country.CountryID,
|
||
CountryName: country.CountryName,
|
||
CountryCode: country.CountryCode,
|
||
CountryDisplayName: country.CountryDisplayName,
|
||
SortOrder: country.SortOrder,
|
||
CreatedAtMs: country.CreatedAtMs,
|
||
UpdatedAtMs: country.UpdatedAtMs,
|
||
IsoAlpha3: country.ISOAlpha3,
|
||
IsoNumeric: country.ISONumeric,
|
||
PhoneCountryCode: country.PhoneCountryCode,
|
||
Enabled: country.Enabled,
|
||
Flag: country.Flag,
|
||
}
|
||
}
|
||
|
||
// toProtoRegion 把区域领域对象转换为管理 RPC 响应。
|
||
func toProtoRegion(region userdomain.Region) *userv1.Region {
|
||
return &userv1.Region{
|
||
RegionId: region.RegionID,
|
||
RegionCode: region.RegionCode,
|
||
Name: region.Name,
|
||
Status: region.Status,
|
||
Countries: append([]string(nil), region.Countries...),
|
||
SortOrder: region.SortOrder,
|
||
CreatedAtMs: region.CreatedAtMs,
|
||
UpdatedAtMs: region.UpdatedAtMs,
|
||
}
|
||
}
|
||
|
||
// toProtoIdentity 把短号领域投影转换为 protobuf 响应。
|
||
func toProtoIdentity(identity userdomain.Identity) *userv1.UserIdentity {
|
||
// Identity proto 用于短号解析和修改结果,字段语义与领域 Identity 保持一致。
|
||
return &userv1.UserIdentity{
|
||
UserId: identity.UserID,
|
||
DisplayUserId: identity.DisplayUserID,
|
||
Status: string(identity.Status),
|
||
DefaultDisplayUserId: identity.DefaultDisplayUserID,
|
||
DisplayUserIdKind: string(identity.DisplayUserIDKind),
|
||
DisplayUserIdExpiresAtMs: identity.DisplayUserIDExpiresAtMs,
|
||
}
|
||
}
|
||
|
||
// toProtoStatus 固定未知状态的安全默认值。
|
||
func toProtoStatus(status userdomain.Status) userv1.UserStatus {
|
||
// 状态枚举转换集中在这里,未知状态使用 UNSPECIFIED 安全兜底。
|
||
switch status {
|
||
case userdomain.StatusActive:
|
||
return userv1.UserStatus_USER_STATUS_ACTIVE
|
||
case userdomain.StatusDisabled:
|
||
return userv1.UserStatus_USER_STATUS_DISABLED
|
||
case userdomain.StatusBanned:
|
||
return userv1.UserStatus_USER_STATUS_BANNED
|
||
default:
|
||
return userv1.UserStatus_USER_STATUS_UNSPECIFIED
|
||
}
|
||
}
|
||
|
||
// authMeta 提取认证链路审计所需的 gateway 透传字段。
|
||
func authMeta(meta *userv1.RequestMeta) authservice.Meta {
|
||
if meta == nil {
|
||
// meta 可选,缺失时审计字段为空但不能让 RPC panic。
|
||
return authservice.Meta{}
|
||
}
|
||
|
||
// 只提取认证审计需要的字段,device_id 在各 RPC 中单独传入。
|
||
return authservice.Meta{
|
||
RequestID: meta.GetRequestId(),
|
||
ClientIP: meta.GetClientIp(),
|
||
UserAgent: meta.GetUserAgent(),
|
||
CountryByIP: meta.GetCountryByIp(),
|
||
}
|
||
}
|