2 Commits 6402ef915b ... e1bf80e495

Autor SHA1 Mensagem Data
  闪电 e1bf80e495 Merge branch 'master' of http://39.164.159.226:3000/hnsh-smart-steward/smart-steward-mobile 3 semanas atrás
  闪电 f0c2a7d255 mod: 考试 3 semanas atrás

+ 15 - 4
src/pages/knowledge/exam/examresults/scoresnotreleased.vue

@@ -1,8 +1,15 @@
1 1
 <script setup lang="ts">
2
+import { useRoute } from 'vue-router'
3
+
2 4
 import kong from '@/assets/kong.png'
3
-const handleClick = () => {
5
+
6
+const route = useRoute()
7
+const examId = Number(route.query.id || 0)
8
+const pid = Number(route.query.pid || 0)
9
+
10
+function handleClick() {
4 11
   uni.navigateTo({
5
-    url: '/pages/knowledge/exam/index',
12
+    url: `/pages/knowledge/exam/result?id=${examId}&pid=${pid}`,
6 13
   })
7 14
 }
8 15
 </script>
@@ -15,12 +22,16 @@ const handleClick = () => {
15 22
         <!-- <text class="icon-check">✓</text> -->
16 23
       </view>
17 24
     </view>
18
-    <view class="success-title">正在批改......</view>
25
+    <view class="success-title">
26
+      正在批改......
27
+    </view>
19 28
     <view class="success-message">
20 29
       请稍后在【我的考试-已考试】中查看成绩。
21 30
     </view>
22 31
     <view class="success-button">
23
-      <view class="button" @click="handleClick">查看我的考试</view>
32
+      <view class="button" @click="handleClick">
33
+        查看我的考试
34
+      </view>
24 35
     </view>
25 36
   </view>
26 37
 </template>

+ 0 - 508
src/pages/knowledge/exam/examresults/index.vue

@@ -1,508 +0,0 @@
1
-<script setup lang="ts">
2
-import { ref } from 'vue'
3
-const list = ref([
4
-  {
5
-    type: 'single',
6
-    title: '第一题单选题(本题分值1分)',
7
-    score: 1,
8
-    list: [
9
-      {
10
-        title: '这是本题的题目,请选择',
11
-        answer: [
12
-          {
13
-            title: 'A.答案1',
14
-            isRight: true,
15
-          },
16
-          {
17
-            title: 'B.答案2',
18
-            isRight: false,
19
-          },
20
-          {
21
-            title: 'B.答案3',
22
-            isRight: '',
23
-          },
24
-          {
25
-            title: 'B.答案4',
26
-            isRight: '',
27
-          },
28
-        ],
29
-        AnswerExplanation:
30
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
31
-      },
32
-      {
33
-        title: '这是本题的题目,请选择',
34
-        answer: [
35
-          {
36
-            title: 'A.答案1',
37
-            isRight: '',
38
-          },
39
-          {
40
-            title: 'B.答案2',
41
-            isRight: true,
42
-          },
43
-          {
44
-            title: 'B.答案3',
45
-            isRight: '',
46
-          },
47
-          {
48
-            title: 'B.答案4',
49
-            isRight: false,
50
-          },
51
-        ],
52
-        AnswerExplanation:
53
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
54
-      },
55
-    ],
56
-  },
57
-  {
58
-    type: 'single',
59
-    title: '第二题多选题(本题分值1分)',
60
-    score: 1,
61
-    list: [
62
-      {
63
-        title: '这是本题的题目,请选择',
64
-        answer: [
65
-          {
66
-            title: 'A.答案1',
67
-            isRight: true,
68
-          },
69
-          {
70
-            title: 'B.答案2',
71
-            isRight: true,
72
-          },
73
-          {
74
-            title: 'B.答案3',
75
-            isRight: true,
76
-          },
77
-          {
78
-            title: 'B.答案4',
79
-            isRight: false,
80
-          },
81
-        ],
82
-        AnswerExplanation:
83
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
84
-      },
85
-      {
86
-        title: '这是本题的题目,请选择',
87
-        answer: [
88
-          {
89
-            title: 'A.答案1',
90
-            isRight: false,
91
-          },
92
-          {
93
-            title: 'B.答案2',
94
-            isRight: true,
95
-          },
96
-          {
97
-            title: 'B.答案3',
98
-            isRight: false,
99
-          },
100
-          {
101
-            title: 'B.答案4',
102
-            isRight: true,
103
-          },
104
-        ],
105
-        AnswerExplanation:
106
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
107
-      },
108
-    ],
109
-  },
110
-  {
111
-    type: 'single',
112
-    title: '第三题判断题(本题分值1分)',
113
-    score: 1,
114
-    list: [
115
-      {
116
-        title: '这是本题的题目,请选择',
117
-        answer: [
118
-          {
119
-            title: 'A.答案1',
120
-            isRight: true,
121
-          },
122
-          {
123
-            title: 'B.答案2',
124
-            isRight: false,
125
-          },
126
-        ],
127
-        AnswerExplanation:
128
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
129
-      },
130
-      {
131
-        title: '这是本题的题目,请选择',
132
-        answer: [
133
-          {
134
-            title: 'A.答案1',
135
-            isRight: false,
136
-          },
137
-          {
138
-            title: 'B.答案2',
139
-            isRight: true,
140
-          },
141
-        ],
142
-        AnswerExplanation:
143
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
144
-      },
145
-    ],
146
-  },
147
-  {
148
-    type: 'single',
149
-    title: '第四题填空题(本题分值1分)',
150
-    score: 1,
151
-    list: [
152
-      {
153
-        title: '1.这是本题的题目(),(),()',
154
-        answer: [
155
-          {
156
-            title: 'A.填空',
157
-            answertext: '考生输入的答案1',
158
-            isRight: true,
159
-          },
160
-          {
161
-            title: 'B.填空',
162
-            answertext: '考生输入的答案2',
163
-            isRight: true,
164
-          },
165
-          {
166
-            title: 'C.填空',
167
-            answertext: '考生输入的答案3',
168
-            isRight: false,
169
-          },
170
-        ],
171
-        AnswerExplanation:
172
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
173
-      },
174
-      {
175
-        title: '2.这是本题的题目(),(),()',
176
-        answer: [
177
-          {
178
-            title: 'A.填空',
179
-            answertext: '考生输入的答案1',
180
-            isRight: true,
181
-          },
182
-          {
183
-            title: 'B.填空',
184
-            answertext: '考生输入的答案2',
185
-            isRight: false,
186
-          },
187
-        ],
188
-        AnswerExplanation:
189
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
190
-      },
191
-    ],
192
-  },
193
-  {
194
-    type: 'single',
195
-    title: '第五题简答题(本题分值1分)',
196
-    score: 1,
197
-    list: [
198
-      {
199
-        title: '1.这是本题的题目。',
200
-        answer: [
201
-          {
202
-            title: '这是一个简答题',
203
-            answertext:
204
-              '考生输入的答案考生输入的答案考生输入的答案考生输入的答案考生输入的答案考生输入的答案',
205
-            Correctanswer: '正确答案正确答案正确答案正确答案正确答案正确答案',
206
-            isRight: true,
207
-          },
208
-        ],
209
-        AnswerExplanation:
210
-          '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
211
-      },
212
-    ],
213
-  },
214
-]) as any
215
-</script>
216
-<template>
217
-  <view class="knowledgebase_exam_explanation">
218
-    <view class="knowledgebase_exam_explanation_title">
219
-      考试名称考试名称考试名称考试考试名称考试名称考试名称
220
-    </view>
221
-    <view class="knowledgebase_exam_explanation_content">
222
-      <view class="knowledgebase_exam_explanation_content_title">
223
-        考试说明
224
-      </view>
225
-      <view class="knowledgebase_exam_explanation_content_text">
226
-        考试说明考试说明考试说明考试说明考试说明考试说明考试说明。
227
-      </view>
228
-    </view>
229
-    <view class="knowledgebase_exam_explanation_float">
230
-      <view class="knowledgebase_exam_explanation_float_title">
231
-        考试总分
232
-        <span class="knowledgebase_exam_explanation_float_title_score"
233
-          >100分</span
234
-        ></view
235
-      >
236
-      <view class="knowledgebase_exam_explanation_float_title">
237
-        及格分数
238
-        <span class="knowledgebase_exam_explanation_float_title_score"
239
-          >60分</span
240
-        ></view
241
-      >
242
-      <view class="knowledgebase_exam_explanation_float_title">
243
-        考试时长
244
-        <span class="knowledgebase_exam_explanation_float_title_score"
245
-          >90分钟</span
246
-        ></view
247
-      >
248
-      <view class="knowledgebase_exam_explanation_float_title">
249
-        考生得分
250
-        <span
251
-          class="knowledgebase_exam_explanation_float_title_score"
252
-          style="color: #215acd"
253
-          >80分</span
254
-        ></view
255
-      >
256
-      <view class="knowledgebase_exam_explanation_float_title">
257
-        考试结果
258
-        <span
259
-          class="knowledgebase_exam_explanation_float_title_score"
260
-          style="color: #38b865"
261
-          >及格</span
262
-        ></view
263
-      >
264
-    </view>
265
-    <view class="AnswerDetails">
266
-      <view class="AnswerDetails_title">答题详情</view>
267
-      <view class="AnswerDetails_content" v-for="value in list">
268
-        <view class="AnswerDetails_content_box">
269
-          <view class="AnswerDetails_content_title">{{ value.title }}</view>
270
-          <view class="AnswerDetails_content_item" v-for="items in value.list">
271
-            <view class="Thisquestiontitle">
272
-              <view class="AnswerDetails_content_item_title">
273
-                {{ items.title }}
274
-              </view>
275
-              <view class="AnswerDetails_content_item_answer">
276
-                <text
277
-                  :style="
278
-                    values.isRight === true
279
-                      ? 'color: #38B865'
280
-                      : values.isRight === false
281
-                        ? 'color: #EB5E12'
282
-                        : ''
283
-                  "
284
-                  v-for="values in items?.answer"
285
-                  :key="values.title"
286
-                >
287
-                  <text
288
-                    v-if="
289
-                      value.title.includes('单选题') ||
290
-                      value.title.includes('多选题') ||
291
-                      value.title.includes('判断题')
292
-                    "
293
-                    >{{ values.title }}</text
294
-                  >
295
-                  <text v-else-if="value.title.includes('填空题')">{{
296
-                    ` ${values.title}: ${values.answertext}`
297
-                  }}</text>
298
-                  <text v-else-if="value.title.includes('简答题')">{{
299
-                    ` ${values.title}: ${values.answertext}`
300
-                  }}</text>
301
-                  <wd-icon
302
-                    v-if="values.isRight"
303
-                    style="
304
-                      color: #38b865;
305
-                      text-align: center;
306
-                      margin-left: 20rpx;
307
-                    "
308
-                    name="check-circle-filled"
309
-                    size="16px"
310
-                  ></wd-icon>
311
-                  <wd-icon
312
-                    v-else-if="values.isRight === false"
313
-                    style="
314
-                      color: #eb5e12;
315
-                      text-align: center;
316
-                      margin-left: 20rpx;
317
-                    "
318
-                    name="close-circle-filled"
319
-                    size="16px"
320
-                  ></wd-icon>
321
-                </text>
322
-              </view>
323
-            </view>
324
-            <view class="AnswerExplanation_box">
325
-              <view class="Correctanswer" style="margin-bottom: 48rpx">
326
-                <text class="Correctanswer_title">正确答案 : </text>
327
-                <text
328
-                  v-if="value.title.includes('简答题')"
329
-                  class="Correctanswer_title Content"
330
-                  v-for="values in items?.answer.filter((a) => a.isRight)"
331
-                  :key="values.title"
332
-                >
333
-                  {{ `${values.Correctanswer};` }}
334
-                </text>
335
-                <text
336
-                  v-else
337
-                  class="Correctanswer_title Content"
338
-                  v-for="values in items?.answer.filter((a) => a.isRight)"
339
-                  :key="values.title"
340
-                >
341
-                  {{ `${values.title};` }}
342
-                </text>
343
-              </view>
344
-              <view class="AnswerExplanation">
345
-                <view class="Correctanswer_title" style="margin-bottom: 32rpx"
346
-                  >答案解析:</view
347
-                >
348
-                <text class="Correctanswer_Content">{{
349
-                  items.AnswerExplanation
350
-                }}</text>
351
-              </view>
352
-            </view>
353
-          </view>
354
-        </view>
355
-      </view>
356
-    </view>
357
-  </view>
358
-</template>
359
-<style scoped lang="scss">
360
-html,
361
-body {
362
-  overflow: hidden;
363
-}
364
-.knowledgebase_exam_explanation {
365
-  height: calc(100vh - 88rpx);
366
-  display: flex;
367
-  flex-direction: column;
368
-  padding: 24rpx;
369
-  box-sizing: border-box;
370
-}
371
-.knowledgebase_exam_explanation_title {
372
-  font-family: Alibaba PuHuiTi 2;
373
-  font-weight: 500;
374
-  font-style: 65 Medium;
375
-  font-size: 48rpx;
376
-  leading-trim: NONE;
377
-  line-height: 48rpx;
378
-  letter-spacing: 0px;
379
-  color: #31373d;
380
-}
381
-.knowledgebase_exam_explanation_content {
382
-  margin-top: 80rpx;
383
-  width: 100%;
384
-  display: flex;
385
-  flex-direction: column;
386
-  gap: 32rpx;
387
-  .knowledgebase_exam_explanation_content_title {
388
-    font-weight: 500;
389
-    font-style: 65 Medium;
390
-    font-size: 36rpx;
391
-    leading-trim: NONE;
392
-    letter-spacing: 0px;
393
-    color: #31373d;
394
-  }
395
-  .knowledgebase_exam_explanation_content_text {
396
-    font-weight: 400;
397
-    font-style: 55 Regular;
398
-    font-size: 28rpx;
399
-    line-height: 48rpx;
400
-    letter-spacing: 0px;
401
-    color: #4e5969;
402
-  }
403
-}
404
-.knowledgebase_exam_explanation_float {
405
-  margin-top: 48rpx;
406
-  margin-bottom: 48rpx;
407
-  border-top: 1rpx solid #eeeeee;
408
-  border-bottom: 1rpx solid #eeeeee;
409
-  padding-top: 48rpx;
410
-  padding-bottom: 48rpx;
411
-  box-sizing: border-box;
412
-  display: flex;
413
-  flex-direction: column;
414
-  gap: 32rpx;
415
-  .knowledgebase_exam_explanation_float_title {
416
-    font-weight: 400;
417
-    font-style: 55 Regular;
418
-    font-size: 28rpx;
419
-    letter-spacing: 0px;
420
-    color: #4e5969;
421
-    .knowledgebase_exam_explanation_float_title_score {
422
-      margin-left: 48rpx;
423
-      color: #31373d;
424
-    }
425
-  }
426
-}
427
-.AnswerDetails {
428
-  flex: 1;
429
-  overflow-y: auto;
430
-  .AnswerDetails_title {
431
-    font-weight: 500;
432
-    font-style: 65 Medium;
433
-    font-size: 36rpx;
434
-    leading-trim: NONE;
435
-    letter-spacing: 0px;
436
-    color: #31373d;
437
-    margin-bottom: 48rpx;
438
-  }
439
-  .AnswerDetails_content {
440
-    // width: 100%;
441
-    // display: flex;
442
-    // flex-direction: column;
443
-    // gap: 24rpx;
444
-    margin-bottom: 24rpx;
445
-    .AnswerDetails_content_box {
446
-      display: flex;
447
-      flex-direction: column;
448
-      gap: 24rpx;
449
-    }
450
-    .AnswerDetails_content_title {
451
-      width: 100%;
452
-      height: 96rpx;
453
-      background-color: #f7f9fa;
454
-      padding-left: 32rpx;
455
-      box-sizing: border-box;
456
-      line-height: 88rpx;
457
-
458
-      font-weight: 500;
459
-      font-size: 32rpx;
460
-      color: #31373d;
461
-    }
462
-    .AnswerDetails_content_item {
463
-      box-sizing: border-box;
464
-      padding: 32rpx;
465
-      width: 100%;
466
-      background-color: #f7f9fa;
467
-      .Thisquestiontitle {
468
-        border-bottom: 1rpx solid #e6e8eb;
469
-        box-sizing: border-box;
470
-        padding-bottom: 48rpx;
471
-        margin-bottom: 48rpx;
472
-        .AnswerDetails_content_item_title {
473
-          margin-bottom: 48rpx;
474
-          font-weight: 400;
475
-          font-size: 32rpx;
476
-          color: #31373d;
477
-        }
478
-        .AnswerDetails_content_item_answer {
479
-          display: flex;
480
-          flex-direction: column;
481
-          gap: 52rpx;
482
-
483
-          font-weight: 400;
484
-          font-size: 28rpx;
485
-          color: #31373d;
486
-        }
487
-      }
488
-      .AnswerExplanation_box {
489
-        .Correctanswer_title {
490
-          font-weight: 400;
491
-          font-size: 28rpx;
492
-          color: #31373d;
493
-        }
494
-        .Content {
495
-          color: #38b865;
496
-          margin-right: 10rpx;
497
-        }
498
-        .Correctanswer_Content {
499
-          font-weight: 400;
500
-          font-size: 32rpx;
501
-          color: #4e5969;
502
-          line-height: 56rpx;
503
-        }
504
-      }
505
-    }
506
-  }
507
-}
508
-</style>

+ 10 - 1
src/pages/knowledge/exam/index.vue

@@ -185,7 +185,16 @@ function goDetail(item) {
185 185
     })
186 186
   }
