diff --git a/internal/dto/dto.go b/internal/dto/dto.go index fe0ef7d..fc4852f 100644 --- a/internal/dto/dto.go +++ b/internal/dto/dto.go @@ -24,6 +24,9 @@ type UserResponse struct { IsFollowing bool `json:"is_following"` IsFollowingMe bool `json:"is_following_me"` CreatedAt string `json:"created_at"` + // 认证信息 + Identity model.UserIdentity `json:"identity,omitempty"` + VerificationStatus model.VerificationStatus `json:"verification_status,omitempty"` } // UserSelfResponse 用户自身信息响应(包含敏感信息,仅本人可见) @@ -46,6 +49,9 @@ type UserSelfResponse struct { CreatedAt string `json:"created_at"` // 隐私设置 PrivacySettings *PrivacySettingsResponse `json:"privacy_settings,omitempty"` + // 认证信息 + Identity model.UserIdentity `json:"identity,omitempty"` + VerificationStatus model.VerificationStatus `json:"verification_status,omitempty"` } // UserDetailResponse 用户详情响应(仅本人可见,包含敏感信息) @@ -70,6 +76,9 @@ type UserDetailResponse struct { CreatedAt string `json:"created_at"` // 隐私设置 PrivacySettings *PrivacySettingsResponse `json:"privacy_settings,omitempty"` + // 认证信息 + Identity model.UserIdentity `json:"identity,omitempty"` + VerificationStatus model.VerificationStatus `json:"verification_status,omitempty"` } // ==================== Admin User DTOs ==================== diff --git a/internal/dto/user_converter.go b/internal/dto/user_converter.go index d21502f..3618ac6 100644 --- a/internal/dto/user_converter.go +++ b/internal/dto/user_converter.go @@ -12,25 +12,38 @@ func getAvatarOrDefault(user *model.User) string { return utils.GetAvatarOrDefault(user.Username, user.Nickname, user.Avatar) } +// publicVerificationFields 返回认证信息: +// - approved 时返回真实身份和状态 +// - 其他状态统一返回 general + none,不暴露具体审核状态 +func publicVerificationFields(user *model.User) (model.UserIdentity, model.VerificationStatus) { + if user.VerificationStatus == model.VerificationStatusApproved { + return user.Identity, user.VerificationStatus + } + return model.UserIdentityGeneral, model.VerificationStatusNone +} + // ConvertUserToResponse 将User转换为UserResponse(公开信息,不包含敏感数据) func ConvertUserToResponse(user *model.User) *UserResponse { if user == nil { return nil } + identity, vs := publicVerificationFields(user) return &UserResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: user.PostsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - CreatedAt: FormatTime(user.CreatedAt), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: user.PostsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + CreatedAt: FormatTime(user.CreatedAt), + Identity: identity, + VerificationStatus: vs, } } @@ -40,23 +53,25 @@ func ConvertUserToSelfResponse(user *model.User, postsCount int) *UserSelfRespon return nil } return &UserSelfResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - Email: user.Email, - Phone: user.Phone, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: postsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - IsVerified: user.IsVerified, - CreatedAt: FormatTime(user.CreatedAt), - PrivacySettings: convertPrivacySettingsToResponse(&user.PrivacySettings), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + Email: user.Email, + Phone: user.Phone, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: postsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + IsVerified: user.IsVerified, + CreatedAt: FormatTime(user.CreatedAt), + PrivacySettings: convertPrivacySettingsToResponse(&user.PrivacySettings), + Identity: user.Identity, + VerificationStatus: user.VerificationStatus, } } @@ -77,22 +92,25 @@ func ConvertUserToResponseWithFollowing(user *model.User, isFollowing bool) *Use if user == nil { return nil } + identity, vs := publicVerificationFields(user) return &UserResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: user.PostsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - IsFollowing: isFollowing, - IsFollowingMe: false, - CreatedAt: FormatTime(user.CreatedAt), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: user.PostsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + IsFollowing: isFollowing, + IsFollowingMe: false, + CreatedAt: FormatTime(user.CreatedAt), + Identity: identity, + VerificationStatus: vs, } } @@ -101,20 +119,23 @@ func ConvertUserToResponseWithPostsCount(user *model.User, postsCount int) *User if user == nil { return nil } + identity, vs := publicVerificationFields(user) return &UserResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: postsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - CreatedAt: FormatTime(user.CreatedAt), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: postsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + CreatedAt: FormatTime(user.CreatedAt), + Identity: identity, + VerificationStatus: vs, } } @@ -123,22 +144,25 @@ func ConvertUserToResponseWithMutualFollow(user *model.User, isFollowing, isFoll if user == nil { return nil } + identity, vs := publicVerificationFields(user) return &UserResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: user.PostsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - IsFollowing: isFollowing, - IsFollowingMe: isFollowingMe, - CreatedAt: FormatTime(user.CreatedAt), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: user.PostsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + IsFollowing: isFollowing, + IsFollowingMe: isFollowingMe, + CreatedAt: FormatTime(user.CreatedAt), + Identity: identity, + VerificationStatus: vs, } } @@ -147,22 +171,25 @@ func ConvertUserToResponseWithMutualFollowAndPostsCount(user *model.User, isFoll if user == nil { return nil } + identity, vs := publicVerificationFields(user) return &UserResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: postsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - IsFollowing: isFollowing, - IsFollowingMe: isFollowingMe, - CreatedAt: FormatTime(user.CreatedAt), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: postsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + IsFollowing: isFollowing, + IsFollowingMe: isFollowingMe, + CreatedAt: FormatTime(user.CreatedAt), + Identity: identity, + VerificationStatus: vs, } } @@ -172,22 +199,24 @@ func ConvertUserToDetailResponse(user *model.User) *UserDetailResponse { return nil } return &UserDetailResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - Email: user.Email, - EmailVerified: user.EmailVerified, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: user.PostsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - IsVerified: user.IsVerified, - CreatedAt: FormatTime(user.CreatedAt), - PrivacySettings: convertPrivacySettingsToResponse(&user.PrivacySettings), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + Email: user.Email, + EmailVerified: user.EmailVerified, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: user.PostsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + IsVerified: user.IsVerified, + CreatedAt: FormatTime(user.CreatedAt), + PrivacySettings: convertPrivacySettingsToResponse(&user.PrivacySettings), + Identity: user.Identity, + VerificationStatus: user.VerificationStatus, } } @@ -197,23 +226,25 @@ func ConvertUserToDetailResponseWithPostsCount(user *model.User, postsCount int) return nil } return &UserDetailResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - Email: user.Email, - EmailVerified: user.EmailVerified, - Phone: user.Phone, - Avatar: getAvatarOrDefault(user), - CoverURL: user.CoverURL, - Bio: user.Bio, - Website: user.Website, - Location: user.Location, - PostsCount: postsCount, - FollowersCount: user.FollowersCount, - FollowingCount: user.FollowingCount, - IsVerified: user.IsVerified, - CreatedAt: FormatTime(user.CreatedAt), - PrivacySettings: convertPrivacySettingsToResponse(&user.PrivacySettings), + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + Email: user.Email, + EmailVerified: user.EmailVerified, + Phone: user.Phone, + Avatar: getAvatarOrDefault(user), + CoverURL: user.CoverURL, + Bio: user.Bio, + Website: user.Website, + Location: user.Location, + PostsCount: postsCount, + FollowersCount: user.FollowersCount, + FollowingCount: user.FollowingCount, + IsVerified: user.IsVerified, + CreatedAt: FormatTime(user.CreatedAt), + PrivacySettings: convertPrivacySettingsToResponse(&user.PrivacySettings), + Identity: user.Identity, + VerificationStatus: user.VerificationStatus, } } diff --git a/internal/model/user.go b/internal/model/user.go index ac1561b..b465ad1 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -54,6 +54,7 @@ const ( VerificationStatusPending VerificationStatus = "pending" // 审核中 VerificationStatusApproved VerificationStatus = "approved" // 已通过 VerificationStatusRejected VerificationStatus = "rejected" // 已拒绝 + VerificationStatusNone VerificationStatus = "none" // 无认证(对外展示用) ) // User 用户实体