Sin descripción

start.vue 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <script setup lang="ts">
  2. import { onMounted, ref } from 'vue'
  3. import { useRoute } from 'vue-router'
  4. import { useMessage, useToast } from 'wot-design-uni'
  5. import { examDetail } from '@/api/exam'
  6. import { startExam } from '@/api/exam/participant'
  7. import { useAuthStore } from '@/store/auth'
  8. import { useTokenStore } from '@/store/token'
  9. const tokenStore: any = useTokenStore()
  10. const toast = useToast()
  11. const wotMessage = useMessage()
  12. const authStore = useAuthStore()
  13. const route = useRoute()
  14. // const id = ref(Number(route.query.id))
  15. const examId = ref(Number(route.query.id || '0'))
  16. console.log(tokenStore.tokenInfo, 'tokenStore.tokenInfo')
  17. const token = ref(tokenStore.tokenInfo?.token || '')
  18. const examInfo: any = ref({
  19. examName: '',
  20. totalScore: 100,
  21. passScore: 60,
  22. examDuration: '30分钟',
  23. examDescription: '',
  24. })
  25. const loginUser: any = ref({
  26. username: '',
  27. password: '',
  28. })
  29. onMounted(async () => {
  30. const res: any = await examDetail(examId.value)
  31. if (res.code === 200) {
  32. examInfo.value = res.data || {}
  33. }
  34. })
  35. function startExamEvent() {
  36. // 判断开始是否在进行中
  37. if (examInfo.value.examStatus !== 'ongoing') {
  38. toast.error('当前考试状态不是进行中,不能开始考试')
  39. return
  40. }
  41. if (
  42. examInfo.value.examStartTime
  43. && new Date(examInfo.value.examStartTime).getTime() > Date.now()
  44. ) {
  45. toast.error('考试还未开始')
  46. return
  47. }
  48. if (
  49. examInfo.value.examEndTime
  50. && new Date(examInfo.value.examEndTime).getTime() < Date.now()
  51. ) {
  52. toast.error('考试已结束')
  53. return
  54. }
  55. // 增加一个二次确认提醒,提醒开始之后必须完成
  56. wotMessage.confirm({
  57. msg: `考试过程中不可以退出,完成之后需要点击提交试卷按钮`,
  58. title: '考试提醒',
  59. }).then(async () => {
  60. try {
  61. const res: any = await startExam(+(examId.value || '0'))
  62. if (res.code !== 200) {
  63. toast.error(`操作失败${res.msg}`)
  64. return
  65. }
  66. const userType = res?.userType || ''
  67. localStorage.setItem('exam:usertype', userType)
  68. if (userType === 'exam') {
  69. // router.replace({
  70. // name: 'Startexamin',
  71. // params: {
  72. // id: route.params.id,
  73. // },
  74. // query: {
  75. // pid: res.id,
  76. // },
  77. // })
  78. uni.navigateTo({
  79. url: `/pages/knowledge/exam/answer?id=${examId.value}&pid=${res?.id}`,
  80. })
  81. }
  82. else {
  83. uni.navigateTo({
  84. url: `/pages/knowledge/exam/answer?id=${examId.value}&pid=${res?.id}`,
  85. })
  86. // router.replace({
  87. // name: 'StartExamin',
  88. // params: {
  89. // id: route.params.id,
  90. // },
  91. // query: {
  92. // pid: res.id,
  93. // },
  94. // })
  95. }
  96. }
  97. catch (error) {
  98. toast.error(`操作失败${error}`)
  99. }
  100. })
  101. }
  102. async function start() {
  103. if (token.value) {
  104. startExamEvent()
  105. }
  106. else {
  107. if (!loginUser.value.username && !loginUser.value.password) {
  108. toast.error('请输入姓名或手机号')
  109. return
  110. }
  111. try {
  112. await authStore.authExamLogin(loginUser.value)
  113. token.value = tokenStore.tokenInfo?.token || ''
  114. startExamEvent()
  115. }
  116. catch (error) {
  117. toast.error(`操作失败${error}`)
  118. }
  119. }
  120. }
  121. </script>
  122. <template>
  123. <view class="knowledgebase_exam_explanation">
  124. <view class="knowledgebase_exam_explanation_title">
  125. {{ examInfo.examName }}
  126. </view>
  127. <view class="knowledgebase_exam_explanation_content">
  128. <view class="knowledgebase_exam_explanation_content_title">
  129. 考试说明
  130. </view>
  131. <view class="knowledgebase_exam_explanation_content_text">
  132. {{ examInfo.examDescription }}
  133. </view>
  134. </view>
  135. <view class="knowledgebase_exam_explanation_float">
  136. <view class="knowledgebase_exam_explanation_float_title">
  137. 考试总分
  138. <span class="knowledgebase_exam_explanation_float_title_score">
  139. {{ examInfo.totalScore }}分
  140. </span>
  141. </view>
  142. <view class="knowledgebase_exam_explanation_float_title">
  143. 及格分数
  144. <span class="knowledgebase_exam_explanation_float_title_score">
  145. {{ examInfo.passScore }}分
  146. </span>
  147. </view>
  148. <view class="knowledgebase_exam_explanation_float_title">
  149. 考试时长
  150. <span class="knowledgebase_exam_explanation_float_title_score">
  151. {{ examInfo.examDuration }} 分钟
  152. </span>
  153. </view>
  154. </view>
  155. <view v-if="!token" class="knowledgebase_exam_explanation_form">
  156. <view class="knowledgebase_exam_explanation_form_item">
  157. <view class="knowledgebase_exam_explanation_form_item_label">
  158. 姓名
  159. </view>
  160. <input
  161. v-model="loginUser.password"
  162. type="text"
  163. class="knowledgebase_exam_explanation_form_item_input"
  164. placeholder="请输入姓名"
  165. >
  166. </view>
  167. <view class="knowledgebase_exam_explanation_form_item">
  168. <view class="knowledgebase_exam_explanation_form_item_label">
  169. 手机号
  170. </view>
  171. <input
  172. v-model="loginUser.username"
  173. type="number"
  174. class="knowledgebase_exam_explanation_form_item_input"
  175. placeholder="请输入手机号"
  176. >
  177. </view>
  178. </view>
  179. <wd-button class="knowledgebase_exam_explanation_float_button" @click="start">
  180. 开始考试
  181. </wd-button>
  182. <!-- <wd-button disabled class="knowledgebase_exam_explanation_float_button"
  183. >考试将于2026-2-1 19:00开始</wd-button
  184. > -->
  185. <wd-toast />
  186. <wd-message-box />
  187. </view>
  188. </template>
  189. <style scoped lang="scss">
  190. html,
  191. body {
  192. overflow: hidden;
  193. }
  194. .knowledgebase_exam_explanation {
  195. height: calc(100vh - 88rpx);
  196. display: flex;
  197. flex-direction: column;
  198. // justify-content: space-between;
  199. padding: 24rpx;
  200. box-sizing: border-box;
  201. }
  202. .knowledgebase_exam_explanation_title {
  203. font-family: Alibaba PuHuiTi 2;
  204. font-weight: 500;
  205. font-style: 65 Medium;
  206. font-size: 48rpx;
  207. leading-trim: NONE;
  208. line-height: 48rpx;
  209. letter-spacing: 0px;
  210. color: #31373d;
  211. }
  212. .knowledgebase_exam_explanation_content {
  213. margin-top: 80rpx;
  214. width: 100%;
  215. display: flex;
  216. flex-direction: column;
  217. gap: 32rpx;
  218. .knowledgebase_exam_explanation_content_title {
  219. font-weight: 500;
  220. font-style: 65 Medium;
  221. font-size: 36rpx;
  222. leading-trim: NONE;
  223. letter-spacing: 0px;
  224. color: #31373d;
  225. }
  226. .knowledgebase_exam_explanation_content_text {
  227. font-weight: 400;
  228. font-style: 55 Regular;
  229. font-size: 28rpx;
  230. line-height: 48rpx;
  231. letter-spacing: 0px;
  232. color: #4e5969;
  233. }
  234. }
  235. .knowledgebase_exam_explanation_float {
  236. margin-top: 48rpx;
  237. border-top: 1rpx solid #eeeeee;
  238. padding-top: 48rpx;
  239. box-sizing: border-box;
  240. display: flex;
  241. flex-direction: column;
  242. gap: 32rpx;
  243. .knowledgebase_exam_explanation_float_title {
  244. font-weight: 400;
  245. font-style: 55 Regular;
  246. font-size: 28rpx;
  247. letter-spacing: 0px;
  248. color: #4e5969;
  249. .knowledgebase_exam_explanation_float_title_score {
  250. margin-left: 48rpx;
  251. color: #31373d;
  252. }
  253. }
  254. }
  255. .knowledgebase_exam_explanation_float_button {
  256. margin-top: auto;
  257. width: 100%;
  258. background-color: #215acd !important;
  259. height: 80rpx !important;
  260. border-radius: 8rpx !important;
  261. }
  262. .knowledgebase_exam_explanation_form {
  263. margin-top: 48rpx;
  264. border-top: 1rpx solid #eeeeee;
  265. padding-top: 48rpx;
  266. box-sizing: border-box;
  267. display: flex;
  268. flex-direction: column;
  269. gap: 32rpx;
  270. }
  271. .knowledgebase_exam_explanation_form_item {
  272. display: flex;
  273. flex-direction: column;
  274. gap: 16rpx;
  275. }
  276. .knowledgebase_exam_explanation_form_item_label {
  277. font-weight: 400;
  278. font-style: 55 Regular;
  279. font-size: 28rpx;
  280. letter-spacing: 0px;
  281. color: #4e5969;
  282. }
  283. .knowledgebase_exam_explanation_form_item_input {
  284. width: 100%;
  285. height: 80rpx;
  286. border: 1rpx solid #dcdfe6;
  287. border-radius: 8rpx;
  288. padding: 0 24rpx;
  289. box-sizing: border-box;
  290. font-size: 28rpx;
  291. color: #31373d;
  292. background-color: #ffffff;
  293. }
  294. .knowledgebase_exam_explanation_form_item_input::placeholder {
  295. color: #c0c4cc;
  296. }
  297. </style>