187 187
   else {
188
-    ExamtakenDetail(item)
188
+    if (item.reviewStatus === 'unreviewed') {
189
+      uni.navigateTo({
190
+        url: `/pages/knowledge/exam/correct?id=${item.id}&pid=${item.participantId}`,
191
+      })
192
+    }
193
+    else {
194
+      uni.navigateTo({
195
+        url: `/pages/knowledge/exam/result?id=${item.id}&pid=${item.participantId}`,
196
+      })
197
+    }
189 198
   }
190 199
 }
191 200
 

+ 738 - 0
src/pages/knowledge/exam/result.vue

@@ -0,0 +1,738 @@
1
+<script setup lang="ts">
2
+import { onMounted, ref } from 'vue'
3
+
4
+import { useRoute } from 'vue-router'
5
+
6
+import { examPaperDetail } from '@/api/exam'
7
+import { getAnswerResult } from '@/api/exam/answer'
8
+import { getParticipantById } from '@/api/exam/participant'
9
+
10
+const route = useRoute()
11
+const examId = Number(route.query.id || 0)
12
+const pid = Number(route.query.pid || 0)
13
+
14
+const participantInfo = ref<any>({})
15
+
16
+// 考试信息
17
+const examInfo = ref<any>({})
18
+// 答题信息
19
+const answerInfo = ref<any>([])
20
+
21
+// onMounted(() => {
22
+//   getParticipantById(pid).then((res: any) => {
23
+//     participantInfo.value = res || {}
24
+//   })
25
+// })
26
+
27
+// 计算用时
28
+function calculateExamTime() {
29
+  if (!participantInfo.value.startTime || !participantInfo.value.submitTime) {
30
+    return '-'
31
+  }
32
+  const startTime = new Date(participantInfo.value.startTime).getTime()
33
+  const submitTime = new Date(participantInfo.value.submitTime).getTime()
34
+  const duration = (submitTime - startTime) / 60_000 // 转换为分钟
35
+  return `${duration.toFixed(2)} 分钟`
36
+}
37
+
38
+// 数据处理工具函数
39
+// 解析JSON字符串,处理异常
40
+function parseJson(str: string) {
41
+  if (!str)
42
+    return []
43
+  try {
44
+    return JSON.parse(str)
45
+  }
46
+  catch (error) {
47
+    console.error('解析JSON失败:', error)
48
+    return []
49
+  }
50
+}
51
+
52
+// 根据paperQuestionId获取答题信息
53
+function getAnswerByPaperQuestionId(paperQuestionId: number) {
54
+  return (
55
+    answerInfo.value.find(
56
+      (item: any) => item.paperQuestionId === paperQuestionId,
57
+    ) || {}
58
+  )
59
+}
60
+// 获取题目类型中文名称
61
+function getQuestionTypeName(type: string) {
62
+  const typeMap: any = {
63
+    single_choice: '单选题',
64
+    multiple_choice: '多选题',
65
+    judgment: '判断题',
66
+    fill_blank: '填空题',
67
+    essay: '简答题',
68
+  }
69
+  return typeMap[type] || type
70
+}
71
+
72
+// 按大题索引分组题目
73
+function getQuestionsByBigIndex() {
74
+  if (!examInfo.value?.paper?.questions)
75
+    return []
76
+
77
+  const grouped: any = {}
78
+  examInfo.value.paper.questions.forEach((question: any) => {
79
+    if (!grouped[question.bigQuestionIndex]) {
80
+      grouped[question.bigQuestionIndex] = []
81
+    }
82
+    grouped[question.bigQuestionIndex].push(question)
83
+  })
84
+
85
+  // 转换为数组并按索引排序
86
+  return Object.keys(grouped)
87
+    .sort((a, b) => Number(a) - Number(b))
88
+    .map(key => grouped[key])
89
+}
90
+
91
+async function init() {
92
+  // 并发请求接口获取数据
93
+  const [examInfoRes, participantRes, answerRes]: any = await Promise.all([
94
+    examPaperDetail(examId),
95
+    getParticipantById(pid),
96
+    getAnswerResult(examId),
97
+  ])
98
+  examInfo.value = examInfoRes.data || {}
99
+  if (examInfo.value?.paper?.bigQuestionNames) {
100
+    examInfo.value.paper.bigQuestionNames = JSON.parse(
101
+      examInfo.value.paper.bigQuestionNames,
102
+    )
103
+  }
104
+  participantInfo.value = participantRes.data || {}
105
+  answerInfo.value = answerRes.data || {}
106
+}
107
+
108
+onMounted(async () => {
109
+  await init()
110
+})
111
+
112
+// const list = ref([
113
+//   {
114
+//     type: 'single',
115
+//     title: '第一题单选题(本题分值1分)',
116
+//     score: 1,
117
+//     list: [
118
+//       {
119
+//         title: '这是本题的题目,请选择',
120
+//         answer: [
121
+//           {
122
+//             title: 'A.答案1',
123
+//             isRight: true,
124
+//           },
125
+//           {
126
+//             title: 'B.答案2',
127
+//             isRight: false,
128
+//           },
129
+//           {
130
+//             title: 'B.答案3',
131
+//             isRight: '',
132
+//           },
133
+//           {
134
+//             title: 'B.答案4',
135
+//             isRight: '',
136
+//           },
137
+//         ],
138
+//         AnswerExplanation:
139
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
140
+//       },
141
+//       {
142
+//         title: '这是本题的题目,请选择',
143
+//         answer: [
144
+//           {
145
+//             title: 'A.答案1',
146
+//             isRight: '',
147
+//           },
148
+//           {
149
+//             title: 'B.答案2',
150
+//             isRight: true,
151
+//           },
152
+//           {
153
+//             title: 'B.答案3',
154
+//             isRight: '',
155
+//           },
156
+//           {
157
+//             title: 'B.答案4',
158
+//             isRight: false,
159
+//           },
160
+//         ],
161
+//         AnswerExplanation:
162
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
163
+//       },
164
+//     ],
165
+//   },
166
+//   {
167
+//     type: 'single',
168
+//     title: '第二题多选题(本题分值1分)',
169
+//     score: 1,
170
+//     list: [
171
+//       {
172
+//         title: '这是本题的题目,请选择',
173
+//         answer: [
174
+//           {
175
+//             title: 'A.答案1',
176
+//             isRight: true,
177
+//           },
178
+//           {
179
+//             title: 'B.答案2',
180
+//             isRight: true,
181
+//           },
182
+//           {
183
+//             title: 'B.答案3',
184
+//             isRight: true,
185
+//           },
186
+//           {
187
+//             title: 'B.答案4',
188
+//             isRight: false,
189
+//           },
190
+//         ],
191
+//         AnswerExplanation:
192
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
193
+//       },
194
+//       {
195
+//         title: '这是本题的题目,请选择',
196
+//         answer: [
197
+//           {
198
+//             title: 'A.答案1',
199
+//             isRight: false,
200
+//           },
201
+//           {
202
+//             title: 'B.答案2',
203
+//             isRight: true,
204
+//           },
205
+//           {
206
+//             title: 'B.答案3',
207
+//             isRight: false,
208
+//           },
209
+//           {
210
+//             title: 'B.答案4',
211
+//             isRight: true,
212
+//           },
213
+//         ],
214
+//         AnswerExplanation:
215
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
216
+//       },
217
+//     ],
218
+//   },
219
+//   {
220
+//     type: 'single',
221
+//     title: '第三题判断题(本题分值1分)',
222
+//     score: 1,
223
+//     list: [
224
+//       {
225
+//         title: '这是本题的题目,请选择',
226
+//         answer: [
227
+//           {
228
+//             title: 'A.答案1',
229
+//             isRight: true,
230
+//           },
231
+//           {
232
+//             title: 'B.答案2',
233
+//             isRight: false,
234
+//           },
235
+//         ],
236
+//         AnswerExplanation:
237
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
238
+//       },
239
+//       {
240
+//         title: '这是本题的题目,请选择',
241
+//         answer: [
242
+//           {
243
+//             title: 'A.答案1',
244
+//             isRight: false,
245
+//           },
246
+//           {
247
+//             title: 'B.答案2',
248
+//             isRight: true,
249
+//           },
250
+//         ],
251
+//         AnswerExplanation:
252
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
253
+//       },
254
+//     ],
255
+//   },
256
+//   {
257
+//     type: 'single',
258
+//     title: '第四题填空题(本题分值1分)',
259
+//     score: 1,
260
+//     list: [
261
+//       {
262
+//         title: '1.这是本题的题目(),(),()',
263
+//         answer: [
264
+//           {
265
+//             title: 'A.填空',
266
+//             answertext: '考生输入的答案1',
267
+//             isRight: true,
268
+//           },
269
+//           {
270
+//             title: 'B.填空',
271
+//             answertext: '考生输入的答案2',
272
+//             isRight: true,
273
+//           },
274
+//           {
275
+//             title: 'C.填空',
276
+//             answertext: '考生输入的答案3',
277
+//             isRight: false,
278
+//           },
279
+//         ],
280
+//         AnswerExplanation:
281
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
282
+//       },
283
+//       {
284
+//         title: '2.这是本题的题目(),(),()',
285
+//         answer: [
286
+//           {
287
+//             title: 'A.填空',
288
+//             answertext: '考生输入的答案1',
289
+//             isRight: true,
290
+//           },
291
+//           {
292
+//             title: 'B.填空',
293
+//             answertext: '考生输入的答案2',
294
+//             isRight: false,
295
+//           },
296
+//         ],
297
+//         AnswerExplanation:
298
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
299
+//       },
300
+//     ],
301
+//   },
302
+//   {
303
+//     type: 'single',
304
+//     title: '第五题简答题(本题分值1分)',
305
+//     score: 1,
306
+//     list: [
307
+//       {
308
+//         title: '1.这是本题的题目。',
309
+//         answer: [
310
+//           {
311
+//             title: '这是一个简答题',
312
+//             answertext:
313
+//               '考生输入的答案考生输入的答案考生输入的答案考生输入的答案考生输入的答案考生输入的答案',
314
+//             Correctanswer: '正确答案正确答案正确答案正确答案正确答案正确答案',
315
+//             isRight: true,
316
+//           },
317
+//         ],
318
+//         AnswerExplanation:
319
+//           '解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析解析',
320
+//       },
321
+//     ],
322
+//   },
323
+// ]) as any
324
+</script>
325
+
326
+<template>
327
+  <view class="knowledgebase_exam_explanation">
328
+    <view class="knowledgebase_exam_explanation_title">
329
+      {{ examInfo.examName || '' }}
330
+    </view>
331
+    <view class="knowledgebase_exam_explanation_content">
332
+      <view class="knowledgebase_exam_explanation_content_title">
333
+        考试说明
334
+      </view>
335
+      <view class="knowledgebase_exam_explanation_content_text">
336
+        {{ examInfo.remark || '' }}
337
+      </view>
338
+    </view>
339
+    <view class="knowledgebase_exam_explanation_float">
340
+      <view class="knowledgebase_exam_explanation_float_title">
341
+        考试总分
342
+        <span class="knowledgebase_exam_explanation_float_title_score">{{ examInfo.totalScore || 0 }}分</span>
343
+      </view>
344
+      <view class="knowledgebase_exam_explanation_float_title">
345
+        及格分数
346
+        <span class="knowledgebase_exam_explanation_float_title_score">{{ examInfo.passScore }}分</span>
347
+      </view>
348
+      <view class="knowledgebase_exam_explanation_float_title">
349
+        考试时长
350
+        <span class="knowledgebase_exam_explanation_float_title_score">{{ examInfo.examDuration }}分钟</span>
351
+      </view>
352
+      <view class="knowledgebase_exam_explanation_float_title">
353
+        考生得分
354
+        <span
355
+          class="knowledgebase_exam_explanation_float_title_score"
356
+          style="color: #215acd"
357
+        >{{ participantInfo.score || 0 }}分</span>
358
+      </view>
359
+      <view class="knowledgebase_exam_explanation_float_title">
360
+        考试结果
361
+        <span
362
+          v-if="participantInfo.score >= examInfo.passScore"
363
+          class="knowledgebase_exam_explanation_float_title_score"
364
+          style="color: #38b865"
365
+        >及格</span>
366
+        <span
367
+          v-else
368
+          class="knowledgebase_exam_explanation_float_title_score"
369
+          style="color: #eb5e12"
370
+        >不及格</span>
371
+      </view>
372
+    </view>
373
+    <view class="AnswerDetails">
374
+      <view class="AnswerDetails_title">
375
+        答题详情
376
+      </view>
377
+      <view
378
+        v-for="(bigQuestion, bigIndex) in examInfo?.paper?.bigQuestionNames"
379
+        :key="bigIndex" class="AnswerDetails_content"
380
+      >
381
+        <view class="AnswerDetails_content_box">
382
+          <view class="AnswerDetails_content_title">
383
+            {{ bigQuestion.name }}(本题分值{{ bigQuestion.score }}分)
384
+          </view>
385
+          <view
386
+            v-for="(question, questionIndex) in getQuestionsByBigIndex()[
387
+              +bigIndex
388
+            ] || []"
389
+            :key="question.id"
390
+            class="AnswerDetails_content_item"
391
+          >
392
+            <view class="Thisquestiontitle">
393
+              <view class="AnswerDetails_content_item_title">
394
+                {{ +questionIndex + 1 }}.
395
+                <span v-html="question.info.questionContent" />({{
396
+                  getQuestionTypeName(question.questionType)
397
+                }},{{ question.smallQuestionScore }}分)
398
+              </view>
399
+              <view
400
+                v-if="
401
+                  ['single_choice', 'multiple_choice', 'judgment'].includes(
402
+                    question.questionType,
403
+                  )
404
+                " class="AnswerDetails_content_item_answer"
405
+              >
406
+                <text
407
+                  v-for="(option, optionIndex) in parseJson(
408
+                    question.info.options,
409
+                  )"
410
+                  :key="optionIndex"
411
+                  :style="
412
+                    getAnswerByPaperQuestionId(question.id).isCorrect === 1
413
+                      ? 'color: #38B865'
414
+                      : getAnswerByPaperQuestionId(question.id).isCorrect === 0
415
+                        ? 'color: #EB5E12'
416
+                        : ''
417
+                  "
418
+                >
419
+                  <text>
420
+                    {{ String.fromCharCode(65 + +optionIndex) }}.
421
+                    <span v-html="option" />
422
+                  </text>
423
+                  <wd-icon
424
+                    v-if="
425
+                      getAnswerByPaperQuestionId(question.id).isCorrect === 1
426
+                    "
427
+                    style="
428
+                      color: #38b865;
429
+                      text-align: center;
430
+                      margin-left: 20rpx;
431
+                    "
432
+                    name="check-circle-filled"
433
+                    size="16px"
434
+                  />
435
+                  <wd-icon
436
+                    v-else
437
+                    style="
438
+                      color: #eb5e12;
439
+                      text-align: center;
440
+                      margin-left: 20rpx;
441
+                    "
442
+                    name="close-circle-filled"
443
+                    size="16px"
444
+                  />
445
+                </text>
446
+              </view>
447
+              <view
448
+                v-else-if="question.questionType === 'fill_blank'"
449
+                class="AnswerDetails_content_item_answer"
450
+              >
451
+                <text
452
+                  v-for="(option, optionIndex) in parseJson(
453
+                    getAnswerByPaperQuestionId(question.id).userAnswer
454
+                      || '[]',
455
+                  )"
456
+                  :key="optionIndex"
457
+                  :style="
458
+                    getAnswerByPaperQuestionId(question.id).isCorrect === 1
459
+                      ? 'color: #38B865'
460
+                      : getAnswerByPaperQuestionId(question.id).isCorrect === 0
461
+                        ? 'color: #EB5E12'
462
+                        : ''
463
+                  "
464
+                >
465
+                  <text>
466
+                    {{ option }}
467
+                  </text>
468
+                  <wd-icon
469
+                    v-if="
470
+                      getAnswerByPaperQuestionId(question.id).isCorrect === 1
471
+                    "
472
+                    style="
473
+                      color: #38b865;
474
+                      text-align: center;
475
+                      margin-left: 20rpx;
476
+                    "
477
+                    name="check-circle-filled"
478
+                    size="16px"
479
+                  />
480
+                  <wd-icon
481
+                    v-else
482
+                    style="
483
+                      color: #eb5e12;
484
+                      text-align: center;
485
+                      margin-left: 20rpx;
486
+                    "
487
+                    name="close-circle-filled"
488
+                    size="16px"
489
+                  />
490
+                </text>
491
+              </view>
492
+              <view
493
+                v-else-if="question.questionType === 'essay'"
494
+                class="AnswerDetails_content_item_answer"
495
+              >
496
+                <text
497
+                  :style="
498
+                    getAnswerByPaperQuestionId(question.id).isCorrect === 1
499
+                      ? 'color: #38B865'
500
+                      : getAnswerByPaperQuestionId(question.id).isCorrect === 0
501
+                        ? 'color: #EB5E12'
502
+                        : ''
503
+                  "
504
+                >
505
+                  <text>
506
+                    {{ getAnswerByPaperQuestionId(question.id).userAnswer
507
+                      || '未作答' }}
508
+                  </text>
509
+                  <wd-icon
510
+                    v-if="
511
+                      getAnswerByPaperQuestionId(question.id).isCorrect === 1
512
+                    "
513
+                    style="
514
+                      color: #38b865;
515
+                      text-align: center;
516
+                      margin-left: 20rpx;
517
+                    "
518
+                    name="check-circle-filled"
519
+                    size="16px"
520
+                  />
521
+                  <wd-icon
522
+                    v-else
523
+                    style="
524
+                      color: #eb5e12;
525
+                      text-align: center;
526
+                      margin-left: 20rpx;
527
+                    "
528
+                    name="close-circle-filled"
529
+                    size="16px"
530
+                  />
531
+                </text>
532
+              </view>
533
+            </view>
534
+            <!-- 答案解析 -->
535
+            <view class="AnswerExplanation_box">
536
+              <view class="Correctanswer" style="margin-bottom: 48rpx">
537
+                <text class="Correctanswer_title">正确答案 : </text>
538
+                <!-- <text
539
+                  v-for="values in items?.answer.filter((a) => a.isRight)"
540
+                  v-if="value.title.includes('简答题')"
541
+                  :key="values.title"
542
+                  class="Correctanswer_title Content"
543
+                >
544
+                  {{ `${values.Correctanswer};` }}
545
+                </text> -->
546
+                <text
547
+                  v-if="
548
+                    ['single_choice', 'multiple_choice', 'judgment', 'fill_blank'].includes(
549
+                      question.questionType,
550
+                    )
551
+                  "
552
+                  class="Correctanswer_title Content"
553
+                >
554
+                  <span
555
+                    v-html="
556
+                      parseJson(question.info.correctAnswer || '[]')
557
+                        .map((idx: number) => String.fromCharCode(65 + idx))
558
+                        .join('、')
559
+                    "
560
+                  />
561
+                </text>
562
+                <text
563
+                  v-else
564
+                  class="Correctanswer_title Content"
565
+                >
566
+                  <span
567
+                    v-html="question.info.correctAnswer || '无'"
568
+                  />
569
+                </text>
570
+              </view>
571
+              <view class="AnswerExplanation">
572
+                <view class="Correctanswer_title" style="margin-bottom: 32rpx">
573
+                  答案解析:
574
+                </view>
575
+                <text class="Correctanswer_Content">
576
+                  <span
577
+                    v-html="question.info.answerAnalysis || '暂无解析'"
578
+                  />
579
+                </text>
580
+              </view>
581
+            </view>
582
+          </view>
583
+        </view>
584
+      </view>
585
+    </view>
586
+  </view>
587
+</template>
588
+
589
+<style scoped lang="scss">
590
+html,
591
+body {
592
+  overflow: hidden;
593
+}
594
+.knowledgebase_exam_explanation {
595
+  height: calc(100vh - 88rpx);
596
+  display: flex;
597
+  flex-direction: column;
598
+  padding: 24rpx;
599
+  box-sizing: border-box;
600
+}
601
+.knowledgebase_exam_explanation_title {
602
+  font-family: Alibaba PuHuiTi 2;
603
+  font-weight: 500;
604
+  font-style: 65 Medium;
605
+  font-size: 48rpx;
606
+  leading-trim: NONE;
607
+  line-height: 48rpx;
608
+  letter-spacing: 0px;
609
+  color: #31373d;
610
+}
611
+.knowledgebase_exam_explanation_content {
612
+  margin-top: 80rpx;
613
+  width: 100%;
614
+  display: flex;
615
+  flex-direction: column;
616
+  gap: 32rpx;
617
+  .knowledgebase_exam_explanation_content_title {
618
+    font-weight: 500;
619
+    font-style: 65 Medium;
620
+    font-size: 36rpx;
621
+    leading-trim: NONE;
622
+    letter-spacing: 0px;
623
+    color: #31373d;
624
+  }
625
+  .knowledgebase_exam_explanation_content_text {
626
+    font-weight: 400;
627
+    font-style: 55 Regular;
628
+    font-size: 28rpx;
629
+    line-height: 48rpx;
630
+    letter-spacing: 0px;
631
+    color: #4e5969;
632
+  }
633
+}
634
+.knowledgebase_exam_explanation_float {
635
+  margin-top: 48rpx;
636
+  margin-bottom: 48rpx;
637
+  border-top: 1rpx solid #eeeeee;
638
+  border-bottom: 1rpx solid #eeeeee;
639
+  padding-top: 48rpx;
640
+  padding-bottom: 48rpx;
641
+  box-sizing: border-box;
642
+  display: flex;
643
+  flex-direction: column;
644
+  gap: 32rpx;
645
+  .knowledgebase_exam_explanation_float_title {
646
+    font-weight: 400;
647
+    font-style: 55 Regular;
648
+    font-size: 28rpx;
649
+    letter-spacing: 0px;
650
+    color: #4e5969;
651
+    .knowledgebase_exam_explanation_float_title_score {
652
+      margin-left: 48rpx;
653
+      color: #31373d;
654
+    }
655
+  }
656
+}
657
+.AnswerDetails {
658
+  flex: 1;
659
+  overflow-y: auto;
660
+  .AnswerDetails_title {
661
+    font-weight: 500;
662
+    font-style: 65 Medium;
663
+    font-size: 36rpx;
664
+    leading-trim: NONE;
665
+    letter-spacing: 0px;
666
+    color: #31373d;
667
+    margin-bottom: 48rpx;
668
+  }
669
+  .AnswerDetails_content {
670
+    // width: 100%;
671
+    // display: flex;
672
+    // flex-direction: column;
673
+    // gap: 24rpx;
674
+    margin-bottom: 24rpx;
675
+    .AnswerDetails_content_box {
676
+      display: flex;
677
+      flex-direction: column;
678
+      gap: 24rpx;
679
+    }
680
+    .AnswerDetails_content_title {
681
+      width: 100%;
682
+      height: 96rpx;
683
+      background-color: #f7f9fa;
684
+      padding-left: 32rpx;
685
+      box-sizing: border-box;
686
+      line-height: 88rpx;
687
+
688
+      font-weight: 500;
689
+      font-size: 32rpx;
690
+      color: #31373d;
691
+    }
692
+    .AnswerDetails_content_item {
693
+      box-sizing: border-box;
694
+      padding: 32rpx;
695
+      width: 100%;
696
+      background-color: #f7f9fa;
697
+      .Thisquestiontitle {
698
+        border-bottom: 1rpx solid #e6e8eb;
699
+        box-sizing: border-box;
700
+        padding-bottom: 48rpx;
701
+        margin-bottom: 48rpx;
702
+        .AnswerDetails_content_item_title {
703
+          margin-bottom: 48rpx;
704
+          font-weight: 400;
705
+          font-size: 32rpx;
706
+          color: #31373d;
707
+        }
708
+        .AnswerDetails_content_item_answer {
709
+          display: flex;
710
+          flex-direction: column;
711
+          gap: 52rpx;
712
+
713
+          font-weight: 400;
714
+          font-size: 28rpx;
715
+          color: #31373d;
716
+        }
717
+      }
718
+      .AnswerExplanation_box {
719
+        .Correctanswer_title {
720
+          font-weight: 400;
721
+          font-size: 28rpx;
722
+          color: #31373d;
723
+        }
724
+        .Content {
725
+          color: #38b865;
726
+          margin-right: 10rpx;
727
+        }
728
+        .Correctanswer_Content {
729
+          font-weight: 400;
730
+          font-size: 32rpx;
731
+          color: #4e5969;
732
+          line-height: 56rpx;
733
+        }
734
+      }
735
+    }
736
+  }
737
+}
738
+</style>

