index.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <view class="quiz-detail">
  3. <view class="quiz-title">
  4. {{ quiz?.title }}
  5. </view>
  6. <view class="quiz-list">
  7. <view class="question-item" v-for="(item, index) in quizItems" :key="item.itemId">
  8. <view class="question-title">{{ index + 1 }}.{{ item.label }}</view>
  9. <uv-radio-group v-model="item.answered" placement="column" :disabled="submitted">
  10. <uv-radio
  11. class="question-radio"
  12. :customStyle="{ margin: '8px' }"
  13. v-for="(iten, indey) in item.options"
  14. :key="indey"
  15. :label="iten.text"
  16. :name="iten.no"
  17. >
  18. <template v-if="iten?.type === 'text'">
  19. {{ iten.text }}
  20. </template>
  21. <template v-if="iten?.type === 'img'">
  22. <uv-image
  23. :src="getImgUrl(iten?.text)"
  24. width="210rpx"
  25. height="180rpx"
  26. @click.stop.self="preImg(iten?.text)"
  27. />
  28. </template>
  29. </uv-radio>
  30. </uv-radio-group>
  31. </view>
  32. </view>
  33. <view class="sign-up-btn">
  34. <template v-if="!submitted">
  35. <button class="btn" @click="submitFn">提 交</button>
  36. </template>
  37. <template v-else>
  38. <div class="result">
  39. {{ quiz?.expand?.finalMark >= quiz?.expand?.passingMark ? '考试通过' : '考试不通过' }}
  40. <text>考试成绩: {{ quiz?.expand?.finalMark }}</text>
  41. </div>
  42. </template>
  43. </view>
  44. </view>
  45. </template>
  46. <script setup lang="ts">
  47. import { onLoad } from '@dcloudio/uni-app'
  48. import { quizDetailApi, quizResultCreateApi } from '@/service/modules/quiz'
  49. import { ref } from 'vue'
  50. const id = ref('')
  51. onLoad((e: any) => {
  52. if (e?.id) {
  53. id.value = e.id
  54. getDetail()
  55. }
  56. })
  57. const quizItems = ref<any[]>([])
  58. const quiz = ref()
  59. const submitted = ref(false)
  60. const getDetail = async () => {
  61. const res = await quizDetailApi({ quizId: id.value })
  62. if (res.code === 0) {
  63. if (!res.data.submitted) {
  64. res.data.items.forEach((item: any) => (item.answered = ''))
  65. }
  66. // 是否已经提交
  67. submitted.value = res.data.submitted
  68. quizItems.value = res.data.items
  69. quiz.value = res.data.quiz
  70. }
  71. }
  72. const getImgUrl = (path: string) => import.meta.env.VITE_APP_URL + path
  73. const preImg = (path: string) => {
  74. const url = getImgUrl(path)
  75. const arr = [url]
  76. uni.previewImage({
  77. urls: arr
  78. })
  79. }
  80. const submitFn = async () => {
  81. const flag = quizItems.value?.every((item: any) => item.answered)
  82. if (!flag) {
  83. return uni.showToast({
  84. title: '请检查是否遗漏',
  85. icon: 'none',
  86. duration: 800
  87. })
  88. }
  89. let finalMark = quizItems.value.reduce((accumulator, item) => {
  90. if (item.answer === item.answered) {
  91. return accumulator + item.mark
  92. }
  93. return accumulator + 0
  94. }, 0)
  95. const obj = {
  96. quizId: quiz.value.quizId,
  97. title: quiz.value.title,
  98. itemQty: quiz.value.expand.itemQty,
  99. totalMark: quiz.value.expand.totalMark,
  100. passingMark: quiz.value.expand.passingMark,
  101. finalMark: finalMark,
  102. items: quizItems.value
  103. }
  104. const res = await quizResultCreateApi({ quizResults: [obj] })
  105. if (res.code === 0) {
  106. uni.showToast({
  107. title: '提交成功',
  108. icon: 'none',
  109. duration: 800
  110. })
  111. setTimeout(() => {
  112. uni.navigateBack()
  113. }, 1000)
  114. // getDetail()
  115. }
  116. }
  117. </script>
  118. <style lang="scss" scoped>
  119. .quiz-detail {
  120. .quiz-title {
  121. text-align: center;
  122. margin: 20rpx auto;
  123. font-weight: 600;
  124. font-size: 36rpx;
  125. }
  126. .quiz-list {
  127. margin-top: 30rpx;
  128. padding-bottom: 120rpx;
  129. .question-item {
  130. .question-title {
  131. font-weight: 36rpx;
  132. margin-bottom: 20rpx;
  133. }
  134. padding: 40rpx 24rpx;
  135. background-color: #fff;
  136. border-bottom: 1px solid #f6f6f6;
  137. }
  138. }
  139. .sign-up-btn {
  140. position: fixed;
  141. background-color: #fff;
  142. bottom: 0;
  143. left: 0;
  144. right: 0;
  145. height: 120rpx;
  146. .btn {
  147. width: 690rpx;
  148. margin: 20rpx 30rpx;
  149. height: 70rpx;
  150. text-align: center;
  151. line-height: 70rpx;
  152. font-size: 30rpx;
  153. color: #fff;
  154. background-color: #6eb657;
  155. border-radius: 20rpx;
  156. }
  157. .result {
  158. width: 690rpx;
  159. margin: 20rpx 30rpx;
  160. height: 70rpx;
  161. text-align: center;
  162. line-height: 70rpx;
  163. font-size: 30rpx;
  164. color: #fff;
  165. background-color: #ccc;
  166. border-radius: 20rpx;
  167. }
  168. .disabled {
  169. background-color: #ccc;
  170. }
  171. }
  172. }
  173. </style>