217 lines
5.9 KiB
TypeScript
217 lines
5.9 KiB
TypeScript
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<string, { text: string; color: string }> = {
|
|
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<string, { text: string; color: string }> = {
|
|
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<string, { text: string; color: string }> = {
|
|
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<string, string> = {
|
|
morning_reading: '早自习',
|
|
morning: '上午',
|
|
afternoon: '下午',
|
|
evening_study: '晚自习',
|
|
night_check: '晚寝',
|
|
};
|
|
|
|
export interface TabProps {
|
|
studentId: number;
|
|
onRefresh: () => void;
|
|
}
|