diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java index 8cf4e11..5522368 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java @@ -141,4 +141,22 @@ public class ExamWordsController { return Response.success(examWordsDetailResultRspVO); } + + @PostMapping("student/history") + @ApiOperationLog(description = "获取学生历史考试结果") + Response> getStudentExamWordsResultList(@RequestBody FindStudentExamWordsResultReqVO findStudentExamWordsResultReqVO) { + Integer studentId = findStudentExamWordsResultReqVO.getStudentId(); + List list = examWordsJudgeService.getStudentExamWordsResultList(studentId).stream().map(examWordsJudgeResultDO -> FindStudentExamWordsResultListRspVO.builder() + .id(examWordsJudgeResultDO.getId()) + .studentId(examWordsJudgeResultDO.getStudentId()) + .examWordsId(examWordsJudgeResultDO.getExamWordsId()) + .correctWordCount(examWordsJudgeResultDO.getCorrectWordCount()) + .wrongWordCount(examWordsJudgeResultDO.getWrongWordCount()) + .startDate(examWordsJudgeResultDO.getStartDate()) + .accuracy((double)examWordsJudgeResultDO.getCorrectWordCount() / (examWordsJudgeResultDO.getCorrectWordCount() + examWordsJudgeResultDO.getWrongWordCount())) + .build() + ).toList(); + + return Response.success(list); + } } diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsJudgeResultDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsJudgeResultDOMapper.java index c4cee3b..fa1fc4a 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsJudgeResultDOMapper.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsJudgeResultDOMapper.java @@ -20,4 +20,6 @@ public interface ExamWordsJudgeResultDOMapper { Integer selectCount(); ExamWordsJudgeResultDO selectDetailById(@Param("id") Integer id); + + List selectByStudentId(@Param("studentId") Integer studentId); } \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/FindStudentExamWordsResultListRspVO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/FindStudentExamWordsResultListRspVO.java new file mode 100644 index 0000000..1db4bef --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/FindStudentExamWordsResultListRspVO.java @@ -0,0 +1,29 @@ +package com.yinlihupo.enlish.service.model.vo.exam; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class FindStudentExamWordsResultListRspVO { + + private Integer id; + + private Integer studentId; + + private Integer examWordsId; + + private Integer correctWordCount; + + private Integer wrongWordCount; + + private Double accuracy; + + private LocalDateTime startDate; +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/FindStudentExamWordsResultReqVO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/FindStudentExamWordsResultReqVO.java new file mode 100644 index 0000000..a020e14 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/FindStudentExamWordsResultReqVO.java @@ -0,0 +1,15 @@ +package com.yinlihupo.enlish.service.model.vo.exam; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class FindStudentExamWordsResultReqVO { + + private Integer studentId; +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsJudgeService.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsJudgeService.java index 3bf55b1..78632ed 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsJudgeService.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsJudgeService.java @@ -2,6 +2,7 @@ package com.yinlihupo.enlish.service.service; import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsJudgeResultDO; +import java.util.Arrays; import java.util.List; public interface ExamWordsJudgeService { @@ -13,4 +14,6 @@ public interface ExamWordsJudgeService { Integer getExamWordsJudgeResultCount(); ExamWordsJudgeResultDO getExamWordsJudgeResultDOById(Integer id); + + List getStudentExamWordsResultList(Integer studentId); } diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/judge/ExamWordsJudgeServiceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/judge/ExamWordsJudgeServiceImpl.java index a98f87a..351974f 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/judge/ExamWordsJudgeServiceImpl.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/judge/ExamWordsJudgeServiceImpl.java @@ -144,4 +144,9 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService { public ExamWordsJudgeResultDO getExamWordsJudgeResultDOById(Integer id) { return examWordsJudgeResultDOMapper.selectDetailById(id); } + + @Override + public List getStudentExamWordsResultList(Integer studentId) { + return examWordsJudgeResultDOMapper.selectByStudentId(studentId); + } } diff --git a/enlish-service/src/main/resources/mapper/ExamWordsJudgeResultDOMapper.xml b/enlish-service/src/main/resources/mapper/ExamWordsJudgeResultDOMapper.xml index bfee8d3..7763ead 100644 --- a/enlish-service/src/main/resources/mapper/ExamWordsJudgeResultDOMapper.xml +++ b/enlish-service/src/main/resources/mapper/ExamWordsJudgeResultDOMapper.xml @@ -66,5 +66,12 @@ from exam_words_judge_result where id = #{id} + \ No newline at end of file diff --git a/enlish-vue/package-lock.json b/enlish-vue/package-lock.json index 7700d53..ff50e31 100644 --- a/enlish-vue/package-lock.json +++ b/enlish-vue/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "axios": "^1.13.2", + "echarts": "^6.0.0", "element-plus": "^2.12.0", "flowbite": "^1.8.1", "nprogress": "^0.2.0", @@ -1647,6 +1648,16 @@ "node": ">= 0.4" } }, + "node_modules/echarts": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz", + "integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "6.0.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.267", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", @@ -3088,6 +3099,12 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, "node_modules/ufo": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", @@ -3420,6 +3437,15 @@ "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", "dev": true, "license": "MIT" + }, + "node_modules/zrender": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz", + "integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } } } } diff --git a/enlish-vue/package.json b/enlish-vue/package.json index 885d703..e01ba84 100644 --- a/enlish-vue/package.json +++ b/enlish-vue/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "axios": "^1.13.2", + "echarts": "^6.0.0", "element-plus": "^2.12.0", "flowbite": "^1.8.1", "nprogress": "^0.2.0", diff --git a/enlish-vue/src/api/exam.js b/enlish-vue/src/api/exam.js index 376590d..f98413a 100644 --- a/enlish-vue/src/api/exam.js +++ b/enlish-vue/src/api/exam.js @@ -55,6 +55,12 @@ export function generateExamWords(data) { }); } +export function getStudentExamHistory(studentId) { + return axios.post('/exam/words/student/history', { + studentId: studentId + }) +} + const resolveBlob = (res, fileName) => { // 创建 Blob 对象,可以指定 type,也可以让浏览器自动推断 const blob = new Blob([res], { type: 'application/octet-stream' }); diff --git a/enlish-vue/src/layouts/components/student/ExamHistoryChart.vue b/enlish-vue/src/layouts/components/student/ExamHistoryChart.vue new file mode 100644 index 0000000..4e8895b --- /dev/null +++ b/enlish-vue/src/layouts/components/student/ExamHistoryChart.vue @@ -0,0 +1,155 @@ + + + diff --git a/enlish-vue/src/pages/student.vue b/enlish-vue/src/pages/student.vue index 72ce05d..27d5be8 100644 --- a/enlish-vue/src/pages/student.vue +++ b/enlish-vue/src/pages/student.vue @@ -6,19 +6,27 @@ -
-
学生详情
- - +
+
+
学生详情
+ + +
+ +
+
学生考试记录
+ +
@@ -31,10 +39,13 @@ import Header from '@/layouts/components/Header.vue' import { ref, onMounted } from 'vue' import { useRoute } from 'vue-router' import { getStudentDetail } from '@/api/student' +import { getStudentExamHistory } from '@/api/exam' +import ExamHistoryChart from '@/layouts/components/student/ExamHistoryChart.vue' const loading = ref(false) const detail = ref(null) const route = useRoute() +const history = ref([]) async function fetchDetail() { const id = route.params.id @@ -49,7 +60,18 @@ async function fetchDetail() { } } +async function fetchExamHistory() { + const id = route.params.id + if (!id) return + const res = await getStudentExamHistory(id) + const d = res.data + history.value = Array.isArray(d?.data) ? d.data.slice().sort((a, b) => { + return new Date(a.startDate).getTime() - new Date(b.startDate).getTime() + }) : [] +} + onMounted(() => { fetchDetail() + fetchExamHistory() })