+ 64 - 0
src/pages/knowledge/exam/start.vue

@@ -168,6 +168,30 @@ async function start() {
168 168
         </span>
169 169
       </view>
170 170
     </view>
171
+    <view v-if="!token" class="knowledgebase_exam_explanation_form">
172
+      <view class="knowledgebase_exam_explanation_form_item">
173
+        <view class="knowledgebase_exam_explanation_form_item_label">
174
+          姓名
175
+        </view>
176
+        <input
177
+          v-model="loginUser.password"
178
+          type="text"
179
+          class="knowledgebase_exam_explanation_form_item_input"
180
+          placeholder="请输入姓名"
181
+        >
182
+      </view>
183
+      <view class="knowledgebase_exam_explanation_form_item">
184
+        <view class="knowledgebase_exam_explanation_form_item_label">
185
+          手机号
186
+        </view>
187
+        <input
188
+          v-model="loginUser.username"
189
+          type="number"
190
+          class="knowledgebase_exam_explanation_form_item_input"
191
+          placeholder="请输入手机号"
192
+        >
193
+      </view>
194
+    </view>
171 195
     <wd-button class="knowledgebase_exam_explanation_float_button" @click="start">
172 196
       开始考试
173 197
     </wd-button>
@@ -252,4 +276,44 @@ body {
252 276
   height: 80rpx !important;
253 277
   border-radius: 8rpx !important;
254 278
 }
279
+
280
+.knowledgebase_exam_explanation_form {
281
+  margin-top: 48rpx;
282
+  border-top: 1rpx solid #eeeeee;
283
+  padding-top: 48rpx;
284
+  box-sizing: border-box;
285
+  display: flex;
286
+  flex-direction: column;
287
+  gap: 32rpx;
288
+}
289
+
290
+.knowledgebase_exam_explanation_form_item {
291
+  display: flex;
292
+  flex-direction: column;
293
+  gap: 16rpx;
294
+}
295
+
296
+.knowledgebase_exam_explanation_form_item_label {
297
+  font-weight: 400;
298
+  font-style: 55 Regular;
299
+  font-size: 28rpx;
300
+  letter-spacing: 0px;
301
+  color: #4e5969;
302
+}
303
+
304
+.knowledgebase_exam_explanation_form_item_input {
305
+  width: 100%;
306
+  height: 80rpx;
307
+  border: 1rpx solid #dcdfe6;
308
+  border-radius: 8rpx;
309
+  padding: 0 24rpx;
310
+  box-sizing: border-box;
311
+  font-size: 28rpx;
312
+  color: #31373d;
313
+  background-color: #ffffff;
314
+}
315
+
316
+.knowledgebase_exam_explanation_form_item_input::placeholder {
317
+  color: #c0c4cc;
318
+}
255 319
 </style>

+ 6 - 1
src/pages/knowledge/exam/submit.vue

@@ -1,7 +1,12 @@
1 1
 <script setup lang="ts">
2
+import { useRoute } from 'vue-router'
3
+
4
+const route = useRoute()
5
+const examId = route.query.id || 0
6
+const participantId = Number(route.query.pid || 0)
2 7
 function handleClick() {
3 8
   uni.navigateTo({
4
-    url: '/pages/knowledge/exam/index',
9
+    url: `/pages/knowledge/exam/result?id=${examId}&pid=${participantId}`,
5 10
   })
6 11
 }
7 12
 </script>