edit.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <div class="app-contain">
  3. <a-row class="do-exam-title" style="background-color: #f5f5dc">
  4. <a-col :span="24">
  5. <span v-for="item in answer.answerItems" :key="item.itemOrder">
  6. <a-tag
  7. :color="questionDoRightTag(item.doRight)"
  8. class="do-exam-title-tag"
  9. @click="goAnchor('question-' + item.itemOrder)"
  10. >
  11. {{ item.itemOrder }}
  12. </a-tag>
  13. </span>
  14. </a-col>
  15. </a-row>
  16. <a-row class="do-exam-title-hidden">
  17. <a-col :span="24">
  18. <span v-for="item in answer.answerItems" :key="item.itemOrder">
  19. <a-tag class="do-exam-title-tag">{{ item.itemOrder }}</a-tag>
  20. </span>
  21. </a-col>
  22. </a-row>
  23. <a-layout class="app-item-contain">
  24. <a-layout-header class="align-center">
  25. <h1>{{ form.name }}</h1>
  26. <div>
  27. <span class="question-title-padding">试卷得分:{{ answer.score }}</span>
  28. <span class="question-title-padding">试卷耗时:{{ formatSeconds(answer.doTime) }}</span>
  29. </div>
  30. </a-layout-header>
  31. <a-layout-content>
  32. <a-spin :spinning="formLoading">
  33. <a-form :model="form">
  34. <template v-for="(titleItem, index) in form.titleItems" :key="index">
  35. <h3 class="question-title">{{ titleItem.name }}</h3>
  36. <a-card class="exampaper-item-box" v-if="titleItem.questionItems.length !== 0">
  37. <a-form-item
  38. v-for="questionItem in titleItem.questionItems"
  39. :key="questionItem.itemOrder"
  40. :label="questionItem.itemOrder + '.'"
  41. :id="'question-' + questionItem.itemOrder"
  42. class="exam-question-item"
  43. :label-col="{ span: 0 }"
  44. :wrapper-col="{ span: 24 }"
  45. :colon="false"
  46. >
  47. <QuestionAnswerShow
  48. :qType="questionItem.questionType"
  49. :question="questionItem"
  50. :answer="answer.answerItems[questionItem.itemOrder - 1]"
  51. />
  52. <div v-if="answer.answerItems[questionItem.itemOrder - 1].doRight === null" style="margin-top: 10px">
  53. <label style="color: #e6a23c">批改:</label>
  54. <a-radio-group v-model:value="answer.answerItems[questionItem.itemOrder - 1].score">
  55. <a-radio v-for="item in scoreSelect(questionItem.score)" :key="item" :value="item">
  56. {{ item }}
  57. </a-radio>
  58. </a-radio-group>
  59. </div>
  60. </a-form-item>
  61. </a-card>
  62. </template>
  63. <a-row class="do-align-center">
  64. <a-button type="primary" @click="submitForm">提交</a-button>
  65. <a-button style="margin-left: 12px">取消</a-button>
  66. </a-row>
  67. </a-form>
  68. </a-spin>
  69. </a-layout-content>
  70. </a-layout>
  71. </div>
  72. </template>
  73. <script setup>
  74. import { ref, onMounted, nextTick } from 'vue'
  75. import { useRoute, useRouter } from 'vue-router'
  76. import { useExamStore } from '@/store/exam'
  77. import { message, Modal } from 'ant-design-vue'
  78. import { formatSeconds } from '@/utils/exam'
  79. import QuestionAnswerShow from '../components/QuestionAnswerShow.vue'
  80. import questionAnswerApi from '@/api/student/examPaperAnswer'
  81. import '../../style.less'
  82. const route = useRoute()
  83. const router = useRouter()
  84. const examStore = useExamStore()
  85. const { enumFormat } = examStore
  86. const doRightTag = examStore.exam.question.answer.doRightTag
  87. const form = ref({ titleItems: [] })
  88. const formLoading = ref(false)
  89. const answer = ref({
  90. id: null,
  91. score: 0,
  92. doTime: 0,
  93. answerItems: [],
  94. doRight: false
  95. })
  96. function questionDoRightTag(status) {
  97. // ant-design-vue的a-tag color支持字符串,直接用value即可
  98. const tag = enumFormat(doRightTag, status)
  99. if (tag === 'success') return 'green'
  100. if (tag === 'danger') return 'red'
  101. if (tag === 'warning') return 'orange'
  102. return 'default'
  103. }
  104. function goAnchor(id) {
  105. nextTick(() => {
  106. const el = document.getElementById(id)
  107. if (el) {
  108. el.scrollIntoView({ behavior: 'instant', block: 'center', inline: 'nearest' })
  109. }
  110. })
  111. }
  112. function scoreSelect(score) {
  113. let array = []
  114. for (let i = 0; i <= parseInt(score); i++) {
  115. array.push(i.toString())
  116. }
  117. if (String(score).indexOf('.') !== -1) {
  118. array.push(score)
  119. }
  120. return array
  121. }
  122. function submitForm() {
  123. formLoading.value = true
  124. questionAnswerApi
  125. .edit(answer.value)
  126. .then((re) => {
  127. Modal.success({
  128. title: '考试结果',
  129. content: `试卷得分:${re}分`,
  130. okText: '返回考试记录',
  131. onOk: () => {
  132. router.push('/student/record/')
  133. }
  134. })
  135. formLoading.value = false
  136. })
  137. .catch((e) => {
  138. message.error(e.message || '提交失败')
  139. formLoading.value = false
  140. })
  141. }
  142. onMounted(() => {
  143. const id = route.query.id
  144. if (id && parseInt(id) !== 0) {
  145. formLoading.value = true
  146. questionAnswerApi.read(id).then((re) => {
  147. form.value = re.paper
  148. answer.value = re.answer
  149. formLoading.value = false
  150. })
  151. }
  152. })
  153. </script>
  154. <style lang="less" scoped>
  155. .align-center {
  156. text-align: center;
  157. }
  158. .exam-question-item {
  159. padding: 10px;
  160. :deep(.ant-form-item-label > label) {
  161. font-size: 15px !important;
  162. }
  163. }
  164. .question-title-padding {
  165. padding-left: 25px;
  166. padding-right: 25px;
  167. }
  168. </style>