Kaynağa Gözat

学习模块基础结构

mingfu 1 ay önce
ebeveyn
işleme
c857e15857
82 değiştirilmiş dosya ile 10284 ekleme ve 0 silme
  1. 44 0
      back-ui/src/api/learn/WrongBook.js
  2. 44 0
      back-ui/src/api/learn/WrongDetail.js
  3. 44 0
      back-ui/src/api/learn/answer.js
  4. 44 0
      back-ui/src/api/learn/directKnowledge.js
  5. 44 0
      back-ui/src/api/learn/examinee.js
  6. 44 0
      back-ui/src/api/learn/knowledgeQuestion.js
  7. 44 0
      back-ui/src/api/learn/knowledgeTree.js
  8. 44 0
      back-ui/src/api/learn/learnPlan.js
  9. 44 0
      back-ui/src/api/learn/learnPlanStudy.js
  10. 44 0
      back-ui/src/api/learn/questionCorrect.js
  11. 496 0
      back-ui/src/views/learn/WrongBook/index.vue
  12. 396 0
      back-ui/src/views/learn/WrongDetail/index.vue
  13. 392 0
      back-ui/src/views/learn/answer/index.vue
  14. 351 0
      back-ui/src/views/learn/directKnowledge/index.vue
  15. 432 0
      back-ui/src/views/learn/examinee/index.vue
  16. 265 0
      back-ui/src/views/learn/knowledgeQuestion/index.vue
  17. 336 0
      back-ui/src/views/learn/knowledgeTree/index.vue
  18. 297 0
      back-ui/src/views/learn/learnPlan/index.vue
  19. 349 0
      back-ui/src/views/learn/learnPlanStudy/index.vue
  20. 274 0
      back-ui/src/views/learn/questionCorrect/index.vue
  21. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnAnswerController.java
  22. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnDirectedKnowledgeController.java
  23. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnExamineeController.java
  24. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnKnowledgeQuestionController.java
  25. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnKnowledgeTreeController.java
  26. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPlanController.java
  27. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPlanStudyController.java
  28. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnQuestionCorrectController.java
  29. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnWrongBookController.java
  30. 104 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnWrongDetailController.java
  31. 26 0
      ie-system/src/main/java/com/ruoyi/enums/PaperType.java
  32. 38 0
      ie-system/src/main/java/com/ruoyi/learn/domain/AnswerSheet.java
  33. 234 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnAnswer.java
  34. 202 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnDirectedKnowledge.java
  35. 268 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnExaminee.java
  36. 98 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnKnowledgeQuestion.java
  37. 172 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnKnowledgeTree.java
  38. 131 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnPlan.java
  39. 176 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnPlanStudy.java
  40. 85 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnQuestionCorrect.java
  41. 341 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnWrongBook.java
  42. 220 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnWrongDetail.java
  43. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnAnswerMapper.java
  44. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnDirectedKnowledgeMapper.java
  45. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnExamineeMapper.java
  46. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnKnowledgeQuestionMapper.java
  47. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnKnowledgeTreeMapper.java
  48. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPlanMapper.java
  49. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPlanStudyMapper.java
  50. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnQuestionCorrectMapper.java
  51. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnWrongBookMapper.java
  52. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnWrongDetailMapper.java
  53. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnAnswerService.java
  54. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnDirectedKnowledgeService.java
  55. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnExamineeService.java
  56. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnKnowledgeQuestionService.java
  57. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnKnowledgeTreeService.java
  58. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnPlanService.java
  59. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnPlanStudyService.java
  60. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnQuestionCorrectService.java
  61. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnWrongBookService.java
  62. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnWrongDetailService.java
  63. 96 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnAnswerServiceImpl.java
  64. 93 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnDirectedKnowledgeServiceImpl.java
  65. 96 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnExamineeServiceImpl.java
  66. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnKnowledgeQuestionServiceImpl.java
  67. 93 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnKnowledgeTreeServiceImpl.java
  68. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPlanServiceImpl.java
  69. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPlanStudyServiceImpl.java
  70. 96 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnQuestionCorrectServiceImpl.java
  71. 93 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnWrongBookServiceImpl.java
  72. 93 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnWrongDetailServiceImpl.java
  73. 124 0
      ie-system/src/main/resources/mapper/learn/LearnAnswerMapper.xml
  74. 106 0
      ie-system/src/main/resources/mapper/learn/LearnDirectedKnowledgeMapper.xml
  75. 134 0
      ie-system/src/main/resources/mapper/learn/LearnExamineeMapper.xml
  76. 75 0
      ie-system/src/main/resources/mapper/learn/LearnKnowledgeQuestionMapper.xml
  77. 96 0
      ie-system/src/main/resources/mapper/learn/LearnKnowledgeTreeMapper.xml
  78. 85 0
      ie-system/src/main/resources/mapper/learn/LearnPlanMapper.xml
  79. 100 0
      ie-system/src/main/resources/mapper/learn/LearnPlanStudyMapper.xml
  80. 78 0
      ie-system/src/main/resources/mapper/learn/LearnQuestionCorrectMapper.xml
  81. 151 0
      ie-system/src/main/resources/mapper/learn/LearnWrongBookMapper.xml
  82. 111 0
      ie-system/src/main/resources/mapper/learn/LearnWrongDetailMapper.xml

