plan_exam_mode.md 9.0 KB

考试模式功能修改计划

一、需求概述

根据后端新增的字段:

  • Assignment.examMode: 是否为考试模式
  • Assignment.examDuration: 考试时长(分钟)
  • EngagementVO.submitted: 是否已交卷

功能要求:

  1. 教师创建作业时可选择是否开启考试模式,并设置考试时长(单位:分钟)
  2. 考试模式下学生可正常使用所有辅助组件(AI助手、词典等)
  3. 考试期间可以暂存内容
  4. 未提交时实时显示考试倒计时
  5. 结束前5分钟给出暂存提示
  6. 倒计时结束时触发自动暂存并提交

二、涉及文件清单

类型定义文件

文件 修改内容
src/types/dto.ts AssignmentDTO 添加 examMode, examDuration 字段
src/types/vo.ts IAssignment, AssignmentVO 添加 examMode, examDuration 字段
engagementVO 添加 submitted 字段

教师端作业创建页面

文件 修改内容
src/views/CourseSquare/component/CourseDetails/component/AssignmentDialogue/WritingAssignmentDialogue.vue 添加考试模式开关和时长输入

Hooks文件(新建)

文件 修改内容
src/hooks/useExamCountdown.ts 新建考试倒计时hook

学生端页面/组件

文件 修改内容
src/views/HomeworkPage/component/HomeworkDetail.vue 显示作业模式标签(普通作业/考试模式)
src/views/EditPage/EditPage.vue 集成倒计时显示
src/views/Home/component/Edit/index.vue 考试模式提交时显示确认提示

三、详细修改计划

阶段1:类型定义更新

1.1 src/types/dto.ts

export interface AssignmentDTO {
    assignmentName: string;
    description: string;
    type: string;
    descriptionFile?: string;
    attachments?: string[];
    startTime: string;
    endTime: string;
    examMode?: boolean;        // 新增:是否为考试模式
    examDuration?: number;     // 新增:考试时长(分钟),仅考试模式有效
}

1.2 src/types/vo.ts

// engagementVO 新增字段
export interface engagementVO {
    "id": number,
    "assignmentId": number,
    "studentId": number,
    "score": number,
    "remark": string,
    "fileUrl": string,
    "version": number,
    "status": string,
    "fileKey": string,
    "quillContent": string,
    "textContent": string,
    "htmlContent": string,
    "submitted": boolean;      // 新增:是否已交卷
}

// IAssignment 新增字段
export interface IAssignment {
    // ... 现有字段
    examMode?: boolean;        // 新增
    examDuration?: number;     // 新增
}

// AssignmentVO 新增字段
export interface AssignmentVO {
    // ... 现有字段
    examMode?: boolean;        // 新增
    examDuration?: number;     // 新增
}

阶段2:新建考试倒计时Hook

2.1 src/hooks/useExamCountdown.ts(新建)

功能:

  • 接收参数:考试开始时间、考试时长(分钟)
  • 实时计算剩余时间
  • 倒计时结束时触发自动暂存并提交回调
  • 提供"剩余时间小于5分钟"的标识,供UI提示暂存
interface UseExamCountdownOptions {
    startTime: Date;      // 作业开始时间
    duration: number;     // 考试时长(分钟)
    onAutoSubmit: () => void;  // 自动交卷回调
    onWarning: () => void;     // 5分钟警告回调
}

返回值:
- remainingTime: ref<number>  // 剩余秒数
- isWarning: ref<boolean>     // 是否进入5分钟警告期
- isExpired: ref<boolean>     // 是否已过期
- formattedTime: computed      // 格式化时间字符串 "HH:mm:ss"

阶段3:教师创建作业页面修改

3.1 WritingAssignmentDialogue.vue

添加考试模式表单项:

<el-form-item label="作业模式">
  <el-switch
    v-model="newAssignmentInfo.examMode"
    active-text="考试模式"
    inactive-text="普通作业"
  />
</el-form-item>
<el-form-item v-if="newAssignmentInfo.examMode" label="考试时长">
  <el-input-number
    v-model="newAssignmentInfo.examDuration"
    :min="1"
    :max="300"
    controls-position="right"
  />
  <span style="margin-left: 10px;">分钟</span>
</el-form-item>

数据初始化修改:

const newAssignmentInfo = reactive<AssignmentDTO>({
  // ... 现有字段
  examMode: false,
  examDuration: 60,  // 默认60分钟
});

编辑时数据回填:

Object.assign(newAssignmentInfo, {
  // ... 现有字段
  examMode: assignment.examMode ?? false,
  examDuration: assignment.examDuration ?? 60,
});

提交验证:

