diff --git a/src/components/business/UserProfileHeader.tsx b/src/components/business/UserProfileHeader.tsx index 9a7e7e4..8b54cde 100644 --- a/src/components/business/UserProfileHeader.tsx +++ b/src/components/business/UserProfileHeader.tsx @@ -17,7 +17,7 @@ import { } from 'react-native'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import { spacing, fontSizes, borderRadius, useAppColors, type AppColors } from '../../theme'; -import { User } from '../../types'; +import { User, UserIdentity, VerificationStatus } from '../../types'; import Text from '../common/Text'; import Avatar from '../common/Avatar'; import { ImageGallery } from '../common'; @@ -281,7 +281,10 @@ const UserProfileHeader: React.FC = ({ {/* 用户名 */} - {user.nickname} + + {user.nickname} + + @{user.username} @@ -477,11 +480,16 @@ function createUserProfileHeaderStyles(colors: AppColors) { nameSection: { marginBottom: spacing.sm, }, + nicknameRow: { + flexDirection: 'row', + alignItems: 'center', + gap: spacing.xs, + marginBottom: 2, + }, nickname: { fontSize: fontSizes['2xl'], fontWeight: '800', color: colors.text.primary, - marginBottom: 2, }, username: { fontSize: fontSizes.md, @@ -564,5 +572,54 @@ function createUserProfileHeaderStyles(colors: AppColors) { import { shadows } from '../../theme'; +// ==================== VerificationBadge ==================== + +interface VerificationBadgeProps { + identity?: UserIdentity; + verificationStatus?: VerificationStatus; +} + +const IDENTITY_CONFIG: Record< + UserIdentity, + { label: string; color: string; bg: string } +> = { + general: { label: '未认证', color: '#9CA3AF', bg: '#F3F4F6' }, + student: { label: '学生认证', color: '#10B981', bg: '#D1FAE5' }, + teacher: { label: '教师认证', color: '#3B82F6', bg: '#DBEAFE' }, + staff: { label: '职工认证', color: '#8B5CF6', bg: '#EDE9FE' }, + alumni: { label: '校友认证', color: '#F59E0B', bg: '#FEF3C7' }, + external: { label: '未认证', color: '#9CA3AF', bg: '#F3F4F6' }, +}; + +const VerificationBadge: React.FC = ({ + identity, + verificationStatus, +}) => { + const colors = useAppColors(); + + // 默认值:未认证状态 + const effectiveIdentity = identity || 'general'; + const effectiveStatus = verificationStatus || 'none'; + + const isApproved = effectiveStatus === 'approved'; + // none 表示未认证,统一用 general 的未认证样式 + const displayIdentity = isApproved ? effectiveIdentity : 'general'; + const config = IDENTITY_CONFIG[displayIdentity] || IDENTITY_CONFIG.general; + + return ( + + {isApproved ? ( + + ) : ( + <> + + + ? + + )} + + ); +}; + const MemoizedUserProfileHeader = React.memo(UserProfileHeader); export default MemoizedUserProfileHeader; diff --git a/src/types/dto.ts b/src/types/dto.ts index 2ee779b..d8cb0c9 100644 --- a/src/types/dto.ts +++ b/src/types/dto.ts @@ -23,6 +23,8 @@ export interface UserDTO { created_at: string; is_following?: boolean; is_following_me?: boolean; + identity?: UserIdentity; + verification_status?: VerificationStatus; } export interface UserDetailDTO { @@ -43,6 +45,8 @@ export interface UserDetailDTO { // 额外字段 is_following?: boolean; // 当前用户是否关注了该用户 is_following_me?: boolean; // 该用户是否关注了当前用户 + identity?: UserIdentity; + verification_status?: VerificationStatus; } // ==================== Post DTOs ==================== @@ -858,7 +862,7 @@ export interface CreateVotePostRequest { // ==================== Verification DTOs ==================== -export type VerificationStatus = 'not_submitted' | 'pending' | 'approved' | 'rejected'; +export type VerificationStatus = 'not_submitted' | 'pending' | 'approved' | 'rejected' | 'none'; export type UserIdentity = 'general' | 'student' | 'teacher' | 'staff' | 'alumni' | 'external'; export interface VerificationStatusDTO {