Ver código fonte

feat:完成听力作业的查询和更新

lalala 1 ano atrás
pai
commit
f61d5a26bd

+ 1 - 5
src/apis/assignment.ts

@@ -34,11 +34,7 @@ const assignmentApis = {
         })
     },
     updateAssignment(assignmentId:number, assignmentDTO:AssignmentDTO){
-        let url = ASSIGNMENT_PREFIX;
-        if(assignmentDTO.type == '听力'){
-            url = ASSIGNMENT_PREFIX + '/listening'
-        } 
-        return axiosInstance.put(`${ASSIGNMENT_PREFIX}`, assignmentDTO, {
+        return axiosInstance.post(`${ASSIGNMENT_PREFIX}/update`, assignmentDTO, {
             params: {
                 assignmentId
             }

+ 1 - 1
src/apis/axios.config.ts

@@ -1,7 +1,7 @@
 import axios from "axios";
 
 // const BASEURL = 'http://47.111.23.171:8081'
-const BASEURL = 'http://localhost:8081'
+const BASEURL = 'http://localhost:8080'
 // const BASEURL = 'http://8.130.126.86:8080'
 // const BASEURL = 'https://air.seec.seecoder.cn/'
 

+ 3 - 1
src/apis/index.ts

@@ -7,6 +7,7 @@ import engagementApis from "@/apis/engagement";
 import assignmentApis from "@/apis/assignment";
 import courseApis from "@/apis/course";
 import fileApis from "@/apis/file";
+import listeningAssignmentApis from "@/apis/listening_assignment";
 
 
 const apis = {
@@ -18,7 +19,8 @@ const apis = {
     ...dictApis,
     ...assignmentApis,
     ...courseApis,
-    ...fileApis
+    ...fileApis,
+    ...listeningAssignmentApis
 }
 
 // hook

+ 35 - 0
src/apis/listening_assignment.ts

@@ -0,0 +1,35 @@
+import axiosInstance from "@/apis/axios.config";
+import type {ListeningAssignmentDTO} from "@/types/dto";
+
+const ASSIGNMENT_PREFIX = "/api/assignment/listening"
+
+const listeningAssignmentApis = {
+    createListeningAssignment(courseId:number, assignmentDTO: ListeningAssignmentDTO){
+        return axiosInstance.post(ASSIGNMENT_PREFIX, assignmentDTO, {
+            params: {
+                courseId
+            }
+        });
+    },
+
+    getListeningAssignmentById(assignmentId: number){
+        return axiosInstance.get(`${ASSIGNMENT_PREFIX}/byAssignment/${assignmentId}`)
+    },
+    getAssignmentByCourseId(courseId:number, page: number=0, size: number=10){
+        return axiosInstance.get(`${ASSIGNMENT_PREFIX}/byCourse/${courseId}`, {
+            params: {
+                page,
+                size
+            }
+        })
+    },
+    updateListeningAssignment(assignmentId:number, assignmentDTO:ListeningAssignmentDTO){
+        return axiosInstance.post(`${ASSIGNMENT_PREFIX}/update`, assignmentDTO, {
+            params: {
+                assignmentId
+            }
+        })
+    }
+}
+
+export default listeningAssignmentApis

+ 354 - 0
src/components/AssignmentDialog/ListeningAssignmentDialog.vue

@@ -0,0 +1,354 @@
+<template>
+  <el-dialog v-model="listeningVisible" :title="dialogConfig.title" 
+             @close="closeDialog"
+             :before-close="closeDialog">
+    <el-form :model="newAssignmentInfo" label-width="auto">
+      <el-form-item label="作业名称">
+        <el-input v-model="newAssignmentInfo.assignmentName" placeholder="请输入名称"></el-input>
+      </el-form-item>
+      <el-form-item label="作业描述">
+        <el-input v-model="newAssignmentInfo.description" placeholder="请输入描述"></el-input>
+      </el-form-item>
+      <el-form-item label="开始时间">
+        <el-date-picker v-model="newAssignmentInfo.startTime" type="datetime" placeholder="开始时间" style="width: 180px"/>
+      </el-form-item>
+      <el-form-item label="截止时间">
+        <el-date-picker v-model="newAssignmentInfo.endTime" type="datetime" placeholder="截止时间" style="width: 180px"/>
+      </el-form-item>
+      <el-form-item label="音频">
+        <el-upload
+          ref="uploadAudioRef"
+          action="/api/audio"
+          multiple
+           v-model:file-list="audioFileList"
+          :before-remove="beforeRemove"
+          :limit="5"
+          :on-success="handleAudioSuccess"
+          :on-error="handleAudioError"
+          :on-exceed="handleAudioExceed"
+          :on-change="handleAudioChange"
+          accept=".mp3, .wav"
+          :auto-upload="false"
+        >
+          <el-button type="primary">点击上传音频</el-button>
+          <template #tip>
+            <div class="el-upload__tip">支持 mp3/wav 文件,大小不超过 10MB</div>
+          </template>
+        </el-upload>
+      </el-form-item>
+      <el-form-item label="题目">
+        <el-upload
+          ref="uploadQuestionRef"
+          action="/api/file"
+          multiple
+          v-model:file-list="questionFileList"
+          :limit="5"
+          :on-success="handleQuestionSuccess"
+          :on-error="handleQuestionError"
+          :on-exceed="handleQuestionExceed"
+          :on-change="handleQuestionChange"
+          accept=".doc, .docx"
+          :auto-upload="false"
+        >
+          <el-button type="primary">点击上传题目</el-button>
+          <template #tip>
+            <div class="el-upload__tip">doc/docx 文件不大于 500kb</div>
+          </template>
+        </el-upload>
+      </el-form-item>
+      <el-form-item v-if="audioFileList.length > 0" label="播放次数">
+        <el-input-number
+          v-model="newAssignmentInfo.playCount"
+          :min="1"
+          :max="10"
+        />
+      </el-form-item>
+      <el-form-item label="平台批改">
+        <el-radio-group v-model="newAssignmentInfo.isCorrectRequired">
+          <el-radio :label="true">是</el-radio>
+          <el-radio :label="false">否</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item v-if="newAssignmentInfo.isCorrectRequired" label="题目数量">
+        <el-input-number
+          v-model="newAssignmentInfo.questionCount"
+          :min="1"
+          :max="10"
+          label="题目数量"
+        />
+      </el-form-item>
+      <el-form-item v-if="newAssignmentInfo.isCorrectRequired" label="题目答案">
+        <el-input
+          type="textarea"
+          v-model="newAssignmentInfo.answers"
+          :placeholder="
+            '请输入 ' + newAssignmentInfo.questionCount + ' 道题的答案,使用;分隔'
+          "
+          :rows="5"
+          :autosize="{ minRows: 5, maxRows: 10 }"
+        ></el-input>
+      </el-form-item>
+      <div class="dialog-footer" style="margin-left: 230px">
+        <el-button @click="closeDialog">取消</el-button>
+        <el-button type="primary" @click="handleSubmit()">确定</el-button>
+      </div>
+    </el-form>
+  </el-dialog>
+</template>
+
+  
+  <script lang="ts" setup>
+import { reactive,ref, defineProps, watch, onMounted } from "vue";
+import type { AssignmentDTO, ListeningAssignmentDTO } from '@/types/dto';
+import useApis from "@/apis";
+import {
+  ElMessage,
+  ElNotification,
+  type UploadFile,
+  type UploadFiles,
+  type UploadProps,
+  type UploadUserFile,
+} from "element-plus";
+import {useFormatDate} from "@/hooks/useFormatDate";
+import { fi } from "element-plus/es/locale";
+const {formatDate} = useFormatDate()
+const apis = useApis();
+const props = defineProps({
+    listeningVisible: Boolean,
+    dialogConfig: Object,
+    courseId: Number,
+    assignmentId: Number
+  });
+const listeningVisible = ref(false)
+
+const newAssignmentInfo = reactive<ListeningAssignmentDTO>({
+  assignmentName: "",
+  description: "",
+  type: "",
+  descriptionFile: "",
+  attachments: [],
+  startTime: "",
+  endTime: "",
+  audios: [],
+  questions: [], 
+  playCount: 1,
+  isCorrectRequired: true,
+  questionCount: 1,
+  answers: "",
+});
+
+const initializeDialog = () => {
+    if (props.dialogConfig.type === 'edit') {
+      apis.getListeningAssignmentById(props.dialogConfig.assignmentId).then((res) => {
+        const assignment = res.data.data
+        Object.assign(newAssignmentInfo, {
+          assignmentName: assignment.assignmentName,
+          description: assignment.description,
+          type: assignment.type,
+          descriptionFile: assignment.descriptionFile,
+          attachments: assignment.attachments,
+          startTime: assignment.startTime,
+          endTime: assignment.endTime,
+          audios:assignment.audios,
+          questions: assignment.questions,
+          playCount: assignment.playCount,
+          isCorrectRequired:assignment.isCorrectRequired,
+          questionCount: assignment.questionCount,
+          answers: assignment.answers
+    });
+      });
+    } else {
+      cleanNewAssignmentInfo();
+    }
+  };
+
+  const cleanNewAssignmentInfo = () => {
+    Object.assign(newAssignmentInfo, {
+      assignmentName: '',
+      description: '',
+      type: '',
+      descriptionFile: '',
+      attachments: [],
+      startTime: '',
+      endTime: '',
+      audios: [],
+      questions: [], 
+      playCount: 1,
+      isCorrectRequired: true,
+      questionCount: 1,
+      answers: ""
+    });
+  };
+
+const audioFileList = ref([]);
+const questionFileList = ref([]);
+let uploadAudioRef = ref();
+let uploadQuestionRef = ref();
+
+// 上传成功处理函数
+const handleAudioSuccess = (response, file, fileList) => {
+  console.log("上传成功", response);
+};
+
+// 上传失败处理函数
+const handleAudioError = (error, file, fileList) => {
+  console.error("上传失败", error);
+};
+
+// 文件超出限制处理函数
+const handleAudioExceed = (files, fileList) => {
+  console.warn("文件超出限制", files, fileList);
+};
+
+const handleAudioChange = (file, fileList) => {
+  console.log(file, fileList)
+  // 获取文件的扩展名
+  const fileAudioType = file.name.match(/\.([^\.]+)$/)[1].toLowerCase();
+  const validAudioTypes = ["mp3", "wav"]; // 支持的音频文件类型
+  const isAudioType = validAudioTypes.includes(fileAudioType);
+  const isLt10MB = file.size / 1024 / 1024 < 10; // 限制文件大小为 10MB
+  // 检查文件类型
+  if (!isAudioType) {
+    ElMessage.error("文件仅支持 mp3 和 wav 格式"); // 提示错误信息
+    uploadAudioRef.value.clearFiles(); // 清空上传文件
+    return false;
+  }
+  // 检查文件大小
+  if (!isLt10MB) {
+    ElMessage.error("文件不能超过 10MB!"); // 提示错误信息
+    uploadAudioRef.value.clearFiles(); // 清空上传文件
+    return false;
+  }
+  // 调用上传接口
+  apis
+    .uploadFile(file.raw)
+    .then((res) => {
+      if(res.data.data != ""){
+        newAssignmentInfo.audios.push(res.data.data);
+        ElMessage.success("音频上传成功");
+      }
+    })
+    .catch((err) => {
+      console.error("音频上传失败:", err);
+      ElMessage.error("音频上传失败");
+    });
+};
+
+const handleQuestionSuccess = (
+  response: any,
+  uploadFile: UploadFile,
+  uploadFiles: UploadFiles
+) => {
+  console.log("上传成功", response);
+};
+
+const handleQuestionError = (error, file, fileList) => {
+  console.error("上传失败", error);
+};
+
+// 文件超出限制处理函数
+const handleQuestionExceed = (files, fileList) => {
+  console.warn("文件超出限制", files, fileList);
+};
+
+const handleQuestionChange = (file, fileList) => {
+  const fileImgType = file.name.match(/\.([^\.]+)$/)[1]; //匹配文件格式(最后一个'.'后的格式)或者匹配file.raw.type
+  const isImageType = ["doc", "docx"];
+  const isLt500KB = file.size / 1024 < 500; //判断图片格式与大小
+  if (isImageType.indexOf(fileImgType) == -1) {
+    ElMessage.error("文件仅支持png、jpg格式"); //限制文件类型
+    uploadQuestionRef.value; //清空上传文件
+    return false;
+  }
+  if (!isLt500KB) {
+    ElMessage.error("文件不能超过500kb!"); //限制文件大小
+    uploadQuestionRef.value.clearFiles(); //清空上传文件
+    return false;
+  }
+  apis
+    .uploadFile(file.raw)
+    .then((res) => {
+      newAssignmentInfo.questions.push(res.data.data);
+      ElMessage.success("题目上传成功");
+    })
+    .catch((err) => {
+      console.log(err);
+    });
+};
+
+const handleSubmit = async () => {
+    newAssignmentInfo.endTime = formatDate(newAssignmentInfo.endTime);
+    newAssignmentInfo.startTime = formatDate(newAssignmentInfo.startTime);
+    newAssignmentInfo.descriptionFile = newAssignmentInfo.questions[0];
+    newAssignmentInfo.type = '听力'
+    if(props.dialogConfig.type == 'add'){
+      apis.createListeningAssignment(props.courseId, newAssignmentInfo)
+      .then((res)=>{
+        if(res.data.code === 200){
+          ElNotification({
+            title: '新增成功',
+            type: 'success',
+          })
+        } else {
+          ElNotification({
+            title: '新增失败',
+            type: 'error',
+          })
+        }
+        listeningVisible.value = false
+      })
+      .catch((err)=> {
+        console.log(err);
+        ElNotification({
+            title: `新增失败${err}`,
+            type: 'error',
+          })
+          listeningVisible.value = false
+      })
+    }else if (props.dialogConfig.type === 'edit') {
+      apis.updateListeningAssignment(props.dialogConfig.assignmentId, newAssignmentInfo)
+      .then((res)=>{
+        if(res.data.code === 200){
+          ElNotification.success('修改成功')
+        } else {
+          ElNotification.error('修改失败')
+        }
+        listeningVisible.value = false
+      })
+      .catch((err)=> {
+        console.log(err);
+        ElNotification.error(`新增失败 ${err}`)
+        listeningVisible.value = false
+      })
+    }
+    listeningVisible.value = false;
+  }
+
+const emit = defineEmits(['update:listeningVisible']);
+const closeDialog = () => {
+  listeningVisible.value = false;
+  cleanNewAssignmentInfo();
+  emit('update:listeningVisible', false); // 触发父组件更新
+};
+
+// 监听父组件传递的 listeningVisible 值
+watch(() => props.listeningVisible, (newVal) => {
+  listeningVisible.value = newVal; // 同步父组件的值
+  if (newVal) {
+    initializeDialog();  // 弹出对话框时初始化
+  } else {
+    cleanNewAssignmentInfo();  // 关闭时清理数据
+  }
+});
+
+onMounted(() => {
+  listeningVisible.value = props.listeningVisible; // 初始值同步
+  console.log(props.dialogConfig);
+});
+
+
+</script>
+  
+  <style scoped>
+</style>
+  

+ 282 - 0
src/components/AssignmentDialog/WritingAssignmentDialog.vue

@@ -0,0 +1,282 @@
+<template>
+    <el-dialog v-model="writingVisible" :title="dialogConfig.title"  
+    @close="closeDialog"
+    :before-close="closeDialog">
+      <el-form :model="newAssignmentInfo" label-width="auto">
+        <el-form-item label="作业名称">
+          <el-input v-model="newAssignmentInfo.assignmentName" placeholder="请输入名称"></el-input>
+        </el-form-item>
+        <el-form-item label="作业描述">
+          <el-input v-model="newAssignmentInfo.description" placeholder="请输入描述"></el-input>
+        </el-form-item>
+        <el-form-item label="开始时间">
+          <el-date-picker v-model="newAssignmentInfo.startTime" type="datetime" placeholder="开始时间" style="width: 180px"/>
+        </el-form-item>
+        <el-form-item label="截止时间">
+          <el-date-picker v-model="newAssignmentInfo.endTime" type="datetime" placeholder="截止时间" style="width: 180px"/>
+        </el-form-item>
+        <el-form-item label="描述文件">
+          <el-upload
+            ref="uploadDescribeRef"
+            action="/api/file"
+            multiple
+            v-model:file-list="describeFileList"
+            :limit="1"
+            :on-success="handleDescribeSuccess"
+            :on-error="handleDescribeError"
+            :on-exceed="handleDescribeExceed"
+            :on-change="handleDescribeChange"
+            accept=".doc, .docx"
+            :auto-upload="false"
+          >
+            <el-button type="primary">点击上传</el-button>
+            <template #tip>
+              <div class="el-upload__tip">
+                doc/docx 文件不大于 500kb
+              </div>
+            </template>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="附件">
+          <el-upload
+            ref="uploadPictureRef"
+            action="/api/file"
+            multiple
+            v-model:file-list="pictureFileList"
+            :limit="1"
+            :on-success="handlePictureSuccess"
+            :on-error="handlePictureError"
+            :on-exceed="handlePictureExceed"
+            :on-change="handlePictureChange"
+            accept=".doc, .docx"
+            :auto-upload="false"
+          >
+            <el-button type="primary">点击上传</el-button>
+            <template #tip>
+              <div class="el-upload__tip">
+                doc/docx 文件不大于 500kb
+              </div>
+            </template>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDialog">取消</el-button>
+          <el-button type="primary" @click="handleSubmit">确定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </template>
+  
+  <script lang="ts" setup>
+  import { ref, reactive, watch, defineProps, defineEmits, onMounted, inject } from 'vue';
+  import { dialogEmits, ElMessage, ElNotification } from 'element-plus';
+  import { AssignmentDTO } from '@/types/dto';
+  import useApis from "@/apis";
+  import {useFormatDate} from "@/hooks/useFormatDate";
+  const {formatDate} = useFormatDate()
+  const apis = useApis()
+  const props = defineProps({
+    writingVisible: Boolean,
+    dialogConfig: Object,
+    courseId: Number
+  });
+  let uploadDescribeRef = ref()
+  let uploadPictureRef = ref()
+  const writingVisible = ref(false)
+  const newAssignmentInfo = reactive<AssignmentDTO>({
+    assignmentName: '',
+    description: '',
+    type: '',
+    descriptionFile: '',
+    attachments: [''],
+    startTime: '',
+    endTime: '',
+  });
+  
+  const describeFileList = ref([]);
+  const pictureFileList = ref([]);
+  
+  const initializeDialog = () => {
+    if (props.dialogConfig.type === 'edit') {
+      // 通过 ID 获取作业详细信息并填充
+      apis.getAssignmentById(props.dialogConfig.assignmentId).then((res) => {
+      const assignment = res.data.data
+        Object.assign(newAssignmentInfo, {
+          assignmentName: assignment.assignmentName,
+          description: assignment.description,
+          type: assignment.type,
+          descriptionFile: assignment.descriptionFile,
+          attachments: assignment.attachments,
+          startTime: assignment.startTime,
+          endTime: assignment.endTime,
+    });
+      });
+    } else {
+      cleanNewAssignmentInfo();
+    }
+  };
+  
+  const handleDescribeSuccess = (response: any) => {
+    newAssignmentInfo.descriptionFile = response.data;
+  };
+  
+  const handlePictureSuccess = (response: any) => {
+    newAssignmentInfo.attachments[0] = response.data;
+  };
+  
+  const handleDescribeError = () => {
+    ElMessage.error('上传描述文件失败');
+  };
+  
+  const handlePictureError = () => {
+    ElMessage.error('上传附件失败');
+  };
+  
+  const handleDescribeExceed = (files: any) => {
+    ElMessage.error('上传文件超过限制');
+  };
+  
+  const handlePictureExceed = (files: any) => {
+    ElMessage.error('上传文件超过限制');
+  };
+  
+  //选择文件
+  const handleDescribeChange = (file,fileList) => {
+    // console.log(file)
+    const fileImgType = file.name.match(/\.([^\.]+)$/)[1];  //匹配文件格式(最后一个'.'后的格式)或者匹配file.raw.type
+    const isImageType = ['doc','docx'];
+    const isLt500KB = file.size / 1024  < 500;  //判断图片格式与大小
+    if (isImageType.indexOf(fileImgType)==-1) {
+      ElMessage.error('文件仅支持png、jpg格式')  //限制文件类型
+      uploadDescribeRef.value.clearFiles()  //清空上传文件
+      return false;
+    }
+    if (!isLt500KB) {
+      ElMessage.error('文件不能超过500kb!')  //限制文件大小
+      uploadDescribeRef.value.clearFiles()  //清空上传文件
+      return false;
+    }
+    apis.uploadFile(file.raw)
+        .then((res) => {
+          newAssignmentInfo.descriptionFile = res.data.data
+        })
+        .catch((err) => {
+          console.log(err)
+        })
+  }
+   
+  
+  const handlePictureChange = (file,fileList) => {
+    // console.log(file)
+    const fileImgType = file.name.match(/\.([^\.]+)$/)[1];  //匹配文件格式(最后一个'.'后的格式)或者匹配file.raw.type
+    // const isImageType = ['png','jpg'];
+    const isImageType = ['doc','docx'];
+    const isLt500KB = file.size / 1024  < 500;  //判断图片格式与大小
+    if (isImageType.indexOf(fileImgType)==-1) {
+      ElMessage.error('文件仅支持png、jpg格式')  //限制文件类型
+      uploadDescribeRef.value.clearFiles()  //清空上传文件
+      return false;
+    }
+    if (!isLt500KB) {
+      ElMessage.error('文件不能超过500kb!')  //限制文件大小
+      uploadDescribeRef.value.clearFiles()  //清空上传文件
+      return false;
+    }
+    apis.uploadFile(file.raw)
+        .then((res) => {
+          newAssignmentInfo.attachments[0] = res.data.data
+        })
+        .catch((err) => {
+          console.log(err)
+        })
+  }
+  
+  const handleSubmit = async () => {
+    newAssignmentInfo.endTime = formatDate(newAssignmentInfo.endTime);
+    newAssignmentInfo.startTime = formatDate(newAssignmentInfo.startTime);
+    if (props.dialogConfig.type === 'add') {
+      newAssignmentInfo.type = '写作'
+      apis.createAssignment(props.courseId, newAssignmentInfo)
+      .then((res)=>{
+        if(res.data.code === 200){
+          ElNotification({
+            title: '新增成功',
+            type: 'success',
+          })
+        } else {
+          ElNotification({
+            title: '新增失败',
+            type: 'error',
+          })
+        }
+        writingVisible.value = false
+      })
+      .catch((err)=> {
+        console.log(err);
+        ElNotification({
+            title: `新增失败${err}`,
+            type: 'error',
+          })
+          writingVisible.value = false
+      })
+  
+    
+    } else if (props.dialogConfig.type === 'edit') {
+      apis.updateAssignment(props.dialogConfig.assignmentId, newAssignmentInfo)
+      .then((res)=>{
+        if(res.data.code === 200){
+          ElNotification.success('修改成功')
+        } else {
+          ElNotification.error('修改失败')
+        }
+        writingVisible.value = false
+      })
+      .catch((err)=> {
+        console.log(err);
+        ElNotification.error(`新增失败 ${err}`)
+        writingVisible.value = false
+      })
+    }
+    writingVisible.value = false;
+  };
+  
+  const cleanNewAssignmentInfo = () => {
+    Object.assign(newAssignmentInfo, {
+      assignmentName: '',
+      description: '',
+      type: '',
+      descriptionFile: '',
+      attachments: [''],
+      startTime: '',
+      endTime: '',
+    });
+  };
+  const emit = defineEmits(['update:writingVisible']);
+  const closeDialog = () => {
+    writingVisible.value = false;
+    cleanNewAssignmentInfo()
+    emit('update:writingVisible', false); 
+  };
+ 
+  watch(() => props.writingVisible, (newVal) => {
+  writingVisible.value = newVal;  // 监听父组件的 visible 变化,确保同步
+  if (newVal) {
+    initializeDialog();  // 每次弹出对话框时初始化
+  } else {
+    cleanNewAssignmentInfo();  // 关闭时清理数据
+  }
+});
+  onMounted (()=>{
+    writingVisible.value = props.writingVisible
+    console.log(props.dialogConfig)
+  })
+  </script>
+  
+  <style scoped>
+  .dialog-footer {
+    text-align: right;
+  }
+  </style>
+  

+ 0 - 230
src/components/AudioUpload.vue

@@ -1,230 +0,0 @@
-<template>
-  <el-form-item label="音频">
-    <el-upload
-      ref="uploadAudioRef"
-      action="/api/audio"
-      multiple
-      v-model:file-list="audioFileList"
-      :limit="5"
-      :on-success="handleAudioSuccess"
-      :on-error="handleAudioError"
-      :on-exceed="handleAudioExceed"
-      :on-change="handleAudioChange"
-      accept=".mp3, .wav"
-      :auto-upload="false"
-    >
-      <el-button type="primary">点击上传音频</el-button>
-      <template #tip>
-        <div class="el-upload__tip">支持 mp3/wav 文件,大小不超过 10MB</div>
-      </template>
-    </el-upload>
-  </el-form-item>
-  <el-form-item label="题目">
-    <el-upload
-      ref="uploadQuestionRef"
-      action="/api/file"
-      multiple
-      v-model:file-list="questionFileList"
-      :limit="5"
-      :on-success="handleQuestionSuccess"
-      :on-error="handleQuestionError"
-      :on-exceed="handleQuestionExceed"
-      :on-change="handleQuestionChange"
-      accept=".doc, .docx"
-      :auto-upload="false"
-    >
-      <el-button type="primary">点击上传题目</el-button>
-      <template #tip>
-        <div class="el-upload__tip">doc/docx 文件不大于 500kb</div>
-      </template>
-    </el-upload>
-  </el-form-item>
-  <el-form-item v-if="audioFileList.length > 0" label="播放次数">
-    <el-input-number
-      v-model="AssignmentInfo.playCount"
-      :min="1"
-      :max="10"
-    />
-  </el-form-item>
-  <el-form-item label="平台批改">
-    <el-radio-group v-model="AssignmentInfo.isCorrectRequired">
-      <el-radio :label="true">是</el-radio>
-      <el-radio :label="false">否</el-radio>
-    </el-radio-group>
-  </el-form-item>
-  <el-form-item v-if="AssignmentInfo.isCorrectRequired" label="题目数量">
-    <el-input-number
-      v-model="AssignmentInfo.questionCount"
-      :min="1"
-      :max="10"
-      label="题目数量"
-    />
-  </el-form-item>
-  <el-form-item v-if="AssignmentInfo.isCorrectRequired" label="题目答案">
-    <el-input
-      type="textarea"
-      v-model="AssignmentInfo.answers"
-      :placeholder="
-        '请输入 ' + AssignmentInfo.questionCount + ' 道题的答案,使用;分隔'
-      "
-      :rows="5"
-      :autosize="{ minRows: 5, maxRows: 10 }"
-    ></el-input>
-  </el-form-item>
-  <div class="dialog-footer" style="margin-left: 230px">
-    <el-button @click="dialogConfig.visible = false">取消</el-button>
-    <el-button type="primary" @click="handleSubmit()">确定</el-button>
-  </div>
-</template>
-  
-  <script lang="ts" setup>
-import { ref, defineProps, watch } from "vue";
-import useApis from "@/apis";
-import {
-  ElMessage,
-  ElNotification,
-  type UploadFile,
-  type UploadFiles,
-  type UploadProps,
-  type UploadUserFile,
-} from "element-plus";
-const apis = useApis();
-const props = defineProps({
-  newAssignmentInfo: {
-    type: Object,
-    required: true,
-  },
-  dialogConfig: {
-    type: Object,
-    required: true,
-  },
-});
-const emit = defineEmits(["update:dialogConfig"]);
-watch(
-  () => props.dialogConfig,
-  (newVal) => emit("update:dialogConfig", newVal),
-  { deep: true }
-);
-const AssignmentInfo = ref({
-  assignmentName: "",
-  description: "",
-  type: "",
-  descriptionFile: "",
-  attachments: [""],
-  startTime: "",
-  endTime: "",
-  audios: [],
-  questions: [], 
-  playCount: 1,
-  isCorrectRequired: true,
-  questionCount: 1,
-  answers: "",
-});
-
-watch(
-  () => props.newAssignmentInfo,
-  (newVal) => {
-    Object.assign(AssignmentInfo.value, newVal); // 将非响应式的 newAssignmentInfo 合并到响应式对象 AssignmentInfo
-  },
-  { immediate: true, deep: true } // immediate 表示组件初始化时触发,deep 表示深度监听对象
-);
-
-const audioFileList = ref([]);
-const questionFileList = ref([]);
-let uploadAudioRef = ref();
-let uploadQuestionRef = ref();
-
-// 上传成功处理函数
-const handleAudioSuccess = (response, file, fileList) => {
-  console.log("上传成功", response);
-};
-
-// 上传失败处理函数
-const handleAudioError = (error, file, fileList) => {
-  console.error("上传失败", error);
-};
-
-// 文件超出限制处理函数
-const handleAudioExceed = (files, fileList) => {
-  console.warn("文件超出限制", files, fileList);
-};
-
-const handleAudioChange = (file, fileList) => {
-  // 获取文件的扩展名
-  const fileAudioType = file.name.match(/\.([^\.]+)$/)[1].toLowerCase();
-  const validAudioTypes = ["mp3", "wav"]; // 支持的音频文件类型
-  const isAudioType = validAudioTypes.includes(fileAudioType);
-  const isLt10MB = file.size / 1024 / 1024 < 10; // 限制文件大小为 10MB
-  // 检查文件类型
-  if (!isAudioType) {
-    ElMessage.error("文件仅支持 mp3 和 wav 格式"); // 提示错误信息
-    uploadAudioRef.value.clearFiles(); // 清空上传文件
-    return false;
-  }
-  // 检查文件大小
-  if (!isLt10MB) {
-    ElMessage.error("文件不能超过 10MB!"); // 提示错误信息
-    uploadAudioRef.value.clearFiles(); // 清空上传文件
-    return false;
-  }
-  // 调用上传接口
-  apis
-    .uploadFile(file.raw)
-    .then((res) => {
-      AssignmentInfo.value.audio.push(res.data.data);
-      console.log(AssignmentInfo.value.audio);
-      ElMessage.success("音频上传成功");
-    })
-    .catch((err) => {
-      console.error("音频上传失败:", err);
-      ElMessage.error("音频上传失败");
-    });
-};
-
-const handleQuestionSuccess = (
-  response: any,
-  uploadFile: UploadFile,
-  uploadFiles: UploadFiles
-) => {
-  console.log("上传成功", response);
-};
-
-const handleQuestionError = (error, file, fileList) => {
-  console.error("上传失败", error);
-};
-
-// 文件超出限制处理函数
-const handleQuestionExceed = (files, fileList) => {
-  console.warn("文件超出限制", files, fileList);
-};
-
-const handleQuestionChange = (file, fileList) => {
-  const fileImgType = file.name.match(/\.([^\.]+)$/)[1]; //匹配文件格式(最后一个'.'后的格式)或者匹配file.raw.type
-  const isImageType = ["doc", "docx"];
-  const isLt500KB = file.size / 1024 < 500; //判断图片格式与大小
-  if (isImageType.indexOf(fileImgType) == -1) {
-    ElMessage.error("文件仅支持png、jpg格式"); //限制文件类型
-    uploadQuestionRef.value; //清空上传文件
-    return false;
-  }
-  if (!isLt500KB) {
-    ElMessage.error("文件不能超过500kb!"); //限制文件大小
-    uploadQuestionRef.value.clearFiles(); //清空上传文件
-    return false;
-  }
-  apis
-    .uploadFile(file.raw)
-    .then((res) => {
-      AssignmentInfo.value.descriptionFile = res.data.data;
-      ElMessage.success("题目上传成功");
-      console.log(AssignmentInfo.value.descriptionFile);
-    })
-    .catch((err) => {
-      console.log(err);
-    });
-};
-</script>
-  
-  <style scoped>
-</style>
-  

+ 17 - 0
src/types/dto.ts

@@ -10,6 +10,23 @@ export interface AssignmentDTO {
     endTime: string; // 结束时间不能缺失 (ISO 8601 日期时间字符串)
 }
 
+export interface ListeningAssignmentDTO {
+    assignmentName: string; // 作业名称不能缺失
+    description: string; // 作业描述不能缺失
+    type:string,//作业类型不能缺失
+    descriptionFile?: string; // 作业要求,Word/Pdf文件 (可选)
+    attachments?: string[]; // 作业附件 (可选)
+    startTime: string; // 起始时间不能缺失 (ISO 8601 日期时间字符串)
+    endTime: string; // 结束时间不能缺失 (ISO 8601 日期时间字符串)
+    audios: string[];
+    questions: string[];
+    playCount: number;
+    isCorrectRequired: boolean;
+    questionCount: number;
+    answers: string;
+}
+
+
 export interface AssignmentQueryDTO {
     assignmentId?: number;
     teacherId?: number;

+ 2 - 0
src/types/query.ts

@@ -14,8 +14,10 @@ export interface AssignmentQuery {
     courseId:number;
     assignmentName:string;
     status:string;
+    type:string;
 }
 
+
 export interface EngagementQuery {
     assignmentId: number,
     status?: number

+ 62 - 316
src/views/CourseSquare/component/CourseDetails/component/CourseHomeworkTable.vue

@@ -6,7 +6,7 @@
 <template>
   <el-card>
     <template v-if="props.role == 'teachers'">
-      <el-button color="#597d3b" @click="cleanNewAssignmentInfo(); changeDialog('add')" v-if="props.isShowNewHomework">新建作业</el-button>
+      <el-button color="#597d3b" @click="chooseAssignmentType()" v-if="props.isShowNewHomework">新建作业</el-button>
     </template>
     <template v-if="props.tableData.length > 0">
       <el-table :data="props.tableData" stripe style="width: 100%" height="100%" show-overflow-tooltip>
@@ -32,7 +32,7 @@
         <el-table-column :label="role == 'teachers'? '编辑':'开始'" width="60">
           <template #default="scope">
             <el-button @mouseover="handleMouse('over', scope.row.teacherId, scope.row.endDate)" @mouseleave="handleMouse('leave', scope.row.teacherId, scope.row.endDate)"
-                color="#597d3b" circle @click="handleFunctionButton(scope.row.assignmentId)" :disabled="props.disabled || isDisabled(scope.row.teacherId, scope.row.endDate)">
+                color="#597d3b" circle @click="handleFunctionButton(scope.row.assignmentId,scope.row.type)" :disabled="props.disabled || isDisabled(scope.row.teacherId, scope.row.endDate)">
               <el-icon :size="18">
                 <Edit />
               </el-icon>
@@ -45,124 +45,41 @@
       <div style="text-align: center;">暂无作业</div>
     </template>
   </el-card>
+  
+  <writing-assignment-dialog
+      v-model:writingVisible="writingVisible"
+      :dialogConfig="dialogConfig"
+      :courseId="props.courseId"
+    />
+  <listening-assignment-dialog
+  v-model:listeningVisible="listeningVisible"
+    :dialogConfig="dialogConfig"
+    :courseId="props.courseId"
+  />
 
-  <el-dialog v-model="dialogConfig.visible" :title="dialogConfig.title">
-    <el-form :model="newAssignmentInfo" label-width="auto">
-      <!--      <el-form-item label="课程图片">-->
-      <el-form-item label="作业名称">
-        <el-input v-model="newAssignmentInfo.assignmentName" placeholder="请输入名称"></el-input>
-      </el-form-item>
-      <el-form-item label="作业描述">
-        <el-input v-model="newAssignmentInfo.description" placeholder="请输入描述"></el-input>
-      </el-form-item>
-      <el-form-item label="作业类型">
-        <el-select v-model="newAssignmentInfo.type"  placeholder="请选择作业类型" :disabled="dialogConfig.type === 'edit'">
-          <el-option label="写作" value="写作"></el-option>
-          <el-option label="听力" value="听力"></el-option>
-          <el-option label="口语" value="口语"></el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="开始时间">
-        <el-date-picker v-model="newAssignmentInfo.startTime" type="datetime" placeholder="截止时间" style="width: 180px"/>
-      </el-form-item>
-      <el-form-item label="截止时间">
-        <el-date-picker v-model="newAssignmentInfo.endTime" type="datetime" placeholder="截止时间" style="width: 180px"/>
-      </el-form-item>
-      <el-form-item label="描述文件" v-if="newAssignmentInfo.type=='写作'">
-        <el-upload
-            ref="uploadDescribeRef"
-            action= "/api/file"
-            multiple
-            v-model:file-list="describeFileList"
-            :limit="1"
-            :on-success="handleDescribeSuccess"
-            :on-error="handleDescribeError"
-            :on-exceed="handleDescribeExceed"
-            :on-change="handleDescribeChange"
-            accept=".doc, .docx"
-            :auto-upload="false"
-        >
-          <el-button type="primary">点击上传</el-button>
-          <template #tip>
-            <div class="el-upload__tip">
-              doc/docx 文件不大于 500kb
-            </div>
-          </template>
-        </el-upload>
-      </el-form-item>
-      <el-form-item label="附件" v-if="newAssignmentInfo.type=='写作'">
-        <el-upload
-            ref="uploadPictureRef"
-            action= "/api/file"
-            multiple
-            v-model:file-list="pictureFileList"
-            :limit="1"
-            :on-success="handlePictureSuccess"
-            :on-error="handlePictureError"
-            :on-exceed="handlePictureExceed"
-            :on-change="handlePictureChange"
-            accept=".doc, .docx"
-            :auto-upload="false"
-        >
-          <el-button type="primary">点击上传</el-button>
-          <template #tip>
-            <div class="el-upload__tip">
-              doc/docx 文件不大于 500kb
-            </div>
-          </template>
-        </el-upload>
-      </el-form-item>
-      <AudioUpload
-        v-if="newAssignmentInfo.type=='听力'"
-        :newAssignmentInfo="newAssignmentInfo"
-        :dialog-config="dialogConfig"
-      />
-
-<!--      <el-form-item label="作业图片" v-if="dialogConfig.type == 'edit'">-->
-<!--        <el-upload-->
-<!--            ref="uploadPictureRef"-->
-<!--            drag-->
-<!--            action= "http://127.0.0.1:8080/api/file"-->
-<!--            multiple-->
-<!--            v-model:file-list="pictureFileList"-->
-<!--            :limit="1"-->
-<!--            :on-success="handlePictureSuccess"-->
-<!--            :on-error="handlePictureError"-->
-<!--            :on-exceed="handlePictureExceed"-->
-<!--            :on-change="handlePictureChange"-->
-<!--            list-type="picture-card"-->
-<!--            accept=".png, .jpg"-->
-<!--            :auto-upload="false"-->
-<!--        >-->
-<!--          <el-icon class="el-icon&#45;&#45;upload"><upload-filled /></el-icon>-->
-<!--          <div class="el-upload__text">-->
-<!--            拖拽上传或<em>点击此处上传</em>-->
-<!--          </div>-->
-<!--          <template #tip>-->
-<!--            <div class="el-upload__tip">-->
-<!--              jpg/png 文件不大于 500kb-->
-<!--            </div>-->
-<!--          </template>-->
-<!--        </el-upload>-->
-<!--      </el-form-item>-->
-    </el-form>
-    <template #footer v-if="newAssignmentInfo.type=='写作'">
-      <div class="dialog-footer">
-        <el-button @click="dialogConfig.visible = false; cleanNewAssignmentInfo()">取消</el-button>
-        <el-button type="primary" @click="handleSubmit">确定</el-button>
-      </div>
-    </template>
+     <!-- 作业类型选择弹窗 -->
+     <el-dialog
+    v-model="isTypeDialogVisible"
+    title="选择作业类型"
+  >
+    <el-radio-group v-model="assignmentType">
+      <el-radio label="写作">写作</el-radio>
+      <el-radio label="听力">听力</el-radio>
+      <el-radio label="口语">口语</el-radio>
+    </el-radio-group>
+    <div class="dialog-footer" style="margin-top:40px;margin-left:350px;">
+      <el-button @click="isTypeDialogVisible = false">取消</el-button>
+      <el-button type="primary" @click="createAssignmentDialog()">确定</el-button>
+    </div>
   </el-dialog>
   <ViewsWordEditor :alert="alertProps" :docxInfo="docxInfo"></ViewsWordEditor>
 </template>
 
 
 <script lang="ts" setup>
-import {defineProps, inject, onMounted, reactive, ref} from 'vue';
+import {defineProps, inject, onMounted, reactive, ref,watch} from 'vue';
   import type {AssignmentVO, IAssignmentTableColumn, IAssignmentTableItem} from "@/types/vo";
   import router from "@/router";
-  import type {AssignmentDTO} from "@/types/dto";
-  import useApis from "@/apis";
   import {
   ElMessage,
   ElNotification,
@@ -171,12 +88,12 @@ import {defineProps, inject, onMounted, reactive, ref} from 'vue';
   type UploadProps,
   type UploadUserFile
 } from "element-plus";
-  import AudioUpload from '@/components/AudioUpload.vue'; // 引入组件
-  import {useFormatDate} from "@/hooks/useFormatDate";
   import ViewsWordEditor from "@/components/ViewsWordEditor/ViewsWordEditor.vue";
   import {useStore} from "@/store";
   import {Search, Edit, UploadFilled, Plus} from "@element-plus/icons-vue"
-
+  import ListeningAssignmentDialog from '@/components/AssignmentDialog/ListeningAssignmentDialog.vue';
+  import WritingAssignmentDialog from '@/components/AssignmentDialog/WritingAssignmentDialog.vue';
+  
   const props = defineProps<{
     tableData: IAssignmentTableItem[],
     columns: IAssignmentTableColumn[],
@@ -185,122 +102,49 @@ import {defineProps, inject, onMounted, reactive, ref} from 'vue';
     isShowNewHomework: boolean,
     disabled: boolean;
   }>()
-
-  const apis = useApis()
   const store = useStore()
-  const doRefresh:Function = inject("reload")
-  const {formatDate} = useFormatDate()
-  let uploadDescribeRef = ref()
-  let uploadPictureRef = ref()
+  const writingVisible = ref(false)
+  const listeningVisible = ref(false)
+  const isTypeDialogVisible = ref(false);
+  let assignmentType = ref()
 
-  // 用于编辑课程展示预览图片
-  const describeFileList = ref<UploadUserFile[]>([])
-  const pictureFileList = ref<UploadUserFile[]>([])
-
-  const handleDescribeSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
-    Object.assign(newAssignmentInfo, {
-      assignmentName: newAssignmentInfo.assignmentName,
-      description: newAssignmentInfo.description,
-      type:newAssignmentInfo.type,
-      descriptionFile: response.data,
-      attachments: newAssignmentInfo.attachments == null? ['']:newAssignmentInfo.attachments,
-      startTime: newAssignmentInfo.startTime,
-      endTime: newAssignmentInfo.endTime
-    })
-  }
-  const handlePictureSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
-    newAssignmentInfo.attachments[0] = response.data
-  }
-
-  const handleDescribeError: UploadProps['onError'] = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
-    console.log(error, uploadFile, uploadFiles)
-  }
-  const handlePictureError: UploadProps['onError'] = (error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
-    console.log(error, uploadFile, uploadFiles)
-  }
-
-  const handleDescribeExceed = (files, fileList) => {
-    // console.log(files)
-    uploadDescribeRef.value.clearFiles()  //清空上传文件(限制一个,所以直接清空即可)
-    const file = files[0]
-    uploadDescribeRef.value.handleStart(file)  //重新上传
-  }
-  const handlePictureExceed = (files, fileList) => {
-    // console.log(files)
-    uploadPictureRef.value.clearFiles()  //清空上传文件(限制一个,所以直接清空即可)
-    const file = files[0]
-    uploadPictureRef.value.handleStart(file)  //重新上传
+  const chooseAssignmentType = ()=>{
+    isTypeDialogVisible.value = true;
   }
 
-  //选择文件
-  const handleDescribeChange = (file,fileList) => {
-    // console.log(file)
-    const fileImgType = file.name.match(/\.([^\.]+)$/)[1];  //匹配文件格式(最后一个'.'后的格式)或者匹配file.raw.type
-    const isImageType = ['doc','docx'];
-    const isLt500KB = file.size / 1024  < 500;  //判断图片格式与大小
-    if (isImageType.indexOf(fileImgType)==-1) {
-      ElMessage.error('文件仅支持png、jpg格式')  //限制文件类型
-      uploadDescribeRef.value.clearFiles()  //清空上传文件
-      return false;
-    }
-    if (!isLt500KB) {
-      ElMessage.error('文件不能超过500kb!')  //限制文件大小
-      uploadDescribeRef.value.clearFiles()  //清空上传文件
-      return false;
-    }
-    apis.uploadFile(file.raw)
-        .then((res) => {
-          newAssignmentInfo.descriptionFile = res.data.data
-        })
-        .catch((err) => {
-          console.log(err)
-        })
-  }
-  const handlePictureChange = (file,fileList) => {
-    // console.log(file)
-    const fileImgType = file.name.match(/\.([^\.]+)$/)[1];  //匹配文件格式(最后一个'.'后的格式)或者匹配file.raw.type
-    // const isImageType = ['png','jpg'];
-    const isImageType = ['doc','docx'];
-    const isLt500KB = file.size / 1024  < 500;  //判断图片格式与大小
-    if (isImageType.indexOf(fileImgType)==-1) {
-      ElMessage.error('文件仅支持png、jpg格式')  //限制文件类型
-      uploadDescribeRef.value.clearFiles()  //清空上传文件
-      return false;
-    }
-    if (!isLt500KB) {
-      ElMessage.error('文件不能超过500kb!')  //限制文件大小
-      uploadDescribeRef.value.clearFiles()  //清空上传文件
-      return false;
+  const createAssignmentDialog = ()=>{
+    isTypeDialogVisible.value = false;
+    if(assignmentType.value != ''){
+     changeDialog('add', 0, assignmentType.value)
+     if(assignmentType.value === '写作'){
+        writingVisible.value = true;
+      } else if(assignmentType.value ==='听力'){
+        listeningVisible.value = true;
+      }
     }
-    apis.uploadFile(file.raw)
-        .then((res) => {
-          newAssignmentInfo.attachments[0] = res.data.data
-        })
-        .catch((err) => {
-          console.log(err)
-        })
   }
+ 
 
   const dialogConfig = reactive({
     type: "",
-    visible: false,
     title: "",
-    disable: false
+    disable: false,
+    assignmentId: 0,
   })
-
-  const changeDialog = (type:string)=>{
-    dialogConfig.visible=true;
+  const changeDialog = (type:string, assignmentId: number, assignmentType: string)=>{
     switch (type){
       case "add": {
         dialogConfig.type="add";
+        dialogConfig.title=`新增${assignmentType}作业`;
         dialogConfig.disable=false;
-        dialogConfig.title="新增作业";
+        dialogConfig.assignmentId = assignmentId;
         break;
       }
       case "edit": {
         dialogConfig.type="edit";
+        dialogConfig.title=`编辑${assignmentType}作业`;
         dialogConfig.disable=false;
-        dialogConfig.title="编辑作业";
+        dialogConfig.assignmentId = assignmentId;
         break;
       }
     }
@@ -320,6 +164,7 @@ import {defineProps, inject, onMounted, reactive, ref} from 'vue';
   });
 
 const openEditor = (url: string, title: string) => {
+
   open.value = true;
   Object.assign(alertProps, {
     open: open.value,
@@ -343,41 +188,6 @@ const openEditor = (url: string, title: string) => {
   })
 };
 
-  let newAssignmentInfo = reactive<AssignmentDTO>({
-    assignmentName: '',
-    description: '',
-    type:'',
-    descriptionFile: '',
-    attachments: [''],
-    startTime: '',
-    endTime: ''
-  })
-
-  const cleanNewAssignmentInfo = () => {
-    Object.assign(newAssignmentInfo, {
-      assignmentName: '',
-      description: '',
-      type:'',
-      descriptionFile: '',
-      attachments: [''],
-      startTime: '',
-      endTime: ''
-    })
-  }
-
-  const setNewAssignmentInfo = (assignment: AssignmentVO) => {
-    Object.assign(newAssignmentInfo, {
-      assignmentName: assignment.assignmentName,
-      description: assignment.description,
-      type:assignment.type,
-      descriptionFile: assignment.descriptionFile,
-      attachments: assignment.attachments == null? ['']:assignment.attachments,
-      startTime: assignment.startTime,
-      endTime: assignment.endTime
-    })
-    // console.log("获取作业信息", newAssignmentInfo)
-  }
-
   /*
   鼠标聚焦于功能按钮(写作or编辑)时,显示提示信息
    */
@@ -389,16 +199,8 @@ const openEditor = (url: string, title: string) => {
       if(props.disabled || isDisabled(teacherId, endDate)){
         if(props.role == 'student'){
           ElMessage.error('作业已经超过截止时间')
-          // ElMessage({
-          //   message: '作业已经超过截止时间',
-          //   type: 'message',
-          // })
         }else if(props.role == 'teachers'){
           ElMessage.error('无权限')
-          // ElMessage({
-          //   message: '无权限',
-          //   type: 'message',
-          // })
         }
       }
     } else if(hover && type == 'leave'){
@@ -407,18 +209,16 @@ const openEditor = (url: string, title: string) => {
   }
 
   // 用于记录当前编辑的作业的id
-  let IAssignmentId = ref(0)
-  const handleFunctionButton = (assignmentId:number) => {
+  const handleFunctionButton = (assignmentId:number, type: string) => {
     if(props.role == 'student'){
       handleWriting(assignmentId)
     } else if(props.role == 'teachers'){
-      apis.getAssignmentById(assignmentId)
-          .then((res:any) => {
-            setNewAssignmentInfo(res.data.data)
-            // console.log("功能按钮方法内部",newAssignmentInfo)
-            IAssignmentId.value = res.data.data.assignmentId
-          })
-      changeDialog('edit')
+      changeDialog('edit', assignmentId, type)
+      if(type === '写作'){
+        writingVisible.value = true;
+      } else if(type === '听力'){
+        listeningVisible.value = true;
+      }
     }
   }
 
@@ -428,60 +228,6 @@ const openEditor = (url: string, title: string) => {
   }
 
 
-  const handleSubmit = async () => {
-    // console.log("提交方法最开始",newAssignmentInfo)
-    newAssignmentInfo.endTime = formatDate(newAssignmentInfo.endTime);
-    newAssignmentInfo.startTime = formatDate(newAssignmentInfo.startTime);
-    // console.log("提交方法,请求前",newAssignmentInfo)
-    if(dialogConfig.type === 'add'){
-      apis.createAssignment(props.courseId, newAssignmentInfo)
-          .then((res) => {
-            console.log("新增作业请求内部",newAssignmentInfo)
-            if(res.data.code===200) {
-              ElNotification({
-                title: '新增成功',
-                type: 'success',
-              })
-            }else {
-              ElNotification({
-                title: '新增失败',
-                type: 'error',
-              })
-            }
-            dialogConfig.visible = false
-            // cleanNewAssignmentInfo()
-          })
-          .catch((err) => {
-            console.log(err)
-          })
-    } else if(dialogConfig.type === 'edit'){
-      // console.log("编辑作业请求前一刻",newAssignmentInfo)
-      apis.updateAssignment(IAssignmentId.value, newAssignmentInfo)
-          .then((res:any) => {
-            // console.log("编辑作业请求内部",newAssignmentInfo)
-            if(res.data.code===200) {
-              ElNotification({
-                title: '修改成功',
-                type: 'success',
-              })
-              // console.log("编辑作业请求内部22",newAssignmentInfo)
-              // setTimeout(() => apis.updateAssignment(IAssignmentId.value, newAssignmentInfo), 300)
-              // console.log("编辑作业请求内部33",newAssignmentInfo)
-            }else {
-              ElNotification({
-                title: '修改失败',
-                type: 'error',
-              })
-            }
-            dialogConfig.visible = false
-            // cleanNewAssignmentInfo()
-          })
-          .catch((err) => {
-            console.log(err)
-          })
-    }
-    doRefresh();
-  }
 
   const isDisabled = (teacherId: string, endDate: string) => {
     if(props.role == 'teachers'){// 是教师且不是作业发布人则禁用