|
@@ -0,0 +1,2062 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+ id="editPaperApp"
|
|
|
+ v-loading="loading"
|
|
|
+ class="paper"
|
|
|
+ element-loading-text="拼命加载中。。。"
|
|
|
+ >
|
|
|
+ <!-- <ckeditor v-model="examRemark"></ckeditor> -->
|
|
|
+ <div class="edit-paper-top">
|
|
|
+ <div class="edit-paper-top-inline">
|
|
|
+ <div class="paper-top-div">
|
|
|
+ <span class="paper-top-title">课程代码:</span>
|
|
|
+ <span class="paper-top-value">{{ paper.course.code }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="paper-top-div">
|
|
|
+ <span class="paper-top-title">课程名称:</span>
|
|
|
+ <span class="paper-top-value">{{ paper.course.name }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="paper-top-div">
|
|
|
+ <span class="paper-top-title">试卷名称:</span>
|
|
|
+ <el-tooltip class="item" effect="dark" placement="top-start">
|
|
|
+ <div slot="content">{{ paper.name }}</div>
|
|
|
+ <input
|
|
|
+ v-model="paper.name"
|
|
|
+ class="paperName-input font_length"
|
|
|
+ placeholder="试卷名称"
|
|
|
+ />
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+ <div class="paper-top-div">
|
|
|
+ <span class="paper-top-title">试卷难度:</span>
|
|
|
+ <span class="paper-top-value">{{ paper.difficultyDegree }}</span>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" size="small" @click="savePaper">
|
|
|
+ 保存
|
|
|
+ </el-button>
|
|
|
+ <el-button type="danger" size="small" @click="deletePaper(paper.id)">
|
|
|
+ <i class="el-icon-delete"></i> 删除
|
|
|
+ </el-button>
|
|
|
+ <el-dropdown class="button_left">
|
|
|
+ <el-button type="primary" size="small">
|
|
|
+ 更多 <i class="el-icon-arrow-down el-icon--right"></i>
|
|
|
+ </el-button>
|
|
|
+ <el-dropdown-menu slot="dropdown">
|
|
|
+ <el-dropdown-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ :loading="duplicateLoading"
|
|
|
+ size="small"
|
|
|
+ @click="getreduplicateQuestions"
|
|
|
+ ><i class="el-icon-zoom-in"></i>查重
|
|
|
+ </el-button>
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item>
|
|
|
+ <el-button
|
|
|
+ v-show="parentView == 'import_paper'"
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="openDialog"
|
|
|
+ ><i class="el-icon-upload2"></i>上传音频
|
|
|
+ </el-button>
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item>
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ @click="exportPaperAnswer()"
|
|
|
+ ><i class="el-icon-download"></i>导出答案</el-button
|
|
|
+ >
|
|
|
+ </el-dropdown-item>
|
|
|
+ <el-dropdown-item>
|
|
|
+ <el-button
|
|
|
+ v-show="parentView == 'import_paper'"
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="openAnswerDialog"
|
|
|
+ ><i class="el-icon-upload2"></i>导入答案
|
|
|
+ </el-button>
|
|
|
+ </el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </el-dropdown>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ style="margin-left: 10px"
|
|
|
+ @click="back"
|
|
|
+ ><i class="el-icon-arrow-left"></i> 返回</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="paperName">
|
|
|
+ <div>
|
|
|
+ <br />
|
|
|
+ <h3 class="text-center">{{ paper.course.name }} 试卷</h3>
|
|
|
+ <h5 class="text-center">
|
|
|
+ <span v-show="paper.hasAudio">(含音频试卷)</span>
|
|
|
+ </h5>
|
|
|
+ <br />
|
|
|
+ <h4 class="text-center">(课程代码 {{ paper.course.code }})</h4>
|
|
|
+ <br />
|
|
|
+ </div>
|
|
|
+ <div class="text-left">
|
|
|
+ <el-table :data="paper.paperDetails" border style="width: 100%">
|
|
|
+ <el-table-column header-align="center" label="大题名称">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.name }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column header-align="center" label="大题总分">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.score }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column header-align="center" label="小题数量">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.unitCount }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column header-align="center" label="公开数量">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.pubCount }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column header-align="center" label="非公开数量">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.noPubCount }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <div class="mainQues" style="margin-top: 20px; margin-left: 0px">
|
|
|
+ <div class="mainQuesTitle">
|
|
|
+ <span>考试说明:</span>
|
|
|
+ <span>
|
|
|
+ <el-button size="small" @click="openEditExamPaperRemark"
|
|
|
+ >编辑</el-button
|
|
|
+ >
|
|
|
+ </span>
|
|
|
+ <div style="width: 550px; margin-left: 20px; margin-top: 20px">
|
|
|
+ <span v-html="paper.examRemark"></span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- end by wwh -->
|
|
|
+ <div>
|
|
|
+ <h1>本试卷满分{{ paper.totalScore }}分。</h1>
|
|
|
+ </div>
|
|
|
+ <br />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <!-- 循环大题 -->
|
|
|
+ <div
|
|
|
+ v-for="(paperDetail, detailIndex) in paper.paperDetails"
|
|
|
+ v-show="paperDetailShow(paperDetail)"
|
|
|
+ :key="detailIndex"
|
|
|
+ class="mainQues"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="mainQuesTitle"
|
|
|
+ @mouseover="quesMouseOver(paperDetail.id)"
|
|
|
+ @mouseout="quesMouseOut(paperDetail.id)"
|
|
|
+ >
|
|
|
+ <span>{{ paperDetail.cnNum }}</span> <span>.</span>
|
|
|
+ <span>{{ paperDetail.name }}</span>
|
|
|
+ <span>
|
|
|
+ ({{ !paperDetail.title ? "本大题" : paperDetail.title + "," }}共{{
|
|
|
+ paperDetail.unitCount
|
|
|
+ }}小题,满分{{ paperDetail.score }}分)
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <span :id="paperDetail.id" class="btnDiv">
|
|
|
+ <el-button
|
|
|
+ v-show="parentView == 'gen_paper'"
|
|
|
+ size="small"
|
|
|
+ @click="selectQues(paperDetail.id)"
|
|
|
+ >选题
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button size="small" @click="openEditPaperDetail(paperDetail)"
|
|
|
+ >编辑
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-if="showUp(paperDetail)"
|
|
|
+ size="small"
|
|
|
+ @click="movePaperDetail(paperDetail, 'up')"
|
|
|
+ >上移
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-if="showDown(paperDetail)"
|
|
|
+ size="small"
|
|
|
+ @click="movePaperDetail(paperDetail, 'down')"
|
|
|
+ >下移
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="danger"
|
|
|
+ @click="deletePaperDetail(paperDetail.id)"
|
|
|
+ >删除
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-show="showButtons[detailIndex].up"
|
|
|
+ size="small"
|
|
|
+ icon="el-icon-arrow-up"
|
|
|
+ @click.stop="hideContent(detailIndex)"
|
|
|
+ ></el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ v-show="!showButtons[detailIndex].up"
|
|
|
+ size="small"
|
|
|
+ icon="el-icon-arrow-down"
|
|
|
+ @click.stop="showContent(detailIndex)"
|
|
|
+ ></el-button>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 循环小题 -->
|
|
|
+ <div v-show="showQuestions[detailIndex].is_show">
|
|
|
+ <div
|
|
|
+ v-for="(paperDetailUnit, unitIndex) in paperDetail.paperDetailUnits"
|
|
|
+ v-show="quesShow(paperDetailUnit.id)"
|
|
|
+ :key="unitIndex"
|
|
|
+ class="ques"
|
|
|
+ >
|
|
|
+ <reduplicate_mark
|
|
|
+ :id="paperDetailUnit.id"
|
|
|
+ :show="reduplicateMarkShow(paperDetailUnit.id)"
|
|
|
+ :fill-color="reduplicateMarkColor(paperDetailUnit.id)"
|
|
|
+ :checked="reduplicateMarkCheck(paperDetailUnit.id)"
|
|
|
+ @reduplicate_mark_check="reduplicate_mark_check"
|
|
|
+ >
|
|
|
+ </reduplicate_mark>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class="quesSelect"
|
|
|
+ @mouseover="quesMouseOver(paperDetailUnit.id)"
|
|
|
+ @mouseout="quesMouseOut(paperDetailUnit.id)"
|
|
|
+ >
|
|
|
+ <div :id="paperDetailUnit.id" class="btnDiv">
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ @click="editQues(paperDetailUnit, paperDetailUnit.question)"
|
|
|
+ >编辑
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ type="danger"
|
|
|
+ size="small"
|
|
|
+ @click="deleteQues(paperDetailUnit)"
|
|
|
+ >删除
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="quesBody">
|
|
|
+ <span class="ques-title">{{ paperDetailUnit.number }}.</span>
|
|
|
+ <span
|
|
|
+ v-question-audio
|
|
|
+ class="ques-body"
|
|
|
+ :hasAudio="paperDetailUnit.question.hasAudio"
|
|
|
+ :questionId="paperDetailUnit.question.id"
|
|
|
+ v-html="paperDetailUnit.question.quesBody"
|
|
|
+ ></span>
|
|
|
+
|
|
|
+ <span class="score-span">
|
|
|
+ ({{ paperDetailUnit.score }}分)
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-for="(quesOption, optionIndex) in paperDetailUnit.question
|
|
|
+ .quesOptions"
|
|
|
+ :key="optionIndex"
|
|
|
+ class="quesOption"
|
|
|
+ >
|
|
|
+ <span class="ques-title"
|
|
|
+ >{{ optionIndex | optionOrderWordFilter }}.
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <span
|
|
|
+ v-question-audio
|
|
|
+ class="ques-body"
|
|
|
+ :hasAudio="paperDetailUnit.question.hasAudio"
|
|
|
+ :questionId="paperDetailUnit.question.id"
|
|
|
+ v-html="quesOption.optionBody"
|
|
|
+ ></span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <br />
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-for="(subQuestion, subIndex) in paperDetailUnit.question
|
|
|
+ .subQuestions"
|
|
|
+ v-show="quesShow(subQuestion.id)"
|
|
|
+ :key="subIndex"
|
|
|
+ class="subQues"
|
|
|
+ >
|
|
|
+ <reduplicate_mark
|
|
|
+ :show="reduplicateMarkShow(subQuestion.id)"
|
|
|
+ ></reduplicate_mark>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class="quesSelect"
|
|
|
+ @mouseover="
|
|
|
+ quesMouseOver(getSubQuesEditId(paperDetailUnit, subQuestion))
|
|
|
+ "
|
|
|
+ @mouseout="
|
|
|
+ quesMouseOut(getSubQuesEditId(paperDetailUnit, subQuestion))
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ :id="getSubQuesEditId(paperDetailUnit, subQuestion)"
|
|
|
+ class="btnDiv"
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ @click="editQues(paperDetailUnit, subQuestion)"
|
|
|
+ >编辑
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="quesBody">
|
|
|
+ <span class="ques-title"
|
|
|
+ >{{ subQuestion.quesParams.number }}.
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <span v-html="subQuestion.quesBody"></span>
|
|
|
+ <span
|
|
|
+ >({{ paperDetailUnit.subScoreList[subIndex] }}分)</span
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-for="(
|
|
|
+ subQuesOption, subOptIndex
|
|
|
+ ) in subQuestion.quesOptions"
|
|
|
+ :key="subOptIndex"
|
|
|
+ class="quesOption"
|
|
|
+ >
|
|
|
+ <span class="ques-title"
|
|
|
+ >{{ subOptIndex | optionOrderWordFilter }}.
|
|
|
+ </span>
|
|
|
+ <span v-html="subQuesOption.optionBody"></span>
|
|
|
+ </div>
|
|
|
+ <br />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <br />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="text-left">
|
|
|
+ <!-- 编辑大题弹框 -->
|
|
|
+ <el-dialog
|
|
|
+ v-loading.body="detailLoading"
|
|
|
+ width="360px"
|
|
|
+ title="大题名称编辑"
|
|
|
+ element-loading-text="保存中。。。"
|
|
|
+ :visible.sync="paperDatailDialog"
|
|
|
+ @close="closeQuesDialog"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ :model="editpaperDetail"
|
|
|
+ label-position="right"
|
|
|
+ label-width="80px"
|
|
|
+ >
|
|
|
+ <el-row :gutter="10">
|
|
|
+ <el-col :xs="10" :sm="10" :md="10" :lg="10">
|
|
|
+ <el-form-item label="大题名称" placeholder="大题名称">
|
|
|
+ <el-input
|
|
|
+ v-model="editpaperDetail.name"
|
|
|
+ class="dialog_input_width"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="savePaperDatail(editpaperDetail)"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
+ <el-button @click="closePaperDatailDialog()">取消</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </el-dialog>
|
|
|
+ <!-- 编辑试题弹框 -->
|
|
|
+ <el-dialog
|
|
|
+ v-loading.body="dialogLoading"
|
|
|
+ title="试题编辑"
|
|
|
+ element-loading-text="保存中。。。"
|
|
|
+ :visible.sync="quesDialog"
|
|
|
+ @close="closeQuesDialog"
|
|
|
+ >
|
|
|
+ <el-form :model="quesModel" label-position="right" label-width="80px">
|
|
|
+ <el-row :gutter="10">
|
|
|
+ <el-col :xs="10" :sm="10" :md="10" :lg="10">
|
|
|
+ <el-form-item label="题型">
|
|
|
+ <el-select
|
|
|
+ v-model="quesModel.questionType"
|
|
|
+ :disabled="true"
|
|
|
+ placeholder="请输入题型"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in questionTypes"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="10" :sm="10" :md="10" :lg="10">
|
|
|
+ <el-form-item label="分值">
|
|
|
+ <el-input
|
|
|
+ v-model="quesModel.score"
|
|
|
+ placeholder="分值"
|
|
|
+ :disabled="quesModel.questionType == 'NESTED_ANSWER_QUESTION'"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <!-- create by weiwenhai 添加难度,公开度,试题属性 -->
|
|
|
+ <el-row :gutter="10">
|
|
|
+ <el-col :xs="10" :sm="10" :md="10" :lg="10">
|
|
|
+ <el-form-item label="难度">
|
|
|
+ <el-select
|
|
|
+ v-model="quesModel.difficultyDegree"
|
|
|
+ placeholder="请输入难度"
|
|
|
+ :disabled="
|
|
|
+ quesModel.questionType == 'NESTED_ANSWER_QUESTION'
|
|
|
+ ? true
|
|
|
+ : updatePorperty
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in difficultyDegreeList"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :xs="10" :sm="10" :md="10" :lg="10">
|
|
|
+ <el-form-item label="公开度">
|
|
|
+ <el-select
|
|
|
+ v-model="quesModel.publicity"
|
|
|
+ placeholder="请输入公开度"
|
|
|
+ :disabled="updatePorperty"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in publicityList"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col
|
|
|
+ v-if="quesModel.questionType == 'TEXT_ANSWER_QUESTION'"
|
|
|
+ :xs="10"
|
|
|
+ :sm="10"
|
|
|
+ :md="10"
|
|
|
+ :lg="10"
|
|
|
+ >
|
|
|
+ <el-form-item label="作答类型">
|
|
|
+ <el-select
|
|
|
+ v-model="quesModel.answerType"
|
|
|
+ :disabled="updatePorperty"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in answerTypes"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="10">
|
|
|
+ <el-col :xs="20" :sm="20" :md="20" :lg="20">
|
|
|
+ <el-form-item label="属性列表">
|
|
|
+ <el-tooltip
|
|
|
+ v-for="(content, propIndex) in quesModel.quesProperties"
|
|
|
+ :key="propIndex"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <div slot="content">
|
|
|
+ <span v-if="content.firstProperty != null"
|
|
|
+ >一级属性:{{ content.firstProperty.name }}</span
|
|
|
+ ><br />
|
|
|
+ <span v-if="content.secondProperty != null"
|
|
|
+ >二级属性:{{ content.secondProperty.name }}</span
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ <span>
|
|
|
+ <el-tag
|
|
|
+ :key="content.id"
|
|
|
+ style="margin-right: 5px"
|
|
|
+ :closable="!updatePorperty"
|
|
|
+ type="primary"
|
|
|
+ @close="handleClose(content)"
|
|
|
+ >
|
|
|
+ {{ content.coursePropertyName }}
|
|
|
+ </el-tag>
|
|
|
+ </span>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="属性名" label-width="60px">
|
|
|
+ <el-select
|
|
|
+ v-model="coursePropertyName"
|
|
|
+ placeholder="属性名"
|
|
|
+ class="property_with"
|
|
|
+ :disabled="updatePorperty"
|
|
|
+ @change="searchFirst"
|
|
|
+ >
|
|
|
+ <el-option label="请选择" value=""></el-option>
|
|
|
+ <el-option
|
|
|
+ v-for="item in coursePropertyList"
|
|
|
+ :key="item.name"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.name"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="一级" label-width="48px">
|
|
|
+ <el-select
|
|
|
+ v-model="firstPropertyId"
|
|
|
+ placeholder="一级"
|
|
|
+ class="property_with"
|
|
|
+ :disabled="updatePorperty"
|
|
|
+ @change="searchSecond"
|
|
|
+ >
|
|
|
+ <el-option label="请选择" value=""></el-option>
|
|
|
+ <el-option
|
|
|
+ v-for="item in firstPropertyList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="二级" label-width="48px">
|
|
|
+ <el-select
|
|
|
+ v-model="secondPropertyId"
|
|
|
+ placeholder="二级"
|
|
|
+ class="property_with"
|
|
|
+ :disabled="updatePorperty"
|
|
|
+ >
|
|
|
+ <el-option label="请选择" value=""></el-option>
|
|
|
+ <el-option
|
|
|
+ v-for="item in secondPropertyList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ style="margin-left: -50px"
|
|
|
+ :disabled="updatePorperty"
|
|
|
+ @click="insertProperty"
|
|
|
+ ><i class="el-icon-plus"></i>新增属性
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <!-- end by weiwenhai -->
|
|
|
+ <div v-if="paper.paperType != 'IMPORT'">
|
|
|
+ <el-row>
|
|
|
+ <el-col>
|
|
|
+ <el-form-item label="题目">
|
|
|
+ <span v-html="quesModel.quesBody"></span>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ v-for="(quesOption, optIndex) in quesModel.quesOptions"
|
|
|
+ :key="optIndex"
|
|
|
+ ><el-col :span="2">
|
|
|
+ <span>{{ optIndex | optionOrderWordFilter }}</span>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="20">
|
|
|
+ <span v-html="quesOption.optionBody"></span>
|
|
|
+ </el-col>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <el-form-item label="答案">
|
|
|
+ <span v-html="quesModel.quesAnswer"></span>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ <!-- 单选或多选 -->
|
|
|
+ </div>
|
|
|
+ <div v-if="paper.paperType == 'IMPORT'">
|
|
|
+ <el-row>
|
|
|
+ <el-col>
|
|
|
+ <el-form-item label="题目">
|
|
|
+ <ckeditor v-model="quesModel.quesBody"></ckeditor>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-form-item
|
|
|
+ v-for="(quesOption, optIndex) in quesModel.quesOptions"
|
|
|
+ :key="optIndex"
|
|
|
+ >
|
|
|
+ <el-col :span="2">
|
|
|
+ <el-radio
|
|
|
+ v-if="quesModel.questionType === 'SINGLE_ANSWER_QUESTION'"
|
|
|
+ v-model="singleRightAnswer"
|
|
|
+ :label="optIndex | optionOrderWordFilter"
|
|
|
+ ></el-radio>
|
|
|
+ <el-checkbox
|
|
|
+ v-if="quesModel.questionType === 'MULTIPLE_ANSWER_QUESTION'"
|
|
|
+ v-model="multipleRightAnswer"
|
|
|
+ :label="optIndex | optionOrderWordFilter"
|
|
|
+ ></el-checkbox>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="20">
|
|
|
+ <ckeditor v-model="quesOption.optionBody"></ckeditor>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="2">
|
|
|
+ <i
|
|
|
+ class="el-icon-delete"
|
|
|
+ title="删除"
|
|
|
+ @click.prevent="removeQuesOption(quesOption)"
|
|
|
+ ></i>
|
|
|
+ </el-col>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-if="
|
|
|
+ quesModel.questionType != 'NESTED_ANSWER_QUESTION' &&
|
|
|
+ quesModel.questionType != 'SINGLE_ANSWER_QUESTION' &&
|
|
|
+ quesModel.questionType != 'MULTIPLE_ANSWER_QUESTION' &&
|
|
|
+ quesModel.questionType != 'BOOL_ANSWER_QUESTION'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <el-form-item label="答案">
|
|
|
+ <ckeditor v-model="quesModel.quesAnswer"></ckeditor>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ <!-- 单选或多选 -->
|
|
|
+ <div
|
|
|
+ v-if="
|
|
|
+ quesModel.questionType == 'SINGLE_ANSWER_QUESTION' ||
|
|
|
+ quesModel.questionType == 'MULTIPLE_ANSWER_QUESTION'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <el-form-item label="答案">
|
|
|
+ <span v-html="answer"></span>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ <div v-if="quesModel.questionType == 'BOOL_ANSWER_QUESTION'">
|
|
|
+ <el-row>
|
|
|
+ <el-col>
|
|
|
+ <el-form-item label="答案" prop="quesAnswer">
|
|
|
+ <el-select
|
|
|
+ v-model="quesModel.quesAnswer"
|
|
|
+ placeholder="请选择"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="op in options"
|
|
|
+ :key="op"
|
|
|
+ :label="op"
|
|
|
+ :value="op"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ :class="{
|
|
|
+ margin_left_30:
|
|
|
+ paper.paperType == 'IMPORT' &&
|
|
|
+ (quesModel.questionType == 'SINGLE_ANSWER_QUESTION' ||
|
|
|
+ quesModel.questionType == 'MULTIPLE_ANSWER_QUESTION'),
|
|
|
+ margin_left_40: !(
|
|
|
+ paper.paperType == 'IMPORT' &&
|
|
|
+ (quesModel.questionType == 'SINGLE_ANSWER_QUESTION' ||
|
|
|
+ quesModel.questionType == 'MULTIPLE_ANSWER_QUESTION')
|
|
|
+ ),
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="
|
|
|
+ paper.paperType == 'IMPORT' &&
|
|
|
+ (quesModel.questionType == 'SINGLE_ANSWER_QUESTION' ||
|
|
|
+ quesModel.questionType == 'MULTIPLE_ANSWER_QUESTION')
|
|
|
+ "
|
|
|
+ type="primary"
|
|
|
+ @click="addQuesOption"
|
|
|
+ ><i class="el-icon-plus"></i> 新增选项
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" @click="savePaperDetailUnit()"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
+ <el-button @click="closeQuesDialog">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </el-dialog>
|
|
|
+ <!-- 考试说明弹框 -->
|
|
|
+ <el-dialog title="考试说明编辑" :visible.sync="paperRemarkDialog">
|
|
|
+ <el-form label-position="right" label-width="80px">
|
|
|
+ <el-row :gutter="10">
|
|
|
+ <el-col :xs="10" :sm="10" :md="10" :lg="10">
|
|
|
+ <el-form-item label="考试说明">
|
|
|
+ <div style="width: 550px">
|
|
|
+ <ckeditor
|
|
|
+ v-model="examRemark"
|
|
|
+ :display="display"
|
|
|
+ :width="wValue"
|
|
|
+ :height="hValue"
|
|
|
+ ></ckeditor>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <div style="margin-top: 20px; margin-left: 40%">
|
|
|
+ <el-button type="primary" @click="savePaperRemark">保存</el-button>
|
|
|
+ <el-button @click="closPaperRemark">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </el-dialog>
|
|
|
+ <!-- 上传音频弹框 -->
|
|
|
+ <el-dialog
|
|
|
+ title="上传音频文件"
|
|
|
+ :visible.sync="dialogRadioFile"
|
|
|
+ :before-close="closeAudioDialog"
|
|
|
+ >
|
|
|
+ <form
|
|
|
+ id="radioForm"
|
|
|
+ method="post"
|
|
|
+ action=""
|
|
|
+ enctype="multipart/form-data"
|
|
|
+ >
|
|
|
+ <input
|
|
|
+ id="radioFile"
|
|
|
+ name="files"
|
|
|
+ type="file"
|
|
|
+ value="上传音频文件"
|
|
|
+ webkitdirectory
|
|
|
+ />
|
|
|
+ <el-button type="warning" @click="checkFile">检查文件名</el-button>
|
|
|
+ <el-button
|
|
|
+ type="info"
|
|
|
+ :loading="uploadAudioLoading"
|
|
|
+ :disabled="isUpload || uploadAudioLoading"
|
|
|
+ @click="uploadAudioFile"
|
|
|
+ >
|
|
|
+ <span v-show="!uploadAudioLoading">开始上传</span>
|
|
|
+ <span v-show="uploadAudioLoading">正在上传中...</span>
|
|
|
+ </el-button>
|
|
|
+ </form>
|
|
|
+ <div v-if="checkResult" style="margin-top: 20px">
|
|
|
+ <span>检查结果:</span><br /><br />
|
|
|
+ <span v-show="message == 'OK!'" style="color: #13ce66">OK!</span>
|
|
|
+ <span v-show="message != 'OK!'" style="color: #ff4949">{{
|
|
|
+ message
|
|
|
+ }}</span>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ <el-dialog
|
|
|
+ title="上传答案文件"
|
|
|
+ :visible.sync="dialogAnswerFile"
|
|
|
+ :before-close="closeAnswerDialog"
|
|
|
+ >
|
|
|
+ <form
|
|
|
+ id="answerForm"
|
|
|
+ method="post"
|
|
|
+ action=""
|
|
|
+ enctype="multipart/form-data"
|
|
|
+ >
|
|
|
+ <input
|
|
|
+ id="answerFile"
|
|
|
+ name="answerFiles"
|
|
|
+ type="file"
|
|
|
+ value="上传答案文件"
|
|
|
+ accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
|
+ />
|
|
|
+ <el-button type="info" @click="downAnswerTemplate">
|
|
|
+ <span>下载模板</span>
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ type="info"
|
|
|
+ :loading="uploadAnswerLoading"
|
|
|
+ :disabled="uploadAnswerLoading"
|
|
|
+ @click="uploadAnswerFile"
|
|
|
+ >
|
|
|
+ <span v-show="!uploadAnswerLoading">开始上传</span>
|
|
|
+ <span v-show="uploadAnswerLoading">正在上传中...</span>
|
|
|
+ </el-button>
|
|
|
+ </form>
|
|
|
+ <div style="margin-top: 20px">
|
|
|
+ <span v-show="answerMessage != ''" style="color: #ff4949">{{
|
|
|
+ answerMessage
|
|
|
+ }}</span>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { QUESTION_API } from "@/constants/constants";
|
|
|
+import { isEmptyStr, QUESTION_TYPES } from "../constants/constants";
|
|
|
+import { mapState } from "vuex";
|
|
|
+import reduplicate_mark from "../component/reduplicate_mark.vue";
|
|
|
+import randomColor from "randomcolor";
|
|
|
+import ckeditor from "../component/ckeditor.vue";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "EditPaperApp",
|
|
|
+ components: {
|
|
|
+ reduplicate_mark,
|
|
|
+ ckeditor,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ hValue: "100px",
|
|
|
+ wValue: "500px",
|
|
|
+ display: "block",
|
|
|
+ uploadAction: "",
|
|
|
+ fileList: [],
|
|
|
+ answerFileList: [],
|
|
|
+ paperId: "",
|
|
|
+ paperDetailId: "",
|
|
|
+ editPaperDetailUnit: "",
|
|
|
+ quesDialog: false,
|
|
|
+ paperDatailDialog: false,
|
|
|
+ paperRemarkDialog: false,
|
|
|
+ parentView: "",
|
|
|
+ paper: {
|
|
|
+ course: {
|
|
|
+ code: "",
|
|
|
+ name: "",
|
|
|
+ },
|
|
|
+ examRemark: "",
|
|
|
+ },
|
|
|
+ loading: false,
|
|
|
+ dialogLoading: false,
|
|
|
+ detailLoading: false,
|
|
|
+ uploadAudioLoading: false,
|
|
|
+ uploadAnswerLoading: false,
|
|
|
+ questionTypes: QUESTION_TYPES,
|
|
|
+ questionType: "",
|
|
|
+ quesModel: { quesProperties: [] },
|
|
|
+ editpaperDetail: {},
|
|
|
+ reduplicateQuestions: [],
|
|
|
+ reduplicateGroup: [],
|
|
|
+ reduplicateQuesColor: [],
|
|
|
+ singleRightAnswer: "", //接收单选答案
|
|
|
+ multipleRightAnswer: [], //接收多选答案
|
|
|
+ options: ["正确", "错误"],
|
|
|
+ duplicateLoading: false,
|
|
|
+ dialogRadioFile: false,
|
|
|
+ dialogAnswerFile: false,
|
|
|
+ isUpload: true,
|
|
|
+ isUploadAnswer: true,
|
|
|
+ message: "",
|
|
|
+ answerMessage: "",
|
|
|
+ checkResult: false,
|
|
|
+ checkResultAnswer: false,
|
|
|
+ fileNameList: [],
|
|
|
+ defaultColor: [
|
|
|
+ "Red",
|
|
|
+ "Blue",
|
|
|
+ "LimeGreen",
|
|
|
+ "GoldenRod",
|
|
|
+ "Black",
|
|
|
+ "BlueViolet",
|
|
|
+ "Chocolate",
|
|
|
+ "DarkCyan",
|
|
|
+ "HotPink",
|
|
|
+ "Orange",
|
|
|
+ "IndianRed",
|
|
|
+ "Indigo",
|
|
|
+ "Green",
|
|
|
+ "Aqua",
|
|
|
+ "CadetBlue",
|
|
|
+ "SkyBlue",
|
|
|
+ "SlateBlue",
|
|
|
+ "SlateGray",
|
|
|
+ "Tomato",
|
|
|
+ "VioletRed",
|
|
|
+ ],
|
|
|
+ difficultyDegreeList: [
|
|
|
+ { label: 0.1, value: 0.1 },
|
|
|
+ { label: 0.2, value: 0.2 },
|
|
|
+ { label: 0.3, value: 0.3 },
|
|
|
+ { label: 0.4, value: 0.4 },
|
|
|
+ { label: 0.5, value: 0.5 },
|
|
|
+ { label: 0.6, value: 0.6 },
|
|
|
+ { label: 0.7, value: 0.7 },
|
|
|
+ { label: 0.8, value: 0.8 },
|
|
|
+ { label: 0.9, value: 0.9 },
|
|
|
+ { label: 1.0, value: 1.0 },
|
|
|
+ ],
|
|
|
+ publicityList: [
|
|
|
+ { label: "公开", value: true },
|
|
|
+ { label: "非公开", value: false },
|
|
|
+ ],
|
|
|
+ answerTypes: [
|
|
|
+ { label: "文本", value: "DIVERSIFIED_TEXT" },
|
|
|
+ { label: "音频", value: "SINGLE_AUDIO" },
|
|
|
+ ],
|
|
|
+ coursePropertyList: [],
|
|
|
+ coursePropertyName: "", //课程属性名
|
|
|
+ firstPropertyList: [], //一级属性集合
|
|
|
+ firstPropertyId: "", //一级属性id
|
|
|
+ secondPropertyList: [], //二级属性集合
|
|
|
+ secondPropertyId: "", //二级属性id
|
|
|
+ examRemark: "",
|
|
|
+ showQuestions: [],
|
|
|
+ showButtons: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState({
|
|
|
+ user: (state) => state.user,
|
|
|
+ }),
|
|
|
+ updatePorperty() {
|
|
|
+ if (this.parentView === "gen_paper") {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ answer() {
|
|
|
+ if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
|
|
|
+ return this.singleRightAnswer;
|
|
|
+ } else if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
|
|
|
+ var obj = this.multipleRightAnswer;
|
|
|
+ return obj.sort().toString();
|
|
|
+ }
|
|
|
+ return this.quesModel.quesAnswer;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ // $("body").attr("style", "");
|
|
|
+ document.getElementsByTagName("body")[0].style = "";
|
|
|
+ this.paperId = this.$route.params.id;
|
|
|
+ this.parentView = this.$route.params.parentView;
|
|
|
+ this.initPaper();
|
|
|
+ this.getreduplicateQuestions();
|
|
|
+ this.uploadAction = QUESTION_API + "/uploadRadio/" + this.paperId;
|
|
|
+ this.uploadHeaders = {
|
|
|
+ key: this.user.key,
|
|
|
+ token: this.user.token,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ movePaperDetail(detail, vector) {
|
|
|
+ let vectorStr = vector == "up" ? "上移" : "下移";
|
|
|
+ this.$alert("您确定" + vectorStr + "吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ callback: (action) => {
|
|
|
+ if (action == "confirm") {
|
|
|
+ this.loading = true;
|
|
|
+ this.$http
|
|
|
+ .put(
|
|
|
+ QUESTION_API +
|
|
|
+ "/paperDetail/" +
|
|
|
+ this.paperId +
|
|
|
+ "/" +
|
|
|
+ detail.id +
|
|
|
+ "/" +
|
|
|
+ vector
|
|
|
+ )
|
|
|
+ .then(() => {
|
|
|
+ this.initPaper();
|
|
|
+ this.loading = true;
|
|
|
+ this.$notify({
|
|
|
+ message: vectorStr + "成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ showUp(detail) {
|
|
|
+ if (this.paper.paperDetails.length <= 1) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (detail.id != this.paper.paperDetails[0].id) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ showDown(detail) {
|
|
|
+ if (this.paper.paperDetails.length <= 1) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ detail.id !=
|
|
|
+ this.paper.paperDetails[this.paper.paperDetails.length - 1].id
|
|
|
+ ) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ downAnswerTemplate() {
|
|
|
+ var key = this.user.key;
|
|
|
+ var token = this.user.token;
|
|
|
+ window.open(
|
|
|
+ QUESTION_API + "/paper/answer/template?$key=" + key + "&$token=" + token
|
|
|
+ );
|
|
|
+ },
|
|
|
+ openAnswerDialog() {
|
|
|
+ this.checkResultAnswer = false;
|
|
|
+ this.isUploadAnswer = true;
|
|
|
+ if (document.getElementById("answerFile")) {
|
|
|
+ document.getElementById("answerFile").value = "";
|
|
|
+ }
|
|
|
+ this.dialogAnswerFile = true;
|
|
|
+ this.answerFileList = [];
|
|
|
+ },
|
|
|
+
|
|
|
+ closeAnswerDialog() {
|
|
|
+ this.answerMessage = "";
|
|
|
+ this.dialogAnswerFile = this.uploadAnswerLoading;
|
|
|
+ },
|
|
|
+ uploadAnswerFile() {
|
|
|
+ this.answerMessage = "";
|
|
|
+ var fileList = document.getElementById("answerFile").files;
|
|
|
+ if (fileList.length == 0) {
|
|
|
+ this.answerMessage = "请选择文件!";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let param = new FormData();
|
|
|
+ //循环添加到formData中
|
|
|
+ for (var i = 0; i < fileList.length; i++) {
|
|
|
+ var file = fileList[i];
|
|
|
+ param.append("dataFile", file, file.name);
|
|
|
+ }
|
|
|
+ let config = {
|
|
|
+ headers: { "Content-Type": "multipart/form-data" },
|
|
|
+ };
|
|
|
+ this.uploadAnswerLoading = true;
|
|
|
+ this.$http
|
|
|
+ .post(
|
|
|
+ QUESTION_API + "/paper/answer/import/" + this.paperId,
|
|
|
+ param,
|
|
|
+ config
|
|
|
+ )
|
|
|
+ .then(() => {
|
|
|
+ this.dialogAnswerFile = false;
|
|
|
+ this.uploadAnswerLoading = false;
|
|
|
+ this.checkResultAnswer = false;
|
|
|
+ this.isUploadAnswer = true;
|
|
|
+ document.getElementById("answerFile").value = "";
|
|
|
+ this.initPaper();
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ this.answerMessage = error.response.data.desc;
|
|
|
+ document.getElementById("answerFile").value = "";
|
|
|
+ this.uploadAnswerLoading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //隐藏大题下的所有小题
|
|
|
+ hideContent(index) {
|
|
|
+ console.log("up");
|
|
|
+ this.showQuestions[index].is_show = false;
|
|
|
+ this.showButtons[index].up = false;
|
|
|
+ },
|
|
|
+ //展开大题下所有小题
|
|
|
+ showContent(index) {
|
|
|
+ console.log("down");
|
|
|
+ this.showQuestions[index].is_show = true;
|
|
|
+ this.showButtons[index].up = true;
|
|
|
+ },
|
|
|
+ quesMouseOver(index) {
|
|
|
+ document.getElementById(index).style.visibility = "visible";
|
|
|
+ },
|
|
|
+ quesMouseOut(index) {
|
|
|
+ document.getElementById(index).style.visibility = "hidden";
|
|
|
+ },
|
|
|
+ selectQues(id) {
|
|
|
+ this.paperDetailId = id;
|
|
|
+ var courseCode = this.paper.course.code;
|
|
|
+ var courseName = this.paper.course.name;
|
|
|
+ this.$router.push({
|
|
|
+ path:
|
|
|
+ "/select_question/" +
|
|
|
+ this.paper.id +
|
|
|
+ "/" +
|
|
|
+ courseCode +
|
|
|
+ "/" +
|
|
|
+ encodeURIComponent(courseName) +
|
|
|
+ "/" +
|
|
|
+ this.paperDetailId +
|
|
|
+ "/" +
|
|
|
+ this.parentView,
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //打开编辑大题题目弹窗
|
|
|
+ openEditPaperDetail(paperDetail) {
|
|
|
+ this.paperDatailDialog = true;
|
|
|
+ this.editpaperDetail = Object.assign({}, paperDetail); //浅拷贝
|
|
|
+ },
|
|
|
+ //关闭编辑大题题目弹窗
|
|
|
+ closePaperDatailDialog() {
|
|
|
+ this.paperDatailDialog = false;
|
|
|
+ this.editpaperDetail = {};
|
|
|
+ },
|
|
|
+ //保存大题题目信息
|
|
|
+ savePaperDatail(editpaperDetail) {
|
|
|
+ this.detailLoading = true;
|
|
|
+ var paperId = this.paper.id;
|
|
|
+ this.$http
|
|
|
+ .post(QUESTION_API + "/updatePaperDetail/" + paperId, editpaperDetail)
|
|
|
+ .then(() => {
|
|
|
+ this.$notify({
|
|
|
+ message: "保存成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.detailLoading = false;
|
|
|
+ this.closePaperDatailDialog();
|
|
|
+ this.initPaper();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //初始化试卷
|
|
|
+ initPaper() {
|
|
|
+ const scrollPosition =
|
|
|
+ document.documentElement.scrollTop || document.body.scrollTop;
|
|
|
+ this.loading = true;
|
|
|
+ this.paper = {
|
|
|
+ course: {
|
|
|
+ code: "",
|
|
|
+ name: "",
|
|
|
+ },
|
|
|
+ };
|
|
|
+ this.$http
|
|
|
+ .get(QUESTION_API + "/paper/" + this.paperId)
|
|
|
+ .then((response) => {
|
|
|
+ this.paper = response.data;
|
|
|
+ //查询所有课程属性名
|
|
|
+ this.initCourseProperty(this.paper.course.code);
|
|
|
+ //将所有小题分为公开和非公开
|
|
|
+ if (this.paper.paperDetails && this.paper.paperDetails.length > 0) {
|
|
|
+ for (let paperDetil of this.paper.paperDetails) {
|
|
|
+ this.showQuestions.push({ is_show: true });
|
|
|
+ this.showButtons.push({ up: true });
|
|
|
+ paperDetil.pubCount = 0;
|
|
|
+ paperDetil.noPubCount = 0;
|
|
|
+ if (
|
|
|
+ paperDetil.paperDetailUnits &&
|
|
|
+ paperDetil.paperDetailUnits.length > 0
|
|
|
+ ) {
|
|
|
+ for (let paperDetilUt of paperDetil.paperDetailUnits) {
|
|
|
+ if (
|
|
|
+ paperDetilUt.question.questionType !=
|
|
|
+ "NESTED_ANSWER_QUESTION"
|
|
|
+ ) {
|
|
|
+ //非套题
|
|
|
+ if (paperDetilUt.question.publicity) {
|
|
|
+ paperDetil.pubCount = paperDetil.pubCount + 1;
|
|
|
+ } else {
|
|
|
+ paperDetil.noPubCount = paperDetil.noPubCount + 1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //循环所有子题
|
|
|
+ for (let ques of paperDetilUt.question.subQuestions) {
|
|
|
+ if (ques.publicity) {
|
|
|
+ paperDetil.pubCount = paperDetil.pubCount + 1;
|
|
|
+ } else {
|
|
|
+ paperDetil.noPubCount = paperDetil.noPubCount + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ document.documentElement.scrollTop = document.body.scrollTop = scrollPosition;
|
|
|
+ console.log(scrollPosition);
|
|
|
+ }, 1000);
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //查询所有课程属性名
|
|
|
+ initCourseProperty(courseCode) {
|
|
|
+ this.$http
|
|
|
+ .get(QUESTION_API + "/courseProperty/enable/" + courseCode)
|
|
|
+ .then((response) => {
|
|
|
+ this.coursePropertyList = response.data;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //删除大题
|
|
|
+ deletePaperDetail(paperDetailsId) {
|
|
|
+ //先判断大题下面是否还有小题
|
|
|
+ var count = 0;
|
|
|
+ for (var i = 0, imax = this.paper.paperDetails.length; i < imax; i++) {
|
|
|
+ if (paperDetailsId == this.paper.paperDetails[i].id) {
|
|
|
+ if (this.paper.paperDetails[i].paperDetailUnits) {
|
|
|
+ count += this.paper.paperDetails[i].paperDetailUnits.length;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (count == 0) {
|
|
|
+ this.$alert("您确定删除吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ callback: (action) => {
|
|
|
+ if (action == "confirm") {
|
|
|
+ this.loading = true;
|
|
|
+ this.$http
|
|
|
+ .delete(
|
|
|
+ QUESTION_API +
|
|
|
+ "/paperDetail/" +
|
|
|
+ this.paperId +
|
|
|
+ "/" +
|
|
|
+ paperDetailsId
|
|
|
+ )
|
|
|
+ .then(() => {
|
|
|
+ this.initPaper();
|
|
|
+ this.loading = true;
|
|
|
+ this.$notify({
|
|
|
+ message: "删除成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$alert("大题下还有小题,不可删除!", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ callback: () => {},
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ quesShow(id) {
|
|
|
+ if (this.reduplicateGroup.length < 1) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ for (var i = 0, imax = this.reduplicateGroup.length; i < imax; i++) {
|
|
|
+ if (id == this.reduplicateGroup[i]) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ reduplicateMarkShow(id) {
|
|
|
+ var found = false;
|
|
|
+ for (var i = 0, imax = this.reduplicateQuestions.length; i < imax; i++) {
|
|
|
+ for (
|
|
|
+ var j = 0, jmax = this.reduplicateQuestions[i].length;
|
|
|
+ j < jmax;
|
|
|
+ j++
|
|
|
+ ) {
|
|
|
+ if (this.reduplicateQuestions[i][j] == id) {
|
|
|
+ found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (found) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return found;
|
|
|
+ },
|
|
|
+ reduplicateMarkColor(id) {
|
|
|
+ for (var i = 0, imax = this.reduplicateQuestions.length; i < imax; i++) {
|
|
|
+ for (
|
|
|
+ var j = 0, jmax = this.reduplicateQuestions[i].length;
|
|
|
+ j < jmax;
|
|
|
+ j++
|
|
|
+ ) {
|
|
|
+ if (this.reduplicateQuestions[i][j] == id) {
|
|
|
+ return this.reduplicateQuesColor[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ reduplicateMarkCheck(id) {
|
|
|
+ for (var i = 0, imax = this.reduplicateGroup.length; i < imax; i++) {
|
|
|
+ if (id == this.reduplicateGroup[i]) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ reduplicate_mark_check(id, checked) {
|
|
|
+ console.log(checked);
|
|
|
+ console.log(this.reduplicateQuestions);
|
|
|
+ console.log(id);
|
|
|
+ if (!checked) {
|
|
|
+ for (
|
|
|
+ var i = 0, imax = this.reduplicateQuestions.length;
|
|
|
+ i < imax;
|
|
|
+ i++
|
|
|
+ ) {
|
|
|
+ for (
|
|
|
+ var j = 0, jmax = this.reduplicateQuestions[i].length;
|
|
|
+ j < jmax;
|
|
|
+ j++
|
|
|
+ ) {
|
|
|
+ if (this.reduplicateQuestions[i][j] == id) {
|
|
|
+ this.reduplicateGroup = [];
|
|
|
+ for (
|
|
|
+ var k = 0, kmax = this.reduplicateQuestions[i].length;
|
|
|
+ k < kmax;
|
|
|
+ k++
|
|
|
+ ) {
|
|
|
+ this.reduplicateGroup.push(this.reduplicateQuestions[i][k]);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.reduplicateGroup = [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //编辑题目
|
|
|
+ editQues(paperDetailUnit, question) {
|
|
|
+ console.log("question:", question);
|
|
|
+ this.coursePropertyName = "";
|
|
|
+ this.firstPropertyId = "";
|
|
|
+ this.secondPropertyId = "";
|
|
|
+ this.editPaperDetailUnit = paperDetailUnit;
|
|
|
+ this.quesModel = JSON.parse(JSON.stringify(question)); //深拷贝
|
|
|
+ this.quesModel.score = paperDetailUnit.score;
|
|
|
+ //如果是套题下面的小题编辑 ( paperDetailUnit的类型是套题,question的类型不是套题)
|
|
|
+ if (
|
|
|
+ paperDetailUnit.questionType == "NESTED_ANSWER_QUESTION" &&
|
|
|
+ question.questionType != "NESTED_ANSWER_QUESTION"
|
|
|
+ ) {
|
|
|
+ for (var i = 0; i < paperDetailUnit.question.subQuestions.length; i++) {
|
|
|
+ if (
|
|
|
+ paperDetailUnit.question.subQuestions[i].id == this.quesModel.id
|
|
|
+ ) {
|
|
|
+ this.quesModel.score = paperDetailUnit.subScoreList[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isEmptyStr(this.quesModel.answerType)) {
|
|
|
+ this.quesModel.answerType = "DIVERSIFIED_TEXT";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.quesModel.questionType == "FILL_BLANK_QUESTION") {
|
|
|
+ this.quesModel.quesBody = this.quesModel.quesBody.replace(
|
|
|
+ /______/g,
|
|
|
+ "###"
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ this.assignAnswers(); //给singleRightAnswer或multipleRightAnswer赋值
|
|
|
+ this.openQuesDialog();
|
|
|
+ },
|
|
|
+ //给singleRightAnswer和multipleRightAnswer赋值
|
|
|
+ assignAnswers() {
|
|
|
+ if (this.quesModel.quesOptions && this.quesModel.quesOptions.length > 0) {
|
|
|
+ this.singleRightAnswer = "";
|
|
|
+ this.multipleRightAnswer = [];
|
|
|
+ for (let i = 0; i < this.quesModel.quesOptions.length; i++) {
|
|
|
+ let option = this.quesModel.quesOptions[i];
|
|
|
+ if (
|
|
|
+ this.quesModel.questionType == "SINGLE_ANSWER_QUESTION" &&
|
|
|
+ option.isCorrect == 1
|
|
|
+ ) {
|
|
|
+ this.singleRightAnswer = String.fromCharCode(65 + i);
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION" &&
|
|
|
+ option.isCorrect == 1
|
|
|
+ ) {
|
|
|
+ this.multipleRightAnswer.push(String.fromCharCode(65 + i));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //打开修改试题编辑框
|
|
|
+ openQuesDialog() {
|
|
|
+ this.quesDialog = true;
|
|
|
+ },
|
|
|
+ //关闭试题编辑框
|
|
|
+ closeQuesDialog() {
|
|
|
+ this.quesDialog = false;
|
|
|
+ this.quesModel = {};
|
|
|
+ },
|
|
|
+ //删除属性
|
|
|
+ handleClose(tag) {
|
|
|
+ this.quesModel.quesProperties.splice(
|
|
|
+ this.quesModel.quesProperties.indexOf(tag),
|
|
|
+ 1
|
|
|
+ );
|
|
|
+ },
|
|
|
+ //查询一级属性
|
|
|
+ searchFirst() {
|
|
|
+ this.firstPropertyId = "";
|
|
|
+ this.secondPropertyId = "";
|
|
|
+ this.secondPropertyList = [];
|
|
|
+ if (this.coursePropertyName) {
|
|
|
+ for (let courseProperty of this.coursePropertyList) {
|
|
|
+ if (courseProperty.name == this.coursePropertyName) {
|
|
|
+ this.$http
|
|
|
+ .get(QUESTION_API + "/property/first/" + courseProperty.id)
|
|
|
+ .then((response) => {
|
|
|
+ this.firstPropertyList = response.data;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //查询二级属性
|
|
|
+ searchSecond() {
|
|
|
+ this.secondPropertyId = "";
|
|
|
+ if (this.firstPropertyId) {
|
|
|
+ this.$http
|
|
|
+ .get(QUESTION_API + "/property/second/" + this.firstPropertyId)
|
|
|
+ .then((response) => {
|
|
|
+ this.secondPropertyList = response.data;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //新增属性
|
|
|
+ insertProperty() {
|
|
|
+ if (!this.checkInsertPro()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ var quesProperty = {
|
|
|
+ id: "",
|
|
|
+ coursePropertyName: "",
|
|
|
+ firstProperty: {},
|
|
|
+ secondProperty: {},
|
|
|
+ };
|
|
|
+ if (
|
|
|
+ this.quesModel.quesProperties == null ||
|
|
|
+ this.quesModel.quesProperties.length == 0
|
|
|
+ ) {
|
|
|
+ this.quesModel.quesProperties = [];
|
|
|
+ }
|
|
|
+ if (this.secondPropertyId) {
|
|
|
+ quesProperty.id =
|
|
|
+ this.coursePropertyName +
|
|
|
+ "-" +
|
|
|
+ this.firstPropertyId +
|
|
|
+ "-" +
|
|
|
+ this.secondPropertyId;
|
|
|
+ } else {
|
|
|
+ quesProperty.id = this.coursePropertyName + "-" + this.firstPropertyId;
|
|
|
+ }
|
|
|
+ for (let quesPro of this.quesModel.quesProperties) {
|
|
|
+ if (quesPro.id == quesProperty.id) {
|
|
|
+ this.$notify({
|
|
|
+ message: "该属性已存在,请重新选择",
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ quesProperty.coursePropertyName = this.coursePropertyName;
|
|
|
+ //取到一级属性对象
|
|
|
+ for (let property of this.firstPropertyList) {
|
|
|
+ if (property.id == this.firstPropertyId) {
|
|
|
+ quesProperty.firstProperty = property;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //判断是否有二级属性
|
|
|
+ if (
|
|
|
+ this.secondPropertyList != undefined &&
|
|
|
+ this.secondPropertyList.length > 0
|
|
|
+ ) {
|
|
|
+ if (!this.secondPropertyId) {
|
|
|
+ this.$notify({
|
|
|
+ message: "请选择二级属性",
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //取到二级属性对象
|
|
|
+ for (let property of this.secondPropertyList) {
|
|
|
+ if (property.id == this.secondPropertyId) {
|
|
|
+ quesProperty.secondProperty = property;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.quesModel.quesProperties.push(quesProperty);
|
|
|
+ this.quesModel = Object.assign({}, this.quesModel);
|
|
|
+ //清空下拉框
|
|
|
+ this.coursePropertyName = "";
|
|
|
+ this.firstPropertyId = "";
|
|
|
+ this.secondPropertyId = "";
|
|
|
+ this.firstPropertyList = [];
|
|
|
+ this.secondPropertyList = [];
|
|
|
+ },
|
|
|
+ //新增属性验证
|
|
|
+ checkInsertPro() {
|
|
|
+ if (!this.coursePropertyName) {
|
|
|
+ this.$notify({
|
|
|
+ message: "请选择属性",
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!this.firstPropertyId) {
|
|
|
+ this.$notify({
|
|
|
+ message: "请选择一级属性",
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ //删除选项
|
|
|
+ removeQuesOption(option) {
|
|
|
+ this.singleRightAnswer = "";
|
|
|
+ this.multipleRightAnswer = [];
|
|
|
+ let index = this.quesModel.quesOptions.indexOf(option);
|
|
|
+ if (index !== -1) {
|
|
|
+ this.quesModel.quesOptions.splice(index, 1);
|
|
|
+ }
|
|
|
+ if (this.quesModel.quesOptions.length > 0) {
|
|
|
+ for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
|
|
|
+ var quesOption = this.quesModel.quesOptions[i];
|
|
|
+ quesOption["number"] = i + 1;
|
|
|
+ if (quesOption.isCorrect == 1) {
|
|
|
+ var answerOrderNum = String.fromCharCode(65 + i);
|
|
|
+ if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
|
|
|
+ this.singleRightAnswer = answerOrderNum;
|
|
|
+ }
|
|
|
+ if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
|
|
|
+ this.multipleRightAnswer.push(answerOrderNum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //新增选项
|
|
|
+ addQuesOption() {
|
|
|
+ this.quesModel.quesOptions.push({
|
|
|
+ number: "",
|
|
|
+ optionBody: "",
|
|
|
+ isCorrect: "",
|
|
|
+ });
|
|
|
+ for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
|
|
|
+ this.quesModel.quesOptions[i]["number"] = i + 1;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ savePaperDetailUnit() {
|
|
|
+ //跟新难度值
|
|
|
+ if (this.quesModel.difficultyDegree < 0.4) {
|
|
|
+ this.quesModel.difficulty = "难";
|
|
|
+ } else if (
|
|
|
+ this.quesModel.difficultyDegree > 0.3 &&
|
|
|
+ this.quesModel.difficultyDegree < 0.8
|
|
|
+ ) {
|
|
|
+ this.quesModel.difficulty = "中";
|
|
|
+ } else {
|
|
|
+ this.quesModel.difficulty = "易";
|
|
|
+ }
|
|
|
+ this.setRightAnswer();
|
|
|
+ if (/^\d+(?=\.{0,1}\d+$|$)/.test(this.quesModel.score)) {
|
|
|
+ console.log("正确");
|
|
|
+ } else {
|
|
|
+ this.$notify({
|
|
|
+ message: "分数只能为正数",
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let paperDetailUnitExp = {
|
|
|
+ id: this.editPaperDetailUnit.id,
|
|
|
+ question: this.quesModel,
|
|
|
+ score: this.quesModel.score,
|
|
|
+ };
|
|
|
+ if (
|
|
|
+ this.quesModel.quesOptions &&
|
|
|
+ this.quesModel.quesOptions.length == 0
|
|
|
+ ) {
|
|
|
+ this.$confirm("无选项将删除该试题, 是否继续?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning",
|
|
|
+ }).then(() => {
|
|
|
+ this.dialogLoading = true;
|
|
|
+ this.$http
|
|
|
+ .delete(
|
|
|
+ QUESTION_API +
|
|
|
+ "/paper/deleteQuestion/" +
|
|
|
+ this.editPaperDetailUnit.id +
|
|
|
+ "/" +
|
|
|
+ this.quesModel.id
|
|
|
+ )
|
|
|
+ .then((response) => {
|
|
|
+ if (response.data.length > 0) {
|
|
|
+ var deleteInfo =
|
|
|
+ "该试题被试卷:" +
|
|
|
+ response.data.join(" , ") +
|
|
|
+ "使用,不能删除";
|
|
|
+ this.$notify({
|
|
|
+ message: deleteInfo,
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$notify({
|
|
|
+ message: "保存成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.dialogLoading = false;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.dialogLoading = true;
|
|
|
+ //校验音频重复
|
|
|
+ let audiomap = new Map();
|
|
|
+ let regex = new RegExp(
|
|
|
+ '<a id="[^<>]+" name="([^<>]+\\.mp3)"></a>',
|
|
|
+ "ig"
|
|
|
+ );
|
|
|
+ let ret = "";
|
|
|
+ let quesBodyStr = paperDetailUnitExp.question.quesBody;
|
|
|
+ if (quesBodyStr) {
|
|
|
+ while ((ret = regex.exec(quesBodyStr))) {
|
|
|
+ if (audiomap.get(ret[1])) {
|
|
|
+ this.dialogLoading = false;
|
|
|
+ this.$notify({
|
|
|
+ type: "error",
|
|
|
+ message: "题干中存在相同的音频文件",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ audiomap.set(ret[1], ret[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let quesAnswerStr = paperDetailUnitExp.question.quesAnswer;
|
|
|
+ if (quesAnswerStr) {
|
|
|
+ while ((ret = regex.exec(quesAnswerStr))) {
|
|
|
+ if (audiomap.get(ret[1])) {
|
|
|
+ this.dialogLoading = false;
|
|
|
+ this.$notify({
|
|
|
+ type: "error",
|
|
|
+ message: "答案中存在相同的音频文件",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ audiomap.set(ret[1], ret[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let quesOptions = paperDetailUnitExp.question.quesOptions;
|
|
|
+ if (quesOptions) {
|
|
|
+ for (let i = 0; i < quesOptions.length; i++) {
|
|
|
+ let quesOptionStr = quesOptions[i].optionBody;
|
|
|
+ while ((ret = regex.exec(quesOptionStr))) {
|
|
|
+ if (audiomap.get(ret[1])) {
|
|
|
+ this.dialogLoading = false;
|
|
|
+ this.$notify({
|
|
|
+ type: "error",
|
|
|
+ message: "选项中存在相同的音频文件",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ audiomap.set(ret[1], ret[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ paperDetailUnitExp.question.quesAnswer = this.answer;
|
|
|
+ this.$http
|
|
|
+ .put(QUESTION_API + "/paperDetailUnit", paperDetailUnitExp)
|
|
|
+ .then(() => {
|
|
|
+ this.$notify({
|
|
|
+ message: "保存成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.dialogLoading = false;
|
|
|
+ this.closeQuesDialog();
|
|
|
+ this.initPaper();
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ this.dialogLoading = false;
|
|
|
+ this.$notify({
|
|
|
+ type: "error",
|
|
|
+ message: err.response.data.desc,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //在正确的option上设置isCorrect=1
|
|
|
+ setRightAnswer() {
|
|
|
+ if (
|
|
|
+ !this.quesModel.quesOptions ||
|
|
|
+ this.quesModel.quesOptions.length == 0
|
|
|
+ ) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
|
|
|
+ var option = this.quesModel.quesOptions[i];
|
|
|
+ var answerOrderNum = String.fromCharCode(65 + i);
|
|
|
+ if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
|
|
|
+ option["isCorrect"] =
|
|
|
+ answerOrderNum == this.singleRightAnswer ? 1 : 0;
|
|
|
+ }
|
|
|
+ if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
|
|
|
+ option["isCorrect"] =
|
|
|
+ this.multipleRightAnswer.indexOf(answerOrderNum) > -1 ? 1 : 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //删除试题
|
|
|
+ deleteQues(paperDetailUnit) {
|
|
|
+ let paperDetailUnitId = paperDetailUnit.id;
|
|
|
+ if (this.paper.paperType == "GENERATE") {
|
|
|
+ this.deleteQues01(paperDetailUnitId);
|
|
|
+ } else {
|
|
|
+ let questionId = paperDetailUnit.question.id;
|
|
|
+ this.deleteQues02(questionId, paperDetailUnitId);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ deleteQues01(paperDetailUnitId) {
|
|
|
+ this.$alert("您确定删除吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ callback: (action) => {
|
|
|
+ if (action == "confirm") {
|
|
|
+ this.loading = true;
|
|
|
+ this.$http
|
|
|
+ .delete(QUESTION_API + "/paperDetailUnit/" + paperDetailUnitId)
|
|
|
+ .then(() => {
|
|
|
+ this.initPaper();
|
|
|
+ this.getreduplicateQuestions();
|
|
|
+ this.reduplicateGroup = [];
|
|
|
+ this.loading = true;
|
|
|
+ this.$notify({
|
|
|
+ message: "删除成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ deleteQues02(questionId, paperDetailUnitId) {
|
|
|
+ this.$alert("您确定删除吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ callback: (action) => {
|
|
|
+ if (action == "confirm") {
|
|
|
+ this.loading = true;
|
|
|
+ this.$http
|
|
|
+ .delete(
|
|
|
+ QUESTION_API +
|
|
|
+ "/paper/deleteQuestion/" +
|
|
|
+ paperDetailUnitId +
|
|
|
+ "/" +
|
|
|
+ questionId
|
|
|
+ )
|
|
|
+ .then((response) => {
|
|
|
+ if (response.data.length > 0) {
|
|
|
+ var deleteInfo =
|
|
|
+ "该试题被试卷:" +
|
|
|
+ response.data.join(" , ") +
|
|
|
+ "使用,不能删除";
|
|
|
+ this.$notify({
|
|
|
+ message: deleteInfo,
|
|
|
+ type: "error",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.initPaper();
|
|
|
+ this.getreduplicateQuestions();
|
|
|
+ this.reduplicateGroup = [];
|
|
|
+ this.loading = true;
|
|
|
+ this.$notify({
|
|
|
+ message: "保存成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ this.loading = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //获取重复试题
|
|
|
+ getreduplicateQuestions() {
|
|
|
+ this.duplicateLoading = true;
|
|
|
+ this.$http
|
|
|
+ .get(QUESTION_API + "/paper/" + this.paperId + "/reduplicate-questions")
|
|
|
+ .then((response) => {
|
|
|
+ this.reduplicateQuestions = response.data;
|
|
|
+ this.duplicateLoading = false;
|
|
|
+ this.initReduplicateQuesColor();
|
|
|
+ // var ques = document.getElementsByClassName("ques")[0];
|
|
|
+ // ques.style.display = "inline";
|
|
|
+ });
|
|
|
+ },
|
|
|
+ exportPaperAnswer() {
|
|
|
+ var key = this.user.key;
|
|
|
+ var token = this.user.token;
|
|
|
+ window.open(
|
|
|
+ QUESTION_API +
|
|
|
+ "/paper/answer/export/" +
|
|
|
+ this.paperId +
|
|
|
+ "?$key=" +
|
|
|
+ key +
|
|
|
+ "&$token=" +
|
|
|
+ token
|
|
|
+ );
|
|
|
+ },
|
|
|
+ initReduplicateQuesColor() {
|
|
|
+ var colorCount = this.reduplicateQuestions.length;
|
|
|
+ if (colorCount > 20) {
|
|
|
+ this.reduplicateQuesColor = randomColor({
|
|
|
+ luminosity: "bright",
|
|
|
+ count: colorCount,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.reduplicateQuesColor = this.defaultColor;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getSubQuesEditId(paperDetailUnit, subQuestion) {
|
|
|
+ return paperDetailUnit.question.id + "_" + subQuestion.quesParams.number;
|
|
|
+ },
|
|
|
+ //打开考试说明编辑框
|
|
|
+ openEditExamPaperRemark() {
|
|
|
+ if (this.paper.examRemark) {
|
|
|
+ this.examRemark = this.paper.examRemark;
|
|
|
+ } else {
|
|
|
+ this.examRemark = "";
|
|
|
+ }
|
|
|
+ this.paperRemarkDialog = true;
|
|
|
+ },
|
|
|
+ //保存考试说明
|
|
|
+ savePaperRemark() {
|
|
|
+ this.paper.examRemark = this.examRemark;
|
|
|
+ this.savePaper();
|
|
|
+ this.paperRemarkDialog = false;
|
|
|
+ },
|
|
|
+ //关闭考试说明编辑框
|
|
|
+ closPaperRemark() {
|
|
|
+ this.examRemark = "";
|
|
|
+ this.paperRemarkDialog = false;
|
|
|
+ },
|
|
|
+ //保存试卷
|
|
|
+ savePaper() {
|
|
|
+ this.loading = true;
|
|
|
+ this.$http
|
|
|
+ .put(QUESTION_API + "/paper", this.paper)
|
|
|
+ .then(() => {
|
|
|
+ this.$notify({
|
|
|
+ message: "保存成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.loading = false;
|
|
|
+ this.initPaper();
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ this.loading = false;
|
|
|
+ this.$notify({
|
|
|
+ type: "error",
|
|
|
+ message: error.response.data.desc,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //删除试卷
|
|
|
+ deletePaper(id) {
|
|
|
+ this.$confirm("确认删除试卷吗?", "提示", {
|
|
|
+ type: "warning",
|
|
|
+ }).then(() => {
|
|
|
+ this.loading = true;
|
|
|
+ this.$http.delete(QUESTION_API + "/paper/" + id).then(
|
|
|
+ () => {
|
|
|
+ this.$notify({
|
|
|
+ message: "删除成功",
|
|
|
+ type: "success",
|
|
|
+ });
|
|
|
+ this.back();
|
|
|
+ },
|
|
|
+ (error) => {
|
|
|
+ this.$notify({
|
|
|
+ message: error.response.data.desc,
|
|
|
+ type: "error",
|
|
|
+ title: "错误",
|
|
|
+ });
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //打开上传音频弹框
|
|
|
+ openDialog() {
|
|
|
+ this.checkResult = false;
|
|
|
+ this.isUpload = true;
|
|
|
+ if (document.getElementById("radioFile")) {
|
|
|
+ document.getElementById("radioFile").value = "";
|
|
|
+ }
|
|
|
+ this.dialogRadioFile = true;
|
|
|
+ this.fileList = [];
|
|
|
+ },
|
|
|
+ //关闭音频弹框
|
|
|
+ closeAudioDialog() {
|
|
|
+ this.dialogRadioFile = this.uploadAudioLoading;
|
|
|
+ },
|
|
|
+ //返回
|
|
|
+ back() {
|
|
|
+ if (sessionStorage.getItem("question_back") == "true") {
|
|
|
+ this.$router.push({
|
|
|
+ path: "/questions/" + this.parentView + "/0",
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$router.push({
|
|
|
+ path: "/questions/" + this.parentView + "/1",
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ paperDetailShow(paperDetail) {
|
|
|
+ if (this.reduplicateGroup.length == 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ let paperDetailUnits = paperDetail.paperDetailUnits;
|
|
|
+ for (let i = 0, imax = paperDetailUnits.length; i < imax; i++) {
|
|
|
+ for (var j = 0, jmax = this.reduplicateGroup.length; j < jmax; j++) {
|
|
|
+ if (paperDetailUnits[i].id == this.reduplicateGroup[j]) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ },
|
|
|
+ //上传文件检查
|
|
|
+ checkFile() {
|
|
|
+ this.fileNameList = [];
|
|
|
+ //读取选取的文件夹里面的文件
|
|
|
+ this.checkResult = true;
|
|
|
+ var files = document.getElementById("radioFile").files;
|
|
|
+ if (files.length == 0) {
|
|
|
+ this.message = "请选择音频文件夹!";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var size = 0;
|
|
|
+ var isGo = false;
|
|
|
+ //取到所有文件的文件名
|
|
|
+ for (var i = 0; i < files.length; i++) {
|
|
|
+ this.fileNameList.push(files[i].name);
|
|
|
+ if (files[i].size > 5 * 1024 * 1024) {
|
|
|
+ isGo = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ size = files[i].size + size;
|
|
|
+ }
|
|
|
+ if (isGo) {
|
|
|
+ this.message = "上传单个文件不能超过5M";
|
|
|
+ this.isUpload = true;
|
|
|
+ }
|
|
|
+ if (size > 50 * 1024 * 1024) {
|
|
|
+ this.message = "上传文件总和不能超过50M";
|
|
|
+ this.isUpload = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$http
|
|
|
+ .post(
|
|
|
+ QUESTION_API + "/checkRadioFile/" + this.paperId,
|
|
|
+ this.fileNameList
|
|
|
+ )
|
|
|
+ .then((response) => {
|
|
|
+ console.log("response:", response);
|
|
|
+ this.message = response.data.errorMsg;
|
|
|
+ if (this.message == "OK") {
|
|
|
+ this.message = "OK!";
|
|
|
+ this.isUpload = false;
|
|
|
+ } else {
|
|
|
+ this.isUpload = true;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ console.log(error);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //读取文件
|
|
|
+ uploadAudioFile() {
|
|
|
+ let param = new FormData();
|
|
|
+ var fileList = document.getElementById("radioFile").files;
|
|
|
+ //循环添加到formData中
|
|
|
+ for (var i = 0; i < fileList.length; i++) {
|
|
|
+ var file = fileList[i];
|
|
|
+ param.append("files", file, file.name);
|
|
|
+ }
|
|
|
+ let config = {
|
|
|
+ headers: { "Content-Type": "multipart/form-data" },
|
|
|
+ };
|
|
|
+ this.$http
|
|
|
+ .post(QUESTION_API + "/uploadRadio/" + this.paperId, param, config)
|
|
|
+ .then(() => {
|
|
|
+ this.dialogRadioFile = false;
|
|
|
+ this.uploadAudioLoading = false;
|
|
|
+ this.checkResult = false;
|
|
|
+ this.isUpload = true;
|
|
|
+ document.getElementById("radioFile").value = "";
|
|
|
+ this.initPaper();
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ this.message = error.response.data.desc;
|
|
|
+ this.uploadAudioLoading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style scoped src="../styles/EditPaper.css">
|
|
|
+.property_with {
|
|
|
+ width: 100px;
|
|
|
+}
|
|
|
+.ck-toolbar {
|
|
|
+ z-index: 9999;
|
|
|
+}
|
|
|
+#app {
|
|
|
+ background-color: white !important;
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style scoped src="../styles/Common.css"></style>
|