diff --git a/src/App.vue b/src/App.vue
index dc20bfa..4336d4a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -3,6 +3,59 @@ import { onMounted } from 'vue'
import { RouterView } from 'vue-router'
import { useUserStore } from '@/stores/user'
import AppLayout from '@/components/layout/AppLayout.vue'
+import { NConfigProvider } from 'naive-ui'
+import type { GlobalThemeOverrides } from 'naive-ui';
+
+
+// 自定义naive-ui主题颜色
+const themeOverrides: GlobalThemeOverrides = {
+ common: {
+ primaryColor: '#0288D1',
+ primaryColorHover: '#0277BD', // A slightly darker shade for hover
+ primaryColorPressed: '#01579B', // A darker shade for pressed
+ errorColor: '#FF4D4F',
+ errorColorHover: '#E54547',
+ errorColorPressed: '#C0383A',
+ },
+ Button: {
+ // For ghost primary buttons
+ textColorGhostPrimary: '#0288D1',
+ borderPrimary: '1px solid #0288D1',
+ // For ghost error buttons
+ textColorGhostError: '#FF4D4F',
+ borderError: '1px solid #FF4D4F',
+ },
+ Tag: {
+ colorPrimary: '#0288D1',
+ colorPrimaryHover: '#0277BD',
+ colorPrimaryPressed: '#01579B',
+ textColorPrimary: '#ffffff',
+ },
+ Card: {
+ borderColor: '#E6E6E6',
+ },
+ Input: {
+ borderHover: '#0288D1',
+ borderFocus: '#0288D1',
+ boxShadowFocus: '0 0 0 1px rgba(2, 136, 209, 0.5)',
+ },
+ InputNumber: {
+ borderHover: '#0288D1',
+ borderFocus: '#0288D1',
+ boxShadowFocus: '0 0 0 1px rgba(2, 136, 209, 0.5)',
+ },
+ Select: {
+ borderHover: '#0288D1',
+ borderFocus: '#0288D1',
+ boxShadowFocus: '0 0 0 1px rgba(2, 136, 209, 0.5)',
+ },
+ Modal: {
+ borderRadius: '8px',
+ },
+ Dialog: {
+ borderRadius: '8px',
+ }
+};
const userStore = useUserStore()
@@ -14,9 +67,11 @@ onMounted(() => {
diff --git a/src/components/admin/ExamComponents/ExamSettingsModal.vue b/src/components/admin/ExamComponents/ExamSettingsModal.vue
index 5438fa3..315bd13 100644
--- a/src/components/admin/ExamComponents/ExamSettingsModal.vue
+++ b/src/components/admin/ExamComponents/ExamSettingsModal.vue
@@ -25,6 +25,12 @@
+
+
+
+
+
+
@@ -292,6 +298,7 @@ interface ExamSettings {
participants: 'all' | 'by_school';
selectedClasses: string[];
instructions: string;
+ examCount: number;
// 考试模式专用
enforceOrder: boolean;
@@ -365,6 +372,7 @@ const formData = ref
({
participants: 'all',
selectedClasses: [],
instructions: '',
+ examCount: 0,
// 考试模式专用
enforceOrder: false,
diff --git a/src/components/common/ImportModal.vue b/src/components/common/ImportModal.vue
new file mode 100644
index 0000000..418cecb
--- /dev/null
+++ b/src/components/common/ImportModal.vue
@@ -0,0 +1,475 @@
+
+
+
+
+
+
+
+
+
+ 模板下载
+
+
+ 请先下载导入模板,按照模板格式填写数据后再上传
+
+
+
+
+
+
+
+ 下载 Excel 模板
+
+
+
+
+
+
+
+
+
+
+
+ 文件上传
+
+
+
+
+
+
+
+
+
+
点击或拖拽文件到此区域上传
+
+ 支持扩展名:.xlsx、.xls,文件大小不超过 10MB
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ selectedFile.name }}
+ ({{ formatFileSize(selectedFile.file?.size || 0) }})
+
+
+
+
+
+
+
+
+
+
+ 上传中... {{ uploadProgress }}%
+
+
+
+
+
+
+
+ {{ importResult.success ? '导入成功' : '导入失败' }}
+
+ {{ importResult.message }}
+
+
成功导入:{{ importResult.details.success }} 条
+
+ 失败:{{ importResult.details.failed }} 条
+
+
+
+
+
+
+
+
+
+
+
+
+ 导入说明
+
+
+ - 请严格按照模板格式填写数据,不要修改表头
+ - 必填字段不能为空,否则导入失败
+ - 导入前请检查数据格式,确保数据的准确性
+
+
+
+
+
+
+ 取消
+
+ {{ importing ? '导入中...' : '开始导入' }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/common/README.md b/src/components/common/README.md
new file mode 100644
index 0000000..b78c318
--- /dev/null
+++ b/src/components/common/README.md
@@ -0,0 +1,136 @@
+# ImportModal 通用导入组件
+
+一个可复用的数据导入弹窗组件,支持模板下载、文件上传、拖拽上传等功能。
+
+## 功能特性
+
+- 📄 **模板下载**:支持下载 Excel 导入模板
+- 📤 **文件上传**:支持点击上传和拖拽上传
+- 📊 **进度显示**:实时显示上传进度
+- ✅ **结果反馈**:详细的导入结果提示
+- 🔒 **文件校验**:文件格式和大小限制
+- 📱 **响应式设计**:适配不同屏幕尺寸
+
+## 使用方法
+
+### 1. 导入组件
+
+```vue
+
+```
+
+### 2. 在模板中使用
+
+```vue
+
+
+ 导入数据
+
+
+
+
+```
+
+### 3. 处理事件
+
+```vue
+
+```
+
+## Props
+
+| 参数 | 类型 | 默认值 | 说明 |
+|------|------|--------|------|
+| show | boolean | - | 控制弹窗显示/隐藏 |
+| templateName | string | 'import_template.xlsx' | 模板文件名 |
+| importType | string | 'default' | 导入类型标识 |
+
+## Events
+
+| 事件名 | 参数 | 说明 |
+|--------|------|------|
+| update:show | boolean | 弹窗显示状态变化 |
+| success | result: ImportResult | 导入成功回调 |
+| template-download | type?: string | 模板下载回调 |
+
+## ImportResult 类型
+
+```typescript
+interface ImportResult {
+ success: boolean;
+ message: string;
+ details?: {
+ success: number;
+ failed: number;
+ };
+}
+```
+
+## 自定义配置
+
+### 文件限制
+- 支持格式:`.xlsx`, `.xls`
+- 文件大小:最大 10MB
+- 同时上传:仅支持单文件
+
+### 样式自定义
+组件使用 scoped 样式,可通过 CSS 变量或深度选择器自定义样式。
+
+## API 集成点
+
+组件中预留了以下 API 集成点,需要根据实际项目进行实现:
+
+1. **模板下载 API**
+ ```javascript
+ // 在 downloadTemplate 函数中实现
+ const downloadTemplate = () => {
+ // TODO: 调用模板下载 API
+ };
+ ```
+
+2. **文件上传 API**
+ ```javascript
+ // 在 handleUpload 函数中实现
+ const handleUpload = (options) => {
+ // TODO: 调用文件上传 API
+ };
+ ```
+
+3. **数据导入 API**
+ ```javascript
+ // 在 startImport 函数中实现
+ const startImport = async () => {
+ // TODO: 调用数据导入 API
+ };
+ ```
+
+## 注意事项
+
+1. 确保后端支持对应的文件格式
+2. 模板格式要与后端解析逻辑一致
+3. 合理设置文件大小限制
+4. 提供清晰的错误提示信息
+5. 考虑网络异常情况的处理
diff --git a/src/router/index.ts b/src/router/index.ts
index b4db1d0..dccb627 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -54,7 +54,10 @@ import GeneralManagement from '@/views/teacher/course/GeneralManagement.vue'
// 作业子组件
import HomeworkLibrary from '@/views/teacher/course/HomeworkLibrary.vue'
import HomeworkReview from '@/views/teacher/course/HomeworkReview.vue'
-// 练考通菜单组件
+// 考试管理组件
+
+import ExamManagement from '@/views/teacher/course/ExamPages/ExamPage.vue'
+import QuestionManagement from '@/views/teacher/course/ExamPages/QuestionManagement.vue'
import ExamLibrary from '@/views/teacher/course/ExamPages/ExamLibrary.vue'
import MarkingCenter from '@/views/teacher/course/ExamPages/MarkingCenter.vue'
import AddExam from '@/views/teacher/course/ExamPages/AddExam.vue'
@@ -156,7 +159,7 @@ const routes: RouteRecordRaw[] = [
path: 'practice',
name: 'PracticeManagement',
component: PracticeManagement,
- meta: { title: '练考通管理' },
+ meta: { title: '考试管理' },
redirect: (to) => `/teacher/course-editor/${to.params.id}/practice/exam-library`,
children: [
{
@@ -241,7 +244,40 @@ const routes: RouteRecordRaw[] = [
name: 'ChapterEditor',
component: ChapterEditor,
meta: { title: '章节编辑' }
- }
+ },
+ {
+ path: 'exam-management',
+ name: 'ExamManagement',
+ component: ExamManagement,
+ meta: { title: '考试管理' },
+ redirect: '/teacher/exam-management/question-management',
+ children: [
+ {
+ path: 'question-management',
+ name: 'QuestionManagement',
+ component: QuestionManagement,
+ meta: { title: '试题管理' }
+ },
+ {
+ path: 'exam-library',
+ name: 'ExamLibrary',
+ component: ExamLibrary,
+ meta: { title: '试卷管理' }
+ },
+ {
+ path: 'marking-center',
+ name: 'MarkingCenter',
+ component: MarkingCenter,
+ meta: { title: '阅卷中心' }
+ },
+ {
+ path: 'add',
+ name: 'AddExam',
+ component: AddExam,
+ meta: { title: '添加试卷' }
+ }
+ ]
+ },
]
},
diff --git a/src/views/teacher/AdminDashboard.vue b/src/views/teacher/AdminDashboard.vue
index 340e96c..3710937 100644
--- a/src/views/teacher/AdminDashboard.vue
+++ b/src/views/teacher/AdminDashboard.vue
@@ -24,6 +24,44 @@
课程管理
+
+
+
+
![]()
+
考试管理
+
+
+
+
+
+
+
+
@@ -50,7 +88,7 @@
-
+
{{ item.title }}
@@ -65,17 +103,43 @@
diff --git a/src/views/teacher/course/ExamPages/ExamPage.vue b/src/views/teacher/course/ExamPages/ExamPage.vue
new file mode 100644
index 0000000..bd441ef
--- /dev/null
+++ b/src/views/teacher/course/ExamPages/ExamPage.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/views/teacher/course/ExamPages/MarkingCenter.vue b/src/views/teacher/course/ExamPages/MarkingCenter.vue
index eb2fad6..57a0808 100644
--- a/src/views/teacher/course/ExamPages/MarkingCenter.vue
+++ b/src/views/teacher/course/ExamPages/MarkingCenter.vue
@@ -1,11 +1,507 @@
-
-
阅卷中心
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ exam.description }}
+
+
+
+
+
+
+ 试卷设置
+
+
+ 删除
+
+
+
+
+
+
+
{{ exam.totalQuestions }}
+
试题
+
+
+
{{ exam.submittedCount }}
+
已交
+
+
+
{{ exam.gradedCount }}
+
{{ exam.status === 'in-progress' ? '0未交' : '0未交' }}
+
+
+
+
+
+ {{ exam.status === 'completed' ? '查看' : (exam.status === 'in-progress' ? '批阅' : '查看') }}
+
+
+
+
+
+
+
diff --git a/src/views/teacher/course/ExamPages/QuestionManagement.vue b/src/views/teacher/course/ExamPages/QuestionManagement.vue
new file mode 100644
index 0000000..579dfe1
--- /dev/null
+++ b/src/views/teacher/course/ExamPages/QuestionManagement.vue
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file