+ 44 - 0
back-ui/src/api/learn/WrongBook.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询学生错题本列表
+export function listWrongBook(query) {
+  return request({
+    url: '/learn/WrongBook/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询学生错题本详细
+export function getWrongBook(wrongId) {
+  return request({
+    url: '/learn/WrongBook/' + wrongId,
+    method: 'get'
+  })
+}
+
+// 新增学生错题本
+export function addWrongBook(data) {
+  return request({
+    url: '/learn/WrongBook',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改学生错题本
+export function updateWrongBook(data) {
+  return request({
+    url: '/learn/WrongBook',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除学生错题本
+export function delWrongBook(wrongId) {
+  return request({
+    url: '/learn/WrongBook/' + wrongId,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/WrongDetail.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询学生错题流水列表
+export function listWrongDetail(query) {
+  return request({
+    url: '/learn/WrongDetail/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询学生错题流水详细
+export function getWrongDetail(wrongDetailId) {
+  return request({
+    url: '/learn/WrongDetail/' + wrongDetailId,
+    method: 'get'
+  })
+}
+
+// 新增学生错题流水
+export function addWrongDetail(data) {
+  return request({
+    url: '/learn/WrongDetail',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改学生错题流水
+export function updateWrongDetail(data) {
+  return request({
+    url: '/learn/WrongDetail',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除学生错题流水
+export function delWrongDetail(wrongDetailId) {
+  return request({
+    url: '/learn/WrongDetail/' + wrongDetailId,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/answer.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询答卷答案列表
+export function listAnswer(query) {
+  return request({
+    url: '/learn/answer/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询答卷答案详细
+export function getAnswer(answerId) {
+  return request({
+    url: '/learn/answer/' + answerId,
+    method: 'get'
+  })
+}
+
+// 新增答卷答案
+export function addAnswer(data) {
+  return request({
+    url: '/learn/answer',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改答卷答案
+export function updateAnswer(data) {
+  return request({
+    url: '/learn/answer',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除答卷答案
+export function delAnswer(answerId) {
+  return request({
+    url: '/learn/answer/' + answerId,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/directKnowledge.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询定向知识点关系列表
+export function listDirectKnowledge(query) {
+  return request({
+    url: '/learn/directKnowledge/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询定向知识点关系详细
+export function getDirectKnowledge(id) {
+  return request({
+    url: '/learn/directKnowledge/' + id,
+    method: 'get'
+  })
+}
+
+// 新增定向知识点关系
+export function addDirectKnowledge(data) {
+  return request({
+    url: '/learn/directKnowledge',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改定向知识点关系
+export function updateDirectKnowledge(data) {
+  return request({
+    url: '/learn/directKnowledge',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除定向知识点关系
+export function delDirectKnowledge(id) {
+  return request({
+    url: '/learn/directKnowledge/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/examinee.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询答卷列表
+export function listExaminee(query) {
+  return request({
+    url: '/learn/examinee/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询答卷详细
+export function getExaminee(examineeId) {
+  return request({
+    url: '/learn/examinee/' + examineeId,
+    method: 'get'
+  })
+}
+
+// 新增答卷
+export function addExaminee(data) {
+  return request({
+    url: '/learn/examinee',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改答卷
+export function updateExaminee(data) {
+  return request({
+    url: '/learn/examinee',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除答卷
+export function delExaminee(examineeId) {
+  return request({
+    url: '/learn/examinee/' + examineeId,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/knowledgeQuestion.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询知识点题关系列表
+export function listKnowledgeQuestion(query) {
+  return request({
+    url: '/learn/knowledgeQuestion/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询知识点题关系详细
+export function getKnowledgeQuestion(id) {
+  return request({
+    url: '/learn/knowledgeQuestion/' + id,
+    method: 'get'
+  })
+}
+
+// 新增知识点题关系
+export function addKnowledgeQuestion(data) {
+  return request({
+    url: '/learn/knowledgeQuestion',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改知识点题关系
+export function updateKnowledgeQuestion(data) {
+  return request({
+    url: '/learn/knowledgeQuestion',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除知识点题关系
+export function delKnowledgeQuestion(id) {
+  return request({
+    url: '/learn/knowledgeQuestion/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/knowledgeTree.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询知识点树列表
+export function listKnowledgeTree(query) {
+  return request({
+    url: '/learn/knowledgeTree/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询知识点树详细
+export function getKnowledgeTree(id) {
+  return request({
+    url: '/learn/knowledgeTree/' + id,
+    method: 'get'
+  })
+}
+
+// 新增知识点树
+export function addKnowledgeTree(data) {
+  return request({
+    url: '/learn/knowledgeTree',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改知识点树
+export function updateKnowledgeTree(data) {
+  return request({
+    url: '/learn/knowledgeTree',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除知识点树
+export function delKnowledgeTree(id) {
+  return request({
+    url: '/learn/knowledgeTree/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/learnPlan.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询学习计划列表
+export function listLearnPlan(query) {
+  return request({
+    url: '/learn/learnPlan/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询学习计划详细
+export function getLearnPlan(id) {
+  return request({
+    url: '/learn/learnPlan/' + id,
+    method: 'get'
+  })
+}
+
+// 新增学习计划
+export function addLearnPlan(data) {
+  return request({
+    url: '/learn/learnPlan',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改学习计划
+export function updateLearnPlan(data) {
+  return request({
+    url: '/learn/learnPlan',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除学习计划
+export function delLearnPlan(id) {
+  return request({
+    url: '/learn/learnPlan/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/learnPlanStudy.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询学生计划执行情况列表
+export function listLearnPlanStudy(query) {
+  return request({
+    url: '/learn/learnPlanStudy/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询学生计划执行情况详细
+export function getLearnPlanStudy(id) {
+  return request({
+    url: '/learn/learnPlanStudy/' + id,
+    method: 'get'
+  })
+}
+
+// 新增学生计划执行情况
+export function addLearnPlanStudy(data) {
+  return request({
+    url: '/learn/learnPlanStudy',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改学生计划执行情况
+export function updateLearnPlanStudy(data) {
+  return request({
+    url: '/learn/learnPlanStudy',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除学生计划执行情况
+export function delLearnPlanStudy(id) {
+  return request({
+    url: '/learn/learnPlanStudy/' + id,
+    method: 'delete'
+  })
+}

+ 44 - 0
back-ui/src/api/learn/questionCorrect.js

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询题纠错列表
+export function listQuestionCorrect(query) {
+  return request({
+    url: '/learn/questionCorrect/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询题纠错详细
+export function getQuestionCorrect(id) {
+  return request({
+    url: '/learn/questionCorrect/' + id,
+    method: 'get'
+  })
+}
+
+// 新增题纠错
+export function addQuestionCorrect(data) {
+  return request({
+    url: '/learn/questionCorrect',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改题纠错
+export function updateQuestionCorrect(data) {
+  return request({
+    url: '/learn/questionCorrect',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除题纠错
+export function delQuestionCorrect(id) {
+  return request({
+    url: '/learn/questionCorrect/' + id,
+    method: 'delete'
+  })
+}

+ 496 - 0
back-ui/src/views/learn/WrongBook/index.vue

@@ -0,0 +1,496 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="学生ID" prop="studentId">
+        <el-input
+          v-model="queryParams.studentId"
+          placeholder="请输入学生ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="题ID" prop="questionId">
+        <el-input
+          v-model="queryParams.questionId"
+          placeholder="请输入题ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="最后来源,练习,试卷,刷题" prop="source">
+        <el-input
+          v-model="queryParams.source"
+          placeholder="请输入最后来源,练习,试卷,刷题"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="最后状态" prop="state">
+        <el-input
+          v-model="queryParams.state"
+          placeholder="请输入最后状态"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="知识点id" prop="knownledgeId">
+        <el-input
+          v-model="queryParams.knownledgeId"
+          placeholder="请输入知识点id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="科目" prop="subjectId">
+        <el-input
+          v-model="queryParams.subjectId"
+          placeholder="请输入科目"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷id" prop="paperId">
+        <el-input
+          v-model="queryParams.paperId"
+          placeholder="请输入试卷id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="总分" prop="scoreTotal">
+        <el-input
+          v-model="queryParams.scoreTotal"
+          placeholder="请输入总分"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="得分" prop="score">
+        <el-input
+          v-model="queryParams.score"
+          placeholder="请输入得分"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="评级" prop="scoreLevel">
+        <el-input
+          v-model="queryParams.scoreLevel"
+          placeholder="请输入评级"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="得分率" prop="scoreRate">
+        <el-input
+          v-model="queryParams.scoreRate"
+          placeholder="请输入得分率"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="错误次数" prop="wrongCount">
+        <el-input
+          v-model="queryParams.wrongCount"
+          placeholder="请输入错误次数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="正确次数" prop="rightCount">
+        <el-input
+          v-model="queryParams.rightCount"
+          placeholder="请输入正确次数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="总次数" prop="totalCount">
+        <el-input
+          v-model="queryParams.totalCount"
+          placeholder="请输入总次数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建时间" prop="createdTime">
+        <el-date-picker clearable
+          v-model="queryParams.createdTime"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择创建时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="更新时间" prop="updatedTime">
+        <el-date-picker clearable
+          v-model="queryParams.updatedTime"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择更新时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="是否收藏" prop="collect">
+        <el-input
+          v-model="queryParams.collect"
+          placeholder="请输入是否收藏"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:WrongBook:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:WrongBook:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:WrongBook:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:WrongBook:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="WrongBookList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="错题id" align="center" prop="wrongId" />
+      <el-table-column label="学生ID" align="center" prop="studentId" />
+      <el-table-column label="题ID" align="center" prop="questionId" />
+      <el-table-column label="最后来源,练习,试卷,刷题" align="center" prop="source" />
+      <el-table-column label="最后状态" align="center" prop="state" />
+      <el-table-column label="知识点id" align="center" prop="knownledgeId" />
+      <el-table-column label="科目" align="center" prop="subjectId" />
+      <el-table-column label="试卷id" align="center" prop="paperId" />
+      <el-table-column label="最后参考答案" align="center" prop="answers" />
+      <el-table-column label="答案1" align="center" prop="answer1" />
+      <el-table-column label="答案2" align="center" prop="answer2" />
+      <el-table-column label="总分" align="center" prop="scoreTotal" />
+      <el-table-column label="得分" align="center" prop="score" />
+      <el-table-column label="评级" align="center" prop="scoreLevel" />
+      <el-table-column label="得分率" align="center" prop="scoreRate" />
+      <el-table-column label="错误次数" align="center" prop="wrongCount" />
+      <el-table-column label="正确次数" align="center" prop="rightCount" />
+      <el-table-column label="总次数" align="center" prop="totalCount" />
+      <el-table-column label="创建时间" align="center" prop="createdTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="更新时间" align="center" prop="updatedTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.updatedTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="是否收藏" align="center" prop="collect" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:WrongBook:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:WrongBook:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改学生错题本对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="WrongBookRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="学生ID" prop="studentId">
+          <el-input v-model="form.studentId" placeholder="请输入学生ID" />
+        </el-form-item>
+        <el-form-item label="题ID" prop="questionId">
+          <el-input v-model="form.questionId" placeholder="请输入题ID" />
+        </el-form-item>
+        <el-form-item label="最后来源,练习,试卷,刷题" prop="source">
+          <el-input v-model="form.source" placeholder="请输入最后来源,练习,试卷,刷题" />
+        </el-form-item>
+        <el-form-item label="最后状态" prop="state">
+          <el-input v-model="form.state" placeholder="请输入最后状态" />
+        </el-form-item>
+        <el-form-item label="知识点id" prop="knownledgeId">
+          <el-input v-model="form.knownledgeId" placeholder="请输入知识点id" />
+        </el-form-item>
+        <el-form-item label="科目" prop="subjectId">
+          <el-input v-model="form.subjectId" placeholder="请输入科目" />
+        </el-form-item>
+        <el-form-item label="试卷id" prop="paperId">
+          <el-input v-model="form.paperId" placeholder="请输入试卷id" />
+        </el-form-item>
+        <el-form-item label="最后参考答案" prop="answers">
+          <el-input v-model="form.answers" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="答案1" prop="answer1">
+          <el-input v-model="form.answer1" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="答案2" prop="answer2">
+          <el-input v-model="form.answer2" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="总分" prop="scoreTotal">
+          <el-input v-model="form.scoreTotal" placeholder="请输入总分" />
+        </el-form-item>
+        <el-form-item label="得分" prop="score">
+          <el-input v-model="form.score" placeholder="请输入得分" />
+        </el-form-item>
+        <el-form-item label="评级" prop="scoreLevel">
+          <el-input v-model="form.scoreLevel" placeholder="请输入评级" />
+        </el-form-item>
+        <el-form-item label="得分率" prop="scoreRate">
+          <el-input v-model="form.scoreRate" placeholder="请输入得分率" />
+        </el-form-item>
+        <el-form-item label="错误次数" prop="wrongCount">
+          <el-input v-model="form.wrongCount" placeholder="请输入错误次数" />
+        </el-form-item>
+        <el-form-item label="正确次数" prop="rightCount">
+          <el-input v-model="form.rightCount" placeholder="请输入正确次数" />
+        </el-form-item>
+        <el-form-item label="总次数" prop="totalCount">
+          <el-input v-model="form.totalCount" placeholder="请输入总次数" />
+        </el-form-item>
+        <el-form-item label="创建时间" prop="createdTime">
+          <el-date-picker clearable
+            v-model="form.createdTime"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择创建时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="更新时间" prop="updatedTime">
+          <el-date-picker clearable
+            v-model="form.updatedTime"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择更新时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="是否收藏" prop="collect">
+          <el-input v-model="form.collect" placeholder="请输入是否收藏" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="WrongBook">
+import { listWrongBook, getWrongBook, delWrongBook, addWrongBook, updateWrongBook } from "@/api/learn/WrongBook"
+
+const { proxy } = getCurrentInstance()
+
+const WrongBookList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    studentId: null,
+    questionId: null,
+    source: null,
+    state: null,
+    knownledgeId: null,
+    subjectId: null,
+    paperId: null,
+    answers: null,
+    answer1: null,
+    answer2: null,
+    scoreTotal: null,
+    score: null,
+    scoreLevel: null,
+    scoreRate: null,
+    wrongCount: null,
+    rightCount: null,
+    totalCount: null,
+    createdTime: null,
+    updatedTime: null,
+    collect: null
+  },
+  rules: {
+    questionId: [
+      { required: true, message: "题ID不能为空", trigger: "blur" }
+    ],
+    createdTime: [
+      { required: true, message: "创建时间不能为空", trigger: "blur" }
+    ],
+    updatedTime: [
+      { required: true, message: "更新时间不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询学生错题本列表 */
+function getList() {
+  loading.value = true
+  listWrongBook(queryParams.value).then(response => {
+    WrongBookList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    wrongId: null,
+    studentId: null,
+    questionId: null,
+    source: null,
+    state: null,
+    knownledgeId: null,
+    subjectId: null,
+    paperId: null,
+    answers: null,
+    answer1: null,
+    answer2: null,
+    scoreTotal: null,
+    score: null,
+    scoreLevel: null,
+    scoreRate: null,
+    wrongCount: null,
+    rightCount: null,
+    totalCount: null,
+    createdTime: null,
+    updatedTime: null,
+    collect: null
+  }
+  proxy.resetForm("WrongBookRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.wrongId)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加学生错题本"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _wrongId = row.wrongId || ids.value
+  getWrongBook(_wrongId).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改学生错题本"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["WrongBookRef"].validate(valid => {
+    if (valid) {
+      if (form.value.wrongId != null) {
+        updateWrongBook(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addWrongBook(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _wrongIds = row.wrongId || ids.value
+  proxy.$modal.confirm('是否确认删除学生错题本编号为"' + _wrongIds + '"的数据项?').then(function() {
+    return delWrongBook(_wrongIds)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/WrongBook/export', {
+    ...queryParams.value
+  }, `WrongBook_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 396 - 0
back-ui/src/views/learn/WrongDetail/index.vue

@@ -0,0 +1,396 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="错题本id" prop="wrongId">
+        <el-input
+          v-model="queryParams.wrongId"
+          placeholder="请输入错题本id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建时间" prop="createdTime">
+        <el-date-picker clearable
+          v-model="queryParams.createdTime"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择创建时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="来源" prop="source">
+        <el-input
+          v-model="queryParams.source"
+          placeholder="请输入来源"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="学生id" prop="studentId">
+        <el-input
+          v-model="queryParams.studentId"
+          placeholder="请输入学生id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="科目" prop="subjectId">
+        <el-input
+          v-model="queryParams.subjectId"
+          placeholder="请输入科目"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="知识点id" prop="knownledgeId">
+        <el-input
+          v-model="queryParams.knownledgeId"
+          placeholder="请输入知识点id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="答卷id" prop="examineeId">
+        <el-input
+          v-model="queryParams.examineeId"
+          placeholder="请输入答卷id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷id" prop="paperId">
+        <el-input
+          v-model="queryParams.paperId"
+          placeholder="请输入试卷id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="总分" prop="scoreTotal">
+        <el-input
+          v-model="queryParams.scoreTotal"
+          placeholder="请输入总分"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="评分" prop="score">
+        <el-input
+          v-model="queryParams.score"
+          placeholder="请输入评分"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="评级" prop="scoreLevel">
+        <el-input
+          v-model="queryParams.scoreLevel"
+          placeholder="请输入评级"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="得分率" prop="scoreRate">
+        <el-input
+          v-model="queryParams.scoreRate"
+          placeholder="请输入得分率"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:WrongDetail:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:WrongDetail:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:WrongDetail:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:WrongDetail:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="WrongDetailList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="wrong_detail_id" align="center" prop="wrongDetailId" />
+      <el-table-column label="错题本id" align="center" prop="wrongId" />
+      <el-table-column label="创建时间" align="center" prop="createdTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="来源" align="center" prop="source" />
+      <el-table-column label="学生id" align="center" prop="studentId" />
+      <el-table-column label="科目" align="center" prop="subjectId" />
+      <el-table-column label="知识点id" align="center" prop="knownledgeId" />
+      <el-table-column label="答卷id" align="center" prop="examineeId" />
+      <el-table-column label="试卷id" align="center" prop="paperId" />
+      <el-table-column label="总分" align="center" prop="scoreTotal" />
+      <el-table-column label="评分" align="center" prop="score" />
+      <el-table-column label="评级" align="center" prop="scoreLevel" />
+      <el-table-column label="得分率" align="center" prop="scoreRate" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:WrongDetail:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:WrongDetail:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改学生错题流水对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="WrongDetailRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="错题本id" prop="wrongId">
+          <el-input v-model="form.wrongId" placeholder="请输入错题本id" />
+        </el-form-item>
+        <el-form-item label="创建时间" prop="createdTime">
+          <el-date-picker clearable
+            v-model="form.createdTime"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择创建时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="来源" prop="source">
+          <el-input v-model="form.source" placeholder="请输入来源" />
+        </el-form-item>
+        <el-form-item label="学生id" prop="studentId">
+          <el-input v-model="form.studentId" placeholder="请输入学生id" />
+        </el-form-item>
+        <el-form-item label="科目" prop="subjectId">
+          <el-input v-model="form.subjectId" placeholder="请输入科目" />
+        </el-form-item>
+        <el-form-item label="知识点id" prop="knownledgeId">
+          <el-input v-model="form.knownledgeId" placeholder="请输入知识点id" />
+        </el-form-item>
+        <el-form-item label="答卷id" prop="examineeId">
+          <el-input v-model="form.examineeId" placeholder="请输入答卷id" />
+        </el-form-item>
+        <el-form-item label="试卷id" prop="paperId">
+          <el-input v-model="form.paperId" placeholder="请输入试卷id" />
+        </el-form-item>
+        <el-form-item label="总分" prop="scoreTotal">
+          <el-input v-model="form.scoreTotal" placeholder="请输入总分" />
+        </el-form-item>
+        <el-form-item label="评分" prop="score">
+          <el-input v-model="form.score" placeholder="请输入评分" />
+        </el-form-item>
+        <el-form-item label="评级" prop="scoreLevel">
+          <el-input v-model="form.scoreLevel" placeholder="请输入评级" />
+        </el-form-item>
+        <el-form-item label="得分率" prop="scoreRate">
+          <el-input v-model="form.scoreRate" placeholder="请输入得分率" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="WrongDetail">
+import { listWrongDetail, getWrongDetail, delWrongDetail, addWrongDetail, updateWrongDetail } from "@/api/learn/WrongDetail"
+
+const { proxy } = getCurrentInstance()
+
+const WrongDetailList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    wrongId: null,
+    createdTime: null,
+    source: null,
+    studentId: null,
+    subjectId: null,
+    knownledgeId: null,
+    examineeId: null,
+    paperId: null,
+    scoreTotal: null,
+    score: null,
+    scoreLevel: null,
+    scoreRate: null
+  },
+  rules: {
+    wrongId: [
+      { required: true, message: "错题本id不能为空", trigger: "blur" }
+    ],
+    createdTime: [
+      { required: true, message: "创建时间不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询学生错题流水列表 */
+function getList() {
+  loading.value = true
+  listWrongDetail(queryParams.value).then(response => {
+    WrongDetailList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    wrongDetailId: null,
+    wrongId: null,
+    createdTime: null,
+    source: null,
+    studentId: null,
+    subjectId: null,
+    knownledgeId: null,
+    examineeId: null,
+    paperId: null,
+    scoreTotal: null,
+    score: null,
+    scoreLevel: null,
+    scoreRate: null
+  }
+  proxy.resetForm("WrongDetailRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.wrongDetailId)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加学生错题流水"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _wrongDetailId = row.wrongDetailId || ids.value
+  getWrongDetail(_wrongDetailId).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改学生错题流水"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["WrongDetailRef"].validate(valid => {
+    if (valid) {
+      if (form.value.wrongDetailId != null) {
+        updateWrongDetail(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addWrongDetail(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _wrongDetailIds = row.wrongDetailId || ids.value
+  proxy.$modal.confirm('是否确认删除学生错题流水编号为"' + _wrongDetailIds + '"的数据项?').then(function() {
+    return delWrongDetail(_wrongDetailIds)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/WrongDetail/export', {
+    ...queryParams.value
+  }, `WrongDetail_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 392 - 0
back-ui/src/views/learn/answer/index.vue

@@ -0,0 +1,392 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="答卷id" prop="examineeId">
+        <el-input
+          v-model="queryParams.examineeId"
+          placeholder="请输入答卷id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="学生用户id加速" prop="studentId">
+        <el-input
+          v-model="queryParams.studentId"
+          placeholder="请输入学生用户id加速"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="题id" prop="questionId">
+        <el-input
+          v-model="queryParams.questionId"
+          placeholder="请输入题id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="题号" prop="seq">
+        <el-input
+          v-model="queryParams.seq"
+          placeholder="请输入题号"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="知识点" prop="knowledgeId">
+        <el-input
+          v-model="queryParams.knowledgeId"
+          placeholder="请输入知识点"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="批改答案" prop="correct">
+        <el-input
+          v-model="queryParams.correct"
+          placeholder="请输入批改答案"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="最长时间" prop="duration">
+        <el-input
+          v-model="queryParams.duration"
+          placeholder="请输入最长时间"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="更新次数" prop="count">
+        <el-input
+          v-model="queryParams.count"
+          placeholder="请输入更新次数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态 1 正确" prop="state">
+        <el-input
+          v-model="queryParams.state"
+          placeholder="请输入状态 1 正确"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="评级" prop="scoreLevel">
+        <el-input
+          v-model="queryParams.scoreLevel"
+          placeholder="请输入评级"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="评分" prop="score">
+        <el-input
+          v-model="queryParams.score"
+          placeholder="请输入评分"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="得分率" prop="scoreRate">
+        <el-input
+          v-model="queryParams.scoreRate"
+          placeholder="请输入得分率"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:answer:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:answer:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:answer:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:answer:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="answerList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="答题id" align="center" prop="answerId" />
+      <el-table-column label="答卷id" align="center" prop="examineeId" />
+      <el-table-column label="学生用户id加速" align="center" prop="studentId" />
+      <el-table-column label="题id" align="center" prop="questionId" />
+      <el-table-column label="题号" align="center" prop="seq" />
+      <el-table-column label="知识点" align="center" prop="knowledgeId" />
+      <el-table-column label="学生答案" align="center" prop="answer" />
+      <el-table-column label="批改答案" align="center" prop="correct" />
+      <el-table-column label="最长时间" align="center" prop="duration" />
+      <el-table-column label="更新次数" align="center" prop="count" />
+      <el-table-column label="状态 1 正确" align="center" prop="state" />
+      <el-table-column label="评级" align="center" prop="scoreLevel" />
+      <el-table-column label="评分" align="center" prop="score" />
+      <el-table-column label="得分率" align="center" prop="scoreRate" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:answer:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:answer:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改答卷答案对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="answerRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="答卷id" prop="examineeId">
+          <el-input v-model="form.examineeId" placeholder="请输入答卷id" />
+        </el-form-item>
+        <el-form-item label="学生用户id加速" prop="studentId">
+          <el-input v-model="form.studentId" placeholder="请输入学生用户id加速" />
+        </el-form-item>
+        <el-form-item label="题id" prop="questionId">
+          <el-input v-model="form.questionId" placeholder="请输入题id" />
+        </el-form-item>
+        <el-form-item label="题号" prop="seq">
+          <el-input v-model="form.seq" placeholder="请输入题号" />
+        </el-form-item>
+        <el-form-item label="知识点" prop="knowledgeId">
+          <el-input v-model="form.knowledgeId" placeholder="请输入知识点" />
+        </el-form-item>
+        <el-form-item label="学生答案" prop="answer">
+          <el-input v-model="form.answer" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="批改答案" prop="correct">
+          <el-input v-model="form.correct" placeholder="请输入批改答案" />
+        </el-form-item>
+        <el-form-item label="最长时间" prop="duration">
+          <el-input v-model="form.duration" placeholder="请输入最长时间" />
+        </el-form-item>
+        <el-form-item label="更新次数" prop="count">
+          <el-input v-model="form.count" placeholder="请输入更新次数" />
+        </el-form-item>
+        <el-form-item label="状态 1 正确" prop="state">
+          <el-input v-model="form.state" placeholder="请输入状态 1 正确" />
+        </el-form-item>
+        <el-form-item label="评级" prop="scoreLevel">
+          <el-input v-model="form.scoreLevel" placeholder="请输入评级" />
+        </el-form-item>
+        <el-form-item label="评分" prop="score">
+          <el-input v-model="form.score" placeholder="请输入评分" />
+        </el-form-item>
+        <el-form-item label="得分率" prop="scoreRate">
+          <el-input v-model="form.scoreRate" placeholder="请输入得分率" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Answer">
+import { listAnswer, getAnswer, delAnswer, addAnswer, updateAnswer } from "@/api/learn/answer"
+
+const { proxy } = getCurrentInstance()
+
+const answerList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    examineeId: null,
+    studentId: null,
+    questionId: null,
+    seq: null,
+    knowledgeId: null,
+    answer: null,
+    correct: null,
+    duration: null,
+    count: null,
+    state: null,
+    scoreLevel: null,
+    score: null,
+    scoreRate: null,
+  },
+  rules: {
+    examineeId: [
+      { required: true, message: "答卷id不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询答卷答案列表 */
+function getList() {
+  loading.value = true
+  listAnswer(queryParams.value).then(response => {
+    answerList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    answerId: null,
+    examineeId: null,
+    studentId: null,
+    questionId: null,
+    seq: null,
+    knowledgeId: null,
+    answer: null,
+    correct: null,
+    duration: null,
+    count: null,
+    state: null,
+    scoreLevel: null,
+    score: null,
+    scoreRate: null,
+    createTime: null,
+    updateTime: null
+  }
+  proxy.resetForm("answerRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.answerId)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加答卷答案"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _answerId = row.answerId || ids.value
+  getAnswer(_answerId).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改答卷答案"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["answerRef"].validate(valid => {
+    if (valid) {
+      if (form.value.answerId != null) {
+        updateAnswer(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addAnswer(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _answerIds = row.answerId || ids.value
+  proxy.$modal.confirm('是否确认删除答卷答案编号为"' + _answerIds + '"的数据项?').then(function() {
+    return delAnswer(_answerIds)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/answer/export', {
+    ...queryParams.value
+  }, `answer_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 351 - 0
back-ui/src/views/learn/directKnowledge/index.vue

@@ -0,0 +1,351 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="年度" prop="year">
+        <el-input
+          v-model="queryParams.year"
+          placeholder="请输入年度"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="定向Key" prop="directKey">
+        <el-input
+          v-model="queryParams.directKey"
+          placeholder="请输入定向Key"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="录取公式" prop="enrollFormula">
+        <el-input
+          v-model="queryParams.enrollFormula"
+          placeholder="请输入录取公式"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="文化科目" prop="cultural">
+        <el-input
+          v-model="queryParams.cultural"
+          placeholder="请输入文化科目"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="专业类别" prop="professional">
+        <el-input
+          v-model="queryParams.professional"
+          placeholder="请输入专业类别"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="专业科目" prop="subjects">
+        <el-input
+          v-model="queryParams.subjects"
+          placeholder="请输入专业科目"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="适用省份" prop="locations">
+        <el-input
+          v-model="queryParams.locations"
+          placeholder="请输入适用省份"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="适用考生类型" prop="examineeTypes">
+        <el-input
+          v-model="queryParams.examineeTypes"
+          placeholder="请输入适用考生类型"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="仿真模拟卷要求" prop="conditions">
+        <el-input
+          v-model="queryParams.conditions"
+          placeholder="请输入仿真模拟卷要求"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:directKnowledge:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:directKnowledge:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:directKnowledge:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:directKnowledge:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="directKnowledgeList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="id" align="center" prop="id" />
+      <el-table-column label="年度" align="center" prop="year" />
+      <el-table-column label="定向Key" align="center" prop="directKey" />
+      <el-table-column label="录取公式" align="center" prop="enrollFormula" />
+      <el-table-column label="文化科目" align="center" prop="cultural" />
+      <el-table-column label="专业类别" align="center" prop="professional" />
+      <el-table-column label="专业科目" align="center" prop="subjects" />
+      <el-table-column label="题型分布" align="center" prop="questionTypes" />
+      <el-table-column label="祖级列表" align="center" prop="knowledges" />
+      <el-table-column label="适用省份" align="center" prop="locations" />
+      <el-table-column label="适用考生类型" align="center" prop="examineeTypes" />
+      <el-table-column label="仿真模拟卷要求" align="center" prop="conditions" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:directKnowledge:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:directKnowledge:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改定向知识点关系对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="directKnowledgeRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="年度" prop="year">
+          <el-input v-model="form.year" placeholder="请输入年度" />
+        </el-form-item>
+        <el-form-item label="定向Key" prop="directKey">
+          <el-input v-model="form.directKey" placeholder="请输入定向Key" />
+        </el-form-item>
+        <el-form-item label="录取公式" prop="enrollFormula">
+          <el-input v-model="form.enrollFormula" placeholder="请输入录取公式" />
+        </el-form-item>
+        <el-form-item label="文化科目" prop="cultural">
+          <el-input v-model="form.cultural" placeholder="请输入文化科目" />
+        </el-form-item>
+        <el-form-item label="专业类别" prop="professional">
+          <el-input v-model="form.professional" placeholder="请输入专业类别" />
+        </el-form-item>
+        <el-form-item label="专业科目" prop="subjects">
+          <el-input v-model="form.subjects" placeholder="请输入专业科目" />
+        </el-form-item>
+        <el-form-item label="题型分布" prop="questionTypes">
+          <el-input v-model="form.questionTypes" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="祖级列表" prop="knowledges">
+          <el-input v-model="form.knowledges" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="适用省份" prop="locations">
+          <el-input v-model="form.locations" placeholder="请输入适用省份" />
+        </el-form-item>
+        <el-form-item label="适用考生类型" prop="examineeTypes">
+          <el-input v-model="form.examineeTypes" placeholder="请输入适用考生类型" />
+        </el-form-item>
+        <el-form-item label="仿真模拟卷要求" prop="conditions">
+          <el-input v-model="form.conditions" placeholder="请输入仿真模拟卷要求" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="DirectKnowledge">
+import { listDirectKnowledge, getDirectKnowledge, delDirectKnowledge, addDirectKnowledge, updateDirectKnowledge } from "@/api/learn/directKnowledge"
+
+const { proxy } = getCurrentInstance()
+
+const directKnowledgeList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    year: null,
+    directKey: null,
+    enrollFormula: null,
+    cultural: null,
+    professional: null,
+    subjects: null,
+    questionTypes: null,
+    knowledges: null,
+    locations: null,
+    examineeTypes: null,
+    conditions: null
+  },
+  rules: {
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询定向知识点关系列表 */
+function getList() {
+  loading.value = true
+  listDirectKnowledge(queryParams.value).then(response => {
+    directKnowledgeList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    year: null,
+    directKey: null,
+    enrollFormula: null,
+    cultural: null,
+    professional: null,
+    subjects: null,
+    questionTypes: null,
+    knowledges: null,
+    locations: null,
+    examineeTypes: null,
+    conditions: null
+  }
+  proxy.resetForm("directKnowledgeRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加定向知识点关系"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _id = row.id || ids.value
+  getDirectKnowledge(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改定向知识点关系"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["directKnowledgeRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateDirectKnowledge(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addDirectKnowledge(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value
+  proxy.$modal.confirm('是否确认删除定向知识点关系编号为"' + _ids + '"的数据项?').then(function() {
+    return delDirectKnowledge(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/directKnowledge/export', {
+    ...queryParams.value
+  }, `directKnowledge_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 432 - 0
back-ui/src/views/learn/examinee/index.vue

@@ -0,0 +1,432 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="学生id" prop="studentId">
+        <el-input
+          v-model="queryParams.studentId"
+          placeholder="请输入学生id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷id" prop="paperId">
+        <el-input
+          v-model="queryParams.paperId"
+          placeholder="请输入试卷id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="开始时间" prop="beginTime">
+        <el-date-picker clearable
+          v-model="queryParams.beginTime"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择开始时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="结束时间" prop="endTime">
+        <el-date-picker clearable
+          v-model="queryParams.endTime"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择结束时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="未答题, 已答题, 通过, 未通过" prop="state">
+        <el-input
+          v-model="queryParams.state"
+          placeholder="请输入未答题, 已答题, 通过, 未通过"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="分级" prop="scoreLevel">
+        <el-input
+          v-model="queryParams.scoreLevel"
+          placeholder="请输入分级"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="分值" prop="score">
+        <el-input
+          v-model="queryParams.score"
+          placeholder="请输入分值"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="分率" prop="scoreRate">
+        <el-input
+          v-model="queryParams.scoreRate"
+          placeholder="请输入分率"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="名次" prop="ranking">
+        <el-input
+          v-model="queryParams.ranking"
+          placeholder="请输入名次"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="年排名次" prop="gradeRanking">
+        <el-input
+          v-model="queryParams.gradeRanking"
+          placeholder="请输入年排名次"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="选择题正确数" prop="chooseCount">
+        <el-input
+          v-model="queryParams.chooseCount"
+          placeholder="请输入选择题正确数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="选择题总数" prop="chooseTotal">
+        <el-input
+          v-model="queryParams.chooseTotal"
+          placeholder="请输入选择题总数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="主观题正确数" prop="subjectiveCount">
+        <el-input
+          v-model="queryParams.subjectiveCount"
+          placeholder="请输入主观题正确数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="主观题总数" prop="subjectiveTotal">
+        <el-input
+          v-model="queryParams.subjectiveTotal"
+          placeholder="请输入主观题总数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:examinee:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:examinee:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:examinee:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:examinee:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="examineeList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="答卷id" align="center" prop="examineeId" />
+      <el-table-column label="学生id" align="center" prop="studentId" />
+      <el-table-column label="试卷类型" align="center" prop="paperType" />
+      <el-table-column label="试卷id" align="center" prop="paperId" />
+      <el-table-column label="开始时间" align="center" prop="beginTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.beginTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="结束时间" align="center" prop="endTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="未答题, 已答题, 通过, 未通过" align="center" prop="state" />
+      <el-table-column label="分级" align="center" prop="scoreLevel" />
+      <el-table-column label="分值" align="center" prop="score" />
+      <el-table-column label="分率" align="center" prop="scoreRate" />
+      <el-table-column label="名次" align="center" prop="ranking" />
+      <el-table-column label="年排名次" align="center" prop="gradeRanking" />
+      <el-table-column label="选择题正确数" align="center" prop="chooseCount" />
+      <el-table-column label="选择题总数" align="center" prop="chooseTotal" />
+      <el-table-column label="主观题正确数" align="center" prop="subjectiveCount" />
+      <el-table-column label="主观题总数" align="center" prop="subjectiveTotal" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:examinee:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:examinee:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改答卷对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="examineeRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="学生id" prop="studentId">
+          <el-input v-model="form.studentId" placeholder="请输入学生id" />
+        </el-form-item>
+        <el-form-item label="试卷id" prop="paperId">
+          <el-input v-model="form.paperId" placeholder="请输入试卷id" />
+        </el-form-item>
+        <el-form-item label="开始时间" prop="beginTime">
+          <el-date-picker clearable
+            v-model="form.beginTime"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择开始时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="结束时间" prop="endTime">
+          <el-date-picker clearable
+            v-model="form.endTime"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择结束时间">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="未答题, 已答题, 通过, 未通过" prop="state">
+          <el-input v-model="form.state" placeholder="请输入未答题, 已答题, 通过, 未通过" />
+        </el-form-item>
+        <el-form-item label="分级" prop="scoreLevel">
+          <el-input v-model="form.scoreLevel" placeholder="请输入分级" />
+        </el-form-item>
+        <el-form-item label="分值" prop="score">
+          <el-input v-model="form.score" placeholder="请输入分值" />
+        </el-form-item>
+        <el-form-item label="分率" prop="scoreRate">
+          <el-input v-model="form.scoreRate" placeholder="请输入分率" />
+        </el-form-item>
+        <el-form-item label="名次" prop="ranking">
+          <el-input v-model="form.ranking" placeholder="请输入名次" />
+        </el-form-item>
+        <el-form-item label="年排名次" prop="gradeRanking">
+          <el-input v-model="form.gradeRanking" placeholder="请输入年排名次" />
+        </el-form-item>
+        <el-form-item label="选择题正确数" prop="chooseCount">
+          <el-input v-model="form.chooseCount" placeholder="请输入选择题正确数" />
+        </el-form-item>
+        <el-form-item label="选择题总数" prop="chooseTotal">
+          <el-input v-model="form.chooseTotal" placeholder="请输入选择题总数" />
+        </el-form-item>
+        <el-form-item label="主观题正确数" prop="subjectiveCount">
+          <el-input v-model="form.subjectiveCount" placeholder="请输入主观题正确数" />
+        </el-form-item>
+        <el-form-item label="主观题总数" prop="subjectiveTotal">
+          <el-input v-model="form.subjectiveTotal" placeholder="请输入主观题总数" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Examinee">
+import { listExaminee, getExaminee, delExaminee, addExaminee, updateExaminee } from "@/api/learn/examinee"
+
+const { proxy } = getCurrentInstance()
+
+const examineeList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    studentId: null,
+    paperType: null,
+    paperId: null,
+    beginTime: null,
+    endTime: null,
+    state: null,
+    scoreLevel: null,
+    score: null,
+    scoreRate: null,
+    ranking: null,
+    gradeRanking: null,
+    chooseCount: null,
+    chooseTotal: null,
+    subjectiveCount: null,
+    subjectiveTotal: null,
+  },
+  rules: {
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询答卷列表 */
+function getList() {
+  loading.value = true
+  listExaminee(queryParams.value).then(response => {
+    examineeList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    examineeId: null,
+    studentId: null,
+    paperType: null,
+    paperId: null,
+    beginTime: null,
+    endTime: null,
+    state: null,
+    scoreLevel: null,
+    score: null,
+    scoreRate: null,
+    ranking: null,
+    gradeRanking: null,
+    chooseCount: null,
+    chooseTotal: null,
+    subjectiveCount: null,
+    subjectiveTotal: null,
+    createTime: null,
+    updateTime: null
+  }
+  proxy.resetForm("examineeRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.examineeId)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加答卷"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _examineeId = row.examineeId || ids.value
+  getExaminee(_examineeId).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改答卷"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["examineeRef"].validate(valid => {
+    if (valid) {
+      if (form.value.examineeId != null) {
+        updateExaminee(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addExaminee(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _examineeIds = row.examineeId || ids.value
+  proxy.$modal.confirm('是否确认删除答卷编号为"' + _examineeIds + '"的数据项?').then(function() {
+    return delExaminee(_examineeIds)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/examinee/export', {
+    ...queryParams.value
+  }, `examinee_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 265 - 0
back-ui/src/views/learn/knowledgeQuestion/index.vue

@@ -0,0 +1,265 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="知识点" prop="knowledgeId">
+        <el-input
+          v-model="queryParams.knowledgeId"
+          placeholder="请输入知识点"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="题ID" prop="questionId">
+        <el-input
+          v-model="queryParams.questionId"
+          placeholder="请输入题ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="顺序" prop="seq">
+        <el-input
+          v-model="queryParams.seq"
+          placeholder="请输入顺序"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:knowledgeQuestion:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:knowledgeQuestion:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:knowledgeQuestion:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:knowledgeQuestion:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="knowledgeQuestionList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="ID" align="center" prop="id" />
+      <el-table-column label="知识点" align="center" prop="knowledgeId" />
+      <el-table-column label="0 默认 1know_test-知识点 2必刷题,3auto-基础题库,4high_error-高频错题" align="center" prop="type" />
+      <el-table-column label="题ID" align="center" prop="questionId" />
+      <el-table-column label="顺序" align="center" prop="seq" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:knowledgeQuestion:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:knowledgeQuestion:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改知识点题关系对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="knowledgeQuestionRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="知识点" prop="knowledgeId">
+          <el-input v-model="form.knowledgeId" placeholder="请输入知识点" />
+        </el-form-item>
+        <el-form-item label="题ID" prop="questionId">
+          <el-input v-model="form.questionId" placeholder="请输入题ID" />
+        </el-form-item>
+        <el-form-item label="顺序" prop="seq">
+          <el-input v-model="form.seq" placeholder="请输入顺序" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="KnowledgeQuestion">
+import { listKnowledgeQuestion, getKnowledgeQuestion, delKnowledgeQuestion, addKnowledgeQuestion, updateKnowledgeQuestion } from "@/api/learn/knowledgeQuestion"
+
+const { proxy } = getCurrentInstance()
+
+const knowledgeQuestionList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    knowledgeId: null,
+    type: null,
+    questionId: null,
+    seq: null,
+  },
+  rules: {
+    type: [
+      { required: true, message: "0 默认 1know_test-知识点 2必刷题,3auto-基础题库,4high_error-高频错题不能为空", trigger: "change" }
+    ],
+    seq: [
+      { required: true, message: "顺序不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询知识点题关系列表 */
+function getList() {
+  loading.value = true
+  listKnowledgeQuestion(queryParams.value).then(response => {
+    knowledgeQuestionList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    knowledgeId: null,
+    type: null,
+    questionId: null,
+    seq: null,
+    createTime: null
+  }
+  proxy.resetForm("knowledgeQuestionRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加知识点题关系"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _id = row.id || ids.value
+  getKnowledgeQuestion(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改知识点题关系"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["knowledgeQuestionRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateKnowledgeQuestion(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addKnowledgeQuestion(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value
+  proxy.$modal.confirm('是否确认删除知识点题关系编号为"' + _ids + '"的数据项?').then(function() {
+    return delKnowledgeQuestion(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/knowledgeQuestion/export', {
+    ...queryParams.value
+  }, `knowledgeQuestion_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 336 - 0
back-ui/src/views/learn/knowledgeTree/index.vue

@@ -0,0 +1,336 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="知识点名称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入知识点名称"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="父ID" prop="pid">
+        <el-input
+          v-model="queryParams.pid"
+          placeholder="请输入父ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="祖级列表" prop="ancestors">
+        <el-input
+          v-model="queryParams.ancestors"
+          placeholder="请输入祖级列表"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="科目id" prop="subjectId">
+        <el-input
+          v-model="queryParams.subjectId"
+          placeholder="请输入科目id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="排序" prop="sort">
+        <el-input
+          v-model="queryParams.sort"
+          placeholder="请输入排序"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="级数" prop="level">
+        <el-input
+          v-model="queryParams.level"
+          placeholder="请输入级数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="题目数" prop="questionsCount">
+        <el-input
+          v-model="queryParams.questionsCount"
+          placeholder="请输入题目数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="适用省份" prop="locations">
+        <el-input
+          v-model="queryParams.locations"
+          placeholder="请输入适用省份"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="适用考生类型" prop="examineeTypes">
+        <el-input
+          v-model="queryParams.examineeTypes"
+          placeholder="请输入适用考生类型"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:knowledgeTree:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:knowledgeTree:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:knowledgeTree:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:knowledgeTree:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="knowledgeTreeList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="知识点id" align="center" prop="id" />
+      <el-table-column label="知识点名称" align="center" prop="name" />
+      <el-table-column label="父ID" align="center" prop="pid" />
+      <el-table-column label="祖级列表" align="center" prop="ancestors" />
+      <el-table-column label="科目id" align="center" prop="subjectId" />
+      <el-table-column label="排序" align="center" prop="sort" />
+      <el-table-column label="级数" align="center" prop="level" />
+      <el-table-column label="题目数" align="center" prop="questionsCount" />
+      <el-table-column label="适用省份" align="center" prop="locations" />
+      <el-table-column label="适用考生类型" align="center" prop="examineeTypes" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:knowledgeTree:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:knowledgeTree:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改知识点树对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="knowledgeTreeRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="知识点名称" prop="name">
+          <el-input v-model="form.name" placeholder="请输入知识点名称" />
+        </el-form-item>
+        <el-form-item label="父ID" prop="pid">
+          <el-input v-model="form.pid" placeholder="请输入父ID" />
+        </el-form-item>
+        <el-form-item label="科目id" prop="subjectId">
+          <el-input v-model="form.subjectId" placeholder="请输入科目id" />
+        </el-form-item>
+        <el-form-item label="排序" prop="sort">
+          <el-input v-model="form.sort" placeholder="请输入排序" />
+        </el-form-item>
+        <el-form-item label="级数" prop="level">
+          <el-input v-model="form.level" placeholder="请输入级数" />
+        </el-form-item>
+        <el-form-item label="题目数" prop="questionsCount">
+          <el-input v-model="form.questionsCount" placeholder="请输入题目数" />
+        </el-form-item>
+        <el-form-item label="适用省份" prop="locations">
+          <el-input v-model="form.locations" placeholder="请输入适用省份" />
+        </el-form-item>
+        <el-form-item label="适用考生类型" prop="examineeTypes">
+          <el-input v-model="form.examineeTypes" placeholder="请输入适用考生类型" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="KnowledgeTree">
+import { listKnowledgeTree, getKnowledgeTree, delKnowledgeTree, addKnowledgeTree, updateKnowledgeTree } from "@/api/learn/knowledgeTree"
+
+const { proxy } = getCurrentInstance()
+
+const knowledgeTreeList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    name: null,
+    pid: null,
+    ancestors: null,
+    subjectId: null,
+    sort: null,
+    level: null,
+    questionsCount: null,
+    locations: null,
+    examineeTypes: null
+  },
+  rules: {
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询知识点树列表 */
+function getList() {
+  loading.value = true
+  listKnowledgeTree(queryParams.value).then(response => {
+    knowledgeTreeList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    name: null,
+    pid: null,
+    ancestors: null,
+    subjectId: null,
+    sort: null,
+    level: null,
+    questionsCount: null,
+    locations: null,
+    examineeTypes: null
+  }
+  proxy.resetForm("knowledgeTreeRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加知识点树"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _id = row.id || ids.value
+  getKnowledgeTree(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改知识点树"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["knowledgeTreeRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateKnowledgeTree(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addKnowledgeTree(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value
+  proxy.$modal.confirm('是否确认删除知识点树编号为"' + _ids + '"的数据项?').then(function() {
+    return delKnowledgeTree(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/knowledgeTree/export', {
+    ...queryParams.value
+  }, `knowledgeTree_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 297 - 0
back-ui/src/views/learn/learnPlan/index.vue

@@ -0,0 +1,297 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="学生id" prop="studentId">
+        <el-input
+          v-model="queryParams.studentId"
+          placeholder="请输入学生id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="视频课时间" prop="videoTime">
+        <el-input
+          v-model="queryParams.videoTime"
+          placeholder="请输入视频课时间"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="练题数" prop="questionCnt">
+        <el-input
+          v-model="queryParams.questionCnt"
+          placeholder="请输入练题数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="开始时间" prop="beginTime">
+        <el-date-picker clearable
+          v-model="queryParams.beginTime"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择开始时间">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:learnPlan:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:learnPlan:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:learnPlan:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:learnPlan:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="learnPlanList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="计划id" align="center" prop="id" />
+      <el-table-column label="学生id" align="center" prop="studentId" />
+      <el-table-column label="视频课时间" align="center" prop="videoTime" />
+      <el-table-column label="练题数" align="center" prop="questionCnt" />
+      <el-table-column label="是否有效" align="center" prop="status" />
+      <el-table-column label="开始时间" align="center" prop="beginTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.beginTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="统计情况" align="center" prop="stats" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:learnPlan:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:learnPlan:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改学习计划对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="learnPlanRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="学生id" prop="studentId">
+          <el-input v-model="form.studentId" placeholder="请输入学生id" />
+        </el-form-item>
+        <el-form-item label="视频课时间" prop="videoTime">
+          <el-input v-model="form.videoTime" placeholder="请输入视频课时间" />
+        </el-form-item>
+        <el-form-item label="练题数" prop="questionCnt">
+          <el-input v-model="form.questionCnt" placeholder="请输入练题数" />
+        </el-form-item>
+        <el-form-item label="开始时间" prop="beginTime">
+          <el-date-picker clearable
+            v-model="form.beginTime"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择开始时间">
+          </el-date-picker>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="LearnPlan">
+import { listLearnPlan, getLearnPlan, delLearnPlan, addLearnPlan, updateLearnPlan } from "@/api/learn/learnPlan"
+
+const { proxy } = getCurrentInstance()
+
+const learnPlanList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    studentId: null,
+    videoTime: null,
+    questionCnt: null,
+    status: null,
+    beginTime: null,
+    stats: null
+  },
+  rules: {
+    studentId: [
+      { required: true, message: "学生id不能为空", trigger: "blur" }
+    ],
+    videoTime: [
+      { required: true, message: "视频课时间不能为空", trigger: "blur" }
+    ],
+    questionCnt: [
+      { required: true, message: "练题数不能为空", trigger: "blur" }
+    ],
+    status: [
+      { required: true, message: "是否有效不能为空", trigger: "change" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询学习计划列表 */
+function getList() {
+  loading.value = true
+  listLearnPlan(queryParams.value).then(response => {
+    learnPlanList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    studentId: null,
+    videoTime: null,
+    questionCnt: null,
+    status: null,
+    beginTime: null,
+    createTime: null,
+    stats: null
+  }
+  proxy.resetForm("learnPlanRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加学习计划"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _id = row.id || ids.value
+  getLearnPlan(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改学习计划"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["learnPlanRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateLearnPlan(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addLearnPlan(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value
+  proxy.$modal.confirm('是否确认删除学习计划编号为"' + _ids + '"的数据项?').then(function() {
+    return delLearnPlan(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/learnPlan/export', {
+    ...queryParams.value
+  }, `learnPlan_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 349 - 0
back-ui/src/views/learn/learnPlanStudy/index.vue

@@ -0,0 +1,349 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="学生id" prop="studentId">
+        <el-input
+          v-model="queryParams.studentId"
+          placeholder="请输入学生id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="对应计划" prop="planId">
+        <el-input
+          v-model="queryParams.planId"
+          placeholder="请输入对应计划"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="月份序号" prop="monthSeq">
+        <el-input
+          v-model="queryParams.monthSeq"
+          placeholder="请输入月份序号"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="周序号" prop="weekSeq">
+        <el-input
+          v-model="queryParams.weekSeq"
+          placeholder="请输入周序号"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="学习日期" prop="reportDate">
+        <el-date-picker clearable
+          v-model="queryParams.reportDate"
+          type="date"
+          value-format="YYYY-MM-DD"
+          placeholder="请选择学习日期">
+        </el-date-picker>
+      </el-form-item>
+      <el-form-item label="完成题数" prop="questionCount">
+        <el-input
+          v-model="queryParams.questionCount"
+          placeholder="请输入完成题数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="完成视频时间" prop="videoTime">
+        <el-input
+          v-model="queryParams.videoTime"
+          placeholder="请输入完成视频时间"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="计划做题数" prop="questionPlan">
+        <el-input
+          v-model="queryParams.questionPlan"
+          placeholder="请输入计划做题数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="计划视频时间" prop="videoPlan">
+        <el-input
+          v-model="queryParams.videoPlan"
+          placeholder="请输入计划视频时间"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:learnPlanStudy:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:learnPlanStudy:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:learnPlanStudy:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:learnPlanStudy:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="learnPlanStudyList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="计划学习id" align="center" prop="id" />
+      <el-table-column label="学生id" align="center" prop="studentId" />
+      <el-table-column label="对应计划" align="center" prop="planId" />
+      <el-table-column label="月份序号" align="center" prop="monthSeq" />
+      <el-table-column label="周序号" align="center" prop="weekSeq" />
+      <el-table-column label="学习日期" align="center" prop="reportDate" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.reportDate, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="完成题数" align="center" prop="questionCount" />
+      <el-table-column label="完成视频时间" align="center" prop="videoTime" />
+      <el-table-column label="计划做题数" align="center" prop="questionPlan" />
+      <el-table-column label="计划视频时间" align="center" prop="videoPlan" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:learnPlanStudy:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:learnPlanStudy:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改学生计划执行情况对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="learnPlanStudyRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="学生id" prop="studentId">
+          <el-input v-model="form.studentId" placeholder="请输入学生id" />
+        </el-form-item>
+        <el-form-item label="对应计划" prop="planId">
+          <el-input v-model="form.planId" placeholder="请输入对应计划" />
+        </el-form-item>
+        <el-form-item label="月份序号" prop="monthSeq">
+          <el-input v-model="form.monthSeq" placeholder="请输入月份序号" />
+        </el-form-item>
+        <el-form-item label="周序号" prop="weekSeq">
+          <el-input v-model="form.weekSeq" placeholder="请输入周序号" />
+        </el-form-item>
+        <el-form-item label="学习日期" prop="reportDate">
+          <el-date-picker clearable
+            v-model="form.reportDate"
+            type="date"
+            value-format="YYYY-MM-DD"
+            placeholder="请选择学习日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="完成题数" prop="questionCount">
+          <el-input v-model="form.questionCount" placeholder="请输入完成题数" />
+        </el-form-item>
+        <el-form-item label="完成视频时间" prop="videoTime">
+          <el-input v-model="form.videoTime" placeholder="请输入完成视频时间" />
+        </el-form-item>
+        <el-form-item label="计划做题数" prop="questionPlan">
+          <el-input v-model="form.questionPlan" placeholder="请输入计划做题数" />
+        </el-form-item>
+        <el-form-item label="计划视频时间" prop="videoPlan">
+          <el-input v-model="form.videoPlan" placeholder="请输入计划视频时间" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="LearnPlanStudy">
+import { listLearnPlanStudy, getLearnPlanStudy, delLearnPlanStudy, addLearnPlanStudy, updateLearnPlanStudy } from "@/api/learn/learnPlanStudy"
+
+const { proxy } = getCurrentInstance()
+
+const learnPlanStudyList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    studentId: null,
+    planId: null,
+    monthSeq: null,
+    weekSeq: null,
+    reportDate: null,
+    questionCount: null,
+    videoTime: null,
+    questionPlan: null,
+    videoPlan: null,
+  },
+  rules: {
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询学生计划执行情况列表 */
+function getList() {
+  loading.value = true
+  listLearnPlanStudy(queryParams.value).then(response => {
+    learnPlanStudyList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    studentId: null,
+    planId: null,
+    monthSeq: null,
+    weekSeq: null,
+    reportDate: null,
+    questionCount: null,
+    videoTime: null,
+    questionPlan: null,
+    videoPlan: null,
+    updateTime: null
+  }
+  proxy.resetForm("learnPlanStudyRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加学生计划执行情况"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _id = row.id || ids.value
+  getLearnPlanStudy(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改学生计划执行情况"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["learnPlanStudyRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateLearnPlanStudy(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addLearnPlanStudy(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value
+  proxy.$modal.confirm('是否确认删除学生计划执行情况编号为"' + _ids + '"的数据项?').then(function() {
+    return delLearnPlanStudy(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/learnPlanStudy/export', {
+    ...queryParams.value
+  }, `learnPlanStudy_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 274 - 0
back-ui/src/views/learn/questionCorrect/index.vue

@@ -0,0 +1,274 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="题ID" prop="questionId">
+        <el-input
+          v-model="queryParams.questionId"
+          placeholder="请输入题ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="纠错人" prop="userId">
+        <el-input
+          v-model="queryParams.userId"
+          placeholder="请输入纠错人"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="状态" prop="state">
+        <el-input
+          v-model="queryParams.state"
+          placeholder="请输入状态"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="Plus"
+          @click="handleAdd"
+          v-hasPermi="['learn:questionCorrect:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:questionCorrect:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:questionCorrect:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:questionCorrect:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="questionCorrectList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="纠错id" align="center" prop="id" />
+      <el-table-column label="题ID" align="center" prop="questionId" />
+      <el-table-column label="纠错人" align="center" prop="userId" />
+      <el-table-column label="纠正说明" align="center" prop="remark" />
+      <el-table-column label="状态" align="center" prop="state" />
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+        <template #default="scope">
+          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['learn:questionCorrect:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:questionCorrect:remove']">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    
+    <pagination
+      v-show="total>0"
+      :total="total"
+      v-model:page="queryParams.pageNum"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改题纠错对话框 -->
+    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
+      <el-form ref="questionCorrectRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="题ID" prop="questionId">
+          <el-input v-model="form.questionId" placeholder="请输入题ID" />
+        </el-form-item>
+        <el-form-item label="纠错人" prop="userId">
+          <el-input v-model="form.userId" placeholder="请输入纠错人" />
+        </el-form-item>
+        <el-form-item label="纠正说明" prop="remark">
+          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="状态" prop="state">
+          <el-input v-model="form.state" placeholder="请输入状态" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="QuestionCorrect">
+import { listQuestionCorrect, getQuestionCorrect, delQuestionCorrect, addQuestionCorrect, updateQuestionCorrect } from "@/api/learn/questionCorrect"
+
+const { proxy } = getCurrentInstance()
+
+const questionCorrectList = ref([])
+const open = ref(false)
+const loading = ref(true)
+const showSearch = ref(true)
+const ids = ref([])
+const single = ref(true)
+const multiple = ref(true)
+const total = ref(0)
+const title = ref("")
+
+const data = reactive({
+  form: {},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    questionId: null,
+    userId: null,
+    state: null,
+  },
+  rules: {
+    questionId: [
+      { required: true, message: "题ID不能为空", trigger: "blur" }
+    ],
+    userId: [
+      { required: true, message: "纠错人不能为空", trigger: "blur" }
+    ],
+    remark: [
+      { required: true, message: "纠正说明不能为空", trigger: "blur" }
+    ],
+    state: [
+      { required: true, message: "状态不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询题纠错列表 */
+function getList() {
+  loading.value = true
+  listQuestionCorrect(queryParams.value).then(response => {
+    questionCorrectList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    questionId: null,
+    userId: null,
+    remark: null,
+    state: null,
+    createTime: null,
+    updateTime: null
+  }
+  proxy.resetForm("questionCorrectRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.id)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加题纠错"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _id = row.id || ids.value
+  getQuestionCorrect(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改题纠错"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["questionCorrectRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateQuestionCorrect(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addQuestionCorrect(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _ids = row.id || ids.value
+  proxy.$modal.confirm('是否确认删除题纠错编号为"' + _ids + '"的数据项?').then(function() {
+    return delQuestionCorrect(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/questionCorrect/export', {
+    ...queryParams.value
+  }, `questionCorrect_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnAnswerController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnAnswer;
+import com.ruoyi.learn.service.ILearnAnswerService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 答卷答案Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/answer")
+public class LearnAnswerController extends BaseController
+{
+    @Autowired
+    private ILearnAnswerService learnAnswerService;
+
+    /**
+     * 查询答卷答案列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:answer:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnAnswer learnAnswer)
+    {
+        startPage();
+        List<LearnAnswer> list = learnAnswerService.selectLearnAnswerList(learnAnswer);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出答卷答案列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:answer:export')")
+    @Log(title = "答卷答案", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnAnswer learnAnswer)
+    {
+        List<LearnAnswer> list = learnAnswerService.selectLearnAnswerList(learnAnswer);
+        ExcelUtil<LearnAnswer> util = new ExcelUtil<LearnAnswer>(LearnAnswer.class);
+        util.exportExcel(response, list, "答卷答案数据");
+    }
+
+    /**
+     * 获取答卷答案详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:answer:query')")
+    @GetMapping(value = "/{answerId}")
+    public AjaxResult getInfo(@PathVariable("answerId") Long answerId)
+    {
+        return success(learnAnswerService.selectLearnAnswerByAnswerId(answerId));
+    }
+
+    /**
+     * 新增答卷答案
+     */
+    @PreAuthorize("@ss.hasPermi('learn:answer:add')")
+    @Log(title = "答卷答案", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnAnswer learnAnswer)
+    {
+        return toAjax(learnAnswerService.insertLearnAnswer(learnAnswer));
+    }
+
+    /**
+     * 修改答卷答案
+     */
+    @PreAuthorize("@ss.hasPermi('learn:answer:edit')")
+    @Log(title = "答卷答案", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnAnswer learnAnswer)
+    {
+        return toAjax(learnAnswerService.updateLearnAnswer(learnAnswer));
+    }
+
+    /**
+     * 删除答卷答案
+     */
+    @PreAuthorize("@ss.hasPermi('learn:answer:remove')")
+    @Log(title = "答卷答案", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{answerIds}")
+    public AjaxResult remove(@PathVariable Long[] answerIds)
+    {
+        return toAjax(learnAnswerService.deleteLearnAnswerByAnswerIds(answerIds));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnDirectedKnowledgeController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnDirectedKnowledge;
+import com.ruoyi.learn.service.ILearnDirectedKnowledgeService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 定向知识点关系Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/directKnowledge")
+public class LearnDirectedKnowledgeController extends BaseController
+{
+    @Autowired
+    private ILearnDirectedKnowledgeService learnDirectedKnowledgeService;
+
+    /**
+     * 查询定向知识点关系列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:directKnowledge:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        startPage();
+        List<LearnDirectedKnowledge> list = learnDirectedKnowledgeService.selectLearnDirectedKnowledgeList(learnDirectedKnowledge);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出定向知识点关系列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:directKnowledge:export')")
+    @Log(title = "定向知识点关系", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        List<LearnDirectedKnowledge> list = learnDirectedKnowledgeService.selectLearnDirectedKnowledgeList(learnDirectedKnowledge);
+        ExcelUtil<LearnDirectedKnowledge> util = new ExcelUtil<LearnDirectedKnowledge>(LearnDirectedKnowledge.class);
+        util.exportExcel(response, list, "定向知识点关系数据");
+    }
+
+    /**
+     * 获取定向知识点关系详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:directKnowledge:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnDirectedKnowledgeService.selectLearnDirectedKnowledgeById(id));
+    }
+
+    /**
+     * 新增定向知识点关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:directKnowledge:add')")
+    @Log(title = "定向知识点关系", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        return toAjax(learnDirectedKnowledgeService.insertLearnDirectedKnowledge(learnDirectedKnowledge));
+    }
+
+    /**
+     * 修改定向知识点关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:directKnowledge:edit')")
+    @Log(title = "定向知识点关系", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        return toAjax(learnDirectedKnowledgeService.updateLearnDirectedKnowledge(learnDirectedKnowledge));
+    }
+
+    /**
+     * 删除定向知识点关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:directKnowledge:remove')")
+    @Log(title = "定向知识点关系", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnDirectedKnowledgeService.deleteLearnDirectedKnowledgeByIds(ids));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnExamineeController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnExaminee;
+import com.ruoyi.learn.service.ILearnExamineeService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 答卷Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/examinee")
+public class LearnExamineeController extends BaseController
+{
+    @Autowired
+    private ILearnExamineeService learnExamineeService;
+
+    /**
+     * 查询答卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:examinee:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnExaminee learnExaminee)
+    {
+        startPage();
+        List<LearnExaminee> list = learnExamineeService.selectLearnExamineeList(learnExaminee);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出答卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:examinee:export')")
+    @Log(title = "答卷", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnExaminee learnExaminee)
+    {
+        List<LearnExaminee> list = learnExamineeService.selectLearnExamineeList(learnExaminee);
+        ExcelUtil<LearnExaminee> util = new ExcelUtil<LearnExaminee>(LearnExaminee.class);
+        util.exportExcel(response, list, "答卷数据");
+    }
+
+    /**
+     * 获取答卷详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:examinee:query')")
+    @GetMapping(value = "/{examineeId}")
+    public AjaxResult getInfo(@PathVariable("examineeId") Long examineeId)
+    {
+        return success(learnExamineeService.selectLearnExamineeByExamineeId(examineeId));
+    }
+
+    /**
+     * 新增答卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:examinee:add')")
+    @Log(title = "答卷", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnExaminee learnExaminee)
+    {
+        return toAjax(learnExamineeService.insertLearnExaminee(learnExaminee));
+    }
+
+    /**
+     * 修改答卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:examinee:edit')")
+    @Log(title = "答卷", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnExaminee learnExaminee)
+    {
+        return toAjax(learnExamineeService.updateLearnExaminee(learnExaminee));
+    }
+
+    /**
+     * 删除答卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:examinee:remove')")
+    @Log(title = "答卷", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{examineeIds}")
+    public AjaxResult remove(@PathVariable Long[] examineeIds)
+    {
+        return toAjax(learnExamineeService.deleteLearnExamineeByExamineeIds(examineeIds));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnKnowledgeQuestionController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnKnowledgeQuestion;
+import com.ruoyi.learn.service.ILearnKnowledgeQuestionService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 知识点题关系Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/knowledgeQuestion")
+public class LearnKnowledgeQuestionController extends BaseController
+{
+    @Autowired
+    private ILearnKnowledgeQuestionService learnKnowledgeQuestionService;
+
+    /**
+     * 查询知识点题关系列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeQuestion:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        startPage();
+        List<LearnKnowledgeQuestion> list = learnKnowledgeQuestionService.selectLearnKnowledgeQuestionList(learnKnowledgeQuestion);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出知识点题关系列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeQuestion:export')")
+    @Log(title = "知识点题关系", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        List<LearnKnowledgeQuestion> list = learnKnowledgeQuestionService.selectLearnKnowledgeQuestionList(learnKnowledgeQuestion);
+        ExcelUtil<LearnKnowledgeQuestion> util = new ExcelUtil<LearnKnowledgeQuestion>(LearnKnowledgeQuestion.class);
+        util.exportExcel(response, list, "知识点题关系数据");
+    }
+
+    /**
+     * 获取知识点题关系详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeQuestion:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnKnowledgeQuestionService.selectLearnKnowledgeQuestionById(id));
+    }
+
+    /**
+     * 新增知识点题关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeQuestion:add')")
+    @Log(title = "知识点题关系", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        return toAjax(learnKnowledgeQuestionService.insertLearnKnowledgeQuestion(learnKnowledgeQuestion));
+    }
+
+    /**
+     * 修改知识点题关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeQuestion:edit')")
+    @Log(title = "知识点题关系", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        return toAjax(learnKnowledgeQuestionService.updateLearnKnowledgeQuestion(learnKnowledgeQuestion));
+    }
+
+    /**
+     * 删除知识点题关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeQuestion:remove')")
+    @Log(title = "知识点题关系", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnKnowledgeQuestionService.deleteLearnKnowledgeQuestionByIds(ids));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnKnowledgeTreeController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnKnowledgeTree;
+import com.ruoyi.learn.service.ILearnKnowledgeTreeService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 知识点树Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/knowledgeTree")
+public class LearnKnowledgeTreeController extends BaseController
+{
+    @Autowired
+    private ILearnKnowledgeTreeService learnKnowledgeTreeService;
+
+    /**
+     * 查询知识点树列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeTree:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnKnowledgeTree learnKnowledgeTree)
+    {
+        startPage();
+        List<LearnKnowledgeTree> list = learnKnowledgeTreeService.selectLearnKnowledgeTreeList(learnKnowledgeTree);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出知识点树列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeTree:export')")
+    @Log(title = "知识点树", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnKnowledgeTree learnKnowledgeTree)
+    {
+        List<LearnKnowledgeTree> list = learnKnowledgeTreeService.selectLearnKnowledgeTreeList(learnKnowledgeTree);
+        ExcelUtil<LearnKnowledgeTree> util = new ExcelUtil<LearnKnowledgeTree>(LearnKnowledgeTree.class);
+        util.exportExcel(response, list, "知识点树数据");
+    }
+
+    /**
+     * 获取知识点树详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeTree:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnKnowledgeTreeService.selectLearnKnowledgeTreeById(id));
+    }
+
+    /**
+     * 新增知识点树
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeTree:add')")
+    @Log(title = "知识点树", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnKnowledgeTree learnKnowledgeTree)
+    {
+        return toAjax(learnKnowledgeTreeService.insertLearnKnowledgeTree(learnKnowledgeTree));
+    }
+
+    /**
+     * 修改知识点树
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeTree:edit')")
+    @Log(title = "知识点树", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnKnowledgeTree learnKnowledgeTree)
+    {
+        return toAjax(learnKnowledgeTreeService.updateLearnKnowledgeTree(learnKnowledgeTree));
+    }
+
+    /**
+     * 删除知识点树
+     */
+    @PreAuthorize("@ss.hasPermi('learn:knowledgeTree:remove')")
+    @Log(title = "知识点树", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnKnowledgeTreeService.deleteLearnKnowledgeTreeByIds(ids));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPlanController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnPlan;
+import com.ruoyi.learn.service.ILearnPlanService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 学习计划Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/learnPlan")
+public class LearnPlanController extends BaseController
+{
+    @Autowired
+    private ILearnPlanService learnPlanService;
+
+    /**
+     * 查询学习计划列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlan:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnPlan learnPlan)
+    {
+        startPage();
+        List<LearnPlan> list = learnPlanService.selectLearnPlanList(learnPlan);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出学习计划列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlan:export')")
+    @Log(title = "学习计划", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnPlan learnPlan)
+    {
+        List<LearnPlan> list = learnPlanService.selectLearnPlanList(learnPlan);
+        ExcelUtil<LearnPlan> util = new ExcelUtil<LearnPlan>(LearnPlan.class);
+        util.exportExcel(response, list, "学习计划数据");
+    }
+
+    /**
+     * 获取学习计划详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlan:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return success(learnPlanService.selectLearnPlanById(id));
+    }
+
+    /**
+     * 新增学习计划
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlan:add')")
+    @Log(title = "学习计划", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnPlan learnPlan)
+    {
+        return toAjax(learnPlanService.insertLearnPlan(learnPlan));
+    }
+
+    /**
+     * 修改学习计划
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlan:edit')")
+    @Log(title = "学习计划", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnPlan learnPlan)
+    {
+        return toAjax(learnPlanService.updateLearnPlan(learnPlan));
+    }
+
+    /**
+     * 删除学习计划
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlan:remove')")
+    @Log(title = "学习计划", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        return toAjax(learnPlanService.deleteLearnPlanByIds(ids));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPlanStudyController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnPlanStudy;
+import com.ruoyi.learn.service.ILearnPlanStudyService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 学生计划执行情况Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/learnPlanStudy")
+public class LearnPlanStudyController extends BaseController
+{
+    @Autowired
+    private ILearnPlanStudyService learnPlanStudyService;
+
+    /**
+     * 查询学生计划执行情况列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlanStudy:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnPlanStudy learnPlanStudy)
+    {
+        startPage();
+        List<LearnPlanStudy> list = learnPlanStudyService.selectLearnPlanStudyList(learnPlanStudy);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出学生计划执行情况列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlanStudy:export')")
+    @Log(title = "学生计划执行情况", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnPlanStudy learnPlanStudy)
+    {
+        List<LearnPlanStudy> list = learnPlanStudyService.selectLearnPlanStudyList(learnPlanStudy);
+        ExcelUtil<LearnPlanStudy> util = new ExcelUtil<LearnPlanStudy>(LearnPlanStudy.class);
+        util.exportExcel(response, list, "学生计划执行情况数据");
+    }
+
+    /**
+     * 获取学生计划执行情况详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlanStudy:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return success(learnPlanStudyService.selectLearnPlanStudyById(id));
+    }
+
+    /**
+     * 新增学生计划执行情况
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlanStudy:add')")
+    @Log(title = "学生计划执行情况", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnPlanStudy learnPlanStudy)
+    {
+        return toAjax(learnPlanStudyService.insertLearnPlanStudy(learnPlanStudy));
+    }
+
+    /**
+     * 修改学生计划执行情况
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlanStudy:edit')")
+    @Log(title = "学生计划执行情况", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnPlanStudy learnPlanStudy)
+    {
+        return toAjax(learnPlanStudyService.updateLearnPlanStudy(learnPlanStudy));
+    }
+
+    /**
+     * 删除学生计划执行情况
+     */
+    @PreAuthorize("@ss.hasPermi('learn:learnPlanStudy:remove')")
+    @Log(title = "学生计划执行情况", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        return toAjax(learnPlanStudyService.deleteLearnPlanStudyByIds(ids));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnQuestionCorrectController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnQuestionCorrect;
+import com.ruoyi.learn.service.ILearnQuestionCorrectService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 题纠错Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/questionCorrect")
+public class LearnQuestionCorrectController extends BaseController
+{
+    @Autowired
+    private ILearnQuestionCorrectService learnQuestionCorrectService;
+
+    /**
+     * 查询题纠错列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questionCorrect:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnQuestionCorrect learnQuestionCorrect)
+    {
+        startPage();
+        List<LearnQuestionCorrect> list = learnQuestionCorrectService.selectLearnQuestionCorrectList(learnQuestionCorrect);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出题纠错列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questionCorrect:export')")
+    @Log(title = "题纠错", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnQuestionCorrect learnQuestionCorrect)
+    {
+        List<LearnQuestionCorrect> list = learnQuestionCorrectService.selectLearnQuestionCorrectList(learnQuestionCorrect);
+        ExcelUtil<LearnQuestionCorrect> util = new ExcelUtil<LearnQuestionCorrect>(LearnQuestionCorrect.class);
+        util.exportExcel(response, list, "题纠错数据");
+    }
+
+    /**
+     * 获取题纠错详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questionCorrect:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnQuestionCorrectService.selectLearnQuestionCorrectById(id));
+    }
+
+    /**
+     * 新增题纠错
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questionCorrect:add')")
+    @Log(title = "题纠错", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnQuestionCorrect learnQuestionCorrect)
+    {
+        return toAjax(learnQuestionCorrectService.insertLearnQuestionCorrect(learnQuestionCorrect));
+    }
+
+    /**
+     * 修改题纠错
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questionCorrect:edit')")
+    @Log(title = "题纠错", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnQuestionCorrect learnQuestionCorrect)
+    {
+        return toAjax(learnQuestionCorrectService.updateLearnQuestionCorrect(learnQuestionCorrect));
+    }
+
+    /**
+     * 删除题纠错
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questionCorrect:remove')")
+    @Log(title = "题纠错", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnQuestionCorrectService.deleteLearnQuestionCorrectByIds(ids));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnWrongBookController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnWrongBook;
+import com.ruoyi.learn.service.ILearnWrongBookService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 学生错题本Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/WrongBook")
+public class LearnWrongBookController extends BaseController
+{
+    @Autowired
+    private ILearnWrongBookService learnWrongBookService;
+
+    /**
+     * 查询学生错题本列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongBook:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnWrongBook learnWrongBook)
+    {
+        startPage();
+        List<LearnWrongBook> list = learnWrongBookService.selectLearnWrongBookList(learnWrongBook);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出学生错题本列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongBook:export')")
+    @Log(title = "学生错题本", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnWrongBook learnWrongBook)
+    {
+        List<LearnWrongBook> list = learnWrongBookService.selectLearnWrongBookList(learnWrongBook);
+        ExcelUtil<LearnWrongBook> util = new ExcelUtil<LearnWrongBook>(LearnWrongBook.class);
+        util.exportExcel(response, list, "学生错题本数据");
+    }
+
+    /**
+     * 获取学生错题本详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongBook:query')")
+    @GetMapping(value = "/{wrongId}")
+    public AjaxResult getInfo(@PathVariable("wrongId") Long wrongId)
+    {
+        return success(learnWrongBookService.selectLearnWrongBookByWrongId(wrongId));
+    }
+
+    /**
+     * 新增学生错题本
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongBook:add')")
+    @Log(title = "学生错题本", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnWrongBook learnWrongBook)
+    {
+        return toAjax(learnWrongBookService.insertLearnWrongBook(learnWrongBook));
+    }
+
+    /**
+     * 修改学生错题本
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongBook:edit')")
+    @Log(title = "学生错题本", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnWrongBook learnWrongBook)
+    {
+        return toAjax(learnWrongBookService.updateLearnWrongBook(learnWrongBook));
+    }
+
+    /**
+     * 删除学生错题本
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongBook:remove')")
+    @Log(title = "学生错题本", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{wrongIds}")
+    public AjaxResult remove(@PathVariable Long[] wrongIds)
+    {
+        return toAjax(learnWrongBookService.deleteLearnWrongBookByWrongIds(wrongIds));
+    }
+}

+ 104 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnWrongDetailController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.learn.domain.LearnWrongDetail;
+import com.ruoyi.learn.service.ILearnWrongDetailService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 学生错题流水Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@RestController
+@RequestMapping("/learn/WrongDetail")
+public class LearnWrongDetailController extends BaseController
+{
+    @Autowired
+    private ILearnWrongDetailService learnWrongDetailService;
+
+    /**
+     * 查询学生错题流水列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongDetail:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnWrongDetail learnWrongDetail)
+    {
+        startPage();
+        List<LearnWrongDetail> list = learnWrongDetailService.selectLearnWrongDetailList(learnWrongDetail);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出学生错题流水列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongDetail:export')")
+    @Log(title = "学生错题流水", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnWrongDetail learnWrongDetail)
+    {
+        List<LearnWrongDetail> list = learnWrongDetailService.selectLearnWrongDetailList(learnWrongDetail);
+        ExcelUtil<LearnWrongDetail> util = new ExcelUtil<LearnWrongDetail>(LearnWrongDetail.class);
+        util.exportExcel(response, list, "学生错题流水数据");
+    }
+
+    /**
+     * 获取学生错题流水详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongDetail:query')")
+    @GetMapping(value = "/{wrongDetailId}")
+    public AjaxResult getInfo(@PathVariable("wrongDetailId") Long wrongDetailId)
+    {
+        return success(learnWrongDetailService.selectLearnWrongDetailByWrongDetailId(wrongDetailId));
+    }
+
+    /**
+     * 新增学生错题流水
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongDetail:add')")
+    @Log(title = "学生错题流水", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnWrongDetail learnWrongDetail)
+    {
+        return toAjax(learnWrongDetailService.insertLearnWrongDetail(learnWrongDetail));
+    }
+
+    /**
+     * 修改学生错题流水
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongDetail:edit')")
+    @Log(title = "学生错题流水", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnWrongDetail learnWrongDetail)
+    {
+        return toAjax(learnWrongDetailService.updateLearnWrongDetail(learnWrongDetail));
+    }
+
+    /**
+     * 删除学生错题流水
+     */
+    @PreAuthorize("@ss.hasPermi('learn:WrongDetail:remove')")
+    @Log(title = "学生错题流水", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{wrongDetailIds}")
+    public AjaxResult remove(@PathVariable Long[] wrongDetailIds)
+    {
+        return toAjax(learnWrongDetailService.deleteLearnWrongDetailByWrongDetailIds(wrongDetailIds));
+    }
+}

+ 26 - 0
ie-system/src/main/java/com/ruoyi/enums/PaperType.java

@@ -0,0 +1,26 @@
+package com.ruoyi.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Getter
+@AllArgsConstructor
+public enum PaperType {
+    Real(10, "真题卷"), Simulated(20, "定向模拟卷"), Test(30, "批次测试卷"), Practice(50, "知识点"),
+    Custom(51, "自组卷"), WrongQuestions(52, "错题"), KeyQuestions(53, "必刷题");
+
+    private final Integer val;
+    private final String title;
+
+    private static final Map<Integer, PaperType> valMap = Arrays.stream(PaperType.values()).collect(Collectors.toMap(PaperType::getVal, Function.identity()));
+
+    public static PaperType of(Integer vol) {
+        return valMap.get(vol);
+    }
+}
+

+ 38 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/AnswerSheet.java

@@ -0,0 +1,38 @@
+package com.ruoyi.learn.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.common.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+@ApiModel("答题卷")
+public class AnswerSheet {
+    @ApiModelProperty("考生答题卡")
+    Long examineeId;
+    @Excel(name = "试卷id")
+    private Long paperId;
+    @ApiModelProperty("测试名称")
+    String name;
+    @ApiModelProperty("考试开始时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    Date beginTime;
+    @ApiModelProperty("考试结束时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    Date endTime;
+    @ApiModelProperty("考试时间 单位秒")
+    Long remaining;
+    @ApiModelProperty("阅卷类型 1 自阅卷 2 老师阅卷")
+    private String scoringType;
+    @ApiModelProperty("考场分钟 90, 120, xxx")
+    private Long mode;
+    @ApiModelProperty("答卷状态 examinee_status")
+    Long state;
+    @ApiModelProperty("答卷状态名称")
+    String stateStr;
+    @ApiModelProperty("是否可答题")
+    Boolean allowAnswer;
+    @ApiModelProperty("是否可阅卷")
+    Boolean allowScore;
+}

+ 234 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnAnswer.java

@@ -0,0 +1,234 @@
+package com.ruoyi.learn.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 答卷答案对象 learn_answer
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnAnswer extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 答题id */
+    private Long answerId;
+
+    /** 答卷id */
+    @Excel(name = "答卷id")
+    private Long examineeId;
+
+    /** 学生用户id加速 */
+    @Excel(name = "学生用户id加速")
+    private Long studentId;
+
+    /** 题id */
+    @Excel(name = "题id")
+    private Long questionId;
+
+    /** 题号 */
+    @Excel(name = "题号")
+    private Long seq;
+
+    /** 知识点 */
+    @Excel(name = "知识点")
+    private Long knowledgeId;
+
+    /** 学生答案 */
+    @Excel(name = "学生答案")
+    private String answer;
+
+    /** 批改答案 */
+    @Excel(name = "批改答案")
+    private String correct;
+
+    /** 最长时间 */
+    @Excel(name = "最长时间")
+    private Long duration;
+
+    /** 更新次数 */
+    @Excel(name = "更新次数")
+    private Long count;
+
+    /** 状态 1 正确 */
+    @Excel(name = "状态 1 正确")
+    private Long state;
+
+    /** 评级 */
+    @Excel(name = "评级")
+    private String scoreLevel;
+
+    /** 评分 */
+    @Excel(name = "评分")
+    private Long score;
+
+    /** 得分率 */
+    @Excel(name = "得分率")
+    private Long scoreRate;
+
+    public void setAnswerId(Long answerId) 
+    {
+        this.answerId = answerId;
+    }
+
+    public Long getAnswerId() 
+    {
+        return answerId;
+    }
+
+    public void setExamineeId(Long examineeId) 
+    {
+        this.examineeId = examineeId;
+    }
+
+    public Long getExamineeId() 
+    {
+        return examineeId;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setQuestionId(Long questionId) 
+    {
+        this.questionId = questionId;
+    }
+
+    public Long getQuestionId() 
+    {
+        return questionId;
+    }
+
+    public void setSeq(Long seq) 
+    {
+        this.seq = seq;
+    }
+
+    public Long getSeq() 
+    {
+        return seq;
+    }
+
+    public void setKnowledgeId(Long knowledgeId) 
+    {
+        this.knowledgeId = knowledgeId;
+    }
+
+    public Long getKnowledgeId() 
+    {
+        return knowledgeId;
+    }
+
+    public void setAnswer(String answer) 
+    {
+        this.answer = answer;
+    }
+
+    public String getAnswer() 
+    {
+        return answer;
+    }
+
+    public void setCorrect(String correct) 
+    {
+        this.correct = correct;
+    }
+
+    public String getCorrect() 
+    {
+        return correct;
+    }
+
+    public void setDuration(Long duration) 
+    {
+        this.duration = duration;
+    }
+
+    public Long getDuration() 
+    {
+        return duration;
+    }
+
+    public void setCount(Long count) 
+    {
+        this.count = count;
+    }
+
+    public Long getCount() 
+    {
+        return count;
+    }
+
+    public void setState(Long state) 
+    {
+        this.state = state;
+    }
+
+    public Long getState() 
+    {
+        return state;
+    }
+
+    public void setScoreLevel(String scoreLevel) 
+    {
+        this.scoreLevel = scoreLevel;
+    }
+
+    public String getScoreLevel() 
+    {
+        return scoreLevel;
+    }
+
+    public void setScore(Long score) 
+    {
+        this.score = score;
+    }
+
+    public Long getScore() 
+    {
+        return score;
+    }
+
+    public void setScoreRate(Long scoreRate) 
+    {
+        this.scoreRate = scoreRate;
+    }
+
+    public Long getScoreRate() 
+    {
+        return scoreRate;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("answerId", getAnswerId())
+            .append("examineeId", getExamineeId())
+            .append("studentId", getStudentId())
+            .append("questionId", getQuestionId())
+            .append("seq", getSeq())
+            .append("knowledgeId", getKnowledgeId())
+            .append("answer", getAnswer())
+            .append("correct", getCorrect())
+            .append("duration", getDuration())
+            .append("count", getCount())
+            .append("state", getState())
+            .append("scoreLevel", getScoreLevel())
+            .append("score", getScore())
+            .append("scoreRate", getScoreRate())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 202 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnDirectedKnowledge.java

@@ -0,0 +1,202 @@
+package com.ruoyi.learn.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 定向知识点关系对象 learn_directed_knowledge
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnDirectedKnowledge extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    private Long id;
+
+    /** 年度 */
+    @Excel(name = "年度")
+    private Long year;
+
+    /** 定向Key */
+    @Excel(name = "定向Key")
+    private String directKey;
+
+    /** 录取公式 */
+    @Excel(name = "录取公式")
+    private String enrollFormula;
+
+    /** 文化科目 */
+    @Excel(name = "文化科目")
+    private String cultural;
+
+    /** 专业类别 */
+    @Excel(name = "专业类别")
+    private String professional;
+
+    /** 专业科目 */
+    @Excel(name = "专业科目")
+    private String subjects;
+
+    /** 题型分布 */
+    @Excel(name = "题型分布")
+    private String questionTypes;
+
+    /** 祖级列表 */
+    @Excel(name = "祖级列表")
+    private String knowledges;
+
+    /** 适用省份 */
+    @Excel(name = "适用省份")
+    private String locations;
+
+    /** 适用考生类型 */
+    @Excel(name = "适用考生类型")
+    private String examineeTypes;
+
+    /** 仿真模拟卷要求 */
+    @Excel(name = "仿真模拟卷要求")
+    private String conditions;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setYear(Long year) 
+    {
+        this.year = year;
+    }
+
+    public Long getYear() 
+    {
+        return year;
+    }
+
+    public void setDirectKey(String directKey) 
+    {
+        this.directKey = directKey;
+    }
+
+    public String getDirectKey() 
+    {
+        return directKey;
+    }
+
+    public void setEnrollFormula(String enrollFormula) 
+    {
+        this.enrollFormula = enrollFormula;
+    }
+
+    public String getEnrollFormula() 
+    {
+        return enrollFormula;
+    }
+
+    public void setCultural(String cultural) 
+    {
+        this.cultural = cultural;
+    }
+
+    public String getCultural() 
+    {
+        return cultural;
+    }
+
+    public void setProfessional(String professional) 
+    {
+        this.professional = professional;
+    }
+
+    public String getProfessional() 
+    {
+        return professional;
+    }
+
+    public void setSubjects(String subjects) 
+    {
+        this.subjects = subjects;
+    }
+
+    public String getSubjects() 
+    {
+        return subjects;
+    }
+
+    public void setQuestionTypes(String questionTypes) 
+    {
+        this.questionTypes = questionTypes;
+    }
+
+    public String getQuestionTypes() 
+    {
+        return questionTypes;
+    }
+
+    public void setKnowledges(String knowledges) 
+    {
+        this.knowledges = knowledges;
+    }
+
+    public String getKnowledges() 
+    {
+        return knowledges;
+    }
+
+    public void setLocations(String locations) 
+    {
+        this.locations = locations;
+    }
+
+    public String getLocations() 
+    {
+        return locations;
+    }
+
+    public void setExamineeTypes(String examineeTypes) 
+    {
+        this.examineeTypes = examineeTypes;
+    }
+
+    public String getExamineeTypes() 
+    {
+        return examineeTypes;
+    }
+
+    public void setConditions(String conditions) 
+    {
+        this.conditions = conditions;
+    }
+
+    public String getConditions() 
+    {
+        return conditions;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("year", getYear())
+            .append("directKey", getDirectKey())
+            .append("enrollFormula", getEnrollFormula())
+            .append("cultural", getCultural())
+            .append("professional", getProfessional())
+            .append("subjects", getSubjects())
+            .append("questionTypes", getQuestionTypes())
+            .append("knowledges", getKnowledges())
+            .append("locations", getLocations())
+            .append("examineeTypes", getExamineeTypes())
+            .append("conditions", getConditions())
+            .toString();
+    }
+}

+ 268 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnExaminee.java

@@ -0,0 +1,268 @@
+package com.ruoyi.learn.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 答卷对象 learn_examinee
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnExaminee extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 答卷id */
+    private Long examineeId;
+
+    /** 学生id */
+    @Excel(name = "学生id")
+    private Long studentId;
+
+    /** 试卷类型 */
+    @Excel(name = "试卷类型")
+    private Long paperType;
+
+    /** 试卷id */
+    @Excel(name = "试卷id")
+    private Long paperId;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date beginTime;
+
+    /** 结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date endTime;
+
+    /** 未答题, 已答题, 通过, 未通过 */
+    @Excel(name = "未答题, 已答题, 通过, 未通过")
+    private Long state;
+
+    /** 分级 */
+    @Excel(name = "分级")
+    private String scoreLevel;
+
+    /** 分值 */
+    @Excel(name = "分值")
+    private Long score;
+
+    /** 分率 */
+    @Excel(name = "分率")
+    private Long scoreRate;
+
+    /** 名次 */
+    @Excel(name = "名次")
+    private Long ranking;
+
+    /** 年排名次 */
+    @Excel(name = "年排名次")
+    private Long gradeRanking;
+
+    /** 选择题正确数 */
+    @Excel(name = "选择题正确数")
+    private Long chooseCount;
+
+    /** 选择题总数 */
+    @Excel(name = "选择题总数")
+    private Long chooseTotal;
+
+    /** 主观题正确数 */
+    @Excel(name = "主观题正确数")
+    private Long subjectiveCount;
+
+    /** 主观题总数 */
+    @Excel(name = "主观题总数")
+    private Long subjectiveTotal;
+
+    public void setExamineeId(Long examineeId) 
+    {
+        this.examineeId = examineeId;
+    }
+
+    public Long getExamineeId() 
+    {
+        return examineeId;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setPaperType(Long paperType) 
+    {
+        this.paperType = paperType;
+    }
+
+    public Long getPaperType() 
+    {
+        return paperType;
+    }
+
+    public void setPaperId(Long paperId) 
+    {
+        this.paperId = paperId;
+    }
+
+    public Long getPaperId() 
+    {
+        return paperId;
+    }
+
+    public void setBeginTime(Date beginTime) 
+    {
+        this.beginTime = beginTime;
+    }
+
+    public Date getBeginTime() 
+    {
+        return beginTime;
+    }
+
+    public void setEndTime(Date endTime) 
+    {
+        this.endTime = endTime;
+    }
+
+    public Date getEndTime() 
+    {
+        return endTime;
+    }
+
+    public void setState(Long state) 
+    {
+        this.state = state;
+    }
+
+    public Long getState() 
+    {
+        return state;
+    }
+
+    public void setScoreLevel(String scoreLevel) 
+    {
+        this.scoreLevel = scoreLevel;
+    }
+
+    public String getScoreLevel() 
+    {
+        return scoreLevel;
+    }
+
+    public void setScore(Long score) 
+    {
+        this.score = score;
+    }
+
+    public Long getScore() 
+    {
+        return score;
+    }
+
+    public void setScoreRate(Long scoreRate) 
+    {
+        this.scoreRate = scoreRate;
+    }
+
+    public Long getScoreRate() 
+    {
+        return scoreRate;
+    }
+
+    public void setRanking(Long ranking) 
+    {
+        this.ranking = ranking;
+    }
+
+    public Long getRanking() 
+    {
+        return ranking;
+    }
+
+    public void setGradeRanking(Long gradeRanking) 
+    {
+        this.gradeRanking = gradeRanking;
+    }
+
+    public Long getGradeRanking() 
+    {
+        return gradeRanking;
+    }
+
+    public void setChooseCount(Long chooseCount) 
+    {
+        this.chooseCount = chooseCount;
+    }
+
+    public Long getChooseCount() 
+    {
+        return chooseCount;
+    }
+
+    public void setChooseTotal(Long chooseTotal) 
+    {
+        this.chooseTotal = chooseTotal;
+    }
+
+    public Long getChooseTotal() 
+    {
+        return chooseTotal;
+    }
+
+    public void setSubjectiveCount(Long subjectiveCount) 
+    {
+        this.subjectiveCount = subjectiveCount;
+    }
+
+    public Long getSubjectiveCount() 
+    {
+        return subjectiveCount;
+    }
+
+    public void setSubjectiveTotal(Long subjectiveTotal) 
+    {
+        this.subjectiveTotal = subjectiveTotal;
+    }
+
+    public Long getSubjectiveTotal() 
+    {
+        return subjectiveTotal;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("examineeId", getExamineeId())
+            .append("studentId", getStudentId())
+            .append("paperType", getPaperType())
+            .append("paperId", getPaperId())
+            .append("beginTime", getBeginTime())
+            .append("endTime", getEndTime())
+            .append("state", getState())
+            .append("scoreLevel", getScoreLevel())
+            .append("score", getScore())
+            .append("scoreRate", getScoreRate())
+            .append("ranking", getRanking())
+            .append("gradeRanking", getGradeRanking())
+            .append("chooseCount", getChooseCount())
+            .append("chooseTotal", getChooseTotal())
+            .append("subjectiveCount", getSubjectiveCount())
+            .append("subjectiveTotal", getSubjectiveTotal())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 98 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnKnowledgeQuestion.java

@@ -0,0 +1,98 @@
+package com.ruoyi.learn.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 知识点题关系对象 learn_knowledge_question
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnKnowledgeQuestion extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** ID */
+    private Long id;
+
+    /** 知识点 */
+    @Excel(name = "知识点")
+    private Long knowledgeId;
+
+    /** 0 默认 1know_test-知识点 2必刷题,3auto-基础题库,4high_error-高频错题 */
+    @Excel(name = "0 默认 1know_test-知识点 2必刷题,3auto-基础题库,4high_error-高频错题")
+    private Long type;
+
+    /** 题ID */
+    @Excel(name = "题ID")
+    private Long questionId;
+
+    /** 顺序 */
+    @Excel(name = "顺序")
+    private Long seq;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setKnowledgeId(Long knowledgeId) 
+    {
+        this.knowledgeId = knowledgeId;
+    }
+
+    public Long getKnowledgeId() 
+    {
+        return knowledgeId;
+    }
+
+    public void setType(Long type) 
+    {
+        this.type = type;
+    }
+
+    public Long getType() 
+    {
+        return type;
+    }
+
+    public void setQuestionId(Long questionId) 
+    {
+        this.questionId = questionId;
+    }
+
+    public Long getQuestionId() 
+    {
+        return questionId;
+    }
+
+    public void setSeq(Long seq) 
+    {
+        this.seq = seq;
+    }
+
+    public Long getSeq() 
+    {
+        return seq;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("knowledgeId", getKnowledgeId())
+            .append("type", getType())
+            .append("questionId", getQuestionId())
+            .append("seq", getSeq())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 172 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnKnowledgeTree.java

@@ -0,0 +1,172 @@
+package com.ruoyi.learn.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 知识点树对象 learn_knowledge_tree
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnKnowledgeTree extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 知识点id */
+    private Long id;
+
+    /** 知识点名称 */
+    @Excel(name = "知识点名称")
+    private String name;
+
+    /** 父ID */
+    @Excel(name = "父ID")
+    private Long pid;
+
+    /** 祖级列表 */
+    @Excel(name = "祖级列表")
+    private String ancestors;
+
+    /** 科目id */
+    @Excel(name = "科目id")
+    private Long subjectId;
+
+    /** 排序 */
+    @Excel(name = "排序")
+    private Long sort;
+
+    /** 级数 */
+    @Excel(name = "级数")
+    private Long level;
+
+    /** 题目数 */
+    @Excel(name = "题目数")
+    private Long questionsCount;
+
+    /** 适用省份 */
+    @Excel(name = "适用省份")
+    private String locations;
+
+    /** 适用考生类型 */
+    @Excel(name = "适用考生类型")
+    private String examineeTypes;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setName(String name) 
+    {
+        this.name = name;
+    }
+
+    public String getName() 
+    {
+        return name;
+    }
+
+    public void setPid(Long pid) 
+    {
+        this.pid = pid;
+    }
+
+    public Long getPid() 
+    {
+        return pid;
+    }
+
+    public void setAncestors(String ancestors) 
+    {
+        this.ancestors = ancestors;
+    }
+
+    public String getAncestors() 
+    {
+        return ancestors;
+    }
+
+    public void setSubjectId(Long subjectId) 
+    {
+        this.subjectId = subjectId;
+    }
+
+    public Long getSubjectId() 
+    {
+        return subjectId;
+    }
+
+    public void setSort(Long sort) 
+    {
+        this.sort = sort;
+    }
+
+    public Long getSort() 
+    {
+        return sort;
+    }
+
+    public void setLevel(Long level) 
+    {
+        this.level = level;
+    }
+
+    public Long getLevel() 
+    {
+        return level;
+    }
+
+    public void setQuestionsCount(Long questionsCount) 
+    {
+        this.questionsCount = questionsCount;
+    }
+
+    public Long getQuestionsCount() 
+    {
+        return questionsCount;
+    }
+
+    public void setLocations(String locations) 
+    {
+        this.locations = locations;
+    }
+
+    public String getLocations() 
+    {
+        return locations;
+    }
+
+    public void setExamineeTypes(String examineeTypes) 
+    {
+        this.examineeTypes = examineeTypes;
+    }
+
+    public String getExamineeTypes() 
+    {
+        return examineeTypes;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("name", getName())
+            .append("pid", getPid())
+            .append("ancestors", getAncestors())
+            .append("subjectId", getSubjectId())
+            .append("sort", getSort())
+            .append("level", getLevel())
+            .append("questionsCount", getQuestionsCount())
+            .append("locations", getLocations())
+            .append("examineeTypes", getExamineeTypes())
+            .toString();
+    }
+}

+ 131 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnPlan.java

@@ -0,0 +1,131 @@
+package com.ruoyi.learn.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 学习计划对象 learn_plan
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnPlan extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 计划id */
+    private String id;
+
+    /** 学生id */
+    @Excel(name = "学生id")
+    private Long studentId;
+
+    /** 视频课时间 */
+    @Excel(name = "视频课时间")
+    private Long videoTime;
+
+    /** 练题数 */
+    @Excel(name = "练题数")
+    private Long questionCnt;
+
+    /** 是否有效 */
+    @Excel(name = "是否有效")
+    private Long status;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date beginTime;
+
+    /** 统计情况 */
+    @Excel(name = "统计情况")
+    private String stats;
+
+    public void setId(String id) 
+    {
+        this.id = id;
+    }
+
+    public String getId() 
+    {
+        return id;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setVideoTime(Long videoTime) 
+    {
+        this.videoTime = videoTime;
+    }
+
+    public Long getVideoTime() 
+    {
+        return videoTime;
+    }
+
+    public void setQuestionCnt(Long questionCnt) 
+    {
+        this.questionCnt = questionCnt;
+    }
+
+    public Long getQuestionCnt() 
+    {
+        return questionCnt;
+    }
+
+    public void setStatus(Long status) 
+    {
+        this.status = status;
+    }
+
+    public Long getStatus() 
+    {
+        return status;
+    }
+
+    public void setBeginTime(Date beginTime) 
+    {
+        this.beginTime = beginTime;
+    }
+
+    public Date getBeginTime() 
+    {
+        return beginTime;
+    }
+
+    public void setStats(String stats) 
+    {
+        this.stats = stats;
+    }
+
+    public String getStats() 
+    {
+        return stats;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("studentId", getStudentId())
+            .append("videoTime", getVideoTime())
+            .append("questionCnt", getQuestionCnt())
+            .append("status", getStatus())
+            .append("beginTime", getBeginTime())
+            .append("createTime", getCreateTime())
+            .append("stats", getStats())
+            .toString();
+    }
+}

+ 176 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnPlanStudy.java

@@ -0,0 +1,176 @@
+package com.ruoyi.learn.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 学生计划执行情况对象 learn_plan_study
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnPlanStudy extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 计划学习id */
+    private String id;
+
+    /** 学生id */
+    @Excel(name = "学生id")
+    private Long studentId;
+
+    /** 对应计划 */
+    @Excel(name = "对应计划")
+    private Long planId;
+
+    /** 月份序号 */
+    @Excel(name = "月份序号")
+    private Long monthSeq;
+
+    /** 周序号 */
+    @Excel(name = "周序号")
+    private Long weekSeq;
+
+    /** 学习日期 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "学习日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date reportDate;
+
+    /** 完成题数 */
+    @Excel(name = "完成题数")
+    private Long questionCount;
+
+    /** 完成视频时间 */
+    @Excel(name = "完成视频时间")
+    private Long videoTime;
+
+    /** 计划做题数 */
+    @Excel(name = "计划做题数")
+    private Long questionPlan;
+
+    /** 计划视频时间 */
+    @Excel(name = "计划视频时间")
+    private Long videoPlan;
+
+    public void setId(String id) 
+    {
+        this.id = id;
+    }
+
+    public String getId() 
+    {
+        return id;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setPlanId(Long planId) 
+    {
+        this.planId = planId;
+    }
+
+    public Long getPlanId() 
+    {
+        return planId;
+    }
+
+    public void setMonthSeq(Long monthSeq) 
+    {
+        this.monthSeq = monthSeq;
+    }
+
+    public Long getMonthSeq() 
+    {
+        return monthSeq;
+    }
+
+    public void setWeekSeq(Long weekSeq) 
+    {
+        this.weekSeq = weekSeq;
+    }
+
+    public Long getWeekSeq() 
+    {
+        return weekSeq;
+    }
+
+    public void setReportDate(Date reportDate) 
+    {
+        this.reportDate = reportDate;
+    }
+
+    public Date getReportDate() 
+    {
+        return reportDate;
+    }
+
+    public void setQuestionCount(Long questionCount) 
+    {
+        this.questionCount = questionCount;
+    }
+
+    public Long getQuestionCount() 
+    {
+        return questionCount;
+    }
+
+    public void setVideoTime(Long videoTime) 
+    {
+        this.videoTime = videoTime;
+    }
+
+    public Long getVideoTime() 
+    {
+        return videoTime;
+    }
+
+    public void setQuestionPlan(Long questionPlan) 
+    {
+        this.questionPlan = questionPlan;
+    }
+
+    public Long getQuestionPlan() 
+    {
+        return questionPlan;
+    }
+
+    public void setVideoPlan(Long videoPlan) 
+    {
+        this.videoPlan = videoPlan;
+    }
+
+    public Long getVideoPlan() 
+    {
+        return videoPlan;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("studentId", getStudentId())
+            .append("planId", getPlanId())
+            .append("monthSeq", getMonthSeq())
+            .append("weekSeq", getWeekSeq())
+            .append("reportDate", getReportDate())
+            .append("questionCount", getQuestionCount())
+            .append("videoTime", getVideoTime())
+            .append("questionPlan", getQuestionPlan())
+            .append("videoPlan", getVideoPlan())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 85 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnQuestionCorrect.java

@@ -0,0 +1,85 @@
+package com.ruoyi.learn.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 题纠错对象 learn_question_correct
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnQuestionCorrect extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 纠错id */
+    private Long id;
+
+    /** 题ID */
+    @Excel(name = "题ID")
+    private Long questionId;
+
+    /** 纠错人 */
+    @Excel(name = "纠错人")
+    private Long userId;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Long state;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setQuestionId(Long questionId) 
+    {
+        this.questionId = questionId;
+    }
+
+    public Long getQuestionId() 
+    {
+        return questionId;
+    }
+
+    public void setUserId(Long userId) 
+    {
+        this.userId = userId;
+    }
+
+    public Long getUserId() 
+    {
+        return userId;
+    }
+
+    public void setState(Long state) 
+    {
+        this.state = state;
+    }
+
+    public Long getState() 
+    {
+        return state;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("questionId", getQuestionId())
+            .append("userId", getUserId())
+            .append("remark", getRemark())
+            .append("state", getState())
+            .append("createTime", getCreateTime())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}

+ 341 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnWrongBook.java

@@ -0,0 +1,341 @@
+package com.ruoyi.learn.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 学生错题本对象 learn_wrong_book
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnWrongBook extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 错题id */
+    private Long wrongId;
+
+    /** 学生ID */
+    @Excel(name = "学生ID")
+    private Long studentId;
+
+    /** 题ID */
+    @Excel(name = "题ID")
+    private Long questionId;
+
+    /** 最后来源,练习,试卷,刷题 */
+    @Excel(name = "最后来源,练习,试卷,刷题")
+    private String source;
+
+    /** 最后状态 */
+    @Excel(name = "最后状态")
+    private Long state;
+
+    /** 知识点id */
+    @Excel(name = "知识点id")
+    private Long knownledgeId;
+
+    /** 科目 */
+    @Excel(name = "科目")
+    private Long subjectId;
+
+    /** 试卷id */
+    @Excel(name = "试卷id")
+    private Long paperId;
+
+    /** 最后参考答案 */
+    @Excel(name = "最后参考答案")
+    private String answers;
+
+    /** 答案1 */
+    @Excel(name = "答案1")
+    private String answer1;
+
+    /** 答案2 */
+    @Excel(name = "答案2")
+    private String answer2;
+
+    /** 总分 */
+    @Excel(name = "总分")
+    private Long scoreTotal;
+
+    /** 得分 */
+    @Excel(name = "得分")
+    private Long score;
+
+    /** 评级 */
+    @Excel(name = "评级")
+    private String scoreLevel;
+
+    /** 得分率 */
+    @Excel(name = "得分率")
+    private Long scoreRate;
+
+    /** 错误次数 */
+    @Excel(name = "错误次数")
+    private Long wrongCount;
+
+    /** 正确次数 */
+    @Excel(name = "正确次数")
+    private Long rightCount;
+
+    /** 总次数 */
+    @Excel(name = "总次数")
+    private Long totalCount;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date createdTime;
+
+    /** 更新时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date updatedTime;
+
+    /** 是否收藏 */
+    @Excel(name = "是否收藏")
+    private Long collect;
+
+    public void setWrongId(Long wrongId) 
+    {
+        this.wrongId = wrongId;
+    }
+
+    public Long getWrongId() 
+    {
+        return wrongId;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setQuestionId(Long questionId) 
+    {
+        this.questionId = questionId;
+    }
+
+    public Long getQuestionId() 
+    {
+        return questionId;
+    }
+
+    public void setSource(String source) 
+    {
+        this.source = source;
+    }
+
+    public String getSource() 
+    {
+        return source;
+    }
+
+    public void setState(Long state) 
+    {
+        this.state = state;
+    }
+
+    public Long getState() 
+    {
+        return state;
+    }
+
+    public void setKnownledgeId(Long knownledgeId) 
+    {
+        this.knownledgeId = knownledgeId;
+    }
+
+    public Long getKnownledgeId() 
+    {
+        return knownledgeId;
+    }
+
+    public void setSubjectId(Long subjectId) 
+    {
+        this.subjectId = subjectId;
+    }
+
+    public Long getSubjectId() 
+    {
+        return subjectId;
+    }
+
+    public void setPaperId(Long paperId) 
+    {
+        this.paperId = paperId;
+    }
+
+    public Long getPaperId() 
+    {
+        return paperId;
+    }
+
+    public void setAnswers(String answers) 
+    {
+        this.answers = answers;
+    }
+
+    public String getAnswers() 
+    {
+        return answers;
+    }
+
+    public void setAnswer1(String answer1) 
+    {
+        this.answer1 = answer1;
+    }
+
+    public String getAnswer1() 
+    {
+        return answer1;
+    }
+
+    public void setAnswer2(String answer2) 
+    {
+        this.answer2 = answer2;
+    }
+
+    public String getAnswer2() 
+    {
+        return answer2;
+    }
+
+    public void setScoreTotal(Long scoreTotal) 
+    {
+        this.scoreTotal = scoreTotal;
+    }
+
+    public Long getScoreTotal() 
+    {
+        return scoreTotal;
+    }
+
+    public void setScore(Long score) 
+    {
+        this.score = score;
+    }
+
+    public Long getScore() 
+    {
+        return score;
+    }
+
+    public void setScoreLevel(String scoreLevel) 
+    {
+        this.scoreLevel = scoreLevel;
+    }
+
+    public String getScoreLevel() 
+    {
+        return scoreLevel;
+    }
+
+    public void setScoreRate(Long scoreRate) 
+    {
+        this.scoreRate = scoreRate;
+    }
+
+    public Long getScoreRate() 
+    {
+        return scoreRate;
+    }
+
+    public void setWrongCount(Long wrongCount) 
+    {
+        this.wrongCount = wrongCount;
+    }
+
+    public Long getWrongCount() 
+    {
+        return wrongCount;
+    }
+
+    public void setRightCount(Long rightCount) 
+    {
+        this.rightCount = rightCount;
+    }
+
+    public Long getRightCount() 
+    {
+        return rightCount;
+    }
+
+    public void setTotalCount(Long totalCount) 
+    {
+        this.totalCount = totalCount;
+    }
+
+    public Long getTotalCount() 
+    {
+        return totalCount;
+    }
+
+    public void setCreatedTime(Date createdTime) 
+    {
+        this.createdTime = createdTime;
+    }
+
+    public Date getCreatedTime() 
+    {
+        return createdTime;
+    }
+
+    public void setUpdatedTime(Date updatedTime) 
+    {
+        this.updatedTime = updatedTime;
+    }
+
+    public Date getUpdatedTime() 
+    {
+        return updatedTime;
+    }
+
+    public void setCollect(Long collect) 
+    {
+        this.collect = collect;
+    }
+
+    public Long getCollect() 
+    {
+        return collect;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("wrongId", getWrongId())
+            .append("studentId", getStudentId())
+            .append("questionId", getQuestionId())
+            .append("source", getSource())
+            .append("state", getState())
+            .append("knownledgeId", getKnownledgeId())
+            .append("subjectId", getSubjectId())
+            .append("paperId", getPaperId())
+            .append("answers", getAnswers())
+            .append("answer1", getAnswer1())
+            .append("answer2", getAnswer2())
+            .append("scoreTotal", getScoreTotal())
+            .append("score", getScore())
+            .append("scoreLevel", getScoreLevel())
+            .append("scoreRate", getScoreRate())
+            .append("wrongCount", getWrongCount())
+            .append("rightCount", getRightCount())
+            .append("totalCount", getTotalCount())
+            .append("createdTime", getCreatedTime())
+            .append("updatedTime", getUpdatedTime())
+            .append("collect", getCollect())
+            .toString();
+    }
+}

+ 220 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnWrongDetail.java

@@ -0,0 +1,220 @@
+package com.ruoyi.learn.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 学生错题流水对象 learn_wrong_detail
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public class LearnWrongDetail extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** wrong_detail_id */
+    private Long wrongDetailId;
+
+    /** 错题本id */
+    @Excel(name = "错题本id")
+    private Long wrongId;
+
+    /** 创建时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date createdTime;
+
+    /** 来源 */
+    @Excel(name = "来源")
+    private String source;
+
+    /** 学生id */
+    @Excel(name = "学生id")
+    private Long studentId;
+
+    /** 科目 */
+    @Excel(name = "科目")
+    private Long subjectId;
+
+    /** 知识点id */
+    @Excel(name = "知识点id")
+    private Long knownledgeId;
+
+    /** 答卷id */
+    @Excel(name = "答卷id")
+    private Long examineeId;
+
+    /** 试卷id */
+    @Excel(name = "试卷id")
+    private Long paperId;
+
+    /** 总分 */
+    @Excel(name = "总分")
+    private Long scoreTotal;
+
+    /** 评分 */
+    @Excel(name = "评分")
+    private Long score;
+
+    /** 评级 */
+    @Excel(name = "评级")
+    private String scoreLevel;
+
+    /** 得分率 */
+    @Excel(name = "得分率")
+    private Long scoreRate;
+
+    public void setWrongDetailId(Long wrongDetailId) 
+    {
+        this.wrongDetailId = wrongDetailId;
+    }
+
+    public Long getWrongDetailId() 
+    {
+        return wrongDetailId;
+    }
+
+    public void setWrongId(Long wrongId) 
+    {
+        this.wrongId = wrongId;
+    }
+
+    public Long getWrongId() 
+    {
+        return wrongId;
+    }
+
+    public void setCreatedTime(Date createdTime) 
+    {
+        this.createdTime = createdTime;
+    }
+
+    public Date getCreatedTime() 
+    {
+        return createdTime;
+    }
+
+    public void setSource(String source) 
+    {
+        this.source = source;
+    }
+
+    public String getSource() 
+    {
+        return source;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setSubjectId(Long subjectId) 
+    {
+        this.subjectId = subjectId;
+    }
+
+    public Long getSubjectId() 
+    {
+        return subjectId;
+    }
+
+    public void setKnownledgeId(Long knownledgeId) 
+    {
+        this.knownledgeId = knownledgeId;
+    }
+
+    public Long getKnownledgeId() 
+    {
+        return knownledgeId;
+    }
+
+    public void setExamineeId(Long examineeId) 
+    {
+        this.examineeId = examineeId;
+    }
+
+    public Long getExamineeId() 
+    {
+        return examineeId;
+    }
+
+    public void setPaperId(Long paperId) 
+    {
+        this.paperId = paperId;
+    }
+
+    public Long getPaperId() 
+    {
+        return paperId;
+    }
+
+    public void setScoreTotal(Long scoreTotal) 
+    {
+        this.scoreTotal = scoreTotal;
+    }
+
+    public Long getScoreTotal() 
+    {
+        return scoreTotal;
+    }
+
+    public void setScore(Long score) 
+    {
+        this.score = score;
+    }
+
+    public Long getScore() 
+    {
+        return score;
+    }
+
+    public void setScoreLevel(String scoreLevel) 
+    {
+        this.scoreLevel = scoreLevel;
+    }
+
+    public String getScoreLevel() 
+    {
+        return scoreLevel;
+    }
+
+    public void setScoreRate(Long scoreRate) 
+    {
+        this.scoreRate = scoreRate;
+    }
+
+    public Long getScoreRate() 
+    {
+        return scoreRate;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("wrongDetailId", getWrongDetailId())
+            .append("wrongId", getWrongId())
+            .append("createdTime", getCreatedTime())
+            .append("source", getSource())
+            .append("studentId", getStudentId())
+            .append("subjectId", getSubjectId())
+            .append("knownledgeId", getKnownledgeId())
+            .append("examineeId", getExamineeId())
+            .append("paperId", getPaperId())
+            .append("scoreTotal", getScoreTotal())
+            .append("score", getScore())
+            .append("scoreLevel", getScoreLevel())
+            .append("scoreRate", getScoreRate())
+            .toString();
+    }
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnAnswerMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnAnswer;
+
+/**
+ * 答卷答案Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnAnswerMapper 
+{
+    /**
+     * 查询答卷答案
+     * 
+     * @param answerId 答卷答案主键
+     * @return 答卷答案
+     */
+    public LearnAnswer selectLearnAnswerByAnswerId(Long answerId);
+
+    /**
+     * 查询答卷答案列表
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 答卷答案集合
+     */
+    public List<LearnAnswer> selectLearnAnswerList(LearnAnswer learnAnswer);
+
+    /**
+     * 新增答卷答案
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 结果
+     */
+    public int insertLearnAnswer(LearnAnswer learnAnswer);
+
+    /**
+     * 修改答卷答案
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 结果
+     */
+    public int updateLearnAnswer(LearnAnswer learnAnswer);
+
+    /**
+     * 删除答卷答案
+     * 
+     * @param answerId 答卷答案主键
+     * @return 结果
+     */
+    public int deleteLearnAnswerByAnswerId(Long answerId);
+
+    /**
+     * 批量删除答卷答案
+     * 
+     * @param answerIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnAnswerByAnswerIds(Long[] answerIds);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnDirectedKnowledgeMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnDirectedKnowledge;
+
+/**
+ * 定向知识点关系Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnDirectedKnowledgeMapper 
+{
+    /**
+     * 查询定向知识点关系
+     * 
+     * @param id 定向知识点关系主键
+     * @return 定向知识点关系
+     */
+    public LearnDirectedKnowledge selectLearnDirectedKnowledgeById(Long id);
+
+    /**
+     * 查询定向知识点关系列表
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 定向知识点关系集合
+     */
+    public List<LearnDirectedKnowledge> selectLearnDirectedKnowledgeList(LearnDirectedKnowledge learnDirectedKnowledge);
+
+    /**
+     * 新增定向知识点关系
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 结果
+     */
+    public int insertLearnDirectedKnowledge(LearnDirectedKnowledge learnDirectedKnowledge);
+
+    /**
+     * 修改定向知识点关系
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 结果
+     */
+    public int updateLearnDirectedKnowledge(LearnDirectedKnowledge learnDirectedKnowledge);
+
+    /**
+     * 删除定向知识点关系
+     * 
+     * @param id 定向知识点关系主键
+     * @return 结果
+     */
+    public int deleteLearnDirectedKnowledgeById(Long id);
+
+    /**
+     * 批量删除定向知识点关系
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnDirectedKnowledgeByIds(Long[] ids);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnExamineeMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnExaminee;
+
+/**
+ * 答卷Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnExamineeMapper 
+{
+    /**
+     * 查询答卷
+     * 
+     * @param examineeId 答卷主键
+     * @return 答卷
+     */
+    public LearnExaminee selectLearnExamineeByExamineeId(Long examineeId);
+
+    /**
+     * 查询答卷列表
+     * 
+     * @param learnExaminee 答卷
+     * @return 答卷集合
+     */
+    public List<LearnExaminee> selectLearnExamineeList(LearnExaminee learnExaminee);
+
+    /**
+     * 新增答卷
+     * 
+     * @param learnExaminee 答卷
+     * @return 结果
+     */
+    public int insertLearnExaminee(LearnExaminee learnExaminee);
+
+    /**
+     * 修改答卷
+     * 
+     * @param learnExaminee 答卷
+     * @return 结果
+     */
+    public int updateLearnExaminee(LearnExaminee learnExaminee);
+
+    /**
+     * 删除答卷
+     * 
+     * @param examineeId 答卷主键
+     * @return 结果
+     */
+    public int deleteLearnExamineeByExamineeId(Long examineeId);
+
+    /**
+     * 批量删除答卷
+     * 
+     * @param examineeIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnExamineeByExamineeIds(Long[] examineeIds);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnKnowledgeQuestionMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnKnowledgeQuestion;
+
+/**
+ * 知识点题关系Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnKnowledgeQuestionMapper 
+{
+    /**
+     * 查询知识点题关系
+     * 
+     * @param id 知识点题关系主键
+     * @return 知识点题关系
+     */
+    public LearnKnowledgeQuestion selectLearnKnowledgeQuestionById(Long id);
+
+    /**
+     * 查询知识点题关系列表
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 知识点题关系集合
+     */
+    public List<LearnKnowledgeQuestion> selectLearnKnowledgeQuestionList(LearnKnowledgeQuestion learnKnowledgeQuestion);
+
+    /**
+     * 新增知识点题关系
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 结果
+     */
+    public int insertLearnKnowledgeQuestion(LearnKnowledgeQuestion learnKnowledgeQuestion);
+
+    /**
+     * 修改知识点题关系
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 结果
+     */
+    public int updateLearnKnowledgeQuestion(LearnKnowledgeQuestion learnKnowledgeQuestion);
+
+    /**
+     * 删除知识点题关系
+     * 
+     * @param id 知识点题关系主键
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeQuestionById(Long id);
+
+    /**
+     * 批量删除知识点题关系
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeQuestionByIds(Long[] ids);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnKnowledgeTreeMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnKnowledgeTree;
+
+/**
+ * 知识点树Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnKnowledgeTreeMapper 
+{
+    /**
+     * 查询知识点树
+     * 
+     * @param id 知识点树主键
+     * @return 知识点树
+     */
+    public LearnKnowledgeTree selectLearnKnowledgeTreeById(Long id);
+
+    /**
+     * 查询知识点树列表
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 知识点树集合
+     */
+    public List<LearnKnowledgeTree> selectLearnKnowledgeTreeList(LearnKnowledgeTree learnKnowledgeTree);
+
+    /**
+     * 新增知识点树
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 结果
+     */
+    public int insertLearnKnowledgeTree(LearnKnowledgeTree learnKnowledgeTree);
+
+    /**
+     * 修改知识点树
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 结果
+     */
+    public int updateLearnKnowledgeTree(LearnKnowledgeTree learnKnowledgeTree);
+
+    /**
+     * 删除知识点树
+     * 
+     * @param id 知识点树主键
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeTreeById(Long id);
+
+    /**
+     * 批量删除知识点树
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeTreeByIds(Long[] ids);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPlanMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPlan;
+
+/**
+ * 学习计划Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnPlanMapper 
+{
+    /**
+     * 查询学习计划
+     * 
+     * @param id 学习计划主键
+     * @return 学习计划
+     */
+    public LearnPlan selectLearnPlanById(String id);
+
+    /**
+     * 查询学习计划列表
+     * 
+     * @param learnPlan 学习计划
+     * @return 学习计划集合
+     */
+    public List<LearnPlan> selectLearnPlanList(LearnPlan learnPlan);
+
+    /**
+     * 新增学习计划
+     * 
+     * @param learnPlan 学习计划
+     * @return 结果
+     */
+    public int insertLearnPlan(LearnPlan learnPlan);
+
+    /**
+     * 修改学习计划
+     * 
+     * @param learnPlan 学习计划
+     * @return 结果
+     */
+    public int updateLearnPlan(LearnPlan learnPlan);
+
+    /**
+     * 删除学习计划
+     * 
+     * @param id 学习计划主键
+     * @return 结果
+     */
+    public int deleteLearnPlanById(String id);
+
+    /**
+     * 批量删除学习计划
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnPlanByIds(String[] ids);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPlanStudyMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPlanStudy;
+
+/**
+ * 学生计划执行情况Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnPlanStudyMapper 
+{
+    /**
+     * 查询学生计划执行情况
+     * 
+     * @param id 学生计划执行情况主键
+     * @return 学生计划执行情况
+     */
+    public LearnPlanStudy selectLearnPlanStudyById(String id);
+
+    /**
+     * 查询学生计划执行情况列表
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 学生计划执行情况集合
+     */
+    public List<LearnPlanStudy> selectLearnPlanStudyList(LearnPlanStudy learnPlanStudy);
+
+    /**
+     * 新增学生计划执行情况
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 结果
+     */
+    public int insertLearnPlanStudy(LearnPlanStudy learnPlanStudy);
+
+    /**
+     * 修改学生计划执行情况
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 结果
+     */
+    public int updateLearnPlanStudy(LearnPlanStudy learnPlanStudy);
+
+    /**
+     * 删除学生计划执行情况
+     * 
+     * @param id 学生计划执行情况主键
+     * @return 结果
+     */
+    public int deleteLearnPlanStudyById(String id);
+
+    /**
+     * 批量删除学生计划执行情况
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnPlanStudyByIds(String[] ids);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnQuestionCorrectMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnQuestionCorrect;
+
+/**
+ * 题纠错Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnQuestionCorrectMapper 
+{
+    /**
+     * 查询题纠错
+     * 
+     * @param id 题纠错主键
+     * @return 题纠错
+     */
+    public LearnQuestionCorrect selectLearnQuestionCorrectById(Long id);
+
+    /**
+     * 查询题纠错列表
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 题纠错集合
+     */
+    public List<LearnQuestionCorrect> selectLearnQuestionCorrectList(LearnQuestionCorrect learnQuestionCorrect);
+
+    /**
+     * 新增题纠错
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 结果
+     */
+    public int insertLearnQuestionCorrect(LearnQuestionCorrect learnQuestionCorrect);
+
+    /**
+     * 修改题纠错
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 结果
+     */
+    public int updateLearnQuestionCorrect(LearnQuestionCorrect learnQuestionCorrect);
+
+    /**
+     * 删除题纠错
+     * 
+     * @param id 题纠错主键
+     * @return 结果
+     */
+    public int deleteLearnQuestionCorrectById(Long id);
+
+    /**
+     * 批量删除题纠错
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnQuestionCorrectByIds(Long[] ids);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnWrongBookMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnWrongBook;
+
+/**
+ * 学生错题本Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnWrongBookMapper 
+{
+    /**
+     * 查询学生错题本
+     * 
+     * @param wrongId 学生错题本主键
+     * @return 学生错题本
+     */
+    public LearnWrongBook selectLearnWrongBookByWrongId(Long wrongId);
+
+    /**
+     * 查询学生错题本列表
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 学生错题本集合
+     */
+    public List<LearnWrongBook> selectLearnWrongBookList(LearnWrongBook learnWrongBook);
+
+    /**
+     * 新增学生错题本
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 结果
+     */
+    public int insertLearnWrongBook(LearnWrongBook learnWrongBook);
+
+    /**
+     * 修改学生错题本
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 结果
+     */
+    public int updateLearnWrongBook(LearnWrongBook learnWrongBook);
+
+    /**
+     * 删除学生错题本
+     * 
+     * @param wrongId 学生错题本主键
+     * @return 结果
+     */
+    public int deleteLearnWrongBookByWrongId(Long wrongId);
+
+    /**
+     * 批量删除学生错题本
+     * 
+     * @param wrongIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnWrongBookByWrongIds(Long[] wrongIds);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/mapper/LearnWrongDetailMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnWrongDetail;
+
+/**
+ * 学生错题流水Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface LearnWrongDetailMapper 
+{
+    /**
+     * 查询学生错题流水
+     * 
+     * @param wrongDetailId 学生错题流水主键
+     * @return 学生错题流水
+     */
+    public LearnWrongDetail selectLearnWrongDetailByWrongDetailId(Long wrongDetailId);
+
+    /**
+     * 查询学生错题流水列表
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 学生错题流水集合
+     */
+    public List<LearnWrongDetail> selectLearnWrongDetailList(LearnWrongDetail learnWrongDetail);
+
+    /**
+     * 新增学生错题流水
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 结果
+     */
+    public int insertLearnWrongDetail(LearnWrongDetail learnWrongDetail);
+
+    /**
+     * 修改学生错题流水
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 结果
+     */
+    public int updateLearnWrongDetail(LearnWrongDetail learnWrongDetail);
+
+    /**
+     * 删除学生错题流水
+     * 
+     * @param wrongDetailId 学生错题流水主键
+     * @return 结果
+     */
+    public int deleteLearnWrongDetailByWrongDetailId(Long wrongDetailId);
+
+    /**
+     * 批量删除学生错题流水
+     * 
+     * @param wrongDetailIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnWrongDetailByWrongDetailIds(Long[] wrongDetailIds);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnAnswerService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnAnswer;
+
+/**
+ * 答卷答案Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnAnswerService 
+{
+    /**
+     * 查询答卷答案
+     * 
+     * @param answerId 答卷答案主键
+     * @return 答卷答案
+     */
+    public LearnAnswer selectLearnAnswerByAnswerId(Long answerId);
+
+    /**
+     * 查询答卷答案列表
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 答卷答案集合
+     */
+    public List<LearnAnswer> selectLearnAnswerList(LearnAnswer learnAnswer);
+
+    /**
+     * 新增答卷答案
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 结果
+     */
+    public int insertLearnAnswer(LearnAnswer learnAnswer);
+
+    /**
+     * 修改答卷答案
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 结果
+     */
+    public int updateLearnAnswer(LearnAnswer learnAnswer);
+
+    /**
+     * 批量删除答卷答案
+     * 
+     * @param answerIds 需要删除的答卷答案主键集合
+     * @return 结果
+     */
+    public int deleteLearnAnswerByAnswerIds(Long[] answerIds);
+
+    /**
+     * 删除答卷答案信息
+     * 
+     * @param answerId 答卷答案主键
+     * @return 结果
+     */
+    public int deleteLearnAnswerByAnswerId(Long answerId);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnDirectedKnowledgeService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnDirectedKnowledge;
+
+/**
+ * 定向知识点关系Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnDirectedKnowledgeService 
+{
+    /**
+     * 查询定向知识点关系
+     * 
+     * @param id 定向知识点关系主键
+     * @return 定向知识点关系
+     */
+    public LearnDirectedKnowledge selectLearnDirectedKnowledgeById(Long id);
+
+    /**
+     * 查询定向知识点关系列表
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 定向知识点关系集合
+     */
+    public List<LearnDirectedKnowledge> selectLearnDirectedKnowledgeList(LearnDirectedKnowledge learnDirectedKnowledge);
+
+    /**
+     * 新增定向知识点关系
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 结果
+     */
+    public int insertLearnDirectedKnowledge(LearnDirectedKnowledge learnDirectedKnowledge);
+
+    /**
+     * 修改定向知识点关系
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 结果
+     */
+    public int updateLearnDirectedKnowledge(LearnDirectedKnowledge learnDirectedKnowledge);
+
+    /**
+     * 批量删除定向知识点关系
+     * 
+     * @param ids 需要删除的定向知识点关系主键集合
+     * @return 结果
+     */
+    public int deleteLearnDirectedKnowledgeByIds(Long[] ids);
+
+    /**
+     * 删除定向知识点关系信息
+     * 
+     * @param id 定向知识点关系主键
+     * @return 结果
+     */
+    public int deleteLearnDirectedKnowledgeById(Long id);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnExamineeService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnExaminee;
+
+/**
+ * 答卷Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnExamineeService 
+{
+    /**
+     * 查询答卷
+     * 
+     * @param examineeId 答卷主键
+     * @return 答卷
+     */
+    public LearnExaminee selectLearnExamineeByExamineeId(Long examineeId);
+
+    /**
+     * 查询答卷列表
+     * 
+     * @param learnExaminee 答卷
+     * @return 答卷集合
+     */
+    public List<LearnExaminee> selectLearnExamineeList(LearnExaminee learnExaminee);
+
+    /**
+     * 新增答卷
+     * 
+     * @param learnExaminee 答卷
+     * @return 结果
+     */
+    public int insertLearnExaminee(LearnExaminee learnExaminee);
+
+    /**
+     * 修改答卷
+     * 
+     * @param learnExaminee 答卷
+     * @return 结果
+     */
+    public int updateLearnExaminee(LearnExaminee learnExaminee);
+
+    /**
+     * 批量删除答卷
+     * 
+     * @param examineeIds 需要删除的答卷主键集合
+     * @return 结果
+     */
+    public int deleteLearnExamineeByExamineeIds(Long[] examineeIds);
+
+    /**
+     * 删除答卷信息
+     * 
+     * @param examineeId 答卷主键
+     * @return 结果
+     */
+    public int deleteLearnExamineeByExamineeId(Long examineeId);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnKnowledgeQuestionService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnKnowledgeQuestion;
+
+/**
+ * 知识点题关系Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnKnowledgeQuestionService 
+{
+    /**
+     * 查询知识点题关系
+     * 
+     * @param id 知识点题关系主键
+     * @return 知识点题关系
+     */
+    public LearnKnowledgeQuestion selectLearnKnowledgeQuestionById(Long id);
+
+    /**
+     * 查询知识点题关系列表
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 知识点题关系集合
+     */
+    public List<LearnKnowledgeQuestion> selectLearnKnowledgeQuestionList(LearnKnowledgeQuestion learnKnowledgeQuestion);
+
+    /**
+     * 新增知识点题关系
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 结果
+     */
+    public int insertLearnKnowledgeQuestion(LearnKnowledgeQuestion learnKnowledgeQuestion);
+
+    /**
+     * 修改知识点题关系
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 结果
+     */
+    public int updateLearnKnowledgeQuestion(LearnKnowledgeQuestion learnKnowledgeQuestion);
+
+    /**
+     * 批量删除知识点题关系
+     * 
+     * @param ids 需要删除的知识点题关系主键集合
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeQuestionByIds(Long[] ids);
+
+    /**
+     * 删除知识点题关系信息
+     * 
+     * @param id 知识点题关系主键
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeQuestionById(Long id);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnKnowledgeTreeService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnKnowledgeTree;
+
+/**
+ * 知识点树Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnKnowledgeTreeService 
+{
+    /**
+     * 查询知识点树
+     * 
+     * @param id 知识点树主键
+     * @return 知识点树
+     */
+    public LearnKnowledgeTree selectLearnKnowledgeTreeById(Long id);
+
+    /**
+     * 查询知识点树列表
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 知识点树集合
+     */
+    public List<LearnKnowledgeTree> selectLearnKnowledgeTreeList(LearnKnowledgeTree learnKnowledgeTree);
+
+    /**
+     * 新增知识点树
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 结果
+     */
+    public int insertLearnKnowledgeTree(LearnKnowledgeTree learnKnowledgeTree);
+
+    /**
+     * 修改知识点树
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 结果
+     */
+    public int updateLearnKnowledgeTree(LearnKnowledgeTree learnKnowledgeTree);
+
+    /**
+     * 批量删除知识点树
+     * 
+     * @param ids 需要删除的知识点树主键集合
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeTreeByIds(Long[] ids);
+
+    /**
+     * 删除知识点树信息
+     * 
+     * @param id 知识点树主键
+     * @return 结果
+     */
+    public int deleteLearnKnowledgeTreeById(Long id);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnPlanService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPlan;
+
+/**
+ * 学习计划Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnPlanService 
+{
+    /**
+     * 查询学习计划
+     * 
+     * @param id 学习计划主键
+     * @return 学习计划
+     */
+    public LearnPlan selectLearnPlanById(String id);
+
+    /**
+     * 查询学习计划列表
+     * 
+     * @param learnPlan 学习计划
+     * @return 学习计划集合
+     */
+    public List<LearnPlan> selectLearnPlanList(LearnPlan learnPlan);
+
+    /**
+     * 新增学习计划
+     * 
+     * @param learnPlan 学习计划
+     * @return 结果
+     */
+    public int insertLearnPlan(LearnPlan learnPlan);
+
+    /**
+     * 修改学习计划
+     * 
+     * @param learnPlan 学习计划
+     * @return 结果
+     */
+    public int updateLearnPlan(LearnPlan learnPlan);
+
+    /**
+     * 批量删除学习计划
+     * 
+     * @param ids 需要删除的学习计划主键集合
+     * @return 结果
+     */
+    public int deleteLearnPlanByIds(String[] ids);
+
+    /**
+     * 删除学习计划信息
+     * 
+     * @param id 学习计划主键
+     * @return 结果
+     */
+    public int deleteLearnPlanById(String id);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnPlanStudyService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPlanStudy;
+
+/**
+ * 学生计划执行情况Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnPlanStudyService 
+{
+    /**
+     * 查询学生计划执行情况
+     * 
+     * @param id 学生计划执行情况主键
+     * @return 学生计划执行情况
+     */
+    public LearnPlanStudy selectLearnPlanStudyById(String id);
+
+    /**
+     * 查询学生计划执行情况列表
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 学生计划执行情况集合
+     */
+    public List<LearnPlanStudy> selectLearnPlanStudyList(LearnPlanStudy learnPlanStudy);
+
+    /**
+     * 新增学生计划执行情况
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 结果
+     */
+    public int insertLearnPlanStudy(LearnPlanStudy learnPlanStudy);
+
+    /**
+     * 修改学生计划执行情况
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 结果
+     */
+    public int updateLearnPlanStudy(LearnPlanStudy learnPlanStudy);
+
+    /**
+     * 批量删除学生计划执行情况
+     * 
+     * @param ids 需要删除的学生计划执行情况主键集合
+     * @return 结果
+     */
+    public int deleteLearnPlanStudyByIds(String[] ids);
+
+    /**
+     * 删除学生计划执行情况信息
+     * 
+     * @param id 学生计划执行情况主键
+     * @return 结果
+     */
+    public int deleteLearnPlanStudyById(String id);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnQuestionCorrectService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnQuestionCorrect;
+
+/**
+ * 题纠错Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnQuestionCorrectService 
+{
+    /**
+     * 查询题纠错
+     * 
+     * @param id 题纠错主键
+     * @return 题纠错
+     */
+    public LearnQuestionCorrect selectLearnQuestionCorrectById(Long id);
+
+    /**
+     * 查询题纠错列表
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 题纠错集合
+     */
+    public List<LearnQuestionCorrect> selectLearnQuestionCorrectList(LearnQuestionCorrect learnQuestionCorrect);
+
+    /**
+     * 新增题纠错
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 结果
+     */
+    public int insertLearnQuestionCorrect(LearnQuestionCorrect learnQuestionCorrect);
+
+    /**
+     * 修改题纠错
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 结果
+     */
+    public int updateLearnQuestionCorrect(LearnQuestionCorrect learnQuestionCorrect);
+
+    /**
+     * 批量删除题纠错
+     * 
+     * @param ids 需要删除的题纠错主键集合
+     * @return 结果
+     */
+    public int deleteLearnQuestionCorrectByIds(Long[] ids);
+
+    /**
+     * 删除题纠错信息
+     * 
+     * @param id 题纠错主键
+     * @return 结果
+     */
+    public int deleteLearnQuestionCorrectById(Long id);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnWrongBookService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnWrongBook;
+
+/**
+ * 学生错题本Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnWrongBookService 
+{
+    /**
+     * 查询学生错题本
+     * 
+     * @param wrongId 学生错题本主键
+     * @return 学生错题本
+     */
+    public LearnWrongBook selectLearnWrongBookByWrongId(Long wrongId);
+
+    /**
+     * 查询学生错题本列表
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 学生错题本集合
+     */
+    public List<LearnWrongBook> selectLearnWrongBookList(LearnWrongBook learnWrongBook);
+
+    /**
+     * 新增学生错题本
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 结果
+     */
+    public int insertLearnWrongBook(LearnWrongBook learnWrongBook);
+
+    /**
+     * 修改学生错题本
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 结果
+     */
+    public int updateLearnWrongBook(LearnWrongBook learnWrongBook);
+
+    /**
+     * 批量删除学生错题本
+     * 
+     * @param wrongIds 需要删除的学生错题本主键集合
+     * @return 结果
+     */
+    public int deleteLearnWrongBookByWrongIds(Long[] wrongIds);
+
+    /**
+     * 删除学生错题本信息
+     * 
+     * @param wrongId 学生错题本主键
+     * @return 结果
+     */
+    public int deleteLearnWrongBookByWrongId(Long wrongId);
+}

+ 61 - 0
ie-system/src/main/java/com/ruoyi/learn/service/ILearnWrongDetailService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnWrongDetail;
+
+/**
+ * 学生错题流水Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+public interface ILearnWrongDetailService 
+{
+    /**
+     * 查询学生错题流水
+     * 
+     * @param wrongDetailId 学生错题流水主键
+     * @return 学生错题流水
+     */
+    public LearnWrongDetail selectLearnWrongDetailByWrongDetailId(Long wrongDetailId);
+
+    /**
+     * 查询学生错题流水列表
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 学生错题流水集合
+     */
+    public List<LearnWrongDetail> selectLearnWrongDetailList(LearnWrongDetail learnWrongDetail);
+
+    /**
+     * 新增学生错题流水
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 结果
+     */
+    public int insertLearnWrongDetail(LearnWrongDetail learnWrongDetail);
+
+    /**
+     * 修改学生错题流水
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 结果
+     */
+    public int updateLearnWrongDetail(LearnWrongDetail learnWrongDetail);
+
+    /**
+     * 批量删除学生错题流水
+     * 
+     * @param wrongDetailIds 需要删除的学生错题流水主键集合
+     * @return 结果
+     */
+    public int deleteLearnWrongDetailByWrongDetailIds(Long[] wrongDetailIds);
+
+    /**
+     * 删除学生错题流水信息
+     * 
+     * @param wrongDetailId 学生错题流水主键
+     * @return 结果
+     */
+    public int deleteLearnWrongDetailByWrongDetailId(Long wrongDetailId);
+}

+ 96 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnAnswerServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnAnswerMapper;
+import com.ruoyi.learn.domain.LearnAnswer;
+import com.ruoyi.learn.service.ILearnAnswerService;
+
+/**
+ * 答卷答案Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnAnswerServiceImpl implements ILearnAnswerService 
+{
+    @Autowired
+    private LearnAnswerMapper learnAnswerMapper;
+
+    /**
+     * 查询答卷答案
+     * 
+     * @param answerId 答卷答案主键
+     * @return 答卷答案
+     */
+    @Override
+    public LearnAnswer selectLearnAnswerByAnswerId(Long answerId)
+    {
+        return learnAnswerMapper.selectLearnAnswerByAnswerId(answerId);
+    }
+
+    /**
+     * 查询答卷答案列表
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 答卷答案
+     */
+    @Override
+    public List<LearnAnswer> selectLearnAnswerList(LearnAnswer learnAnswer)
+    {
+        return learnAnswerMapper.selectLearnAnswerList(learnAnswer);
+    }
+
+    /**
+     * 新增答卷答案
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 结果
+     */
+    @Override
+    public int insertLearnAnswer(LearnAnswer learnAnswer)
+    {
+        learnAnswer.setCreateTime(DateUtils.getNowDate());
+        return learnAnswerMapper.insertLearnAnswer(learnAnswer);
+    }
+
+    /**
+     * 修改答卷答案
+     * 
+     * @param learnAnswer 答卷答案
+     * @return 结果
+     */
+    @Override
+    public int updateLearnAnswer(LearnAnswer learnAnswer)
+    {
+        learnAnswer.setUpdateTime(DateUtils.getNowDate());
+        return learnAnswerMapper.updateLearnAnswer(learnAnswer);
+    }
+
+    /**
+     * 批量删除答卷答案
+     * 
+     * @param answerIds 需要删除的答卷答案主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnAnswerByAnswerIds(Long[] answerIds)
+    {
+        return learnAnswerMapper.deleteLearnAnswerByAnswerIds(answerIds);
+    }
+
+    /**
+     * 删除答卷答案信息
+     * 
+     * @param answerId 答卷答案主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnAnswerByAnswerId(Long answerId)
+    {
+        return learnAnswerMapper.deleteLearnAnswerByAnswerId(answerId);
+    }
+}

+ 93 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnDirectedKnowledgeServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnDirectedKnowledgeMapper;
+import com.ruoyi.learn.domain.LearnDirectedKnowledge;
+import com.ruoyi.learn.service.ILearnDirectedKnowledgeService;
+
+/**
+ * 定向知识点关系Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnDirectedKnowledgeServiceImpl implements ILearnDirectedKnowledgeService 
+{
+    @Autowired
+    private LearnDirectedKnowledgeMapper learnDirectedKnowledgeMapper;
+
+    /**
+     * 查询定向知识点关系
+     * 
+     * @param id 定向知识点关系主键
+     * @return 定向知识点关系
+     */
+    @Override
+    public LearnDirectedKnowledge selectLearnDirectedKnowledgeById(Long id)
+    {
+        return learnDirectedKnowledgeMapper.selectLearnDirectedKnowledgeById(id);
+    }
+
+    /**
+     * 查询定向知识点关系列表
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 定向知识点关系
+     */
+    @Override
+    public List<LearnDirectedKnowledge> selectLearnDirectedKnowledgeList(LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        return learnDirectedKnowledgeMapper.selectLearnDirectedKnowledgeList(learnDirectedKnowledge);
+    }
+
+    /**
+     * 新增定向知识点关系
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 结果
+     */
+    @Override
+    public int insertLearnDirectedKnowledge(LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        return learnDirectedKnowledgeMapper.insertLearnDirectedKnowledge(learnDirectedKnowledge);
+    }
+
+    /**
+     * 修改定向知识点关系
+     * 
+     * @param learnDirectedKnowledge 定向知识点关系
+     * @return 结果
+     */
+    @Override
+    public int updateLearnDirectedKnowledge(LearnDirectedKnowledge learnDirectedKnowledge)
+    {
+        return learnDirectedKnowledgeMapper.updateLearnDirectedKnowledge(learnDirectedKnowledge);
+    }
+
+    /**
+     * 批量删除定向知识点关系
+     * 
+     * @param ids 需要删除的定向知识点关系主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnDirectedKnowledgeByIds(Long[] ids)
+    {
+        return learnDirectedKnowledgeMapper.deleteLearnDirectedKnowledgeByIds(ids);
+    }
+
+    /**
+     * 删除定向知识点关系信息
+     * 
+     * @param id 定向知识点关系主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnDirectedKnowledgeById(Long id)
+    {
+        return learnDirectedKnowledgeMapper.deleteLearnDirectedKnowledgeById(id);
+    }
+}

+ 96 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnExamineeServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnExamineeMapper;
+import com.ruoyi.learn.domain.LearnExaminee;
+import com.ruoyi.learn.service.ILearnExamineeService;
+
+/**
+ * 答卷Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnExamineeServiceImpl implements ILearnExamineeService 
+{
+    @Autowired
+    private LearnExamineeMapper learnExamineeMapper;
+
+    /**
+     * 查询答卷
+     * 
+     * @param examineeId 答卷主键
+     * @return 答卷
+     */
+    @Override
+    public LearnExaminee selectLearnExamineeByExamineeId(Long examineeId)
+    {
+        return learnExamineeMapper.selectLearnExamineeByExamineeId(examineeId);
+    }
+
+    /**
+     * 查询答卷列表
+     * 
+     * @param learnExaminee 答卷
+     * @return 答卷
+     */
+    @Override
+    public List<LearnExaminee> selectLearnExamineeList(LearnExaminee learnExaminee)
+    {
+        return learnExamineeMapper.selectLearnExamineeList(learnExaminee);
+    }
+
+    /**
+     * 新增答卷
+     * 
+     * @param learnExaminee 答卷
+     * @return 结果
+     */
+    @Override
+    public int insertLearnExaminee(LearnExaminee learnExaminee)
+    {
+        learnExaminee.setCreateTime(DateUtils.getNowDate());
+        return learnExamineeMapper.insertLearnExaminee(learnExaminee);
+    }
+
+    /**
+     * 修改答卷
+     * 
+     * @param learnExaminee 答卷
+     * @return 结果
+     */
+    @Override
+    public int updateLearnExaminee(LearnExaminee learnExaminee)
+    {
+        learnExaminee.setUpdateTime(DateUtils.getNowDate());
+        return learnExamineeMapper.updateLearnExaminee(learnExaminee);
+    }
+
+    /**
+     * 批量删除答卷
+     * 
+     * @param examineeIds 需要删除的答卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnExamineeByExamineeIds(Long[] examineeIds)
+    {
+        return learnExamineeMapper.deleteLearnExamineeByExamineeIds(examineeIds);
+    }
+
+    /**
+     * 删除答卷信息
+     * 
+     * @param examineeId 答卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnExamineeByExamineeId(Long examineeId)
+    {
+        return learnExamineeMapper.deleteLearnExamineeByExamineeId(examineeId);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnKnowledgeQuestionServiceImpl.java

@@ -0,0 +1,95 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnKnowledgeQuestionMapper;
+import com.ruoyi.learn.domain.LearnKnowledgeQuestion;
+import com.ruoyi.learn.service.ILearnKnowledgeQuestionService;
+
+/**
+ * 知识点题关系Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnKnowledgeQuestionServiceImpl implements ILearnKnowledgeQuestionService 
+{
+    @Autowired
+    private LearnKnowledgeQuestionMapper learnKnowledgeQuestionMapper;
+
+    /**
+     * 查询知识点题关系
+     * 
+     * @param id 知识点题关系主键
+     * @return 知识点题关系
+     */
+    @Override
+    public LearnKnowledgeQuestion selectLearnKnowledgeQuestionById(Long id)
+    {
+        return learnKnowledgeQuestionMapper.selectLearnKnowledgeQuestionById(id);
+    }
+
+    /**
+     * 查询知识点题关系列表
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 知识点题关系
+     */
+    @Override
+    public List<LearnKnowledgeQuestion> selectLearnKnowledgeQuestionList(LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        return learnKnowledgeQuestionMapper.selectLearnKnowledgeQuestionList(learnKnowledgeQuestion);
+    }
+
+    /**
+     * 新增知识点题关系
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 结果
+     */
+    @Override
+    public int insertLearnKnowledgeQuestion(LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        learnKnowledgeQuestion.setCreateTime(DateUtils.getNowDate());
+        return learnKnowledgeQuestionMapper.insertLearnKnowledgeQuestion(learnKnowledgeQuestion);
+    }
+
+    /**
+     * 修改知识点题关系
+     * 
+     * @param learnKnowledgeQuestion 知识点题关系
+     * @return 结果
+     */
+    @Override
+    public int updateLearnKnowledgeQuestion(LearnKnowledgeQuestion learnKnowledgeQuestion)
+    {
+        return learnKnowledgeQuestionMapper.updateLearnKnowledgeQuestion(learnKnowledgeQuestion);
+    }
+
+    /**
+     * 批量删除知识点题关系
+     * 
+     * @param ids 需要删除的知识点题关系主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnKnowledgeQuestionByIds(Long[] ids)
+    {
+        return learnKnowledgeQuestionMapper.deleteLearnKnowledgeQuestionByIds(ids);
+    }
+
+    /**
+     * 删除知识点题关系信息
+     * 
+     * @param id 知识点题关系主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnKnowledgeQuestionById(Long id)
+    {
+        return learnKnowledgeQuestionMapper.deleteLearnKnowledgeQuestionById(id);
+    }
+}

+ 93 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnKnowledgeTreeServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnKnowledgeTreeMapper;
+import com.ruoyi.learn.domain.LearnKnowledgeTree;
+import com.ruoyi.learn.service.ILearnKnowledgeTreeService;
+
+/**
+ * 知识点树Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnKnowledgeTreeServiceImpl implements ILearnKnowledgeTreeService 
+{
+    @Autowired
+    private LearnKnowledgeTreeMapper learnKnowledgeTreeMapper;
+
+    /**
+     * 查询知识点树
+     * 
+     * @param id 知识点树主键
+     * @return 知识点树
+     */
+    @Override
+    public LearnKnowledgeTree selectLearnKnowledgeTreeById(Long id)
+    {
+        return learnKnowledgeTreeMapper.selectLearnKnowledgeTreeById(id);
+    }
+
+    /**
+     * 查询知识点树列表
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 知识点树
+     */
+    @Override
+    public List<LearnKnowledgeTree> selectLearnKnowledgeTreeList(LearnKnowledgeTree learnKnowledgeTree)
+    {
+        return learnKnowledgeTreeMapper.selectLearnKnowledgeTreeList(learnKnowledgeTree);
+    }
+
+    /**
+     * 新增知识点树
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 结果
+     */
+    @Override
+    public int insertLearnKnowledgeTree(LearnKnowledgeTree learnKnowledgeTree)
+    {
+        return learnKnowledgeTreeMapper.insertLearnKnowledgeTree(learnKnowledgeTree);
+    }
+
+    /**
+     * 修改知识点树
+     * 
+     * @param learnKnowledgeTree 知识点树
+     * @return 结果
+     */
+    @Override
+    public int updateLearnKnowledgeTree(LearnKnowledgeTree learnKnowledgeTree)
+    {
+        return learnKnowledgeTreeMapper.updateLearnKnowledgeTree(learnKnowledgeTree);
+    }
+
+    /**
+     * 批量删除知识点树
+     * 
+     * @param ids 需要删除的知识点树主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnKnowledgeTreeByIds(Long[] ids)
+    {
+        return learnKnowledgeTreeMapper.deleteLearnKnowledgeTreeByIds(ids);
+    }
+
+    /**
+     * 删除知识点树信息
+     * 
+     * @param id 知识点树主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnKnowledgeTreeById(Long id)
+    {
+        return learnKnowledgeTreeMapper.deleteLearnKnowledgeTreeById(id);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPlanServiceImpl.java

@@ -0,0 +1,95 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnPlanMapper;
+import com.ruoyi.learn.domain.LearnPlan;
+import com.ruoyi.learn.service.ILearnPlanService;
+
+/**
+ * 学习计划Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnPlanServiceImpl implements ILearnPlanService 
+{
+    @Autowired
+    private LearnPlanMapper learnPlanMapper;
+
+    /**
+     * 查询学习计划
+     * 
+     * @param id 学习计划主键
+     * @return 学习计划
+     */
+    @Override
+    public LearnPlan selectLearnPlanById(String id)
+    {
+        return learnPlanMapper.selectLearnPlanById(id);
+    }
+
+    /**
+     * 查询学习计划列表
+     * 
+     * @param learnPlan 学习计划
+     * @return 学习计划
+     */
+    @Override
+    public List<LearnPlan> selectLearnPlanList(LearnPlan learnPlan)
+    {
+        return learnPlanMapper.selectLearnPlanList(learnPlan);
+    }
+
+    /**
+     * 新增学习计划
+     * 
+     * @param learnPlan 学习计划
+     * @return 结果
+     */
+    @Override
+    public int insertLearnPlan(LearnPlan learnPlan)
+    {
+        learnPlan.setCreateTime(DateUtils.getNowDate());
+        return learnPlanMapper.insertLearnPlan(learnPlan);
+    }
+
+    /**
+     * 修改学习计划
+     * 
+     * @param learnPlan 学习计划
+     * @return 结果
+     */
+    @Override
+    public int updateLearnPlan(LearnPlan learnPlan)
+    {
+        return learnPlanMapper.updateLearnPlan(learnPlan);
+    }
+
+    /**
+     * 批量删除学习计划
+     * 
+     * @param ids 需要删除的学习计划主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPlanByIds(String[] ids)
+    {
+        return learnPlanMapper.deleteLearnPlanByIds(ids);
+    }
+
+    /**
+     * 删除学习计划信息
+     * 
+     * @param id 学习计划主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPlanById(String id)
+    {
+        return learnPlanMapper.deleteLearnPlanById(id);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPlanStudyServiceImpl.java

@@ -0,0 +1,95 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnPlanStudyMapper;
+import com.ruoyi.learn.domain.LearnPlanStudy;
+import com.ruoyi.learn.service.ILearnPlanStudyService;
+
+/**
+ * 学生计划执行情况Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnPlanStudyServiceImpl implements ILearnPlanStudyService 
+{
+    @Autowired
+    private LearnPlanStudyMapper learnPlanStudyMapper;
+
+    /**
+     * 查询学生计划执行情况
+     * 
+     * @param id 学生计划执行情况主键
+     * @return 学生计划执行情况
+     */
+    @Override
+    public LearnPlanStudy selectLearnPlanStudyById(String id)
+    {
+        return learnPlanStudyMapper.selectLearnPlanStudyById(id);
+    }
+
+    /**
+     * 查询学生计划执行情况列表
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 学生计划执行情况
+     */
+    @Override
+    public List<LearnPlanStudy> selectLearnPlanStudyList(LearnPlanStudy learnPlanStudy)
+    {
+        return learnPlanStudyMapper.selectLearnPlanStudyList(learnPlanStudy);
+    }
+
+    /**
+     * 新增学生计划执行情况
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 结果
+     */
+    @Override
+    public int insertLearnPlanStudy(LearnPlanStudy learnPlanStudy)
+    {
+        return learnPlanStudyMapper.insertLearnPlanStudy(learnPlanStudy);
+    }
+
+    /**
+     * 修改学生计划执行情况
+     * 
+     * @param learnPlanStudy 学生计划执行情况
+     * @return 结果
+     */
+    @Override
+    public int updateLearnPlanStudy(LearnPlanStudy learnPlanStudy)
+    {
+        learnPlanStudy.setUpdateTime(DateUtils.getNowDate());
+        return learnPlanStudyMapper.updateLearnPlanStudy(learnPlanStudy);
+    }
+
+    /**
+     * 批量删除学生计划执行情况
+     * 
+     * @param ids 需要删除的学生计划执行情况主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPlanStudyByIds(String[] ids)
+    {
+        return learnPlanStudyMapper.deleteLearnPlanStudyByIds(ids);
+    }
+
+    /**
+     * 删除学生计划执行情况信息
+     * 
+     * @param id 学生计划执行情况主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPlanStudyById(String id)
+    {
+        return learnPlanStudyMapper.deleteLearnPlanStudyById(id);
+    }
+}

+ 96 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnQuestionCorrectServiceImpl.java

@@ -0,0 +1,96 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnQuestionCorrectMapper;
+import com.ruoyi.learn.domain.LearnQuestionCorrect;
+import com.ruoyi.learn.service.ILearnQuestionCorrectService;
+
+/**
+ * 题纠错Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnQuestionCorrectServiceImpl implements ILearnQuestionCorrectService 
+{
+    @Autowired
+    private LearnQuestionCorrectMapper learnQuestionCorrectMapper;
+
+    /**
+     * 查询题纠错
+     * 
+     * @param id 题纠错主键
+     * @return 题纠错
+     */
+    @Override
+    public LearnQuestionCorrect selectLearnQuestionCorrectById(Long id)
+    {
+        return learnQuestionCorrectMapper.selectLearnQuestionCorrectById(id);
+    }
+
+    /**
+     * 查询题纠错列表
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 题纠错
+     */
+    @Override
+    public List<LearnQuestionCorrect> selectLearnQuestionCorrectList(LearnQuestionCorrect learnQuestionCorrect)
+    {
+        return learnQuestionCorrectMapper.selectLearnQuestionCorrectList(learnQuestionCorrect);
+    }
+
+    /**
+     * 新增题纠错
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 结果
+     */
+    @Override
+    public int insertLearnQuestionCorrect(LearnQuestionCorrect learnQuestionCorrect)
+    {
+        learnQuestionCorrect.setCreateTime(DateUtils.getNowDate());
+        return learnQuestionCorrectMapper.insertLearnQuestionCorrect(learnQuestionCorrect);
+    }
+
+    /**
+     * 修改题纠错
+     * 
+     * @param learnQuestionCorrect 题纠错
+     * @return 结果
+     */
+    @Override
+    public int updateLearnQuestionCorrect(LearnQuestionCorrect learnQuestionCorrect)
+    {
+        learnQuestionCorrect.setUpdateTime(DateUtils.getNowDate());
+        return learnQuestionCorrectMapper.updateLearnQuestionCorrect(learnQuestionCorrect);
+    }
+
+    /**
+     * 批量删除题纠错
+     * 
+     * @param ids 需要删除的题纠错主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnQuestionCorrectByIds(Long[] ids)
+    {
+        return learnQuestionCorrectMapper.deleteLearnQuestionCorrectByIds(ids);
+    }
+
+    /**
+     * 删除题纠错信息
+     * 
+     * @param id 题纠错主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnQuestionCorrectById(Long id)
+    {
+        return learnQuestionCorrectMapper.deleteLearnQuestionCorrectById(id);
+    }
+}

+ 93 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnWrongBookServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnWrongBookMapper;
+import com.ruoyi.learn.domain.LearnWrongBook;
+import com.ruoyi.learn.service.ILearnWrongBookService;
+
+/**
+ * 学生错题本Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnWrongBookServiceImpl implements ILearnWrongBookService 
+{
+    @Autowired
+    private LearnWrongBookMapper learnWrongBookMapper;
+
+    /**
+     * 查询学生错题本
+     * 
+     * @param wrongId 学生错题本主键
+     * @return 学生错题本
+     */
+    @Override
+    public LearnWrongBook selectLearnWrongBookByWrongId(Long wrongId)
+    {
+        return learnWrongBookMapper.selectLearnWrongBookByWrongId(wrongId);
+    }
+
+    /**
+     * 查询学生错题本列表
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 学生错题本
+     */
+    @Override
+    public List<LearnWrongBook> selectLearnWrongBookList(LearnWrongBook learnWrongBook)
+    {
+        return learnWrongBookMapper.selectLearnWrongBookList(learnWrongBook);
+    }
+
+    /**
+     * 新增学生错题本
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 结果
+     */
+    @Override
+    public int insertLearnWrongBook(LearnWrongBook learnWrongBook)
+    {
+        return learnWrongBookMapper.insertLearnWrongBook(learnWrongBook);
+    }
+
+    /**
+     * 修改学生错题本
+     * 
+     * @param learnWrongBook 学生错题本
+     * @return 结果
+     */
+    @Override
+    public int updateLearnWrongBook(LearnWrongBook learnWrongBook)
+    {
+        return learnWrongBookMapper.updateLearnWrongBook(learnWrongBook);
+    }
+
+    /**
+     * 批量删除学生错题本
+     * 
+     * @param wrongIds 需要删除的学生错题本主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnWrongBookByWrongIds(Long[] wrongIds)
+    {
+        return learnWrongBookMapper.deleteLearnWrongBookByWrongIds(wrongIds);
+    }
+
+    /**
+     * 删除学生错题本信息
+     * 
+     * @param wrongId 学生错题本主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnWrongBookByWrongId(Long wrongId)
+    {
+        return learnWrongBookMapper.deleteLearnWrongBookByWrongId(wrongId);
+    }
+}

+ 93 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnWrongDetailServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.learn.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.learn.mapper.LearnWrongDetailMapper;
+import com.ruoyi.learn.domain.LearnWrongDetail;
+import com.ruoyi.learn.service.ILearnWrongDetailService;
+
+/**
+ * 学生错题流水Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-25
+ */
+@Service
+public class LearnWrongDetailServiceImpl implements ILearnWrongDetailService 
+{
+    @Autowired
+    private LearnWrongDetailMapper learnWrongDetailMapper;
+
+    /**
+     * 查询学生错题流水
+     * 
+     * @param wrongDetailId 学生错题流水主键
+     * @return 学生错题流水
+     */
+    @Override
+    public LearnWrongDetail selectLearnWrongDetailByWrongDetailId(Long wrongDetailId)
+    {
+        return learnWrongDetailMapper.selectLearnWrongDetailByWrongDetailId(wrongDetailId);
+    }
+
+    /**
+     * 查询学生错题流水列表
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 学生错题流水
+     */
+    @Override
+    public List<LearnWrongDetail> selectLearnWrongDetailList(LearnWrongDetail learnWrongDetail)
+    {
+        return learnWrongDetailMapper.selectLearnWrongDetailList(learnWrongDetail);
+    }
+
+    /**
+     * 新增学生错题流水
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 结果
+     */
+    @Override
+    public int insertLearnWrongDetail(LearnWrongDetail learnWrongDetail)
+    {
+        return learnWrongDetailMapper.insertLearnWrongDetail(learnWrongDetail);
+    }
+
+    /**
+     * 修改学生错题流水
+     * 
+     * @param learnWrongDetail 学生错题流水
+     * @return 结果
+     */
+    @Override
+    public int updateLearnWrongDetail(LearnWrongDetail learnWrongDetail)
+    {
+        return learnWrongDetailMapper.updateLearnWrongDetail(learnWrongDetail);
+    }
+
+    /**
+     * 批量删除学生错题流水
+     * 
+     * @param wrongDetailIds 需要删除的学生错题流水主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnWrongDetailByWrongDetailIds(Long[] wrongDetailIds)
+    {
+        return learnWrongDetailMapper.deleteLearnWrongDetailByWrongDetailIds(wrongDetailIds);
+    }
+
+    /**
+     * 删除学生错题流水信息
+     * 
+     * @param wrongDetailId 学生错题流水主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnWrongDetailByWrongDetailId(Long wrongDetailId)
+    {
+        return learnWrongDetailMapper.deleteLearnWrongDetailByWrongDetailId(wrongDetailId);
+    }
+}

+ 124 - 0
ie-system/src/main/resources/mapper/learn/LearnAnswerMapper.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnAnswerMapper">
+    
+    <resultMap type="LearnAnswer" id="LearnAnswerResult">
+        <result property="answerId"    column="answer_id"    />
+        <result property="examineeId"    column="examinee_id"    />
+        <result property="studentId"    column="student_id"    />
+        <result property="questionId"    column="question_id"    />
+        <result property="seq"    column="seq"    />
+        <result property="knowledgeId"    column="knowledge_id"    />
+        <result property="answer"    column="answer"    />
+        <result property="correct"    column="correct"    />
+        <result property="duration"    column="duration"    />
+        <result property="count"    column="count"    />
+        <result property="state"    column="state"    />
+        <result property="scoreLevel"    column="score_level"    />
+        <result property="score"    column="score"    />
+        <result property="scoreRate"    column="score_rate"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectLearnAnswerVo">
+        select answer_id, examinee_id, student_id, question_id, seq, knowledge_id, answer, correct, duration, count, state, score_level, score, score_rate, create_time, update_time from learn_answer
+    </sql>
+
+    <select id="selectLearnAnswerList" parameterType="LearnAnswer" resultMap="LearnAnswerResult">
+        <include refid="selectLearnAnswerVo"/>
+        <where>  
+            <if test="examineeId != null "> and examinee_id = #{examineeId}</if>
+            <if test="studentId != null "> and student_id = #{studentId}</if>
+            <if test="questionId != null "> and question_id = #{questionId}</if>
+            <if test="seq != null "> and seq = #{seq}</if>
+            <if test="knowledgeId != null "> and knowledge_id = #{knowledgeId}</if>
+            <if test="answer != null  and answer != ''"> and answer = #{answer}</if>
+            <if test="correct != null  and correct != ''"> and correct = #{correct}</if>
+            <if test="duration != null "> and duration = #{duration}</if>
+            <if test="count != null "> and count = #{count}</if>
+            <if test="state != null "> and state = #{state}</if>
+            <if test="scoreLevel != null  and scoreLevel != ''"> and score_level = #{scoreLevel}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="scoreRate != null "> and score_rate = #{scoreRate}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnAnswerByAnswerId" parameterType="Long" resultMap="LearnAnswerResult">
+        <include refid="selectLearnAnswerVo"/>
+        where answer_id = #{answerId}
+    </select>
+
+    <insert id="insertLearnAnswer" parameterType="LearnAnswer" useGeneratedKeys="true" keyProperty="answerId">
+        insert into learn_answer
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="examineeId != null">examinee_id,</if>
+            <if test="studentId != null">student_id,</if>
+            <if test="questionId != null">question_id,</if>
+            <if test="seq != null">seq,</if>
+            <if test="knowledgeId != null">knowledge_id,</if>
+            <if test="answer != null">answer,</if>
+            <if test="correct != null">correct,</if>
+            <if test="duration != null">duration,</if>
+            <if test="count != null">count,</if>
+            <if test="state != null">state,</if>
+            <if test="scoreLevel != null">score_level,</if>
+            <if test="score != null">score,</if>
+            <if test="scoreRate != null">score_rate,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="examineeId != null">#{examineeId},</if>
+            <if test="studentId != null">#{studentId},</if>
+            <if test="questionId != null">#{questionId},</if>
+            <if test="seq != null">#{seq},</if>
+            <if test="knowledgeId != null">#{knowledgeId},</if>
+            <if test="answer != null">#{answer},</if>
+            <if test="correct != null">#{correct},</if>
+            <if test="duration != null">#{duration},</if>
+            <if test="count != null">#{count},</if>
+            <if test="state != null">#{state},</if>
+            <if test="scoreLevel != null">#{scoreLevel},</if>
+            <if test="score != null">#{score},</if>
+            <if test="scoreRate != null">#{scoreRate},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnAnswer" parameterType="LearnAnswer">
+        update learn_answer
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="examineeId != null">examinee_id = #{examineeId},</if>
+            <if test="studentId != null">student_id = #{studentId},</if>
+            <if test="questionId != null">question_id = #{questionId},</if>
+            <if test="seq != null">seq = #{seq},</if>
+            <if test="knowledgeId != null">knowledge_id = #{knowledgeId},</if>
+            <if test="answer != null">answer = #{answer},</if>
+            <if test="correct != null">correct = #{correct},</if>
+            <if test="duration != null">duration = #{duration},</if>
+            <if test="count != null">count = #{count},</if>
+            <if test="state != null">state = #{state},</if>
+            <if test="scoreLevel != null">score_level = #{scoreLevel},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="scoreRate != null">score_rate = #{scoreRate},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where answer_id = #{answerId}
+    </update>
+
+    <delete id="deleteLearnAnswerByAnswerId" parameterType="Long">
+        delete from learn_answer where answer_id = #{answerId}
+    </delete>
+
+    <delete id="deleteLearnAnswerByAnswerIds" parameterType="String">
+        delete from learn_answer where answer_id in 
+        <foreach item="answerId" collection="array" open="(" separator="," close=")">
+            #{answerId}
+        </foreach>
+    </delete>
+</mapper>

+ 106 - 0
ie-system/src/main/resources/mapper/learn/LearnDirectedKnowledgeMapper.xml

@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnDirectedKnowledgeMapper">
+    
+    <resultMap type="LearnDirectedKnowledge" id="LearnDirectedKnowledgeResult">
+        <result property="id"    column="id"    />
+        <result property="year"    column="year"    />
+        <result property="directKey"    column="direct_key"    />
+        <result property="enrollFormula"    column="enrollFormula"    />
+        <result property="cultural"    column="cultural"    />
+        <result property="professional"    column="professional"    />
+        <result property="subjects"    column="subjects"    />
+        <result property="questionTypes"    column="question_types"    />
+        <result property="knowledges"    column="knowledges"    />
+        <result property="locations"    column="locations"    />
+        <result property="examineeTypes"    column="examineeTypes"    />
+        <result property="conditions"    column="conditions"    />
+    </resultMap>
+
+    <sql id="selectLearnDirectedKnowledgeVo">
+        select id, year, direct_key, enrollFormula, cultural, professional, subjects, question_types, knowledges, locations, examineeTypes, conditions from learn_directed_knowledge
+    </sql>
+
+    <select id="selectLearnDirectedKnowledgeList" parameterType="LearnDirectedKnowledge" resultMap="LearnDirectedKnowledgeResult">
+        <include refid="selectLearnDirectedKnowledgeVo"/>
+        <where>  
+            <if test="year != null "> and year = #{year}</if>
+            <if test="directKey != null  and directKey != ''"> and direct_key = #{directKey}</if>
+            <if test="enrollFormula != null  and enrollFormula != ''"> and enrollFormula = #{enrollFormula}</if>
+            <if test="cultural != null  and cultural != ''"> and cultural = #{cultural}</if>
+            <if test="professional != null  and professional != ''"> and professional = #{professional}</if>
+            <if test="subjects != null  and subjects != ''"> and subjects = #{subjects}</if>
+            <if test="questionTypes != null  and questionTypes != ''"> and question_types = #{questionTypes}</if>
+            <if test="knowledges != null  and knowledges != ''"> and knowledges = #{knowledges}</if>
+            <if test="locations != null  and locations != ''"> and locations = #{locations}</if>
+            <if test="examineeTypes != null  and examineeTypes != ''"> and examineeTypes = #{examineeTypes}</if>
+            <if test="conditions != null  and conditions != ''"> and conditions = #{conditions}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnDirectedKnowledgeById" parameterType="Long" resultMap="LearnDirectedKnowledgeResult">
+        <include refid="selectLearnDirectedKnowledgeVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnDirectedKnowledge" parameterType="LearnDirectedKnowledge" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_directed_knowledge
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="year != null">year,</if>
+            <if test="directKey != null">direct_key,</if>
+            <if test="enrollFormula != null">enrollFormula,</if>
+            <if test="cultural != null">cultural,</if>
+            <if test="professional != null">professional,</if>
+            <if test="subjects != null">subjects,</if>
+            <if test="questionTypes != null">question_types,</if>
+            <if test="knowledges != null">knowledges,</if>
+            <if test="locations != null">locations,</if>
+            <if test="examineeTypes != null">examineeTypes,</if>
+            <if test="conditions != null">conditions,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="year != null">#{year},</if>
+            <if test="directKey != null">#{directKey},</if>
+            <if test="enrollFormula != null">#{enrollFormula},</if>
+            <if test="cultural != null">#{cultural},</if>
+            <if test="professional != null">#{professional},</if>
+            <if test="subjects != null">#{subjects},</if>
+            <if test="questionTypes != null">#{questionTypes},</if>
+            <if test="knowledges != null">#{knowledges},</if>
+            <if test="locations != null">#{locations},</if>
+            <if test="examineeTypes != null">#{examineeTypes},</if>
+            <if test="conditions != null">#{conditions},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnDirectedKnowledge" parameterType="LearnDirectedKnowledge">
+        update learn_directed_knowledge
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="year != null">year = #{year},</if>
+            <if test="directKey != null">direct_key = #{directKey},</if>
+            <if test="enrollFormula != null">enrollFormula = #{enrollFormula},</if>
+            <if test="cultural != null">cultural = #{cultural},</if>
+            <if test="professional != null">professional = #{professional},</if>
+            <if test="subjects != null">subjects = #{subjects},</if>
+            <if test="questionTypes != null">question_types = #{questionTypes},</if>
+            <if test="knowledges != null">knowledges = #{knowledges},</if>
+            <if test="locations != null">locations = #{locations},</if>
+            <if test="examineeTypes != null">examineeTypes = #{examineeTypes},</if>
+            <if test="conditions != null">conditions = #{conditions},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnDirectedKnowledgeById" parameterType="Long">
+        delete from learn_directed_knowledge where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnDirectedKnowledgeByIds" parameterType="String">
+        delete from learn_directed_knowledge where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 134 - 0
ie-system/src/main/resources/mapper/learn/LearnExamineeMapper.xml

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnExamineeMapper">
+    
+    <resultMap type="LearnExaminee" id="LearnExamineeResult">
+        <result property="examineeId"    column="examinee_id"    />
+        <result property="studentId"    column="student_id"    />
+        <result property="paperType"    column="paper_type"    />
+        <result property="paperId"    column="paper_id"    />
+        <result property="beginTime"    column="begin_time"    />
+        <result property="endTime"    column="end_time"    />
+        <result property="state"    column="state"    />
+        <result property="scoreLevel"    column="score_level"    />
+        <result property="score"    column="score"    />
+        <result property="scoreRate"    column="score_rate"    />
+        <result property="ranking"    column="ranking"    />
+        <result property="gradeRanking"    column="grade_ranking"    />
+        <result property="chooseCount"    column="choose_count"    />
+        <result property="chooseTotal"    column="choose_total"    />
+        <result property="subjectiveCount"    column="subjective_count"    />
+        <result property="subjectiveTotal"    column="subjective_total"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectLearnExamineeVo">
+        select examinee_id, student_id, paper_type, paper_id, begin_time, end_time, state, score_level, score, score_rate, ranking, grade_ranking, choose_count, choose_total, subjective_count, subjective_total, create_time, update_time from learn_examinee
+    </sql>
+
+    <select id="selectLearnExamineeList" parameterType="LearnExaminee" resultMap="LearnExamineeResult">
+        <include refid="selectLearnExamineeVo"/>
+        <where>  
+            <if test="studentId != null "> and student_id = #{studentId}</if>
+            <if test="paperType != null "> and paper_type = #{paperType}</if>
+            <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="beginTime != null "> and begin_time = #{beginTime}</if>
+            <if test="endTime != null "> and end_time = #{endTime}</if>
+            <if test="state != null "> and state = #{state}</if>
+            <if test="scoreLevel != null  and scoreLevel != ''"> and score_level = #{scoreLevel}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="scoreRate != null "> and score_rate = #{scoreRate}</if>
+            <if test="ranking != null "> and ranking = #{ranking}</if>
+            <if test="gradeRanking != null "> and grade_ranking = #{gradeRanking}</if>
+            <if test="chooseCount != null "> and choose_count = #{chooseCount}</if>
+            <if test="chooseTotal != null "> and choose_total = #{chooseTotal}</if>
+            <if test="subjectiveCount != null "> and subjective_count = #{subjectiveCount}</if>
+            <if test="subjectiveTotal != null "> and subjective_total = #{subjectiveTotal}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnExamineeByExamineeId" parameterType="Long" resultMap="LearnExamineeResult">
+        <include refid="selectLearnExamineeVo"/>
+        where examinee_id = #{examineeId}
+    </select>
+
+    <insert id="insertLearnExaminee" parameterType="LearnExaminee" useGeneratedKeys="true" keyProperty="examineeId">
+        insert into learn_examinee
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">student_id,</if>
+            <if test="paperType != null">paper_type,</if>
+            <if test="paperId != null">paper_id,</if>
+            <if test="beginTime != null">begin_time,</if>
+            <if test="endTime != null">end_time,</if>
+            <if test="state != null">state,</if>
+            <if test="scoreLevel != null">score_level,</if>
+            <if test="score != null">score,</if>
+            <if test="scoreRate != null">score_rate,</if>
+            <if test="ranking != null">ranking,</if>
+            <if test="gradeRanking != null">grade_ranking,</if>
+            <if test="chooseCount != null">choose_count,</if>
+            <if test="chooseTotal != null">choose_total,</if>
+            <if test="subjectiveCount != null">subjective_count,</if>
+            <if test="subjectiveTotal != null">subjective_total,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">#{studentId},</if>
+            <if test="paperType != null">#{paperType},</if>
+            <if test="paperId != null">#{paperId},</if>
+            <if test="beginTime != null">#{beginTime},</if>
+            <if test="endTime != null">#{endTime},</if>
+            <if test="state != null">#{state},</if>
+            <if test="scoreLevel != null">#{scoreLevel},</if>
+            <if test="score != null">#{score},</if>
+            <if test="scoreRate != null">#{scoreRate},</if>
+            <if test="ranking != null">#{ranking},</if>
+            <if test="gradeRanking != null">#{gradeRanking},</if>
+            <if test="chooseCount != null">#{chooseCount},</if>
+            <if test="chooseTotal != null">#{chooseTotal},</if>
+            <if test="subjectiveCount != null">#{subjectiveCount},</if>
+            <if test="subjectiveTotal != null">#{subjectiveTotal},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnExaminee" parameterType="LearnExaminee">
+        update learn_examinee
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="studentId != null">student_id = #{studentId},</if>
+            <if test="paperType != null">paper_type = #{paperType},</if>
+            <if test="paperId != null">paper_id = #{paperId},</if>
+            <if test="beginTime != null">begin_time = #{beginTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="state != null">state = #{state},</if>
+            <if test="scoreLevel != null">score_level = #{scoreLevel},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="scoreRate != null">score_rate = #{scoreRate},</if>
+            <if test="ranking != null">ranking = #{ranking},</if>
+            <if test="gradeRanking != null">grade_ranking = #{gradeRanking},</if>
+            <if test="chooseCount != null">choose_count = #{chooseCount},</if>
+            <if test="chooseTotal != null">choose_total = #{chooseTotal},</if>
+            <if test="subjectiveCount != null">subjective_count = #{subjectiveCount},</if>
+            <if test="subjectiveTotal != null">subjective_total = #{subjectiveTotal},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where examinee_id = #{examineeId}
+    </update>
+
+    <delete id="deleteLearnExamineeByExamineeId" parameterType="Long">
+        delete from learn_examinee where examinee_id = #{examineeId}
+    </delete>
+
+    <delete id="deleteLearnExamineeByExamineeIds" parameterType="String">
+        delete from learn_examinee where examinee_id in 
+        <foreach item="examineeId" collection="array" open="(" separator="," close=")">
+            #{examineeId}
+        </foreach>
+    </delete>
+</mapper>

+ 75 - 0
ie-system/src/main/resources/mapper/learn/LearnKnowledgeQuestionMapper.xml

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnKnowledgeQuestionMapper">
+    
+    <resultMap type="LearnKnowledgeQuestion" id="LearnKnowledgeQuestionResult">
+        <result property="id"    column="id"    />
+        <result property="knowledgeId"    column="knowledge_id"    />
+        <result property="type"    column="type"    />
+        <result property="questionId"    column="question_id"    />
+        <result property="seq"    column="seq"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectLearnKnowledgeQuestionVo">
+        select id, knowledge_id, type, question_id, seq, create_time from learn_knowledge_question
+    </sql>
+
+    <select id="selectLearnKnowledgeQuestionList" parameterType="LearnKnowledgeQuestion" resultMap="LearnKnowledgeQuestionResult">
+        <include refid="selectLearnKnowledgeQuestionVo"/>
+        <where>  
+            <if test="knowledgeId != null "> and knowledge_id = #{knowledgeId}</if>
+            <if test="type != null "> and type = #{type}</if>
+            <if test="questionId != null "> and question_id = #{questionId}</if>
+            <if test="seq != null "> and seq = #{seq}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnKnowledgeQuestionById" parameterType="Long" resultMap="LearnKnowledgeQuestionResult">
+        <include refid="selectLearnKnowledgeQuestionVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnKnowledgeQuestion" parameterType="LearnKnowledgeQuestion" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_knowledge_question
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="knowledgeId != null">knowledge_id,</if>
+            <if test="type != null">type,</if>
+            <if test="questionId != null">question_id,</if>
+            <if test="seq != null">seq,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="knowledgeId != null">#{knowledgeId},</if>
+            <if test="type != null">#{type},</if>
+            <if test="questionId != null">#{questionId},</if>
+            <if test="seq != null">#{seq},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnKnowledgeQuestion" parameterType="LearnKnowledgeQuestion">
+        update learn_knowledge_question
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="knowledgeId != null">knowledge_id = #{knowledgeId},</if>
+            <if test="type != null">type = #{type},</if>
+            <if test="questionId != null">question_id = #{questionId},</if>
+            <if test="seq != null">seq = #{seq},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnKnowledgeQuestionById" parameterType="Long">
+        delete from learn_knowledge_question where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnKnowledgeQuestionByIds" parameterType="String">
+        delete from learn_knowledge_question where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 96 - 0
ie-system/src/main/resources/mapper/learn/LearnKnowledgeTreeMapper.xml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnKnowledgeTreeMapper">
+    
+    <resultMap type="LearnKnowledgeTree" id="LearnKnowledgeTreeResult">
+        <result property="id"    column="id"    />
+        <result property="name"    column="name"    />
+        <result property="pid"    column="pid"    />
+        <result property="ancestors"    column="ancestors"    />
+        <result property="subjectId"    column="subjectId"    />
+        <result property="sort"    column="sort"    />
+        <result property="level"    column="level"    />
+        <result property="questionsCount"    column="questionsCount"    />
+        <result property="locations"    column="locations"    />
+        <result property="examineeTypes"    column="examineeTypes"    />
+    </resultMap>
+
+    <sql id="selectLearnKnowledgeTreeVo">
+        select id, name, pid, ancestors, subjectId, sort, level, questionsCount, locations, examineeTypes from learn_knowledge_tree
+    </sql>
+
+    <select id="selectLearnKnowledgeTreeList" parameterType="LearnKnowledgeTree" resultMap="LearnKnowledgeTreeResult">
+        <include refid="selectLearnKnowledgeTreeVo"/>
+        <where>  
+            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
+            <if test="pid != null "> and pid = #{pid}</if>
+            <if test="ancestors != null  and ancestors != ''"> and ancestors = #{ancestors}</if>
+            <if test="subjectId != null "> and subjectId = #{subjectId}</if>
+            <if test="sort != null "> and sort = #{sort}</if>
+            <if test="level != null "> and level = #{level}</if>
+            <if test="questionsCount != null "> and questionsCount = #{questionsCount}</if>
+            <if test="locations != null  and locations != ''"> and locations = #{locations}</if>
+            <if test="examineeTypes != null  and examineeTypes != ''"> and examineeTypes = #{examineeTypes}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnKnowledgeTreeById" parameterType="Long" resultMap="LearnKnowledgeTreeResult">
+        <include refid="selectLearnKnowledgeTreeVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnKnowledgeTree" parameterType="LearnKnowledgeTree" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_knowledge_tree
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="name != null">name,</if>
+            <if test="pid != null">pid,</if>
+            <if test="ancestors != null">ancestors,</if>
+            <if test="subjectId != null">subjectId,</if>
+            <if test="sort != null">sort,</if>
+            <if test="level != null">level,</if>
+            <if test="questionsCount != null">questionsCount,</if>
+            <if test="locations != null">locations,</if>
+            <if test="examineeTypes != null">examineeTypes,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="name != null">#{name},</if>
+            <if test="pid != null">#{pid},</if>
+            <if test="ancestors != null">#{ancestors},</if>
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="sort != null">#{sort},</if>
+            <if test="level != null">#{level},</if>
+            <if test="questionsCount != null">#{questionsCount},</if>
+            <if test="locations != null">#{locations},</if>
+            <if test="examineeTypes != null">#{examineeTypes},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnKnowledgeTree" parameterType="LearnKnowledgeTree">
+        update learn_knowledge_tree
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="name != null">name = #{name},</if>
+            <if test="pid != null">pid = #{pid},</if>
+            <if test="ancestors != null">ancestors = #{ancestors},</if>
+            <if test="subjectId != null">subjectId = #{subjectId},</if>
+            <if test="sort != null">sort = #{sort},</if>
+            <if test="level != null">level = #{level},</if>
+            <if test="questionsCount != null">questionsCount = #{questionsCount},</if>
+            <if test="locations != null">locations = #{locations},</if>
+            <if test="examineeTypes != null">examineeTypes = #{examineeTypes},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnKnowledgeTreeById" parameterType="Long">
+        delete from learn_knowledge_tree where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnKnowledgeTreeByIds" parameterType="String">
+        delete from learn_knowledge_tree where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 85 - 0
ie-system/src/main/resources/mapper/learn/LearnPlanMapper.xml

@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnPlanMapper">
+    
+    <resultMap type="LearnPlan" id="LearnPlanResult">
+        <result property="id"    column="id"    />
+        <result property="studentId"    column="studentId"    />
+        <result property="videoTime"    column="video_time"    />
+        <result property="questionCnt"    column="question_cnt"    />
+        <result property="status"    column="status"    />
+        <result property="beginTime"    column="begin_time"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="stats"    column="stats"    />
+    </resultMap>
+
+    <sql id="selectLearnPlanVo">
+        select id, studentId, video_time, question_cnt, status, begin_time, create_time, stats from learn_plan
+    </sql>
+
+    <select id="selectLearnPlanList" parameterType="LearnPlan" resultMap="LearnPlanResult">
+        <include refid="selectLearnPlanVo"/>
+        <where>  
+            <if test="studentId != null "> and studentId = #{studentId}</if>
+            <if test="videoTime != null "> and video_time = #{videoTime}</if>
+            <if test="questionCnt != null "> and question_cnt = #{questionCnt}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="beginTime != null "> and begin_time = #{beginTime}</if>
+            <if test="stats != null  and stats != ''"> and stats = #{stats}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnPlanById" parameterType="String" resultMap="LearnPlanResult">
+        <include refid="selectLearnPlanVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnPlan" parameterType="LearnPlan" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_plan
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">studentId,</if>
+            <if test="videoTime != null">video_time,</if>
+            <if test="questionCnt != null">question_cnt,</if>
+            <if test="status != null">status,</if>
+            <if test="beginTime != null">begin_time,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="stats != null">stats,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">#{studentId},</if>
+            <if test="videoTime != null">#{videoTime},</if>
+            <if test="questionCnt != null">#{questionCnt},</if>
+            <if test="status != null">#{status},</if>
+            <if test="beginTime != null">#{beginTime},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="stats != null">#{stats},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnPlan" parameterType="LearnPlan">
+        update learn_plan
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="studentId != null">studentId = #{studentId},</if>
+            <if test="videoTime != null">video_time = #{videoTime},</if>
+            <if test="questionCnt != null">question_cnt = #{questionCnt},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="beginTime != null">begin_time = #{beginTime},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="stats != null">stats = #{stats},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnPlanById" parameterType="String">
+        delete from learn_plan where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnPlanByIds" parameterType="String">
+        delete from learn_plan where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 100 - 0
ie-system/src/main/resources/mapper/learn/LearnPlanStudyMapper.xml

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnPlanStudyMapper">
+    
+    <resultMap type="LearnPlanStudy" id="LearnPlanStudyResult">
+        <result property="id"    column="id"    />
+        <result property="studentId"    column="student_id"    />
+        <result property="planId"    column="plan_id"    />
+        <result property="monthSeq"    column="month_seq"    />
+        <result property="weekSeq"    column="week_seq"    />
+        <result property="reportDate"    column="report_date"    />
+        <result property="questionCount"    column="question_count"    />
+        <result property="videoTime"    column="video_time"    />
+        <result property="questionPlan"    column="question_plan"    />
+        <result property="videoPlan"    column="video_plan"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectLearnPlanStudyVo">
+        select id, student_id, plan_id, month_seq, week_seq, report_date, question_count, video_time, question_plan, video_plan, update_time from learn_plan_study
+    </sql>
+
+    <select id="selectLearnPlanStudyList" parameterType="LearnPlanStudy" resultMap="LearnPlanStudyResult">
+        <include refid="selectLearnPlanStudyVo"/>
+        <where>  
+            <if test="studentId != null "> and student_id = #{studentId}</if>
+            <if test="planId != null "> and plan_id = #{planId}</if>
+            <if test="monthSeq != null "> and month_seq = #{monthSeq}</if>
+            <if test="weekSeq != null "> and week_seq = #{weekSeq}</if>
+            <if test="reportDate != null "> and report_date = #{reportDate}</if>
+            <if test="questionCount != null "> and question_count = #{questionCount}</if>
+            <if test="videoTime != null "> and video_time = #{videoTime}</if>
+            <if test="questionPlan != null "> and question_plan = #{questionPlan}</if>
+            <if test="videoPlan != null "> and video_plan = #{videoPlan}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnPlanStudyById" parameterType="String" resultMap="LearnPlanStudyResult">
+        <include refid="selectLearnPlanStudyVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnPlanStudy" parameterType="LearnPlanStudy" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_plan_study
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">student_id,</if>
+            <if test="planId != null">plan_id,</if>
+            <if test="monthSeq != null">month_seq,</if>
+            <if test="weekSeq != null">week_seq,</if>
+            <if test="reportDate != null">report_date,</if>
+            <if test="questionCount != null">question_count,</if>
+            <if test="videoTime != null">video_time,</if>
+            <if test="questionPlan != null">question_plan,</if>
+            <if test="videoPlan != null">video_plan,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">#{studentId},</if>
+            <if test="planId != null">#{planId},</if>
+            <if test="monthSeq != null">#{monthSeq},</if>
+            <if test="weekSeq != null">#{weekSeq},</if>
+            <if test="reportDate != null">#{reportDate},</if>
+            <if test="questionCount != null">#{questionCount},</if>
+            <if test="videoTime != null">#{videoTime},</if>
+            <if test="questionPlan != null">#{questionPlan},</if>
+            <if test="videoPlan != null">#{videoPlan},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnPlanStudy" parameterType="LearnPlanStudy">
+        update learn_plan_study
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="studentId != null">student_id = #{studentId},</if>
+            <if test="planId != null">plan_id = #{planId},</if>
+            <if test="monthSeq != null">month_seq = #{monthSeq},</if>
+            <if test="weekSeq != null">week_seq = #{weekSeq},</if>
+            <if test="reportDate != null">report_date = #{reportDate},</if>
+            <if test="questionCount != null">question_count = #{questionCount},</if>
+            <if test="videoTime != null">video_time = #{videoTime},</if>
+            <if test="questionPlan != null">question_plan = #{questionPlan},</if>
+            <if test="videoPlan != null">video_plan = #{videoPlan},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnPlanStudyById" parameterType="String">
+        delete from learn_plan_study where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnPlanStudyByIds" parameterType="String">
+        delete from learn_plan_study where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 78 - 0
ie-system/src/main/resources/mapper/learn/LearnQuestionCorrectMapper.xml

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnQuestionCorrectMapper">
+    
+    <resultMap type="LearnQuestionCorrect" id="LearnQuestionCorrectResult">
+        <result property="id"    column="id"    />
+        <result property="questionId"    column="question_id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="remark"    column="remark"    />
+        <result property="state"    column="state"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectLearnQuestionCorrectVo">
+        select id, question_id, user_id, remark, state, create_time, update_time from learn_question_correct
+    </sql>
+
+    <select id="selectLearnQuestionCorrectList" parameterType="LearnQuestionCorrect" resultMap="LearnQuestionCorrectResult">
+        <include refid="selectLearnQuestionCorrectVo"/>
+        <where>  
+            <if test="questionId != null "> and question_id = #{questionId}</if>
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="state != null "> and state = #{state}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnQuestionCorrectById" parameterType="Long" resultMap="LearnQuestionCorrectResult">
+        <include refid="selectLearnQuestionCorrectVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnQuestionCorrect" parameterType="LearnQuestionCorrect" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_question_correct
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="questionId != null">question_id,</if>
+            <if test="userId != null">user_id,</if>
+            <if test="remark != null and remark != ''">remark,</if>
+            <if test="state != null">state,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="questionId != null">#{questionId},</if>
+            <if test="userId != null">#{userId},</if>
+            <if test="remark != null and remark != ''">#{remark},</if>
+            <if test="state != null">#{state},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnQuestionCorrect" parameterType="LearnQuestionCorrect">
+        update learn_question_correct
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="questionId != null">question_id = #{questionId},</if>
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="remark != null and remark != ''">remark = #{remark},</if>
+            <if test="state != null">state = #{state},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnQuestionCorrectById" parameterType="Long">
+        delete from learn_question_correct where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnQuestionCorrectByIds" parameterType="String">
+        delete from learn_question_correct where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 151 - 0
ie-system/src/main/resources/mapper/learn/LearnWrongBookMapper.xml

@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnWrongBookMapper">
+    
+    <resultMap type="LearnWrongBook" id="LearnWrongBookResult">
+        <result property="wrongId"    column="wrong_id"    />
+        <result property="studentId"    column="student_id"    />
+        <result property="questionId"    column="question_id"    />
+        <result property="source"    column="source"    />
+        <result property="state"    column="state"    />
+        <result property="knownledgeId"    column="knownledge_id"    />
+        <result property="subjectId"    column="subject_id"    />
+        <result property="paperId"    column="paper_id"    />
+        <result property="answers"    column="answers"    />
+        <result property="answer1"    column="answer1"    />
+        <result property="answer2"    column="answer2"    />
+        <result property="scoreTotal"    column="score_total"    />
+        <result property="score"    column="score"    />
+        <result property="scoreLevel"    column="score_level"    />
+        <result property="scoreRate"    column="score_rate"    />
+        <result property="wrongCount"    column="wrong_count"    />
+        <result property="rightCount"    column="right_count"    />
+        <result property="totalCount"    column="total_count"    />
+        <result property="createdTime"    column="created_time"    />
+        <result property="updatedTime"    column="updated_time"    />
+        <result property="collect"    column="collect"    />
+    </resultMap>
+
+    <sql id="selectLearnWrongBookVo">
+        select wrong_id, student_id, question_id, source, state, knownledge_id, subject_id, paper_id, answers, answer1, answer2, score_total, score, score_level, score_rate, wrong_count, right_count, total_count, created_time, updated_time, collect from learn_wrong_book
+    </sql>
+
+    <select id="selectLearnWrongBookList" parameterType="LearnWrongBook" resultMap="LearnWrongBookResult">
+        <include refid="selectLearnWrongBookVo"/>
+        <where>  
+            <if test="studentId != null "> and student_id = #{studentId}</if>
+            <if test="questionId != null "> and question_id = #{questionId}</if>
+            <if test="source != null  and source != ''"> and source = #{source}</if>
+            <if test="state != null "> and state = #{state}</if>
+            <if test="knownledgeId != null "> and knownledge_id = #{knownledgeId}</if>
+            <if test="subjectId != null "> and subject_id = #{subjectId}</if>
+            <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="answers != null  and answers != ''"> and answers = #{answers}</if>
+            <if test="answer1 != null  and answer1 != ''"> and answer1 = #{answer1}</if>
+            <if test="answer2 != null  and answer2 != ''"> and answer2 = #{answer2}</if>
+            <if test="scoreTotal != null "> and score_total = #{scoreTotal}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="scoreLevel != null  and scoreLevel != ''"> and score_level = #{scoreLevel}</if>
+            <if test="scoreRate != null "> and score_rate = #{scoreRate}</if>
+            <if test="wrongCount != null "> and wrong_count = #{wrongCount}</if>
+            <if test="rightCount != null "> and right_count = #{rightCount}</if>
+            <if test="totalCount != null "> and total_count = #{totalCount}</if>
+            <if test="createdTime != null "> and created_time = #{createdTime}</if>
+            <if test="updatedTime != null "> and updated_time = #{updatedTime}</if>
+            <if test="collect != null "> and collect = #{collect}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnWrongBookByWrongId" parameterType="Long" resultMap="LearnWrongBookResult">
+        <include refid="selectLearnWrongBookVo"/>
+        where wrong_id = #{wrongId}
+    </select>
+
+    <insert id="insertLearnWrongBook" parameterType="LearnWrongBook" useGeneratedKeys="true" keyProperty="wrongId">
+        insert into learn_wrong_book
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">student_id,</if>
+            <if test="questionId != null">question_id,</if>
+            <if test="source != null">source,</if>
+            <if test="state != null">state,</if>
+            <if test="knownledgeId != null">knownledge_id,</if>
+            <if test="subjectId != null">subject_id,</if>
+            <if test="paperId != null">paper_id,</if>
+            <if test="answers != null">answers,</if>
+            <if test="answer1 != null">answer1,</if>
+            <if test="answer2 != null">answer2,</if>
+            <if test="scoreTotal != null">score_total,</if>
+            <if test="score != null">score,</if>
+            <if test="scoreLevel != null">score_level,</if>
+            <if test="scoreRate != null">score_rate,</if>
+            <if test="wrongCount != null">wrong_count,</if>
+            <if test="rightCount != null">right_count,</if>
+            <if test="totalCount != null">total_count,</if>
+            <if test="createdTime != null">created_time,</if>
+            <if test="updatedTime != null">updated_time,</if>
+            <if test="collect != null">collect,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">#{studentId},</if>
+            <if test="questionId != null">#{questionId},</if>
+            <if test="source != null">#{source},</if>
+            <if test="state != null">#{state},</if>
+            <if test="knownledgeId != null">#{knownledgeId},</if>
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="paperId != null">#{paperId},</if>
+            <if test="answers != null">#{answers},</if>
+            <if test="answer1 != null">#{answer1},</if>
+            <if test="answer2 != null">#{answer2},</if>
+            <if test="scoreTotal != null">#{scoreTotal},</if>
+            <if test="score != null">#{score},</if>
+            <if test="scoreLevel != null">#{scoreLevel},</if>
+            <if test="scoreRate != null">#{scoreRate},</if>
+            <if test="wrongCount != null">#{wrongCount},</if>
+            <if test="rightCount != null">#{rightCount},</if>
+            <if test="totalCount != null">#{totalCount},</if>
+            <if test="createdTime != null">#{createdTime},</if>
+            <if test="updatedTime != null">#{updatedTime},</if>
+            <if test="collect != null">#{collect},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnWrongBook" parameterType="LearnWrongBook">
+        update learn_wrong_book
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="studentId != null">student_id = #{studentId},</if>
+            <if test="questionId != null">question_id = #{questionId},</if>
+            <if test="source != null">source = #{source},</if>
+            <if test="state != null">state = #{state},</if>
+            <if test="knownledgeId != null">knownledge_id = #{knownledgeId},</if>
+            <if test="subjectId != null">subject_id = #{subjectId},</if>
+            <if test="paperId != null">paper_id = #{paperId},</if>
+            <if test="answers != null">answers = #{answers},</if>
+            <if test="answer1 != null">answer1 = #{answer1},</if>
+            <if test="answer2 != null">answer2 = #{answer2},</if>
+            <if test="scoreTotal != null">score_total = #{scoreTotal},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="scoreLevel != null">score_level = #{scoreLevel},</if>
+            <if test="scoreRate != null">score_rate = #{scoreRate},</if>
+            <if test="wrongCount != null">wrong_count = #{wrongCount},</if>
+            <if test="rightCount != null">right_count = #{rightCount},</if>
+            <if test="totalCount != null">total_count = #{totalCount},</if>
+            <if test="createdTime != null">created_time = #{createdTime},</if>
+            <if test="updatedTime != null">updated_time = #{updatedTime},</if>
+            <if test="collect != null">collect = #{collect},</if>
+        </trim>
+        where wrong_id = #{wrongId}
+    </update>
+
+    <delete id="deleteLearnWrongBookByWrongId" parameterType="Long">
+        delete from learn_wrong_book where wrong_id = #{wrongId}
+    </delete>
+
+    <delete id="deleteLearnWrongBookByWrongIds" parameterType="String">
+        delete from learn_wrong_book where wrong_id in 
+        <foreach item="wrongId" collection="array" open="(" separator="," close=")">
+            #{wrongId}
+        </foreach>
+    </delete>
+</mapper>

+ 111 - 0
ie-system/src/main/resources/mapper/learn/LearnWrongDetailMapper.xml

@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.learn.mapper.LearnWrongDetailMapper">
+    
+    <resultMap type="LearnWrongDetail" id="LearnWrongDetailResult">
+        <result property="wrongDetailId"    column="wrong_detail_id"    />
+        <result property="wrongId"    column="wrong_id"    />
+        <result property="createdTime"    column="created_time"    />
+        <result property="source"    column="source"    />
+        <result property="studentId"    column="student_id"    />
+        <result property="subjectId"    column="subject_id"    />
+        <result property="knownledgeId"    column="knownledge_id"    />
+        <result property="examineeId"    column="examinee_id"    />
+        <result property="paperId"    column="paper_id"    />
+        <result property="scoreTotal"    column="score_total"    />
+        <result property="score"    column="score"    />
+        <result property="scoreLevel"    column="score_level"    />
+        <result property="scoreRate"    column="score_rate"    />
+    </resultMap>
+
+    <sql id="selectLearnWrongDetailVo">
+        select wrong_detail_id, wrong_id, created_time, source, student_id, subject_id, knownledge_id, examinee_id, paper_id, score_total, score, score_level, score_rate from learn_wrong_detail
+    </sql>
+
+    <select id="selectLearnWrongDetailList" parameterType="LearnWrongDetail" resultMap="LearnWrongDetailResult">
+        <include refid="selectLearnWrongDetailVo"/>
+        <where>  
+            <if test="wrongId != null "> and wrong_id = #{wrongId}</if>
+            <if test="createdTime != null "> and created_time = #{createdTime}</if>
+            <if test="source != null  and source != ''"> and source = #{source}</if>
+            <if test="studentId != null "> and student_id = #{studentId}</if>
+            <if test="subjectId != null "> and subject_id = #{subjectId}</if>
+            <if test="knownledgeId != null "> and knownledge_id = #{knownledgeId}</if>
+            <if test="examineeId != null "> and examinee_id = #{examineeId}</if>
+            <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="scoreTotal != null "> and score_total = #{scoreTotal}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="scoreLevel != null  and scoreLevel != ''"> and score_level = #{scoreLevel}</if>
+            <if test="scoreRate != null "> and score_rate = #{scoreRate}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnWrongDetailByWrongDetailId" parameterType="Long" resultMap="LearnWrongDetailResult">
+        <include refid="selectLearnWrongDetailVo"/>
+        where wrong_detail_id = #{wrongDetailId}
+    </select>
+
+    <insert id="insertLearnWrongDetail" parameterType="LearnWrongDetail" useGeneratedKeys="true" keyProperty="wrongDetailId">
+        insert into learn_wrong_detail
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="wrongId != null">wrong_id,</if>
+            <if test="createdTime != null">created_time,</if>
+            <if test="source != null">source,</if>
+            <if test="studentId != null">student_id,</if>
+            <if test="subjectId != null">subject_id,</if>
+            <if test="knownledgeId != null">knownledge_id,</if>
+            <if test="examineeId != null">examinee_id,</if>
+            <if test="paperId != null">paper_id,</if>
+            <if test="scoreTotal != null">score_total,</if>
+            <if test="score != null">score,</if>
+            <if test="scoreLevel != null">score_level,</if>
+            <if test="scoreRate != null">score_rate,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="wrongId != null">#{wrongId},</if>
+            <if test="createdTime != null">#{createdTime},</if>
+            <if test="source != null">#{source},</if>
+            <if test="studentId != null">#{studentId},</if>
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="knownledgeId != null">#{knownledgeId},</if>
+            <if test="examineeId != null">#{examineeId},</if>
+            <if test="paperId != null">#{paperId},</if>
+            <if test="scoreTotal != null">#{scoreTotal},</if>
+            <if test="score != null">#{score},</if>
+            <if test="scoreLevel != null">#{scoreLevel},</if>
+            <if test="scoreRate != null">#{scoreRate},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnWrongDetail" parameterType="LearnWrongDetail">
+        update learn_wrong_detail
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="wrongId != null">wrong_id = #{wrongId},</if>
+            <if test="createdTime != null">created_time = #{createdTime},</if>
+            <if test="source != null">source = #{source},</if>
+            <if test="studentId != null">student_id = #{studentId},</if>
+            <if test="subjectId != null">subject_id = #{subjectId},</if>
+            <if test="knownledgeId != null">knownledge_id = #{knownledgeId},</if>
+            <if test="examineeId != null">examinee_id = #{examineeId},</if>
+            <if test="paperId != null">paper_id = #{paperId},</if>
+            <if test="scoreTotal != null">score_total = #{scoreTotal},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="scoreLevel != null">score_level = #{scoreLevel},</if>
+            <if test="scoreRate != null">score_rate = #{scoreRate},</if>
+        </trim>
+        where wrong_detail_id = #{wrongDetailId}
+    </update>
+
+    <delete id="deleteLearnWrongDetailByWrongDetailId" parameterType="Long">
+        delete from learn_wrong_detail where wrong_detail_id = #{wrongDetailId}
+    </delete>
+
+    <delete id="deleteLearnWrongDetailByWrongDetailIds" parameterType="String">
+        delete from learn_wrong_detail where wrong_detail_id in 
+        <foreach item="wrongDetailId" collection="array" open="(" separator="," close=")">
+            #{wrongDetailId}
+        </foreach>
+    </delete>
+</mapper>