New file |
| | |
| | | <!-- 计算题 --> |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <vue-ueditor-wrap v-model="content" editor-id="editor" :config="editorConfig" |
| | | :editorDependencies="['ueditor.config.js', 'ueditor.all.js']" /> |
| | | </div> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref,watchEffect } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | |
| | | const examStore = useExamStore(); |
| | | |
| | | const editorConfig = { |
| | | // 后端服务地址,后端处理参考 |
| | | // https://open-doc.modstart.com/ueditor-plus/backend.html |
| | | serverUrl: '/api/path/to/server', |
| | | UEDITOR_HOME_URL: '/static/UEditorPlus/', |
| | | UEDITOR_CORS_URL: '/static/UEditorPlus/', |
| | | initialFrameWidth: '95%', |
| | | initialFrameHeight: 400, |
| | | toolbars: [ |
| | | ['fullscreen', 'undo','redo', '|', 'fontfamily', 'fontsize', '|', |
| | | 'forecolor', 'backcolor', 'bold', 'italic', 'underline','strikethrough','|', |
| | | 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', |
| | | 'inserttable', 'deletetable', 'insertparagraph', 'insertrow', 'deleterow', |
| | | 'insertcol', 'deletecol','mergecells','mergerow','mergecol', 'splittocells', |
| | | 'splittorows','splittocols', '|', 'formula'] |
| | | ] |
| | | }; |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | const content = ref(activeQuestion.value.answer); |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | |
| | | </style> |
New file |
| | |
| | | <!-- 判断题 --> |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar class="flex-1 mr-4"> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <div class="answer-item flex" v-for="item, index in activeQuestion.questionItemList" :class="answerState(item)"> |
| | | <div class="answer-icon flex flex-col justify-center items-center flex-shrink-0">{{ item.prefix }}</div> |
| | | <div class="answer-text text-gray-700" v-html="item.content"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-scrollbar> |
| | | |
| | | <el-scrollbar class="flex-1 ml-4"> |
| | | <div class="analysis-container"> |
| | | <div class="analysis-item" :class="analysisState"> |
| | | <div class="item-label">您的答案</div> |
| | | <div class="item-info">{{ activeQuestion.answer }}</div> |
| | | </div> |
| | | |
| | | <div class="analysis-item analysis-right"> |
| | | <div class="item-label">正确答案</div> |
| | | <div class="item-info">{{ activeQuestion.questionAnswer }}</div> |
| | | </div> |
| | | |
| | | <div class="analysis-item text-gray-700"> |
| | | <div class="item-label">解析</div> |
| | | <div class="item-info" v-html="activeQuestion.analyze"></div> |
| | | </div> |
| | | </div> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | const examStore = useExamStore(); |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | |
| | | |
| | | const answerState = (item) => { |
| | | if (activeQuestion.value.answer === item.prefix) { |
| | | item.isActive = true; |
| | | } |
| | | return { |
| | | active: item.isActive || item.prefix === activeQuestion.value.answer |
| | | }; |
| | | }; |
| | | |
| | | const analysisState = computed(() => { |
| | | return { |
| | | 'analysis-right': activeQuestion.value.isRight, |
| | | 'analysis-wrong': !activeQuestion.value.isRight |
| | | }; |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .answer-container { |
| | | --right-color: #67c23a; |
| | | --wrong-color: #f56c6c; |
| | | } |
| | | |
| | | .answer-item { |
| | | max-width: 500px; |
| | | border-radius: 10px; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | margin-bottom: 20px; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | |
| | | .answer-icon { |
| | | width: 50px; |
| | | background-color: #F0F2F5; |
| | | border-right: 1px solid #ffffff; |
| | | } |
| | | |
| | | .answer-text { |
| | | min-height: 50px; |
| | | padding: 15px 0; |
| | | margin: 0 10px; |
| | | } |
| | | } |
| | | |
| | | .right { |
| | | border-color: var(--right-color) !important; |
| | | background-color: rgba($color: #67c23a, $alpha: 0.2) !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: var(--right-color) !important; |
| | | background-color: var(--right-color) !important; |
| | | } |
| | | |
| | | .answer-text { |
| | | color: var(--right-color) !important; |
| | | } |
| | | } |
| | | |
| | | .wrong { |
| | | border-color: var(--wrong-color) !important; |
| | | background-color: rgba($color: #f56c6c, $alpha: 0.2) !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: var(--wrong-color) !important; |
| | | background-color: var(--wrong-color) !important; |
| | | } |
| | | |
| | | .answer-text { |
| | | color: var(--wrong-color) !important; |
| | | } |
| | | } |
| | | |
| | | .analysis-item { |
| | | margin-bottom: 10px; |
| | | |
| | | .item-label { |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | |
| | | .analysis-right { |
| | | color: var(--right-color); |
| | | } |
| | | |
| | | .analysis-wrong { |
| | | color: var(--wrong-color); |
| | | } |
| | | </style> |
New file |
| | |
| | | <!-- 填空题 --> |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <div class="answer-item flex" v-for="item, index in activeQuestion.questionItemList" :class="answerState(item,index)"> |
| | | <div class="answer-icon flex flex-col justify-center items-center flex-shrink-0">{{ item.prefix }}</div> |
| | | <div class="answer-text text-gray-700" v-html="item.content"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref,computed } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | const examStore = useExamStore(); |
| | | |
| | | |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | |
| | | |
| | | const answerState = (item,index) => { |
| | | if(Array.isArray(activeQuestion.value.answerList) && activeQuestion.value.answerList[index]) { |
| | | item.isActive = true; |
| | | } |
| | | return { |
| | | active: item.isActive |
| | | }; |
| | | }; |
| | | |
| | | const analysisState = computed(() => { |
| | | return { |
| | | 'analysis-right': activeQuestion.value.isRight, |
| | | 'analysis-wrong': !activeQuestion.value.isRight |
| | | }; |
| | | }); |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .answer-container { |
| | | --right-color: #67c23a; |
| | | --wrong-color: #f56c6c; |
| | | } |
| | | |
| | | .answer-item { |
| | | max-width: 500px; |
| | | border-radius: 10px; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | margin-bottom: 20px; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | |
| | | .answer-icon { |
| | | width: 50px; |
| | | background-color: #F0F2F5; |
| | | border-right: 1px solid #ffffff; |
| | | } |
| | | |
| | | .answer-text { |
| | | min-height: 50px; |
| | | padding: 15px 0; |
| | | margin: 0 10px; |
| | | } |
| | | } |
| | | |
| | | .right { |
| | | border-color: var(--right-color) !important; |
| | | background-color: rgba($color: #67c23a, $alpha: 0.2) !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: var(--right-color) !important; |
| | | background-color: var(--right-color) !important; |
| | | } |
| | | |
| | | .answer-text { |
| | | color: var(--right-color) !important; |
| | | } |
| | | } |
| | | |
| | | .wrong { |
| | | border-color: var(--wrong-color) !important; |
| | | background-color: rgba($color: #f56c6c, $alpha: 0.2) !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: var(--wrong-color) !important; |
| | | background-color: var(--wrong-color) !important; |
| | | } |
| | | |
| | | .answer-text { |
| | | color: var(--wrong-color) !important; |
| | | } |
| | | } |
| | | |
| | | .analysis-item { |
| | | margin-bottom: 10px; |
| | | |
| | | .item-label { |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | |
| | | .analysis-right { |
| | | color: var(--right-color); |
| | | } |
| | | |
| | | .analysis-wrong { |
| | | color: var(--wrong-color); |
| | | } |
| | | </style> |
New file |
| | |
| | | <!-- 简答题 --> |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <vue-ueditor-wrap v-model="content" editor-id="editor" :config="editorConfig" |
| | | :editorDependencies="['ueditor.config.js', 'ueditor.all.js']" /> |
| | | </div> |
| | | <el-button @click="testClick">内容显示</el-button> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref,watchEffect } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | |
| | | const examStore = useExamStore(); |
| | | |
| | | const editorConfig = { |
| | | // 后端服务地址,后端处理参考 |
| | | // https://open-doc.modstart.com/ueditor-plus/backend.html |
| | | serverUrl: '/api/path/to/server', |
| | | UEDITOR_HOME_URL: '/static/UEditorPlus/', |
| | | UEDITOR_CORS_URL: '/static/UEditorPlus/', |
| | | initialFrameWidth: '95%', |
| | | initialFrameHeight: 400, |
| | | toolbars: [ |
| | | ['fullscreen', 'undo','redo', '|', 'fontfamily', 'fontsize', '|', |
| | | 'forecolor', 'backcolor', 'bold', 'italic', 'underline','strikethrough','|', |
| | | 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', |
| | | 'inserttable', 'deletetable', 'insertparagraph', 'insertrow', 'deleterow', |
| | | 'insertcol', 'deletecol','mergecells','mergerow','mergecol', 'splittocells', |
| | | 'splittorows','splittocols', '|', 'formula'] |
| | | ] |
| | | }; |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | const content = ref(activeQuestion.value.answer); |
| | | |
| | | const testClick = () => { |
| | | console.log(content.value); |
| | | } |
| | | watchEffect(() => { |
| | | examStore.setQuestionAnswer(currentType.value, currentIndex.value, content.value); |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | |
| | | </style> |
| | |
| | | <div class="answer-content"> |
| | | <div class="answer-item flex" v-for="item, index in activeQuestion.questionItemList" :class="answerState(item)"> |
| | | <div class="answer-icon flex flex-col justify-center items-center flex-shrink-0">{{ item.prefix }}</div> |
| | | <div class="answer-text text-gray-700">{{ item.content }}</div> |
| | | <div class="answer-text text-gray-700" v-html="item.content"></div> |
| | | </div> |
| | | </div> |
| | | </el-scrollbar> |
| | |
| | | import AnswerSingle from './components/answer-main/answer-single/index.vue'; |
| | | import AnswerMultiple from './components/answer-main/answer-multiple/index.vue'; |
| | | import AnswerAudio from './components/answer-main/answer-audio/index.vue'; |
| | | import AnswerFill from './components/answer-main/answer-fill/index.vue'; |
| | | import AnswerDetermine from './components/answer-main/answer-determine/index.vue'; |
| | | import AnswerShort from './components/answer-main/answer-short/index.vue'; |
| | | import AnswerCount from './components/answer-main/answer-count/index.vue'; |
| | | |
| | | import { useGradeStore } from '@/store/index.js'; |
| | | import { useRouter } from 'vue-router'; |
| | |
| | | const typeComponent = { |
| | | 1: AnswerSingle, |
| | | 2: AnswerMultiple, |
| | | 3: AnswerAudio, |
| | | 3: AnswerDetermine, |
| | | 4: AnswerFill, |
| | | 5: AnswerShort, |
| | | 6: AnswerAudio, |
| | | 7: AnswerCount, |
| | | 8: AnswerShort, |
| | | }; |
| | | |
| | | |