|
|
@@ -0,0 +1,230 @@
|
|
|
+<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>
|
|
|
+
|