if (newAssignmentInfo.examMode && (!newAssignmentInfo.examDuration || newAssignmentInfo.examDuration < 1)) {
  ElNotification({ title: '考试模式下考试时长不得为空', type: 'error' });
  return;
}

阶段4:作业详情页修改

4.1 HomeworkDetail.vue

修改点:显示模式标识和时长

<div class="item">
  <span style="font-weight: 600">作业模式: </span>
  <el-tag :type="data.examMode ? 'warning' : 'success'">
    {{ data.examMode ? '考试模式' : '普通作业' }}
  </el-tag>
  <span v-if="data.examMode && data.examDuration" style="margin-left: 10px;">
    时长: {{ data.examDuration }}分钟
  </span>
</div>

阶段5:写作页面修改(核心)

5.1 EditPage.vue

考试模式下的布局调整:

<div class="my-work" >
  <!-- 左侧:AI助手 + 词典(考试模式下正常显示) -->
  <div class="my-work-slider">
    <el-button class="back" ...>返回</el-button>
    <AIChatter ... />  <!-- 考试模式下正常显示 -->
    <Dictionaries />   <!-- 考试模式下正常显示 -->
  </div>

  <!-- 考试模式:显示倒计时横幅 -->
  <div v-if="isExamMode" class="exam-countdown-header">
    <el-tag type="warning">考试模式</el-tag>
    <span class="countdown-time">{{ formattedTime }}</span>
    <el-tag v-if="isWarning" type="danger" effect="plain">
      距离结束还有5分钟,请及时暂存内容!
    </el-tag>
  </div>

  <!-- 中间:编辑区 -->
  <div class="my-work-input">
    <Edit :engagement="dataForm.engagement" />
  </div>

  <!-- 右侧:作业要求和批改(考试模式下隐藏) -->
  <Slider v-if="!isExamMode" ... />
</div>

考试倒计时集成:

import { useExamCountdown } from '@/hooks/useExamCountdown';

// 计算属性
const isExamMode = computed(() => dataForm.assignment?.examMode ?? false);
const examDuration = computed(() => dataForm.assignment?.examDuration ?? 0);

// 倒计时hook
const { remainingTime, isWarning, formattedTime, start: startCountdown } = useExamCountdown({
  startTime: new Date(dataForm.assignment.startTime),
  duration: examDuration.value,
  onAutoSubmit: async () => {
    ElMessage.warning('考试时间已到,正在自动提交...');
    await handleStage();  // 自动暂存
    await handleSubmit(); // 自动提交
  },
  onWarning: () => {
    ElMessage.info('距离考试结束还有5分钟,请注意暂存您的内容!');
  }
});

onMounted(() => {
  if (isExamMode.value) {
    startCountdown();
  }
});

阶段6:编辑组件提交确认

6.1 Edit/index.vue

考试模式提交确认:

const handleSubmit = async () => {
  if (isExamMode) {
    // 考试模式:确认提示
    await ElMessageBox.confirm(
      '考试时间结束后将自动交卷,确认现在提交吗?提交后不可再修改。',
      '确认交卷',
      {
        confirmButtonText: '确认提交',
        cancelButtonText: '取消',
        type: 'warning',
      }
    );
  }
  // 执行提交...
};

Props接收考试模式标识:

interface IEditProps {
  engagement: engagementVO
  isExamMode?: boolean;
}
defineProps<IEditProps>();

四、考试模式功能差异对照表

功能 普通作业模式 考试模式
AI助手 ✅ 正常显示 ✅ 正常显示
词典 ✅ 正常显示 ✅ 正常显示
暂存按钮 ✅ 显示 ✅ 显示(考试期间可暂存)
批改区域 ✅ 显示 ❌ 隐藏
倒计时 ❌ 不显示 ✅ 显示
提交次数限制 多次 仅一次
提交确认提示 有"不可修改"提示
5分钟警告 有暂存提示
自动交卷 倒计时结束自动暂存并提交

五、实施顺序

  1. 类型定义更新(dto.ts, vo.ts)
  2. 新建 useExamCountdown hook
  3. WritingAssignmentDialogue.vue - 教师端添加考试模式选项
  4. HomeworkDetail.vue - 显示模式标识
  5. EditPage.vue - 集成倒计时横幅
  6. Edit/index.vue - 考试模式提交确认
  7. 样式文件 - 考试模式UI

六、注意事项

  1. 考试时长从 assignment 获取(教师设置),不是从 engagement
  2. 倒计时基于 startTime + examDuration 计算结束时间
  3. 自动交卷需要先暂存当前内容,再提交
  4. 已提交状态的严格校验在后端完成
  5. 考试模式下的各个辅助功能正常可用,仅隐藏批改区域