123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702 |
- <template>
- <div v-loading="fullscreenLoading">
- <!-- 头信息 -->
- <div class="part-box">
- <div class="part-box-header">
- <h1 class="part-box-title">
- {{ quesModel.id ? "试题修改" : "试题新增" }}
- </h1>
- <div>
- <el-button
- type="primary"
- icon="icon icon-save-white"
- :disabled="saveDisabled"
- @click="submitForm('quesModel')"
- >保存</el-button
- >
- <el-button
- type="danger"
- plain
- icon="icon icon-back"
- @click="backToQuesList()"
- >返回
- </el-button>
- </div>
- </div>
- <!-- 正文信息 -->
- <el-form
- ref="quesModel"
- class="padding-tb-20 form-tight"
- :model="quesModel"
- :rules="rules"
- label-width="100px"
- >
- <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-form-item label="分数">
- <el-input placeholder="分数" v-model="quesModel.score" style="width:50px;"></el-input>
- </el-form-item>
- -->
- <!-- created by weiwenhai -->
- <el-form-item label="难度">
- <el-select
- v-model="quesModel.difficultyDegree"
- placeholder="请输入难度"
- >
- <el-option
- v-for="item in difficultyDegreeList"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="公开度">
- <el-select v-model="quesModel.publicity" placeholder="请输入公开度">
- <el-option
- v-for="item in publicityList"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item
- v-if="quesModel.questionType == 'TEXT_ANSWER_QUESTION'"
- label="作答类型"
- >
- <el-select v-model="quesModel.answerType">
- <el-option
- v-for="item in answerTypes"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- >
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="属性列表">
- <el-tooltip
- v-for="(content, index) in quesModel.quesProperties"
- :key="index"
- placement="top"
- >
- <div slot="content">
- <span v-if="content.firstProperty != null"
- >一级属性:{{ content.firstProperty.name }}({{
- content.firstProperty.code
- }})</span
- ><br />
- <span v-if="content.secondProperty != null"
- >二级属性:{{ content.secondProperty.name }}({{
- content.secondProperty.code
- }})</span
- >
- </div>
- <el-tag
- :key="content.id"
- style="margin-right: 5px"
- closable
- effect="dark"
- type="primary"
- @close="handleClose(content)"
- >
- {{ content.coursePropertyName || content.courseProperty.name }}
- </el-tag>
- </el-tooltip>
- </el-form-item>
- <el-row :gutter="10">
- <el-col :xs="6" :sm="6" :md="6" :lg="6">
- <el-form-item label="属性名">
- <el-select
- v-model="coursePropertyName"
- placeholder="属性名"
- class="property_with"
- @change="searchFirst"
- >
- <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 :xs="6" :sm="6" :md="6" :lg="6">
- <el-form-item label="一级">
- <el-select
- v-model="firstPropertyId"
- placeholder="一级"
- class="property_with"
- @change="searchSecond"
- >
- <el-option
- v-for="item in firstPropertyList"
- :key="item.id"
- :label="item.name + '(' + item.code + ')'"
- :value="item.id"
- >
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :xs="6" :sm="6" :md="6" :lg="6">
- <el-form-item label="二级">
- <el-select
- v-model="secondPropertyId"
- placeholder="二级"
- class="property_with"
- >
- <el-option
- v-for="item in secondPropertyList"
- :key="item.id"
- :label="item.name + '(' + item.code + ')'"
- :value="item.id"
- >
- </el-option>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :xs="3" :sm="3" :md="3" :lg="3">
- <el-form-item label-width="0px">
- <el-button
- type="primary"
- icon="icon icon-plus-white"
- @click="insertProperty"
- >新增属性</el-button
- >
- </el-form-item>
- </el-col>
- </el-row>
- <!-- end -->
- </el-form>
- </div>
- <div class="part-box">
- <el-form class="form-tight" label-width="100px">
- <el-form-item label="题干" prop="quesBody">
- <ckeditor v-model="quesModel.quesBody"></ckeditor>
- </el-form-item>
- <el-form-item
- v-for="(option, index) in quesModel.quesOptions"
- :key="option.number"
- >
- <div class="question-edit-option">
- <div class="option-check">
- <el-radio
- v-if="quesModel.questionType === 'SINGLE_ANSWER_QUESTION'"
- v-model="singleRightAnswer"
- :label="index | optionOrderWordFilter"
- ></el-radio>
- <el-checkbox
- v-if="quesModel.questionType === 'MULTIPLE_ANSWER_QUESTION'"
- v-model="multipleRightAnswer"
- :label="index | optionOrderWordFilter"
- ></el-checkbox>
- </div>
- <div class="option-body">
- <ckeditor v-model="option.optionBody"></ckeditor>
- </div>
- <div class="option-delete">
- <el-button
- size="mini"
- circle
- type="danger"
- icon="el-icon-delete"
- title="删除"
- @click.prevent="removeQuesOption(option)"
- ></el-button>
- </div>
- </div>
- </el-form-item>
- <el-form-item>
- <el-button
- type="primary"
- icon="icon icon-plus-white"
- @click="addQuesOption"
- >新增选项</el-button
- >
- </el-form-item>
- <div class="line-seperator"></div>
- <el-form-item label="答案">
- <div v-html="answer"></div>
- </el-form-item>
- </el-form>
- </div>
- </div>
- </template>
- <script>
- import { QUESTION_API } from "@/constants/constants";
- import { isEmptyStr, QUESTION_TYPES } from "../constants/constants";
- import ckeditor from "../component/ckeditor.vue";
- export default {
- name: "EditSelectApp",
- components: { ckeditor },
- data() {
- return {
- questionTypes: QUESTION_TYPES,
- fullscreenLoading: false,
- paperId: "",
- paperDetailId: "",
- questionId: "",
- quesModel: {
- quesBody: "",
- quesOptions: [],
- quesAnswer: "",
- questionType: "",
- courseName: "",
- courseNo: "",
- difficultyDegree: 0.5,
- publicity: true,
- answerType: "",
- quesProperties: [],
- score: 1,
- },
- 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
- //验证
- rules: {
- // quesBody: [
- // { required: true, message: '请输入题干', trigger: 'blur'}
- // ]
- },
- singleRightAnswer: "", //接收单选答案
- multipleRightAnswer: [], //接收多选答案
- };
- },
- computed: {
- 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;
- },
- saveDisabled() {
- if (!this.questionId && this.quesModel.quesOptions.length == 0) {
- return true;
- }
- return false;
- },
- },
- created() {
- let questionId = this.$route.params.id;
- if (questionId) {
- this.questionId = questionId;
- this.quesModel["id"] = questionId;
- this.findQuestionById(questionId);
- }
- this.paperId = this.$route.params.paperId;
- this.paperDetailId = this.$route.params.paperDetailId;
- this.courseNo = this.$route.params.courseNo;
- let questionType = this.$route.params.questionType;
- if (questionType) {
- this.quesModel.questionType = questionType;
- }
- if (this.courseNo) {
- this.$http
- .get(
- QUESTION_API +
- "/courseProperty/enable?courseCode=" +
- encodeURIComponent(this.courseNo)
- )
- .then((response) => {
- this.coursePropertyList = response.data;
- });
- }
- if (isEmptyStr(this.quesModel.answerType)) {
- this.quesModel.answerType = "DIVERSIFIED_TEXT";
- }
- },
- mounted() {
- setTimeout(() => {
- if (this.quesModel.id) {
- this.$store.commit("UPDATE_CURRENT_PATHS", ["试题管理", "试题修改"]);
- } else {
- this.$store.commit("UPDATE_CURRENT_PATHS", ["试题管理", "试题新增"]);
- }
- }, 200);
- },
- methods: {
- findQuestionById(questionId) {
- this.$http
- .get(QUESTION_API + "/question/" + questionId)
- .then((response) => {
- this.quesModel = response.data;
- if (this.quesModel.quesOptions) {
- for (var i = 0; i < this.quesModel.quesOptions.length; i++) {
- var 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));
- }
- }
- }
- if (isEmptyStr(this.quesModel.answerType)) {
- this.quesModel.answerType = "DIVERSIFIED_TEXT";
- }
- this.initCourseProperty();
- });
- },
- submitForm(formName) {
- this.$refs[formName].validate((valid) => {
- if (valid) {
- this.setRightAnswer();
- if (!this.hasAnswer()) {
- this.$notify({
- message: "请选择答案",
- type: "error",
- });
- return false;
- }
- if (this.questionId) {
- this.editQuestion();
- } else {
- this.saveNewQuestion();
- }
- } else {
- return false;
- }
- });
- },
- //修改试题
- editQuestion() {
- if (this.quesModel.quesOptions.length == 0) {
- this.$confirm("无选项将删除该试题, 是否继续?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(() => {
- this.fullscreenLoading = true;
- this.$http
- .delete(
- QUESTION_API + "/paper/deleteQuestion/" + this.quesModel.id
- )
- .then((response) => {
- if (response.data.length > 0) {
- this.deleteInfo =
- "该试题被试卷:" +
- response.data.join(" , ") +
- "使用,不能删除";
- this.deleteDialogVisible = true;
- } else {
- this.$notify({
- message: "删除成功",
- type: "success",
- });
- this.$router.push({ path: "/questions/question_list/0" });
- }
- });
- })
- .catch(() => {});
- } else {
- this.fullscreenLoading = true;
- this.$http.put(QUESTION_API + "/question", this.quesModel).then(() => {
- this.$notify({
- message: "保存成功",
- type: "success",
- });
- this.fullscreenLoading = false;
- });
- }
- },
- //新增试题
- saveNewQuestion() {
- if (!this.quesModel.difficultyDegree) {
- this.$notify({
- message: "请选择试题难度",
- type: "error",
- });
- return false;
- }
- this.fullscreenLoading = true;
- this.$http
- .post(
- QUESTION_API +
- "/paper/addQuestion/" +
- this.paperId +
- "/" +
- this.paperDetailId,
- this.quesModel
- )
- .then(() => {
- this.fullscreenLoading = false;
- this.$notify({
- type: "success",
- message: "保存成功",
- });
- this.$router.push({ path: "/questions/question_list/0" });
- })
- .catch(() => {
- this.fullscreenLoading = false;
- });
- },
- //新增选项
- 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;
- }
- },
- //删除选项
- 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);
- }
- }
- }
- }
- },
- //在正确的option上设置isCorrect=1
- setRightAnswer() {
- if (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;
- }
- }
- },
- hasAnswer() {
- if (this.quesModel.questionType == "SINGLE_ANSWER_QUESTION") {
- if (!this.singleRightAnswer || this.singleRightAnswer == "") {
- return false;
- } else {
- return true;
- }
- }
- if (this.quesModel.questionType == "MULTIPLE_ANSWER_QUESTION") {
- if (!this.multipleRightAnswer || this.multipleRightAnswer == "") {
- return false;
- } else {
- return true;
- }
- }
- },
- backToQuesList() {
- this.$router.push({
- path: "/questions/question_list/1",
- });
- },
- //查询所有课程属性名
- initCourseProperty() {
- var code = this.quesModel.course.code;
- this.$http
- .get(
- QUESTION_API +
- "/courseProperty/enable?courseCode=" +
- encodeURIComponent(code)
- )
- .then((response) => {
- this.coursePropertyList = response.data;
- });
- },
- //查询一级属性
- searchFirst() {
- this.firstPropertyId = "";
- this.secondPropertyId = "";
- this.secondPropertyList = [];
- 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 === undefined ||
- this.quesModel.quesProperties === null ||
- this.quesModel.quesProperties.length == 0
- ) {
- this.quesModel.quesProperties = [];
- }
- quesProperty.id =
- this.coursePropertyName +
- "-" +
- this.firstPropertyId +
- "-" +
- this.secondPropertyId;
- 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 = [];
- },
- //删除属性
- handleClose(tag) {
- this.quesModel.quesProperties.splice(
- this.quesModel.quesProperties.indexOf(tag),
- 1
- );
- this.quesModel = Object.assign({}, this.quesModel);
- },
- //新增属性验证
- checkInsertPro() {
- if (!this.coursePropertyName) {
- this.$notify({
- message: "请选择属性",
- type: "error",
- });
- return false;
- }
- if (!this.firstPropertyId) {
- this.$notify({
- message: "请选择一级属性",
- type: "error",
- });
- return false;
- }
- return true;
- },
- },
- };
- </script>
|