import React, { useState, useRef } from 'react'; import { useLocalStorage } from './hooks/useLocalStorage'; import { SchoolForm } from './components/SchoolForm'; import { MajorGroupForm } from './components/MajorGroupForm'; import { DataTable } from './components/DataTable'; import { Toast } from './components/Toast'; import { exportToCSV, exportToExcel, importFromCSV, importFromExcel, } from './utils/importExport'; import type { School, ToastMessage } from './types'; import { Plus, Download, Upload, GraduationCap, RefreshCw, } from 'lucide-react'; function App() { const { data, loading, addSchool, updateSchool, deleteSchool, addMajorGroup, updateMajorGroup, deleteMajorGroup, saveData, } = useLocalStorage(); const [showSchoolForm, setShowSchoolForm] = useState(false); const [editingSchool, setEditingSchool] = useState(null); const [showMajorGroupForm, setShowMajorGroupForm] = useState(false); const [editingMajorGroup, setEditingMajorGroup] = useState<{ schoolId: string; majorGroup: School['majorGroups'][0]; } | null>(null); const [addingMajorGroupToSchool, setAddingMajorGroupToSchool] = useState(null); const [toastMessages, setToastMessages] = useState([]); const [importing, setImporting] = useState(false); const fileInputRef = useRef(null); const addToast = (type: ToastMessage['type'], message: string) => { const id = Date.now().toString(); setToastMessages((prev) => [...prev, { id, type, message }]); }; const removeToast = (id: string) => { setToastMessages((prev) => prev.filter((msg) => msg.id !== id)); }; const handleAddSchool = (schoolData: Omit) => { addSchool(schoolData); setShowSchoolForm(false); addToast('success', '学校添加成功'); }; const handleEditSchool = (schoolData: Omit) => { if (editingSchool) { updateSchool(editingSchool.id, schoolData); setEditingSchool(null); setShowSchoolForm(false); addToast('success', '学校信息更新成功'); } }; const handleDeleteSchool = (id: string) => { if (window.confirm('确定要删除这所学校及其所有专业组吗?')) { deleteSchool(id); addToast('success', '学校删除成功'); } }; const handleAddMajorGroup = (majorGroupData: Omit) => { if (addingMajorGroupToSchool) { addMajorGroup(addingMajorGroupToSchool, majorGroupData); setAddingMajorGroupToSchool(null); setShowMajorGroupForm(false); addToast('success', '专业组添加成功'); } }; const handleEditMajorGroup = (majorGroupData: Omit) => { if (editingMajorGroup) { updateMajorGroup( editingMajorGroup.schoolId, editingMajorGroup.majorGroup.id, majorGroupData ); setEditingMajorGroup(null); setShowMajorGroupForm(false); addToast('success', '专业组信息更新成功'); } }; const handleDeleteMajorGroup = (schoolId: string, majorGroupId: string) => { if (window.confirm('确定要删除这个专业组吗?')) { deleteMajorGroup(schoolId, majorGroupId); addToast('success', '专业组删除成功'); } }; const handleExportCSV = () => { const csv = exportToCSV(data); const blob = new Blob([`\uFEFF${csv}`], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = `志愿意向数据_${new Date().toISOString().slice(0, 10)}.csv`; document.body.appendChild(link); link.click(); document.body.removeChild(link); addToast('success', 'CSV导出成功'); }; const handleExportExcel = () => { const blob = exportToExcel(data); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = `志愿意向数据_${new Date().toISOString().slice(0, 10)}.xlsx`; document.body.appendChild(link); link.click(); document.body.removeChild(link); addToast('success', 'Excel导出成功'); }; const handleFileChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setImporting(true); try { let importedData: School[]; if (file.name.endsWith('.csv')) { const text = await file.text(); importedData = importFromCSV(text); } else if (file.name.endsWith('.xlsx') || file.name.endsWith('.xls')) { importedData = await importFromExcel(file); } else { throw new Error('不支持的文件格式,请上传CSV或Excel文件'); } saveData(importedData); addToast('success', `成功导入${importedData.length}所学校数据`); } catch (error) { addToast('error', (error as Error).message); } finally { setImporting(false); if (fileInputRef.current) { fileInputRef.current.value = ''; } } }; const handleRefresh = () => { window.location.reload(); }; return (

志愿意向录入系统

管理您的志愿填报信息

{loading ? (
) : ( { setEditingSchool(school); setShowSchoolForm(true); }} onDeleteSchool={handleDeleteSchool} onAddMajorGroup={(schoolId) => { setAddingMajorGroupToSchool(schoolId); setEditingMajorGroup(null); setShowMajorGroupForm(true); }} onEditMajorGroup={(schoolId, majorGroup) => { setEditingMajorGroup({ schoolId, majorGroup }); setAddingMajorGroupToSchool(null); setShowMajorGroupForm(true); }} onDeleteMajorGroup={handleDeleteMajorGroup} /> )}

数据统计

{data.length}
学校总数
{data.reduce((sum, s) => sum + s.majorGroups.length, 0)}
专业组总数
{data.filter((s) => s.type === '双一流').length}
双一流院校
{data.filter((s) => s.type === '985').length}
985院校
{showSchoolForm && ( { setShowSchoolForm(false); setEditingSchool(null); }} /> )} {showMajorGroupForm && ( { setShowMajorGroupForm(false); setEditingMajorGroup(null); setAddingMajorGroupToSchool(null); }} /> )}
); } export default App;