SelectQuestion.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <template>
  2. <div class="select-question">
  3. <el-form
  4. ref="modalFormComp"
  5. :model="modalForm"
  6. :rules="rules"
  7. label-width="100px"
  8. >
  9. <el-form-item v-if="showQuesBody" prop="quesBody" label="题干">
  10. <v-editor
  11. v-model="modalForm.quesBody"
  12. @change="quesBodyChange"
  13. ></v-editor>
  14. </el-form-item>
  15. <el-form-item
  16. v-for="(option, oindex) in modalForm.quesOptions"
  17. :key="option.nmuber"
  18. :prop="`quesOptions.${oindex}.optionBody`"
  19. :rules="optionRule"
  20. >
  21. <div class="question-edit-option">
  22. <div class="option-check">
  23. <el-radio
  24. v-if="IS_SIMPLE"
  25. v-model="quesAnswer"
  26. :label="option.number"
  27. @change="answerChange"
  28. >
  29. {{ (option.number - 1) | optionOrderWordFilter }}
  30. </el-radio>
  31. <el-checkbox
  32. v-else
  33. v-model="option.isCorrect"
  34. :label="option.number"
  35. @change="answerChange"
  36. >
  37. {{ (option.number - 1) | optionOrderWordFilter }}
  38. </el-checkbox>
  39. </div>
  40. <div class="option-body">
  41. <v-editor
  42. v-model="option.optionBody"
  43. @change="() => optionBodyChange(oindex)"
  44. ></v-editor>
  45. </div>
  46. <div class="option-delete">
  47. <el-button
  48. size="mini"
  49. circle
  50. type="primary"
  51. icon="el-icon-plus"
  52. title="新增"
  53. @click.prevent="addQuesOption(oindex)"
  54. ></el-button>
  55. <el-button
  56. size="mini"
  57. circle
  58. type="danger"
  59. icon="el-icon-delete"
  60. title="删除"
  61. :disabled="deleleOptionDisabled"
  62. @click.prevent="removeQuesOption(oindex)"
  63. ></el-button>
  64. </div>
  65. </div>
  66. </el-form-item>
  67. <el-form-item prop="quesAnswer" label="答案">
  68. <span>{{ answer }}</span>
  69. <!-- <el-radio-group
  70. v-if="IS_SIMPLE"
  71. v-model="quesAnswer"
  72. @change="answerChange"
  73. >
  74. <el-radio
  75. v-for="option in modalForm.quesOptions"
  76. :key="option.number"
  77. :label="option.number"
  78. >
  79. {{ (option.number - 1) | optionOrderWordFilter }}
  80. </el-radio>
  81. </el-radio-group>
  82. <el-checkbox-group
  83. v-if="IS_SIMPLE"
  84. v-model="quesAnswer"
  85. @change="answerChange"
  86. >
  87. <el-checkbox
  88. v-for="option in modalForm.quesOptions"
  89. :key="option.number"
  90. :label="option.number"
  91. >
  92. {{ (option.number - 1) | optionOrderWordFilter }}
  93. </el-checkbox>
  94. </el-checkbox-group> -->
  95. </el-form-item>
  96. <el-form-item
  97. prop="ignoreOptionRepeat"
  98. label="允许答案重复"
  99. v-if="$store.state.checkOptionRepeat"
  100. >
  101. <el-switch
  102. v-model="modalForm.ignoreOptionRepeat"
  103. active-text="是"
  104. inactive-text="否"
  105. >
  106. </el-switch>
  107. </el-form-item>
  108. <el-form-item label="答案解析">
  109. <v-editor
  110. v-model="modalForm.answerAnalysis"
  111. :enable-audio="false"
  112. ></v-editor>
  113. </el-form-item>
  114. </el-form>
  115. <question-info-edit
  116. v-if="canEditQuestionInfo"
  117. ref="QuestionInfoEdit"
  118. :question="modalForm"
  119. @change="questionInfoChange"
  120. ></question-info-edit>
  121. </div>
  122. </template>
  123. <script>
  124. import { isAnEmptyRichText } from "@/utils/utils";
  125. import { getInitQuestionModel } from "./questionModel";
  126. import QuestionInfoEdit from "../QuestionInfoEdit.vue";
  127. export default {
  128. name: "SelectQuestion",
  129. components: { QuestionInfoEdit },
  130. props: {
  131. question: {
  132. type: Object,
  133. default() {
  134. return {};
  135. },
  136. },
  137. showQuesBody: {
  138. type: Boolean,
  139. default: true,
  140. },
  141. quesBodyRequired: {
  142. type: Boolean,
  143. default: true,
  144. },
  145. canEditQuestionInfo: {
  146. type: Boolean,
  147. default: true,
  148. },
  149. },
  150. data() {
  151. return {
  152. modalForm: {},
  153. quesAnswer: null,
  154. rules: {
  155. quesBody: [
  156. {
  157. validator: (rule, value, callback) => {
  158. if (
  159. this.quesBodyRequired &&
  160. (!value || isAnEmptyRichText(value))
  161. ) {
  162. return callback(new Error(`请输入题干`));
  163. }
  164. callback();
  165. },
  166. trigger: "change",
  167. },
  168. ],
  169. quesAnswer: [
  170. {
  171. validator: (rule, value, callback) => {
  172. if (!value || !value.length) {
  173. return callback(new Error(`请设置答案`));
  174. }
  175. callback();
  176. },
  177. trigger: "change",
  178. },
  179. ],
  180. },
  181. optionRule: {
  182. validator: (rule, value, callback) => {
  183. if (!value || isAnEmptyRichText(value)) {
  184. return callback(new Error(`请输入选项内容`));
  185. }
  186. callback();
  187. },
  188. trigger: "change",
  189. },
  190. };
  191. },
  192. computed: {
  193. IS_SIMPLE() {
  194. return this.question.questionType === "SINGLE_ANSWER_QUESTION";
  195. },
  196. answer() {
  197. if (!this.quesAnswer) return "";
  198. const quesAnswer = this.IS_SIMPLE ? [this.quesAnswer] : this.quesAnswer;
  199. return quesAnswer
  200. .map((value) => String.fromCharCode(64 + value))
  201. .join("");
  202. },
  203. deleleOptionDisabled() {
  204. return this.modalForm.quesOptions.length === 1;
  205. },
  206. },
  207. created() {
  208. this.initData();
  209. },
  210. methods: {
  211. initData() {
  212. this.modalForm = this.$objAssign(
  213. getInitQuestionModel("SINGLE_ANSWER_QUESTION"),
  214. this.question
  215. );
  216. this.modalForm.quesAnswer = this.question.quesAnswer
  217. ? JSON.parse(this.question.quesAnswer)
  218. : [];
  219. if (this.IS_SIMPLE) {
  220. this.quesAnswer = this.modalForm.quesAnswer
  221. ? this.modalForm.quesAnswer[0]
  222. : null;
  223. } else {
  224. this.quesAnswer = this.modalForm.quesAnswer || [];
  225. this.modalForm.quesOptions.forEach((item) => {
  226. item.isCorrect = this.quesAnswer.includes(item.number);
  227. });
  228. }
  229. },
  230. addQuesOption(index) {
  231. if (this.modalForm.quesOptions.length >= 20) {
  232. this.$message.error("选项最多20个");
  233. return;
  234. }
  235. this.modalForm.quesOptions.splice(index + 1, 0, {
  236. number: 0,
  237. body: { sections: [] },
  238. });
  239. this.resetNumberAndSaveOptions();
  240. },
  241. removeQuesOption(index) {
  242. if (this.deleleOptionDisabled) return;
  243. this.modalForm.quesOptions.splice(index, 1);
  244. this.resetNumberAndSaveOptions();
  245. },
  246. resetNumberAndSaveOptions() {
  247. this.modalForm.quesOptions.forEach((option, index) => {
  248. option.number = index + 1;
  249. });
  250. const optionCount = this.modalForm.quesOptions.length;
  251. if (this.IS_SIMPLE && this.quesAnswer > optionCount) {
  252. this.quesAnswer = null;
  253. }
  254. this.answerChange();
  255. },
  256. quesBodyChange() {
  257. this.$refs.modalFormComp.validateField(`quesBody`, () => {});
  258. },
  259. optionBodyChange(oindex) {
  260. this.$refs.modalFormComp.validateField(
  261. `quesOptions.${oindex}.optionBody`,
  262. () => {}
  263. );
  264. },
  265. answerChange() {
  266. if (this.IS_SIMPLE) {
  267. this.modalForm.quesAnswer =
  268. this.quesAnswer || this.quesAnswer === 0 ? [this.quesAnswer] : [];
  269. } else {
  270. this.quesAnswer = this.modalForm.quesOptions
  271. .filter((item) => item.isCorrect)
  272. .map((item) => item.number);
  273. this.modalForm.quesAnswer = this.quesAnswer;
  274. }
  275. this.$refs.modalFormComp.validateField(`quesAnswer`, () => {});
  276. },
  277. questionInfoChange(questionInfo) {
  278. this.modalForm = Object.assign({}, this.modalForm, questionInfo);
  279. },
  280. validate() {
  281. return this.$refs.modalFormComp.validate();
  282. },
  283. getData() {
  284. let data = { ...this.modalForm };
  285. data.quesOptions = this.modalForm.quesOptions.map((item) => {
  286. return {
  287. number: item.number,
  288. optionBody: item.optionBody,
  289. };
  290. });
  291. data.quesAnswer = JSON.stringify(this.modalForm.quesAnswer);
  292. return data;
  293. },
  294. },
  295. };
  296. </script>