export interface StudentInfo { id: number; name: string; phone: string; idNumber: string; studentNo: string; gender?: string; ethnicity?: string; emergencyContact?: string; emergencyPhone?: string; organizationId?: number; organization?: { id?: number; name?: string } | null; supervisor?: string; status: string; } export interface ProfileData { targetCollege?: string; targetMajor?: string; collegeSchool?: string; collegeMajor?: string; subjectDirection?: string; grade?: string; profileDate?: string; notes?: string; } export interface EnrollmentRecord { id: number; courseCategory: string; classType: string; className?: string; headTeacher?: string; subjectTeacher?: string; startDate?: string; endDate?: string; status: string; } export interface ExamScoreRecord { id: number; status?: string; examId?: number; exam?: { class?: { name?: string } }; examType: string; examName?: string; subject: string; score: number | null; classAvg?: number; rank?: number; examDate?: string; enrollmentId?: number; } export interface LearningRecord { id: number; status?: string; recordDate: string; recordType: string; content: string; followUpMethod?: string; nextStep?: string; } export interface ResultData { cultureFinalScore?: number; professionalFinalScore?: number; admissionStatus?: string; admittedCollege?: string; admittedMajor?: string; } export interface AttachmentRecord { id: number; status?: string; category: string; fileName: string; fileSize: number; } export interface AttendanceRecordItem { id: number; attendanceDate: string; session: string; status: string; source?: string; remark?: string | null; punchTime?: string | null; punchDeviceName?: string | null; punchDeviceId?: string | null; schedule?: { subject?: string } | null; class?: { name?: string } | null; } export interface StudentProfileAggregate { student: StudentInfo; profile: ProfileData | null; enrollments: EnrollmentRecord[]; examScores: ExamScoreRecord[]; learningRecords: LearningRecord[]; result: ResultData | null; attachments: AttachmentRecord[]; attendances: AttendanceRecordItem[]; } export interface StudentProfileContentProps { studentId: number; inDrawer?: boolean; onClose?: () => void; } export const ADMISSION_STATUS_MAP: Record = { admitted: { text: '已录取', color: 'green' }, pending: { text: '待录取', color: 'orange' }, rejected: { text: '未录取', color: 'red' }, withdrawn: { text: '放弃', color: '#999' }, }; export const EXAM_TYPE_OPTIONS = [ { value: 'monthly', label: '月考' }, { value: 'midterm', label: '期中' }, { value: 'final', label: '期末' }, { value: 'mock', label: '模拟考' }, { value: 'entrance', label: '入学测试' }, { value: 'other', label: '其他' }, ]; export const RECORD_TYPE_OPTIONS = [ { value: 'study_feedback', label: '学习反馈' }, { value: 'parent_communication', label: '家长沟通' }, { value: 'behavior_note', label: '行为记录' }, { value: 'meeting', label: '会议记录' }, { value: 'other', label: '其他' }, ]; export const ENROLLMENT_STATUS_MAP: Record = { active: { text: '报读中', color: 'green' }, completed: { text: '已结课', color: 'blue' }, withdrawn: { text: '已退训', color: 'red' }, archived: { text: '已归档', color: '#999' }, }; export const COURSE_CATEGORY_OPTIONS = [ { value: 'culture', label: '文化课' }, { value: 'professional', label: '专业课' }, { value: 'comprehensive', label: '综合' }, ]; export const CLASS_TYPE_OPTIONS = [ { value: 'one_on_one', label: '一对一' }, { value: 'small_group', label: '小班' }, { value: 'large_class', label: '大班' }, { value: 'online', label: '线上' }, { value: 'offline', label: '线下' }, ]; export const getOptionLabel = ( options: Array<{ value: string; label: string }>, value?: string | null, ): string => { if (!value) return '-'; return options.find((option) => option.value === value)?.label || value; }; export const getCourseCategoryLabel = (value?: string | null): string => getOptionLabel(COURSE_CATEGORY_OPTIONS, value); export const getClassTypeLabel = (value?: string | null): string => getOptionLabel(CLASS_TYPE_OPTIONS, value); export const getEnrollmentStatus = (value?: string | null): { text: string; color: string } => { if (!value) return { text: '-', color: 'default' }; return ENROLLMENT_STATUS_MAP[value] || { text: value, color: 'default' }; }; export const formatEnrollmentDisplayName = (enrollment: EnrollmentRecord): string => enrollment.className || (enrollment.courseCategory ? getCourseCategoryLabel(enrollment.courseCategory) : String(enrollment.id)); export const ATTACHMENT_CATEGORY_OPTIONS = [ { value: 'id_card', label: '身份证' }, { value: 'transcript', label: '成绩单' }, { value: 'certificate', label: '证书' }, { value: 'contract', label: '合同' }, { value: 'photo', label: '照片' }, { value: 'other', label: '其他' }, ]; export const formatFileSize = (bytes: number): string => { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; }; export const ATTENDANCE_STATUS_MAP: Record = { present: { text: '出勤', color: 'green' }, late: { text: '迟到', color: 'orange' }, absent: { text: '缺勤', color: 'red' }, leave: { text: '请假', color: 'blue' }, pending: { text: '待确认', color: 'default' }, }; export const SESSION_LABELS: Record = { morning_reading: '早自习', morning: '上午', afternoon: '下午', evening_study: '晚自习', night_check: '晚寝', }; export interface TabProps { studentId: number; onRefresh: () => void; }