瀏覽代碼

生成学习管理-卷、题、学生关系

mingfu 1 月之前
父節點
當前提交
f4c27ce505
共有 64 個文件被更改,包括 8324 次插入0 次删除
  1. 44 0
      back-ui/src/api/learn/paper.js
  2. 44 0
      back-ui/src/api/learn/paper_question.js
  3. 44 0
      back-ui/src/api/learn/paper_real.js
  4. 44 0
      back-ui/src/api/learn/questions.js
  5. 44 0
      back-ui/src/api/learn/student.js
  6. 44 0
      back-ui/src/api/learn/test.js
  7. 44 0
      back-ui/src/api/learn/test_paper.js
  8. 44 0
      back-ui/src/api/learn/test_student.js
  9. 406 0
      back-ui/src/views/learn/paper/index.vue
  10. 296 0
      back-ui/src/views/learn/paper_question/index.vue
  11. 396 0
      back-ui/src/views/learn/paper_real/index.vue
  12. 669 0
      back-ui/src/views/learn/questions/index.vue
  13. 227 0
      back-ui/src/views/learn/student/index.vue
  14. 251 0
      back-ui/src/views/learn/test/index.vue
  15. 291 0
      back-ui/src/views/learn/test_paper/index.vue
  16. 322 0
      back-ui/src/views/learn/test_student/index.vue
  17. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPaperController.java
  18. 106 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPaperQuestionController.java
  19. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPaperRealController.java
  20. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnQuestionsController.java
  21. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnStudentController.java
  22. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTestController.java
  23. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTestPaperController.java
  24. 107 0
      ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTestStudentController.java
  25. 248 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaper.java
  26. 98 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaperQuestion.java
  27. 233 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaperReal.java
  28. 684 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnQuestions.java
  29. 52 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnStudent.java
  30. 68 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnTest.java
  31. 113 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnTestPaper.java
  32. 143 0
      ie-system/src/main/java/com/ruoyi/learn/domain/LearnTestStudent.java
  33. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPaperMapper.java
  34. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPaperQuestionMapper.java
  35. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnPaperRealMapper.java
  36. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnQuestionsMapper.java
  37. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnStudentMapper.java
  38. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnTestMapper.java
  39. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnTestPaperMapper.java
  40. 61 0
      ie-system/src/main/java/com/ruoyi/learn/mapper/LearnTestStudentMapper.java
  41. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnPaperQuestionService.java
  42. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnPaperRealService.java
  43. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnPaperService.java
  44. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnQuestionsService.java
  45. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnStudentService.java
  46. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnTestPaperService.java
  47. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnTestService.java
  48. 61 0
      ie-system/src/main/java/com/ruoyi/learn/service/ILearnTestStudentService.java
  49. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperQuestionServiceImpl.java
  50. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperRealServiceImpl.java
  51. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperServiceImpl.java
  52. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnQuestionsServiceImpl.java
  53. 93 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnStudentServiceImpl.java
  54. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnTestPaperServiceImpl.java
  55. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnTestServiceImpl.java
  56. 95 0
      ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnTestStudentServiceImpl.java
  57. 126 0
      ie-system/src/main/resources/mapper/learn/LearnPaperMapper.xml
  58. 76 0
      ie-system/src/main/resources/mapper/learn/LearnPaperQuestionMapper.xml
  59. 121 0
      ie-system/src/main/resources/mapper/learn/LearnPaperRealMapper.xml
  60. 270 0
      ie-system/src/main/resources/mapper/learn/LearnQuestionsMapper.xml
  61. 58 0
      ie-system/src/main/resources/mapper/learn/LearnStudentMapper.xml
  62. 65 0
      ie-system/src/main/resources/mapper/learn/LearnTestMapper.xml
  63. 80 0
      ie-system/src/main/resources/mapper/learn/LearnTestPaperMapper.xml
  64. 90 0
      ie-system/src/main/resources/mapper/learn/LearnTestStudentMapper.xml

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询试卷列表
+export function listPaper(query) {
+  return request({
+    url: '/learn/paper/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询试卷详细
+export function getPaper(id) {
+  return request({
+    url: '/learn/paper/' + id,
+    method: 'get'
+  })
+}
+
+// 新增试卷
+export function addPaper(data) {
+  return request({
+    url: '/learn/paper',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改试卷
+export function updatePaper(data) {
+  return request({
+    url: '/learn/paper',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除试卷
+export function delPaper(id) {
+  return request({
+    url: '/learn/paper/' + id,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询试卷题关系列表
+export function listPaper_question(query) {
+  return request({
+    url: '/learn/paper_question/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询试卷题关系详细
+export function getPaper_question(id) {
+  return request({
+    url: '/learn/paper_question/' + id,
+    method: 'get'
+  })
+}
+
+// 新增试卷题关系
+export function addPaper_question(data) {
+  return request({
+    url: '/learn/paper_question',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改试卷题关系
+export function updatePaper_question(data) {
+  return request({
+    url: '/learn/paper_question',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除试卷题关系
+export function delPaper_question(id) {
+  return request({
+    url: '/learn/paper_question/' + id,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询真题卷列表
+export function listPaper_real(query) {
+  return request({
+    url: '/learn/paper_real/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询真题卷详细
+export function getPaper_real(id) {
+  return request({
+    url: '/learn/paper_real/' + id,
+    method: 'get'
+  })
+}
+
+// 新增真题卷
+export function addPaper_real(data) {
+  return request({
+    url: '/learn/paper_real',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改真题卷
+export function updatePaper_real(data) {
+  return request({
+    url: '/learn/paper_real',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除真题卷
+export function delPaper_real(id) {
+  return request({
+    url: '/learn/paper_real/' + id,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询试题列表
+export function listQuestions(query) {
+  return request({
+    url: '/learn/questions/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询试题详细
+export function getQuestions(id) {
+  return request({
+    url: '/learn/questions/' + id,
+    method: 'get'
+  })
+}
+
+// 新增试题
+export function addQuestions(data) {
+  return request({
+    url: '/learn/questions',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改试题
+export function updateQuestions(data) {
+  return request({
+    url: '/learn/questions',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除试题
+export function delQuestions(id) {
+  return request({
+    url: '/learn/questions/' + id,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询学生列表
+export function listStudent(query) {
+  return request({
+    url: '/learn/student/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询学生详细
+export function getStudent(studentId) {
+  return request({
+    url: '/learn/student/' + studentId,
+    method: 'get'
+  })
+}
+
+// 新增学生
+export function addStudent(data) {
+  return request({
+    url: '/learn/student',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改学生
+export function updateStudent(data) {
+  return request({
+    url: '/learn/student',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除学生
+export function delStudent(studentId) {
+  return request({
+    url: '/learn/student/' + studentId,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询试卷批次列表
+export function listTest(query) {
+  return request({
+    url: '/learn/test/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询试卷批次详细
+export function getTest(batchId) {
+  return request({
+    url: '/learn/test/' + batchId,
+    method: 'get'
+  })
+}
+
+// 新增试卷批次
+export function addTest(data) {
+  return request({
+    url: '/learn/test',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改试卷批次
+export function updateTest(data) {
+  return request({
+    url: '/learn/test',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除试卷批次
+export function delTest(batchId) {
+  return request({
+    url: '/learn/test/' + batchId,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询批次测试卷列表
+export function listTest_paper(query) {
+  return request({
+    url: '/learn/test_paper/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询批次测试卷详细
+export function getTest_paper(id) {
+  return request({
+    url: '/learn/test_paper/' + id,
+    method: 'get'
+  })
+}
+
+// 新增批次测试卷
+export function addTest_paper(data) {
+  return request({
+    url: '/learn/test_paper',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改批次测试卷
+export function updateTest_paper(data) {
+  return request({
+    url: '/learn/test_paper',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除批次测试卷
+export function delTest_paper(id) {
+  return request({
+    url: '/learn/test_paper/' + id,
+    method: 'delete'
+  })
+}

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

@@ -0,0 +1,44 @@
+import request from '@/utils/request'
+
+// 查询测试学生列表
+export function listTest_student(query) {
+  return request({
+    url: '/learn/test_student/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询测试学生详细
+export function getTest_student(id) {
+  return request({
+    url: '/learn/test_student/' + id,
+    method: 'get'
+  })
+}
+
+// 新增测试学生
+export function addTest_student(data) {
+  return request({
+    url: '/learn/test_student',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改测试学生
+export function updateTest_student(data) {
+  return request({
+    url: '/learn/test_student',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除测试学生
+export function delTest_student(id) {
+  return request({
+    url: '/learn/test_student/' + id,
+    method: 'delete'
+  })
+}

+ 406 - 0
back-ui/src/views/learn/paper/index.vue

@@ -0,0 +1,406 @@
+<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="subjectId">
+        <el-input
+          v-model="queryParams.subjectId"
+          placeholder="请输入科目id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷名称" prop="paperName">
+        <el-input
+          v-model="queryParams.paperName"
+          placeholder="请输入试卷名称"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建年度" prop="year">
+        <el-input
+          v-model="queryParams.year"
+          placeholder="请输入创建年度"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷题数" prop="number">
+        <el-input
+          v-model="queryParams.number"
+          placeholder="请输入试卷题数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷总分数" prop="fenshu">
+        <el-input
+          v-model="queryParams.fenshu"
+          placeholder="请输入试卷总分数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试券来源" prop="paperSource">
+        <el-input
+          v-model="queryParams.paperSource"
+          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="tiid">
+        <el-input
+          v-model="queryParams.tiid"
+          placeholder="请输入标识"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="真题卷id或组卷人id" prop="relateId">
+        <el-input
+          v-model="queryParams.relateId"
+          placeholder="请输入真题卷id或组卷人id"
+          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="createTime">
+        <el-date-picker clearable
+          v-model="queryParams.createTime"
+          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:paper:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:paper:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:paper:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:paper:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="paperList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="${comment}" align="center" prop="id" />
+      <el-table-column label="科目id" align="center" prop="subjectId" />
+      <el-table-column label="试卷名称" align="center" prop="paperName" />
+      <el-table-column label="创建年度" align="center" prop="year" />
+      <el-table-column label="历年真题,模拟卷,必刷题;组卷;练习卷;刷题卷;know_test-知识点,auto-基础题库,high_error-高频错题,smart_test-智能刷题,paper-真题,试卷" align="center" prop="paperType" />
+      <el-table-column label="试卷题数" align="center" prop="number" />
+      <el-table-column label="试卷总分数" align="center" prop="fenshu" />
+      <el-table-column label="试券来源" align="center" prop="paperSource" />
+      <el-table-column label="定向key" align="center" prop="directKey" />
+      <el-table-column label="标识" align="center" prop="tiid" />
+      <el-table-column label="路径" align="center" prop="osspath" />
+      <el-table-column label="源文件名" align="center" prop="filename" />
+      <el-table-column label="真题卷id或组卷人id" align="center" prop="relateId" />
+      <el-table-column label="适用地区" align="center" prop="locations" />
+      <el-table-column label="适用考生" align="center" prop="examineeTypes" />
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <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:paper:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:paper: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="paperRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="科目id" prop="subjectId">
+          <el-input v-model="form.subjectId" placeholder="请输入科目id" />
+        </el-form-item>
+        <el-form-item label="试卷名称" prop="paperName">
+          <el-input v-model="form.paperName" placeholder="请输入试卷名称" />
+        </el-form-item>
+        <el-form-item label="创建年度" prop="year">
+          <el-input v-model="form.year" placeholder="请输入创建年度" />
+        </el-form-item>
+        <el-form-item label="试卷题数" prop="number">
+          <el-input v-model="form.number" placeholder="请输入试卷题数" />
+        </el-form-item>
+        <el-form-item label="试卷总分数" prop="fenshu">
+          <el-input v-model="form.fenshu" placeholder="请输入试卷总分数" />
+        </el-form-item>
+        <el-form-item label="试券来源" prop="paperSource">
+          <el-input v-model="form.paperSource" 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="tiid">
+          <el-input v-model="form.tiid" placeholder="请输入标识" />
+        </el-form-item>
+        <el-form-item label="路径" prop="osspath">
+          <el-input v-model="form.osspath" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="源文件名" prop="filename">
+          <el-input v-model="form.filename" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="真题卷id或组卷人id" prop="relateId">
+          <el-input v-model="form.relateId" placeholder="请输入真题卷id或组卷人id" />
+        </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="Paper">
+import { listPaper, getPaper, delPaper, addPaper, updatePaper } from "@/api/learn/paper"
+
+const { proxy } = getCurrentInstance()
+
+const paperList = 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,
+    subjectId: null,
+    paperName: null,
+    year: null,
+    paperType: null,
+    number: null,
+    fenshu: null,
+    paperSource: null,
+    directKey: null,
+    tiid: null,
+    osspath: null,
+    filename: null,
+    relateId: null,
+    locations: null,
+    examineeTypes: null,
+    createTime: null
+  },
+  rules: {
+    subjectId: [
+      { required: true, message: "科目id不能为空", trigger: "blur" }
+    ],
+    paperSource: [
+      { required: true, message: "试券来源不能为空", trigger: "blur" }
+    ],
+    directKey: [
+      { required: true, message: "定向key不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询试卷列表 */
+function getList() {
+  loading.value = true
+  listPaper(queryParams.value).then(response => {
+    paperList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    subjectId: null,
+    paperName: null,
+    year: null,
+    paperType: null,
+    number: null,
+    fenshu: null,
+    paperSource: null,
+    directKey: null,
+    tiid: null,
+    osspath: null,
+    filename: null,
+    relateId: null,
+    locations: null,
+    examineeTypes: null,
+    createTime: null
+  }
+  proxy.resetForm("paperRef")
+}
+
+/** 搜索按钮操作 */
+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
+  getPaper(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改试卷"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["paperRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updatePaper(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addPaper(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 delPaper(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/paper/export', {
+    ...queryParams.value
+  }, `paper_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 296 - 0
back-ui/src/views/learn/paper_question/index.vue

@@ -0,0 +1,296 @@
+<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="paperId">
+        <el-input
+          v-model="queryParams.paperId"
+          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="score">
+        <el-input
+          v-model="queryParams.score"
+          placeholder="请输入分值"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建时间" prop="createTime">
+        <el-date-picker clearable
+          v-model="queryParams.createTime"
+          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:paper_question:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:paper_question:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:paper_question:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:paper_question:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="paper_questionList" @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="paperId" />
+      <el-table-column label="题id" align="center" prop="questionId" />
+      <el-table-column label="顺序" align="center" prop="seq" />
+      <el-table-column label="分值" align="center" prop="score" />
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <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:paper_question:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:paper_question: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="paper_questionRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="试卷id" prop="paperId">
+          <el-input v-model="form.paperId" 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="score">
+          <el-input v-model="form.score" 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="Paper_question">
+import { listPaper_question, getPaper_question, delPaper_question, addPaper_question, updatePaper_question } from "@/api/learn/paper_question"
+
+const { proxy } = getCurrentInstance()
+
+const paper_questionList = 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,
+    paperId: null,
+    questionId: null,
+    seq: null,
+    score: null,
+    createTime: null
+  },
+  rules: {
+    paperId: [
+      { required: true, message: "试卷id不能为空", trigger: "blur" }
+    ],
+    questionId: [
+      { required: true, message: "题id不能为空", trigger: "blur" }
+    ],
+    seq: [
+      { required: true, message: "顺序不能为空", trigger: "blur" }
+    ],
+    score: [
+      { required: true, message: "分值不能为空", trigger: "blur" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询试卷题关系列表 */
+function getList() {
+  loading.value = true
+  listPaper_question(queryParams.value).then(response => {
+    paper_questionList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    paperId: null,
+    questionId: null,
+    seq: null,
+    score: null,
+    createTime: null
+  }
+  proxy.resetForm("paper_questionRef")
+}
+
+/** 搜索按钮操作 */
+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
+  getPaper_question(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改试卷题关系"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["paper_questionRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updatePaper_question(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addPaper_question(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 delPaper_question(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/paper_question/export', {
+    ...queryParams.value
+  }, `paper_question_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 396 - 0
back-ui/src/views/learn/paper_real/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="subjectId">
+        <el-input
+          v-model="queryParams.subjectId"
+          placeholder="请输入科目ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷名称" prop="paperName">
+        <el-input
+          v-model="queryParams.paperName"
+          placeholder="请输入试卷名称"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷年份" prop="year">
+        <el-input
+          v-model="queryParams.year"
+          placeholder="请输入试卷年份"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷题数" prop="number">
+        <el-input
+          v-model="queryParams.number"
+          placeholder="请输入试卷题数"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试卷总分" prop="fenshu">
+        <el-input
+          v-model="queryParams.fenshu"
+          placeholder="请输入试卷总分"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="0 默认 1 精品试卷" prop="paperSource">
+        <el-input
+          v-model="queryParams.paperSource"
+          placeholder="请输入0 默认 1 精品试卷"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="是否有在线卷" prop="online">
+        <el-input
+          v-model="queryParams.online"
+          placeholder="请输入是否有在线卷"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="唯一标识" prop="tiid">
+        <el-input
+          v-model="queryParams.tiid"
+          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="createTime">
+        <el-date-picker clearable
+          v-model="queryParams.createTime"
+          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:paper_real:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:paper_real:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:paper_real:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:paper_real:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="paper_realList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="${comment}" align="center" prop="id" />
+      <el-table-column label="科目ID" align="center" prop="subjectId" />
+      <el-table-column label="试卷名称" align="center" prop="paperName" />
+      <el-table-column label="试卷年份" align="center" prop="year" />
+      <el-table-column label="历年真题,模拟卷,必刷题" align="center" prop="paperType" />
+      <el-table-column label="试卷题数" align="center" prop="number" />
+      <el-table-column label="试卷总分" align="center" prop="fenshu" />
+      <el-table-column label="0 默认 1 精品试卷" align="center" prop="paperSource" />
+      <el-table-column label="是否有在线卷" align="center" prop="online" />
+      <el-table-column label="唯一标识" align="center" prop="tiid" />
+      <el-table-column label="下载路径" align="center" prop="osspath" />
+      <el-table-column label="原始文件名" align="center" prop="filename" />
+      <el-table-column label="适用地区" align="center" prop="locations" />
+      <el-table-column label="适用考生" align="center" prop="examineeType" />
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+        </template>
+      </el-table-column>
+      <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:paper_real:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:paper_real: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="paper_realRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="科目ID" prop="subjectId">
+          <el-input v-model="form.subjectId" placeholder="请输入科目ID" />
+        </el-form-item>
+        <el-form-item label="试卷名称" prop="paperName">
+          <el-input v-model="form.paperName" placeholder="请输入试卷名称" />
+        </el-form-item>
+        <el-form-item label="试卷年份" prop="year">
+          <el-input v-model="form.year" placeholder="请输入试卷年份" />
+        </el-form-item>
+        <el-form-item label="试卷题数" prop="number">
+          <el-input v-model="form.number" placeholder="请输入试卷题数" />
+        </el-form-item>
+        <el-form-item label="试卷总分" prop="fenshu">
+          <el-input v-model="form.fenshu" placeholder="请输入试卷总分" />
+        </el-form-item>
+        <el-form-item label="0 默认 1 精品试卷" prop="paperSource">
+          <el-input v-model="form.paperSource" placeholder="请输入0 默认 1 精品试卷" />
+        </el-form-item>
+        <el-form-item label="是否有在线卷" prop="online">
+          <el-input v-model="form.online" placeholder="请输入是否有在线卷" />
+        </el-form-item>
+        <el-form-item label="唯一标识" prop="tiid">
+          <el-input v-model="form.tiid" placeholder="请输入唯一标识" />
+        </el-form-item>
+        <el-form-item label="下载路径" prop="osspath">
+          <el-input v-model="form.osspath" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="原始文件名" prop="filename">
+          <el-input v-model="form.filename" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="适用地区" prop="locations">
+          <el-input v-model="form.locations" 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="Paper_real">
+import { listPaper_real, getPaper_real, delPaper_real, addPaper_real, updatePaper_real } from "@/api/learn/paper_real"
+
+const { proxy } = getCurrentInstance()
+
+const paper_realList = 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,
+    subjectId: null,
+    paperName: null,
+    year: null,
+    paperType: null,
+    number: null,
+    fenshu: null,
+    paperSource: null,
+    online: null,
+    tiid: null,
+    osspath: null,
+    filename: null,
+    locations: null,
+    examineeType: null,
+    createTime: null
+  },
+  rules: {
+    subjectId: [
+      { required: true, message: "科目ID不能为空", trigger: "blur" }
+    ],
+    paperName: [
+      { required: true, message: "试卷名称不能为空", trigger: "blur" }
+    ],
+    year: [
+      { required: true, message: "试卷年份不能为空", trigger: "blur" }
+    ],
+    fenshu: [
+      { required: true, message: "试卷总分不能为空", trigger: "blur" }
+    ],
+    paperSource: [
+      { required: true, message: "0 默认 1 精品试卷不能为空", trigger: "blur" }
+    ],
+    online: [
+      { required: true, message: "是否有在线卷不能为空", trigger: "blur" }
+    ],
+    locations: [
+      { required: true, message: "适用地区不能为空", trigger: "blur" }
+    ],
+    examineeType: [
+      { required: true, message: "适用考生不能为空", trigger: "change" }
+    ],
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询真题卷列表 */
+function getList() {
+  loading.value = true
+  listPaper_real(queryParams.value).then(response => {
+    paper_realList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    subjectId: null,
+    paperName: null,
+    year: null,
+    paperType: null,
+    number: null,
+    fenshu: null,
+    paperSource: null,
+    online: null,
+    tiid: null,
+    osspath: null,
+    filename: null,
+    locations: null,
+    examineeType: null,
+    createTime: null
+  }
+  proxy.resetForm("paper_realRef")
+}
+
+/** 搜索按钮操作 */
+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
+  getPaper_real(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改真题卷"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["paper_realRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updatePaper_real(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addPaper_real(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 delPaper_real(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/paper_real/export', {
+    ...queryParams.value
+  }, `paper_real_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 669 - 0
back-ui/src/views/learn/questions/index.vue

@@ -0,0 +1,669 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="类型" prop="qtpye">
+        <el-input
+          v-model="queryParams.qtpye"
+          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="${comment}" prop="paperId">
+        <el-input
+          v-model="queryParams.paperId"
+          placeholder="请输入${comment}"
+          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="${comment}" prop="diff">
+        <el-input
+          v-model="queryParams.diff"
+          placeholder="请输入${comment}"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试题在题库中的相似度,相似度越高,质量越低" prop="similarity">
+        <el-input
+          v-model="queryParams.similarity"
+          placeholder="请输入试题在题库中的相似度,相似度越高,质量越低"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="${comment}" prop="knowId">
+        <el-input
+          v-model="queryParams.knowId"
+          placeholder="请输入${comment}"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="年级ID" prop="gradeId">
+        <el-input
+          v-model="queryParams.gradeId"
+          placeholder="请输入年级ID"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="${comment}" prop="knowledges">
+        <el-input
+          v-model="queryParams.knowledges"
+          placeholder="请输入${comment}"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试题区域" prop="area">
+        <el-input
+          v-model="queryParams.area"
+          placeholder="请输入试题区域"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试题年份" prop="year">
+        <el-input
+          v-model="queryParams.year"
+          placeholder="请输入试题年份"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他" prop="paperTpye">
+        <el-input
+          v-model="queryParams.paperTpye"
+          placeholder="请输入试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他"
+          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="fromSite">
+        <el-input
+          v-model="queryParams.fromSite"
+          placeholder="请输入试题来源"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="是否存在图片水印" prop="isSub">
+        <el-input
+          v-model="queryParams.isSub"
+          placeholder="请输入是否存在图片水印"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1" prop="isNormal">
+        <el-input
+          v-model="queryParams.isNormal"
+          placeholder="请输入是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="是否匹配章节知识点,1匹配,0不匹配" prop="isKonw">
+        <el-input
+          v-model="queryParams.isKonw"
+          placeholder="请输入是否匹配章节知识点,1匹配,0不匹配"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试题的tiid,结合fromsite进行同网站试题排重,用于增量更新" prop="tiid">
+        <el-input
+          v-model="queryParams.tiid"
+          placeholder="请输入试题的tiid,结合fromsite进行同网站试题排重,用于增量更新"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="试题题干的md5值" prop="md5">
+        <el-input
+          v-model="queryParams.md5"
+          placeholder="请输入试题题干的md5值"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="${comment}" prop="isunique">
+        <el-input
+          v-model="queryParams.isunique"
+          placeholder="请输入${comment}"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="${comment}" prop="md52">
+        <el-input
+          v-model="queryParams.md52"
+          placeholder="请输入${comment}"
+          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="${comment}" prop="number">
+        <el-input
+          v-model="queryParams.number"
+          placeholder="请输入${comment}"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="${comment}" prop="paperTypeTitle">
+        <el-input
+          v-model="queryParams.paperTypeTitle"
+          placeholder="请输入${comment}"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="是否更新" prop="isUpdate">
+        <el-input
+          v-model="queryParams.isUpdate"
+          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:questions:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:questions:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:questions:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:questions:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="questionsList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="${comment}" align="center" prop="id" />
+      <el-table-column label="试题-题干" align="center" prop="title" />
+      <el-table-column label="选项A" align="center" prop="optionA" />
+      <el-table-column label="选项B" align="center" prop="optionB" />
+      <el-table-column label="选项C" align="center" prop="optionC" />
+      <el-table-column label="选项D" align="center" prop="optionD" />
+      <el-table-column label="选项E" align="center" prop="optionE" />
+      <el-table-column label="选项D" align="center" prop="optionF" />
+      <el-table-column label="选项E" align="center" prop="optionG" />
+      <el-table-column label="${comment}" align="center" prop="answer1" />
+      <el-table-column label="非标准格式答案或含部分过程说明的答案" align="center" prop="answer2" />
+      <el-table-column label="类型" align="center" prop="qtpye" />
+      <el-table-column label="学科Id" align="center" prop="subjectId" />
+      <el-table-column label="${comment}" align="center" prop="paperId" />
+      <el-table-column label="知识点" align="center" prop="knowledgeId" />
+      <el-table-column label="${comment}" align="center" prop="diff" />
+      <el-table-column label="试题在题库中的相似度,相似度越高,质量越低" align="center" prop="similarity" />
+      <el-table-column label="试题解析" align="center" prop="parse" />
+      <el-table-column label="${comment}" align="center" prop="knowId" />
+      <el-table-column label="年级ID" align="center" prop="gradeId" />
+      <el-table-column label="${comment}" align="center" prop="knowledges" />
+      <el-table-column label="试题区域" align="center" prop="area" />
+      <el-table-column label="试题年份" align="center" prop="year" />
+      <el-table-column label="试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他" align="center" prop="paperTpye" />
+      <el-table-column label="来源" align="center" prop="source" />
+      <el-table-column label="试题来源" align="center" prop="fromSite" />
+      <el-table-column label="是否存在图片水印" align="center" prop="isSub" />
+      <el-table-column label="是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1" align="center" prop="isNormal" />
+      <el-table-column label="是否匹配章节知识点,1匹配,0不匹配" align="center" prop="isKonw" />
+      <el-table-column label="试题的tiid,结合fromsite进行同网站试题排重,用于增量更新" align="center" prop="tiid" />
+      <el-table-column label="试题题干的md5值" align="center" prop="md5" />
+      <el-table-column label="${comment}" align="center" prop="isunique" />
+      <el-table-column label="${comment}" align="center" prop="md52" />
+      <el-table-column label="得分" align="center" prop="score" />
+      <el-table-column label="选项" align="center" prop="options" />
+      <el-table-column label="${comment}" align="center" prop="number" />
+      <el-table-column label="${comment}" align="center" prop="paperTypeTitle" />
+      <el-table-column label="选项" align="center" prop="options0" />
+      <el-table-column label="试题-材料题题干" align="center" prop="title0" />
+      <el-table-column label="试题-材料题题干" align="center" prop="title1" />
+      <el-table-column label="试题解析" align="center" prop="parse0" />
+      <el-table-column label="${comment}" align="center" prop="answer0" />
+      <el-table-column label="是否更新" align="center" prop="isUpdate" />
+      <el-table-column label="子题类型" align="center" prop="isSubType" />
+      <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:questions:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:questions: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="questionsRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="试题-题干" prop="title">
+          <el-input v-model="form.title" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项A" prop="optionA">
+          <el-input v-model="form.optionA" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项B" prop="optionB">
+          <el-input v-model="form.optionB" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项C" prop="optionC">
+          <el-input v-model="form.optionC" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项D" prop="optionD">
+          <el-input v-model="form.optionD" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项E" prop="optionE">
+          <el-input v-model="form.optionE" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项D" prop="optionF">
+          <el-input v-model="form.optionF" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="选项E" prop="optionG">
+          <el-input v-model="form.optionG" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="answer1">
+          <el-input v-model="form.answer1" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="非标准格式答案或含部分过程说明的答案" prop="answer2">
+          <el-input v-model="form.answer2" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="类型" prop="qtpye">
+          <el-input v-model="form.qtpye" placeholder="请输入类型" />
+        </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="${comment}" prop="paperId">
+          <el-input v-model="form.paperId" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="知识点" prop="knowledgeId">
+          <el-input v-model="form.knowledgeId" placeholder="请输入知识点" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="diff">
+          <el-input v-model="form.diff" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="试题在题库中的相似度,相似度越高,质量越低" prop="similarity">
+          <el-input v-model="form.similarity" placeholder="请输入试题在题库中的相似度,相似度越高,质量越低" />
+        </el-form-item>
+        <el-form-item label="试题解析" prop="parse">
+          <el-input v-model="form.parse" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="knowId">
+          <el-input v-model="form.knowId" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="年级ID" prop="gradeId">
+          <el-input v-model="form.gradeId" placeholder="请输入年级ID" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="knowledges">
+          <el-input v-model="form.knowledges" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="试题区域" prop="area">
+          <el-input v-model="form.area" placeholder="请输入试题区域" />
+        </el-form-item>
+        <el-form-item label="试题年份" prop="year">
+          <el-input v-model="form.year" placeholder="请输入试题年份" />
+        </el-form-item>
+        <el-form-item label="试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他" prop="paperTpye">
+          <el-input v-model="form.paperTpye" placeholder="请输入试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他" />
+        </el-form-item>
+        <el-form-item label="来源" prop="source">
+          <el-input v-model="form.source" placeholder="请输入来源" />
+        </el-form-item>
+        <el-form-item label="试题来源" prop="fromSite">
+          <el-input v-model="form.fromSite" placeholder="请输入试题来源" />
+        </el-form-item>
+        <el-form-item label="是否存在图片水印" prop="isSub">
+          <el-input v-model="form.isSub" placeholder="请输入是否存在图片水印" />
+        </el-form-item>
+        <el-form-item label="是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1" prop="isNormal">
+          <el-input v-model="form.isNormal" placeholder="请输入是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1" />
+        </el-form-item>
+        <el-form-item label="是否匹配章节知识点,1匹配,0不匹配" prop="isKonw">
+          <el-input v-model="form.isKonw" placeholder="请输入是否匹配章节知识点,1匹配,0不匹配" />
+        </el-form-item>
+        <el-form-item label="试题的tiid,结合fromsite进行同网站试题排重,用于增量更新" prop="tiid">
+          <el-input v-model="form.tiid" placeholder="请输入试题的tiid,结合fromsite进行同网站试题排重,用于增量更新" />
+        </el-form-item>
+        <el-form-item label="试题题干的md5值" prop="md5">
+          <el-input v-model="form.md5" placeholder="请输入试题题干的md5值" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="isunique">
+          <el-input v-model="form.isunique" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="md52">
+          <el-input v-model="form.md52" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="得分" prop="score">
+          <el-input v-model="form.score" placeholder="请输入得分" />
+        </el-form-item>
+        <el-form-item label="选项" prop="options">
+          <el-input v-model="form.options" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="number">
+          <el-input v-model="form.number" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="paperTypeTitle">
+          <el-input v-model="form.paperTypeTitle" placeholder="请输入${comment}" />
+        </el-form-item>
+        <el-form-item label="选项" prop="options0">
+          <el-input v-model="form.options0" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="试题-材料题题干" prop="title0">
+          <el-input v-model="form.title0" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="试题-材料题题干" prop="title1">
+          <el-input v-model="form.title1" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="试题解析" prop="parse0">
+          <el-input v-model="form.parse0" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="${comment}" prop="answer0">
+          <el-input v-model="form.answer0" type="textarea" placeholder="请输入内容" />
+        </el-form-item>
+        <el-form-item label="是否更新" prop="isUpdate">
+          <el-input v-model="form.isUpdate" 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="Questions">
+import { listQuestions, getQuestions, delQuestions, addQuestions, updateQuestions } from "@/api/learn/questions"
+
+const { proxy } = getCurrentInstance()
+
+const questionsList = 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,
+    title: null,
+    optionA: null,
+    optionB: null,
+    optionC: null,
+    optionD: null,
+    optionE: null,
+    optionF: null,
+    optionG: null,
+    answer1: null,
+    answer2: null,
+    qtpye: null,
+    subjectId: null,
+    paperId: null,
+    knowledgeId: null,
+    diff: null,
+    similarity: null,
+    parse: null,
+    knowId: null,
+    gradeId: null,
+    knowledges: null,
+    area: null,
+    year: null,
+    paperTpye: null,
+    source: null,
+    fromSite: null,
+    isSub: null,
+    isNormal: null,
+    isKonw: null,
+    tiid: null,
+    md5: null,
+    isunique: null,
+    md52: null,
+    score: null,
+    options: null,
+    number: null,
+    paperTypeTitle: null,
+    options0: null,
+    title0: null,
+    title1: null,
+    parse0: null,
+    answer0: null,
+    isUpdate: null,
+    isSubType: null
+  },
+  rules: {
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询试题列表 */
+function getList() {
+  loading.value = true
+  listQuestions(queryParams.value).then(response => {
+    questionsList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    title: null,
+    optionA: null,
+    optionB: null,
+    optionC: null,
+    optionD: null,
+    optionE: null,
+    optionF: null,
+    optionG: null,
+    answer1: null,
+    answer2: null,
+    qtpye: null,
+    subjectId: null,
+    paperId: null,
+    knowledgeId: null,
+    diff: null,
+    similarity: null,
+    parse: null,
+    knowId: null,
+    gradeId: null,
+    knowledges: null,
+    area: null,
+    year: null,
+    paperTpye: null,
+    source: null,
+    fromSite: null,
+    isSub: null,
+    isNormal: null,
+    isKonw: null,
+    tiid: null,
+    md5: null,
+    isunique: null,
+    md52: null,
+    createTime: null,
+    score: null,
+    options: null,
+    number: null,
+    paperTypeTitle: null,
+    options0: null,
+    title0: null,
+    title1: null,
+    parse0: null,
+    answer0: null,
+    isUpdate: null,
+    isSubType: null
+  }
+  proxy.resetForm("questionsRef")
+}
+
+/** 搜索按钮操作 */
+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
+  getQuestions(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改试题"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["questionsRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateQuestions(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addQuestions(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 delQuestions(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/questions/export', {
+    ...queryParams.value
+  }, `questions_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 227 - 0
back-ui/src/views/learn/student/index.vue

@@ -0,0 +1,227 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+      <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>
+        <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:student:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:student:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:student:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:student:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="studentList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="学生用户ID" align="center" prop="studentId" />
+      <el-table-column label="定向Key" align="center" prop="directKey" />
+      <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:student:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:student: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="studentRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="定向Key" prop="directKey">
+          <el-input v-model="form.directKey" placeholder="请输入定向Key" />
+        </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="Student">
+import { listStudent, getStudent, delStudent, addStudent, updateStudent } from "@/api/learn/student"
+
+const { proxy } = getCurrentInstance()
+
+const studentList = 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,
+    directKey: null
+  },
+  rules: {
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询学生列表 */
+function getList() {
+  loading.value = true
+  listStudent(queryParams.value).then(response => {
+    studentList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    studentId: null,
+    directKey: null
+  }
+  proxy.resetForm("studentRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.studentId)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加学生"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _studentId = row.studentId || ids.value
+  getStudent(_studentId).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改学生"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["studentRef"].validate(valid => {
+    if (valid) {
+      if (form.value.studentId != null) {
+        updateStudent(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addStudent(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _studentIds = row.studentId || ids.value
+  proxy.$modal.confirm('是否确认删除学生编号为"' + _studentIds + '"的数据项?').then(function() {
+    return delStudent(_studentIds)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/student/export', {
+    ...queryParams.value
+  }, `student_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 251 - 0
back-ui/src/views/learn/test/index.vue

@@ -0,0 +1,251 @@
+<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="创建人" prop="creatorId">
+        <el-input
+          v-model="queryParams.creatorId"
+          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:test:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:test:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:test:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:test:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="testList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center" />
+      <el-table-column label="考卷批次" align="center" prop="batchId" />
+      <el-table-column label="批次名称" align="center" prop="name" />
+      <el-table-column label="创建人" align="center" prop="creatorId" />
+      <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:test:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:test: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="testRef" :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="创建人" prop="creatorId">
+          <el-input v-model="form.creatorId" 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="Test">
+import { listTest, getTest, delTest, addTest, updateTest } from "@/api/learn/test"
+
+const { proxy } = getCurrentInstance()
+
+const testList = 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,
+    creatorId: null,
+  },
+  rules: {
+    name: [
+      { required: true, message: "批次名称不能为空", trigger: "blur" }
+    ],
+    creatorId: [
+      { required: true, message: "创建人不能为空", trigger: "blur" }
+    ],
+    createTime: [
+      { required: true, message: "创建时间不能为空", trigger: "blur" }
+    ]
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询试卷批次列表 */
+function getList() {
+  loading.value = true
+  listTest(queryParams.value).then(response => {
+    testList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    batchId: null,
+    name: null,
+    creatorId: null,
+    createTime: null
+  }
+  proxy.resetForm("testRef")
+}
+
+/** 搜索按钮操作 */
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+function resetQuery() {
+  proxy.resetForm("queryRef")
+  handleQuery()
+}
+
+// 多选框选中数据
+function handleSelectionChange(selection) {
+  ids.value = selection.map(item => item.batchId)
+  single.value = selection.length != 1
+  multiple.value = !selection.length
+}
+
+/** 新增按钮操作 */
+function handleAdd() {
+  reset()
+  open.value = true
+  title.value = "添加试卷批次"
+}
+
+/** 修改按钮操作 */
+function handleUpdate(row) {
+  reset()
+  const _batchId = row.batchId || ids.value
+  getTest(_batchId).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改试卷批次"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["testRef"].validate(valid => {
+    if (valid) {
+      if (form.value.batchId != null) {
+        updateTest(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addTest(form.value).then(response => {
+          proxy.$modal.msgSuccess("新增成功")
+          open.value = false
+          getList()
+        })
+      }
+    }
+  })
+}
+
+/** 删除按钮操作 */
+function handleDelete(row) {
+  const _batchIds = row.batchId || ids.value
+  proxy.$modal.confirm('是否确认删除试卷批次编号为"' + _batchIds + '"的数据项?').then(function() {
+    return delTest(_batchIds)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/test/export', {
+    ...queryParams.value
+  }, `test_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 291 - 0
back-ui/src/views/learn/test_paper/index.vue

@@ -0,0 +1,291 @@
+<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="batchId">
+        <el-input
+          v-model="queryParams.batchId"
+          placeholder="请输入批次id"
+          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="卷id" prop="paperId">
+        <el-input
+          v-model="queryParams.paperId"
+          placeholder="请输入卷id"
+          clearable
+          @keyup.enter="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="创建人" prop="creatorId">
+        <el-input
+          v-model="queryParams.creatorId"
+          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:test_paper:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:test_paper:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:test_paper:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:test_paper:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="test_paperList" @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="batchId" />
+      <el-table-column label="定向key" align="center" prop="directKey" />
+      <el-table-column label="卷id" align="center" prop="paperId" />
+      <el-table-column label="试卷生成条件" align="center" prop="condions" />
+      <el-table-column label="创建人" align="center" prop="creatorId" />
+      <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:test_paper:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:test_paper: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="test_paperRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="批次id" prop="batchId">
+          <el-input v-model="form.batchId" placeholder="请输入批次id" />
+        </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="卷id" prop="paperId">
+          <el-input v-model="form.paperId" placeholder="请输入卷id" />
+        </el-form-item>
+        <el-form-item label="创建人" prop="creatorId">
+          <el-input v-model="form.creatorId" 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="Test_paper">
+import { listTest_paper, getTest_paper, delTest_paper, addTest_paper, updateTest_paper } from "@/api/learn/test_paper"
+
+const { proxy } = getCurrentInstance()
+
+const test_paperList = 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,
+    batchId: null,
+    directKey: null,
+    paperId: null,
+    condions: null,
+    creatorId: null,
+  },
+  rules: {
+    batchId: [
+      { required: true, message: "批次id不能为空", trigger: "blur" }
+    ],
+    directKey: [
+      { required: true, message: "定向key不能为空", trigger: "blur" }
+    ],
+    paperId: [
+      { required: true, message: "卷id不能为空", trigger: "blur" }
+    ],
+    condions: [
+      { required: true, message: "试卷生成条件不能为空", trigger: "blur" }
+    ],
+    creatorId: [
+      { required: true, message: "创建人不能为空", trigger: "blur" }
+    ],
+    createTime: [
+      { required: true, message: "创建时间不能为空", trigger: "blur" }
+    ]
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询批次测试卷列表 */
+function getList() {
+  loading.value = true
+  listTest_paper(queryParams.value).then(response => {
+    test_paperList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    batchId: null,
+    directKey: null,
+    paperId: null,
+    condions: null,
+    creatorId: null,
+    createTime: null
+  }
+  proxy.resetForm("test_paperRef")
+}
+
+/** 搜索按钮操作 */
+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
+  getTest_paper(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改批次测试卷"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["test_paperRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateTest_paper(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addTest_paper(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 delTest_paper(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/test_paper/export', {
+    ...queryParams.value
+  }, `test_paper_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 322 - 0
back-ui/src/views/learn/test_student/index.vue

@@ -0,0 +1,322 @@
+<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="batchId">
+        <el-input
+          v-model="queryParams.batchId"
+          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="定向标识学生可能有多个" prop="directKey">
+        <el-input
+          v-model="queryParams.directKey"
+          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="classId">
+        <el-input
+          v-model="queryParams.classId"
+          placeholder="请输入学生班级"
+          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>
+        <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:test_student:add']"
+        >新增</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          plain
+          icon="Edit"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['learn:test_student:edit']"
+        >修改</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          plain
+          icon="Delete"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['learn:test_student:remove']"
+        >删除</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          v-hasPermi="['learn:test_student:export']"
+        >导出</el-button>
+      </el-col>
+      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="test_studentList" @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="batchId" />
+      <el-table-column label="学生id" align="center" prop="studentId" />
+      <el-table-column label="定向标识学生可能有多个" align="center" prop="directKey" />
+      <el-table-column label="批次卷id" align="center" prop="paperId" />
+      <el-table-column label="学生班级" align="center" prop="classId" />
+      <el-table-column label="考卷ID" align="center" prop="examineeId" />
+      <el-table-column label="状态" align="center" prop="status" />
+      <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:test_student:edit']">修改</el-button>
+          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['learn:test_student: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="test_studentRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="批次id" prop="batchId">
+          <el-input v-model="form.batchId" 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="定向标识学生可能有多个" prop="directKey">
+          <el-input v-model="form.directKey" 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="classId">
+          <el-input v-model="form.classId" placeholder="请输入学生班级" />
+        </el-form-item>
+        <el-form-item label="考卷ID" prop="examineeId">
+          <el-input v-model="form.examineeId" placeholder="请输入考卷ID" />
+        </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="Test_student">
+import { listTest_student, getTest_student, delTest_student, addTest_student, updateTest_student } from "@/api/learn/test_student"
+
+const { proxy } = getCurrentInstance()
+
+const test_studentList = 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,
+    batchId: null,
+    studentId: null,
+    directKey: null,
+    paperId: null,
+    classId: null,
+    examineeId: null,
+    status: null,
+  },
+  rules: {
+    batchId: [
+      { required: true, message: "批次id不能为空", trigger: "blur" }
+    ],
+    studentId: [
+      { required: true, message: "学生id不能为空", trigger: "blur" }
+    ],
+    directKey: [
+      { required: true, message: "定向标识学生可能有多个不能为空", trigger: "blur" }
+    ],
+    paperId: [
+      { required: true, message: "批次卷id不能为空", trigger: "blur" }
+    ],
+    classId: [
+      { required: true, message: "学生班级不能为空", trigger: "blur" }
+    ],
+    status: [
+      { required: true, message: "状态不能为空", trigger: "change" }
+    ],
+    createTime: [
+      { required: true, message: "发布时间不能为空", trigger: "blur" }
+    ]
+  }
+})
+
+const { queryParams, form, rules } = toRefs(data)
+
+/** 查询测试学生列表 */
+function getList() {
+  loading.value = true
+  listTest_student(queryParams.value).then(response => {
+    test_studentList.value = response.rows
+    total.value = response.total
+    loading.value = false
+  })
+}
+
+// 取消按钮
+function cancel() {
+  open.value = false
+  reset()
+}
+
+// 表单重置
+function reset() {
+  form.value = {
+    id: null,
+    batchId: null,
+    studentId: null,
+    directKey: null,
+    paperId: null,
+    classId: null,
+    examineeId: null,
+    status: null,
+    createTime: null
+  }
+  proxy.resetForm("test_studentRef")
+}
+
+/** 搜索按钮操作 */
+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
+  getTest_student(_id).then(response => {
+    form.value = response.data
+    open.value = true
+    title.value = "修改测试学生"
+  })
+}
+
+/** 提交按钮 */
+function submitForm() {
+  proxy.$refs["test_studentRef"].validate(valid => {
+    if (valid) {
+      if (form.value.id != null) {
+        updateTest_student(form.value).then(response => {
+          proxy.$modal.msgSuccess("修改成功")
+          open.value = false
+          getList()
+        })
+      } else {
+        addTest_student(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 delTest_student(_ids)
+  }).then(() => {
+    getList()
+    proxy.$modal.msgSuccess("删除成功")
+  }).catch(() => {})
+}
+
+/** 导出按钮操作 */
+function handleExport() {
+  proxy.download('learn/test_student/export', {
+    ...queryParams.value
+  }, `test_student_${new Date().getTime()}.xlsx`)
+}
+
+getList()
+</script>

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPaperController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnPaper;
+import com.ruoyi.learn.service.ILearnPaperService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 试卷Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/paper")
+@Api("后台-学习 - 卷")
+public class LearnPaperController extends BaseController
+{
+    @Autowired
+    private ILearnPaperService learnPaperService;
+
+    /**
+     * 查询试卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnPaper learnPaper)
+    {
+        startPage();
+        List<LearnPaper> list = learnPaperService.selectLearnPaperList(learnPaper);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出试卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper:export')")
+    @Log(title = "试卷", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnPaper learnPaper)
+    {
+        List<LearnPaper> list = learnPaperService.selectLearnPaperList(learnPaper);
+        ExcelUtil<LearnPaper> util = new ExcelUtil<LearnPaper>(LearnPaper.class);
+        util.exportExcel(response, list, "试卷数据");
+    }
+
+    /**
+     * 获取试卷详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnPaperService.selectLearnPaperById(id));
+    }
+
+    /**
+     * 新增试卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper:add')")
+    @Log(title = "试卷", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnPaper learnPaper)
+    {
+        return toAjax(learnPaperService.insertLearnPaper(learnPaper));
+    }
+
+    /**
+     * 修改试卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper:edit')")
+    @Log(title = "试卷", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnPaper learnPaper)
+    {
+        return toAjax(learnPaperService.updateLearnPaper(learnPaper));
+    }
+
+    /**
+     * 删除试卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper:remove')")
+    @Log(title = "试卷", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnPaperService.deleteLearnPaperByIds(ids));
+    }
+}

+ 106 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPaperQuestionController.java

@@ -0,0 +1,106 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnPaperQuestion;
+import com.ruoyi.learn.service.ILearnPaperQuestionService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 试卷题关系Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/paper_question")
+public class LearnPaperQuestionController extends BaseController
+{
+    @Autowired
+    private ILearnPaperQuestionService learnPaperQuestionService;
+
+    /**
+     * 查询试卷题关系列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_question:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnPaperQuestion learnPaperQuestion)
+    {
+        startPage();
+        List<LearnPaperQuestion> list = learnPaperQuestionService.selectLearnPaperQuestionList(learnPaperQuestion);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出试卷题关系列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_question:export')")
+    @Log(title = "试卷题关系", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnPaperQuestion learnPaperQuestion)
+    {
+        List<LearnPaperQuestion> list = learnPaperQuestionService.selectLearnPaperQuestionList(learnPaperQuestion);
+        ExcelUtil<LearnPaperQuestion> util = new ExcelUtil<LearnPaperQuestion>(LearnPaperQuestion.class);
+        util.exportExcel(response, list, "试卷题关系数据");
+    }
+
+    /**
+     * 获取试卷题关系详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_question:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnPaperQuestionService.selectLearnPaperQuestionById(id));
+    }
+
+    /**
+     * 新增试卷题关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_question:add')")
+    @Log(title = "试卷题关系", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnPaperQuestion learnPaperQuestion)
+    {
+        return toAjax(learnPaperQuestionService.insertLearnPaperQuestion(learnPaperQuestion));
+    }
+
+    /**
+     * 修改试卷题关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_question:edit')")
+    @Log(title = "试卷题关系", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnPaperQuestion learnPaperQuestion)
+    {
+        return toAjax(learnPaperQuestionService.updateLearnPaperQuestion(learnPaperQuestion));
+    }
+
+    /**
+     * 删除试卷题关系
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_question:remove')")
+    @Log(title = "试卷题关系", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnPaperQuestionService.deleteLearnPaperQuestionByIds(ids));
+    }
+}

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnPaperRealController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnPaperReal;
+import com.ruoyi.learn.service.ILearnPaperRealService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 真题卷Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/paper_real")
+@Api("后台-学习 - 真题")
+public class LearnPaperRealController extends BaseController
+{
+    @Autowired
+    private ILearnPaperRealService learnPaperRealService;
+
+    /**
+     * 查询真题卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_real:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnPaperReal learnPaperReal)
+    {
+        startPage();
+        List<LearnPaperReal> list = learnPaperRealService.selectLearnPaperRealList(learnPaperReal);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出真题卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_real:export')")
+    @Log(title = "真题卷", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnPaperReal learnPaperReal)
+    {
+        List<LearnPaperReal> list = learnPaperRealService.selectLearnPaperRealList(learnPaperReal);
+        ExcelUtil<LearnPaperReal> util = new ExcelUtil<LearnPaperReal>(LearnPaperReal.class);
+        util.exportExcel(response, list, "真题卷数据");
+    }
+
+    /**
+     * 获取真题卷详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_real:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnPaperRealService.selectLearnPaperRealById(id));
+    }
+
+    /**
+     * 新增真题卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_real:add')")
+    @Log(title = "真题卷", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnPaperReal learnPaperReal)
+    {
+        return toAjax(learnPaperRealService.insertLearnPaperReal(learnPaperReal));
+    }
+
+    /**
+     * 修改真题卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_real:edit')")
+    @Log(title = "真题卷", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnPaperReal learnPaperReal)
+    {
+        return toAjax(learnPaperRealService.updateLearnPaperReal(learnPaperReal));
+    }
+
+    /**
+     * 删除真题卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:paper_real:remove')")
+    @Log(title = "真题卷", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnPaperRealService.deleteLearnPaperRealByIds(ids));
+    }
+}

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnQuestionsController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnQuestions;
+import com.ruoyi.learn.service.ILearnQuestionsService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 试题Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/questions")
+@Api("后台-学习 - 题")
+public class LearnQuestionsController extends BaseController
+{
+    @Autowired
+    private ILearnQuestionsService learnQuestionsService;
+
+    /**
+     * 查询试题列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questions:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnQuestions learnQuestions)
+    {
+        startPage();
+        List<LearnQuestions> list = learnQuestionsService.selectLearnQuestionsList(learnQuestions);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出试题列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questions:export')")
+    @Log(title = "试题", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnQuestions learnQuestions)
+    {
+        List<LearnQuestions> list = learnQuestionsService.selectLearnQuestionsList(learnQuestions);
+        ExcelUtil<LearnQuestions> util = new ExcelUtil<LearnQuestions>(LearnQuestions.class);
+        util.exportExcel(response, list, "试题数据");
+    }
+
+    /**
+     * 获取试题详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questions:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(learnQuestionsService.selectLearnQuestionsById(id));
+    }
+
+    /**
+     * 新增试题
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questions:add')")
+    @Log(title = "试题", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnQuestions learnQuestions)
+    {
+        return toAjax(learnQuestionsService.insertLearnQuestions(learnQuestions));
+    }
+
+    /**
+     * 修改试题
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questions:edit')")
+    @Log(title = "试题", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnQuestions learnQuestions)
+    {
+        return toAjax(learnQuestionsService.updateLearnQuestions(learnQuestions));
+    }
+
+    /**
+     * 删除试题
+     */
+    @PreAuthorize("@ss.hasPermi('learn:questions:remove')")
+    @Log(title = "试题", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(learnQuestionsService.deleteLearnQuestionsByIds(ids));
+    }
+}

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnStudentController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnStudent;
+import com.ruoyi.learn.service.ILearnStudentService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 学生Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/student")
+@Api("后台-学习 - 学生")
+public class LearnStudentController extends BaseController
+{
+    @Autowired
+    private ILearnStudentService learnStudentService;
+
+    /**
+     * 查询学生列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:student:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnStudent learnStudent)
+    {
+        startPage();
+        List<LearnStudent> list = learnStudentService.selectLearnStudentList(learnStudent);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出学生列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:student:export')")
+    @Log(title = "学生", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnStudent learnStudent)
+    {
+        List<LearnStudent> list = learnStudentService.selectLearnStudentList(learnStudent);
+        ExcelUtil<LearnStudent> util = new ExcelUtil<LearnStudent>(LearnStudent.class);
+        util.exportExcel(response, list, "学生数据");
+    }
+
+    /**
+     * 获取学生详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:student:query')")
+    @GetMapping(value = "/{studentId}")
+    public AjaxResult getInfo(@PathVariable("studentId") Long studentId)
+    {
+        return success(learnStudentService.selectLearnStudentByStudentId(studentId));
+    }
+
+    /**
+     * 新增学生
+     */
+    @PreAuthorize("@ss.hasPermi('learn:student:add')")
+    @Log(title = "学生", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnStudent learnStudent)
+    {
+        return toAjax(learnStudentService.insertLearnStudent(learnStudent));
+    }
+
+    /**
+     * 修改学生
+     */
+    @PreAuthorize("@ss.hasPermi('learn:student:edit')")
+    @Log(title = "学生", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnStudent learnStudent)
+    {
+        return toAjax(learnStudentService.updateLearnStudent(learnStudent));
+    }
+
+    /**
+     * 删除学生
+     */
+    @PreAuthorize("@ss.hasPermi('learn:student:remove')")
+    @Log(title = "学生", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{studentIds}")
+    public AjaxResult remove(@PathVariable Long[] studentIds)
+    {
+        return toAjax(learnStudentService.deleteLearnStudentByStudentIds(studentIds));
+    }
+}

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTestController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnTest;
+import com.ruoyi.learn.service.ILearnTestService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 试卷批次Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/test")
+@Api("后台-学习 - 批次")
+public class LearnTestController extends BaseController
+{
+    @Autowired
+    private ILearnTestService learnTestService;
+
+    /**
+     * 查询试卷批次列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnTest learnTest)
+    {
+        startPage();
+        List<LearnTest> list = learnTestService.selectLearnTestList(learnTest);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出试卷批次列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test:export')")
+    @Log(title = "试卷批次", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnTest learnTest)
+    {
+        List<LearnTest> list = learnTestService.selectLearnTestList(learnTest);
+        ExcelUtil<LearnTest> util = new ExcelUtil<LearnTest>(LearnTest.class);
+        util.exportExcel(response, list, "试卷批次数据");
+    }
+
+    /**
+     * 获取试卷批次详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test:query')")
+    @GetMapping(value = "/{batchId}")
+    public AjaxResult getInfo(@PathVariable("batchId") String batchId)
+    {
+        return success(learnTestService.selectLearnTestByBatchId(batchId));
+    }
+
+    /**
+     * 新增试卷批次
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test:add')")
+    @Log(title = "试卷批次", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnTest learnTest)
+    {
+        return toAjax(learnTestService.insertLearnTest(learnTest));
+    }
+
+    /**
+     * 修改试卷批次
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test:edit')")
+    @Log(title = "试卷批次", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnTest learnTest)
+    {
+        return toAjax(learnTestService.updateLearnTest(learnTest));
+    }
+
+    /**
+     * 删除试卷批次
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test:remove')")
+    @Log(title = "试卷批次", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{batchIds}")
+    public AjaxResult remove(@PathVariable String[] batchIds)
+    {
+        return toAjax(learnTestService.deleteLearnTestByBatchIds(batchIds));
+    }
+}

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTestPaperController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnTestPaper;
+import com.ruoyi.learn.service.ILearnTestPaperService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 批次测试卷Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/test_paper")
+@Api("后台-学习 - 批次卷管理")
+public class LearnTestPaperController extends BaseController
+{
+    @Autowired
+    private ILearnTestPaperService learnTestPaperService;
+
+    /**
+     * 查询批次测试卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_paper:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnTestPaper learnTestPaper)
+    {
+        startPage();
+        List<LearnTestPaper> list = learnTestPaperService.selectLearnTestPaperList(learnTestPaper);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出批次测试卷列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_paper:export')")
+    @Log(title = "批次测试卷", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnTestPaper learnTestPaper)
+    {
+        List<LearnTestPaper> list = learnTestPaperService.selectLearnTestPaperList(learnTestPaper);
+        ExcelUtil<LearnTestPaper> util = new ExcelUtil<LearnTestPaper>(LearnTestPaper.class);
+        util.exportExcel(response, list, "批次测试卷数据");
+    }
+
+    /**
+     * 获取批次测试卷详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_paper:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return success(learnTestPaperService.selectLearnTestPaperById(id));
+    }
+
+    /**
+     * 新增批次测试卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_paper:add')")
+    @Log(title = "批次测试卷", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnTestPaper learnTestPaper)
+    {
+        return toAjax(learnTestPaperService.insertLearnTestPaper(learnTestPaper));
+    }
+
+    /**
+     * 修改批次测试卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_paper:edit')")
+    @Log(title = "批次测试卷", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnTestPaper learnTestPaper)
+    {
+        return toAjax(learnTestPaperService.updateLearnTestPaper(learnTestPaper));
+    }
+
+    /**
+     * 删除批次测试卷
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_paper:remove')")
+    @Log(title = "批次测试卷", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        return toAjax(learnTestPaperService.deleteLearnTestPaperByIds(ids));
+    }
+}

+ 107 - 0
ie-admin/src/main/java/com/ruoyi/web/controller/learn/LearnTestStudentController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.learn;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+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.LearnTestStudent;
+import com.ruoyi.learn.service.ILearnTestStudentService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 测试学生Controller
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@RestController
+@RequestMapping("/learn/test_student")
+@Api("后台-学习 - 批次卷发布")
+public class LearnTestStudentController extends BaseController
+{
+    @Autowired
+    private ILearnTestStudentService learnTestStudentService;
+
+    /**
+     * 查询测试学生列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_student:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(LearnTestStudent learnTestStudent)
+    {
+        startPage();
+        List<LearnTestStudent> list = learnTestStudentService.selectLearnTestStudentList(learnTestStudent);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出测试学生列表
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_student:export')")
+    @Log(title = "测试学生", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, LearnTestStudent learnTestStudent)
+    {
+        List<LearnTestStudent> list = learnTestStudentService.selectLearnTestStudentList(learnTestStudent);
+        ExcelUtil<LearnTestStudent> util = new ExcelUtil<LearnTestStudent>(LearnTestStudent.class);
+        util.exportExcel(response, list, "测试学生数据");
+    }
+
+    /**
+     * 获取测试学生详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_student:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return success(learnTestStudentService.selectLearnTestStudentById(id));
+    }
+
+    /**
+     * 新增测试学生
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_student:add')")
+    @Log(title = "测试学生", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody LearnTestStudent learnTestStudent)
+    {
+        return toAjax(learnTestStudentService.insertLearnTestStudent(learnTestStudent));
+    }
+
+    /**
+     * 修改测试学生
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_student:edit')")
+    @Log(title = "测试学生", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody LearnTestStudent learnTestStudent)
+    {
+        return toAjax(learnTestStudentService.updateLearnTestStudent(learnTestStudent));
+    }
+
+    /**
+     * 删除测试学生
+     */
+    @PreAuthorize("@ss.hasPermi('learn:test_student:remove')")
+    @Log(title = "测试学生", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable String[] ids)
+    {
+        return toAjax(learnTestStudentService.deleteLearnTestStudentByIds(ids));
+    }
+}

+ 248 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaper.java

@@ -0,0 +1,248 @@
+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_paper
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnPaper extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 科目id */
+    @Excel(name = "科目id")
+    private Long subjectId;
+
+    /** 试卷名称 */
+    @Excel(name = "试卷名称")
+    private String paperName;
+
+    /** 创建年度 */
+    @Excel(name = "创建年度")
+    private Long year;
+
+    /** 历年真题,模拟卷,必刷题;组卷;练习卷;刷题卷;know_test-知识点,auto-基础题库,high_error-高频错题,smart_test-智能刷题,paper-真题,试卷 */
+    @Excel(name = "历年真题,模拟卷,必刷题;组卷;练习卷;刷题卷;know_test-知识点,auto-基础题库,high_error-高频错题,smart_test-智能刷题,paper-真题,试卷")
+    private String paperType;
+
+    /** 试卷题数 */
+    @Excel(name = "试卷题数")
+    private String number;
+
+    /** 试卷总分数 */
+    @Excel(name = "试卷总分数")
+    private Long fenshu;
+
+    /** 试券来源 */
+    @Excel(name = "试券来源")
+    private Long paperSource;
+
+    /** 定向key */
+    @Excel(name = "定向key")
+    private String directKey;
+
+    /** 标识 */
+    @Excel(name = "标识")
+    private String tiid;
+
+    /** 路径 */
+    @Excel(name = "路径")
+    private String osspath;
+
+    /** 源文件名 */
+    @Excel(name = "源文件名")
+    private String filename;
+
+    /** 真题卷id或组卷人id */
+    @Excel(name = "真题卷id或组卷人id")
+    private Long relateId;
+
+    /** 适用地区 */
+    @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 setSubjectId(Long subjectId) 
+    {
+        this.subjectId = subjectId;
+    }
+
+    public Long getSubjectId() 
+    {
+        return subjectId;
+    }
+
+    public void setPaperName(String paperName) 
+    {
+        this.paperName = paperName;
+    }
+
+    public String getPaperName() 
+    {
+        return paperName;
+    }
+
+    public void setYear(Long year) 
+    {
+        this.year = year;
+    }
+
+    public Long getYear() 
+    {
+        return year;
+    }
+
+    public void setPaperType(String paperType) 
+    {
+        this.paperType = paperType;
+    }
+
+    public String getPaperType() 
+    {
+        return paperType;
+    }
+
+    public void setNumber(String number) 
+    {
+        this.number = number;
+    }
+
+    public String getNumber() 
+    {
+        return number;
+    }
+
+    public void setFenshu(Long fenshu) 
+    {
+        this.fenshu = fenshu;
+    }
+
+    public Long getFenshu() 
+    {
+        return fenshu;
+    }
+
+    public void setPaperSource(Long paperSource) 
+    {
+        this.paperSource = paperSource;
+    }
+
+    public Long getPaperSource() 
+    {
+        return paperSource;
+    }
+
+    public void setDirectKey(String directKey) 
+    {
+        this.directKey = directKey;
+    }
+
+    public String getDirectKey() 
+    {
+        return directKey;
+    }
+
+    public void setTiid(String tiid) 
+    {
+        this.tiid = tiid;
+    }
+
+    public String getTiid() 
+    {
+        return tiid;
+    }
+
+    public void setOsspath(String osspath) 
+    {
+        this.osspath = osspath;
+    }
+
+    public String getOsspath() 
+    {
+        return osspath;
+    }
+
+    public void setFilename(String filename) 
+    {
+        this.filename = filename;
+    }
+
+    public String getFilename() 
+    {
+        return filename;
+    }
+
+    public void setRelateId(Long relateId) 
+    {
+        this.relateId = relateId;
+    }
+
+    public Long getRelateId() 
+    {
+        return relateId;
+    }
+
+    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("subjectId", getSubjectId())
+            .append("paperName", getPaperName())
+            .append("year", getYear())
+            .append("paperType", getPaperType())
+            .append("number", getNumber())
+            .append("fenshu", getFenshu())
+            .append("paperSource", getPaperSource())
+            .append("directKey", getDirectKey())
+            .append("tiid", getTiid())
+            .append("osspath", getOsspath())
+            .append("filename", getFilename())
+            .append("relateId", getRelateId())
+            .append("locations", getLocations())
+            .append("examineeTypes", getExamineeTypes())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 98 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaperQuestion.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_paper_question
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnPaperQuestion extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 试卷题id */
+    private Long id;
+
+    /** 试卷id */
+    @Excel(name = "试卷id")
+    private Long paperId;
+
+    /** 题id */
+    @Excel(name = "题id")
+    private Long questionId;
+
+    /** 顺序 */
+    @Excel(name = "顺序")
+    private Long seq;
+
+    /** 分值 */
+    @Excel(name = "分值")
+    private Long score;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setPaperId(Long paperId) 
+    {
+        this.paperId = paperId;
+    }
+
+    public Long getPaperId() 
+    {
+        return paperId;
+    }
+
+    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 setScore(Long score) 
+    {
+        this.score = score;
+    }
+
+    public Long getScore() 
+    {
+        return score;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("paperId", getPaperId())
+            .append("questionId", getQuestionId())
+            .append("seq", getSeq())
+            .append("score", getScore())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 233 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnPaperReal.java

@@ -0,0 +1,233 @@
+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_paper_real
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnPaperReal extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 科目ID */
+    @Excel(name = "科目ID")
+    private Long subjectId;
+
+    /** 试卷名称 */
+    @Excel(name = "试卷名称")
+    private String paperName;
+
+    /** 试卷年份 */
+    @Excel(name = "试卷年份")
+    private Long year;
+
+    /** 历年真题,模拟卷,必刷题 */
+    @Excel(name = "历年真题,模拟卷,必刷题")
+    private String paperType;
+
+    /** 试卷题数 */
+    @Excel(name = "试卷题数")
+    private String number;
+
+    /** 试卷总分 */
+    @Excel(name = "试卷总分")
+    private Long fenshu;
+
+    /** 0 默认 1 精品试卷 */
+    @Excel(name = "0 默认 1 精品试卷")
+    private Long paperSource;
+
+    /** 是否有在线卷 */
+    @Excel(name = "是否有在线卷")
+    private Long online;
+
+    /** 唯一标识 */
+    @Excel(name = "唯一标识")
+    private String tiid;
+
+    /** 下载路径 */
+    @Excel(name = "下载路径")
+    private String osspath;
+
+    /** 原始文件名 */
+    @Excel(name = "原始文件名")
+    private String filename;
+
+    /** 适用地区 */
+    @Excel(name = "适用地区")
+    private String locations;
+
+    /** 适用考生 */
+    @Excel(name = "适用考生")
+    private String examineeType;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setSubjectId(Long subjectId) 
+    {
+        this.subjectId = subjectId;
+    }
+
+    public Long getSubjectId() 
+    {
+        return subjectId;
+    }
+
+    public void setPaperName(String paperName) 
+    {
+        this.paperName = paperName;
+    }
+
+    public String getPaperName() 
+    {
+        return paperName;
+    }
+
+    public void setYear(Long year) 
+    {
+        this.year = year;
+    }
+
+    public Long getYear() 
+    {
+        return year;
+    }
+
+    public void setPaperType(String paperType) 
+    {
+        this.paperType = paperType;
+    }
+
+    public String getPaperType() 
+    {
+        return paperType;
+    }
+
+    public void setNumber(String number) 
+    {
+        this.number = number;
+    }
+
+    public String getNumber() 
+    {
+        return number;
+    }
+
+    public void setFenshu(Long fenshu) 
+    {
+        this.fenshu = fenshu;
+    }
+
+    public Long getFenshu() 
+    {
+        return fenshu;
+    }
+
+    public void setPaperSource(Long paperSource) 
+    {
+        this.paperSource = paperSource;
+    }
+
+    public Long getPaperSource() 
+    {
+        return paperSource;
+    }
+
+    public void setOnline(Long online) 
+    {
+        this.online = online;
+    }
+
+    public Long getOnline() 
+    {
+        return online;
+    }
+
+    public void setTiid(String tiid) 
+    {
+        this.tiid = tiid;
+    }
+
+    public String getTiid() 
+    {
+        return tiid;
+    }
+
+    public void setOsspath(String osspath) 
+    {
+        this.osspath = osspath;
+    }
+
+    public String getOsspath() 
+    {
+        return osspath;
+    }
+
+    public void setFilename(String filename) 
+    {
+        this.filename = filename;
+    }
+
+    public String getFilename() 
+    {
+        return filename;
+    }
+
+    public void setLocations(String locations) 
+    {
+        this.locations = locations;
+    }
+
+    public String getLocations() 
+    {
+        return locations;
+    }
+
+    public void setExamineeType(String examineeType) 
+    {
+        this.examineeType = examineeType;
+    }
+
+    public String getExamineeType() 
+    {
+        return examineeType;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("subjectId", getSubjectId())
+            .append("paperName", getPaperName())
+            .append("year", getYear())
+            .append("paperType", getPaperType())
+            .append("number", getNumber())
+            .append("fenshu", getFenshu())
+            .append("paperSource", getPaperSource())
+            .append("online", getOnline())
+            .append("tiid", getTiid())
+            .append("osspath", getOsspath())
+            .append("filename", getFilename())
+            .append("locations", getLocations())
+            .append("examineeType", getExamineeType())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 684 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnQuestions.java

@@ -0,0 +1,684 @@
+package com.ruoyi.learn.domain;
+
+import java.math.BigDecimal;
+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_questions
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnQuestions extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 试题-题干 */
+    @Excel(name = "试题-题干")
+    private String title;
+
+    /** 选项A */
+    @Excel(name = "选项A")
+    private String optionA;
+
+    /** 选项B */
+    @Excel(name = "选项B")
+    private String optionB;
+
+    /** 选项C */
+    @Excel(name = "选项C")
+    private String optionC;
+
+    /** 选项D */
+    @Excel(name = "选项D")
+    private String optionD;
+
+    /** 选项E */
+    @Excel(name = "选项E")
+    private String optionE;
+
+    /** 选项D */
+    @Excel(name = "选项D")
+    private String optionF;
+
+    /** 选项E */
+    @Excel(name = "选项E")
+    private String optionG;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String answer1;
+
+    /** 非标准格式答案或含部分过程说明的答案 */
+    @Excel(name = "非标准格式答案或含部分过程说明的答案")
+    private String answer2;
+
+    /** 类型(1判断题;2单选题;3多选题;4主观题,简答题) */
+    @Excel(name = "类型", readConverterExp = "1=判断题;2单选题;3多选题;4主观题,简答题")
+    private String qtpye;
+
+    /** 学科Id */
+    @Excel(name = "学科Id")
+    private Long subjectId;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long paperId;
+
+    /** 知识点 */
+    @Excel(name = "知识点")
+    private Long knowledgeId;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private BigDecimal diff;
+
+    /** 试题在题库中的相似度,相似度越高,质量越低 */
+    @Excel(name = "试题在题库中的相似度,相似度越高,质量越低")
+    private Long similarity;
+
+    /** 试题解析 */
+    @Excel(name = "试题解析")
+    private String parse;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long knowId;
+
+    /** 年级ID */
+    @Excel(name = "年级ID")
+    private Long gradeId;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String knowledges;
+
+    /** 试题区域 */
+    @Excel(name = "试题区域")
+    private String area;
+
+    /** 试题年份 */
+    @Excel(name = "试题年份")
+    private Long year;
+
+    /** 试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他 */
+    @Excel(name = "试题类型:1,月考;2,模拟考;3,中考;4,高考;5,学业考试;6,其他")
+    private String paperTpye;
+
+    /** 来源(1gzdz,2dk,3self,4自制) */
+    @Excel(name = "来源", readConverterExp = "1=gzdz,2dk,3self,4自制")
+    private String source;
+
+    /** 试题来源(网站) */
+    @Excel(name = "试题来源", readConverterExp = "网=站")
+    private String fromSite;
+
+    /** 是否存在图片水印 */
+    @Excel(name = "是否存在图片水印")
+    private Integer isSub;
+
+    /** 是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1 */
+    @Excel(name = "是否常规题,如果选择题无法正常提取标准答案或者选项,有小题的答题无法正常提取小题,则isNormal为0,否则为1")
+    private Integer isNormal;
+
+    /** 是否匹配章节知识点,1匹配,0不匹配 */
+    @Excel(name = "是否匹配章节知识点,1匹配,0不匹配")
+    private Integer isKonw;
+
+    /** 试题的tiid,结合fromsite进行同网站试题排重,用于增量更新 */
+    @Excel(name = "试题的tiid,结合fromsite进行同网站试题排重,用于增量更新")
+    private String tiid;
+
+    /** 试题题干的md5值 */
+    @Excel(name = "试题题干的md5值")
+    private String md5;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long isunique;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String md52;
+
+    /** 得分 */
+    @Excel(name = "得分")
+    private BigDecimal score;
+
+    /** 选项 */
+    @Excel(name = "选项")
+    private String options;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long number;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String paperTypeTitle;
+
+    /** 选项 */
+    @Excel(name = "选项")
+    private String options0;
+
+    /** 试题-材料题题干 */
+    @Excel(name = "试题-材料题题干")
+    private String title0;
+
+    /** 试题-材料题题干 */
+    @Excel(name = "试题-材料题题干")
+    private String title1;
+
+    /** 试题解析 */
+    @Excel(name = "试题解析")
+    private String parse0;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String answer0;
+
+    /** 是否更新 */
+    @Excel(name = "是否更新")
+    private Long isUpdate;
+
+    /** 子题类型 */
+    @Excel(name = "子题类型")
+    private String isSubType;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+
+    public void setTitle(String title) 
+    {
+        this.title = title;
+    }
+
+    public String getTitle() 
+    {
+        return title;
+    }
+
+    public void setOptionA(String optionA) 
+    {
+        this.optionA = optionA;
+    }
+
+    public String getOptionA() 
+    {
+        return optionA;
+    }
+
+    public void setOptionB(String optionB) 
+    {
+        this.optionB = optionB;
+    }
+
+    public String getOptionB() 
+    {
+        return optionB;
+    }
+
+    public void setOptionC(String optionC) 
+    {
+        this.optionC = optionC;
+    }
+
+    public String getOptionC() 
+    {
+        return optionC;
+    }
+
+    public void setOptionD(String optionD) 
+    {
+        this.optionD = optionD;
+    }
+
+    public String getOptionD() 
+    {
+        return optionD;
+    }
+
+    public void setOptionE(String optionE) 
+    {
+        this.optionE = optionE;
+    }
+
+    public String getOptionE() 
+    {
+        return optionE;
+    }
+
+    public void setOptionF(String optionF) 
+    {
+        this.optionF = optionF;
+    }
+
+    public String getOptionF() 
+    {
+        return optionF;
+    }
+
+    public void setOptionG(String optionG) 
+    {
+        this.optionG = optionG;
+    }
+
+    public String getOptionG() 
+    {
+        return optionG;
+    }
+
+    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 setQtpye(String qtpye) 
+    {
+        this.qtpye = qtpye;
+    }
+
+    public String getQtpye() 
+    {
+        return qtpye;
+    }
+
+    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 setKnowledgeId(Long knowledgeId) 
+    {
+        this.knowledgeId = knowledgeId;
+    }
+
+    public Long getKnowledgeId() 
+    {
+        return knowledgeId;
+    }
+
+    public void setDiff(BigDecimal diff) 
+    {
+        this.diff = diff;
+    }
+
+    public BigDecimal getDiff() 
+    {
+        return diff;
+    }
+
+    public void setSimilarity(Long similarity) 
+    {
+        this.similarity = similarity;
+    }
+
+    public Long getSimilarity() 
+    {
+        return similarity;
+    }
+
+    public void setParse(String parse) 
+    {
+        this.parse = parse;
+    }
+
+    public String getParse() 
+    {
+        return parse;
+    }
+
+    public void setKnowId(Long knowId) 
+    {
+        this.knowId = knowId;
+    }
+
+    public Long getKnowId() 
+    {
+        return knowId;
+    }
+
+    public void setGradeId(Long gradeId) 
+    {
+        this.gradeId = gradeId;
+    }
+
+    public Long getGradeId() 
+    {
+        return gradeId;
+    }
+
+    public void setKnowledges(String knowledges) 
+    {
+        this.knowledges = knowledges;
+    }
+
+    public String getKnowledges() 
+    {
+        return knowledges;
+    }
+
+    public void setArea(String area) 
+    {
+        this.area = area;
+    }
+
+    public String getArea() 
+    {
+        return area;
+    }
+
+    public void setYear(Long year) 
+    {
+        this.year = year;
+    }
+
+    public Long getYear() 
+    {
+        return year;
+    }
+
+    public void setPaperTpye(String paperTpye) 
+    {
+        this.paperTpye = paperTpye;
+    }
+
+    public String getPaperTpye() 
+    {
+        return paperTpye;
+    }
+
+    public void setSource(String source) 
+    {
+        this.source = source;
+    }
+
+    public String getSource() 
+    {
+        return source;
+    }
+
+    public void setFromSite(String fromSite) 
+    {
+        this.fromSite = fromSite;
+    }
+
+    public String getFromSite() 
+    {
+        return fromSite;
+    }
+
+    public void setIsSub(Integer isSub) 
+    {
+        this.isSub = isSub;
+    }
+
+    public Integer getIsSub() 
+    {
+        return isSub;
+    }
+
+    public void setIsNormal(Integer isNormal) 
+    {
+        this.isNormal = isNormal;
+    }
+
+    public Integer getIsNormal() 
+    {
+        return isNormal;
+    }
+
+    public void setIsKonw(Integer isKonw) 
+    {
+        this.isKonw = isKonw;
+    }
+
+    public Integer getIsKonw() 
+    {
+        return isKonw;
+    }
+
+    public void setTiid(String tiid) 
+    {
+        this.tiid = tiid;
+    }
+
+    public String getTiid() 
+    {
+        return tiid;
+    }
+
+    public void setMd5(String md5) 
+    {
+        this.md5 = md5;
+    }
+
+    public String getMd5() 
+    {
+        return md5;
+    }
+
+    public void setIsunique(Long isunique) 
+    {
+        this.isunique = isunique;
+    }
+
+    public Long getIsunique() 
+    {
+        return isunique;
+    }
+
+    public void setMd52(String md52) 
+    {
+        this.md52 = md52;
+    }
+
+    public String getMd52() 
+    {
+        return md52;
+    }
+
+    public void setScore(BigDecimal score) 
+    {
+        this.score = score;
+    }
+
+    public BigDecimal getScore() 
+    {
+        return score;
+    }
+
+    public void setOptions(String options) 
+    {
+        this.options = options;
+    }
+
+    public String getOptions() 
+    {
+        return options;
+    }
+
+    public void setNumber(Long number) 
+    {
+        this.number = number;
+    }
+
+    public Long getNumber() 
+    {
+        return number;
+    }
+
+    public void setPaperTypeTitle(String paperTypeTitle) 
+    {
+        this.paperTypeTitle = paperTypeTitle;
+    }
+
+    public String getPaperTypeTitle() 
+    {
+        return paperTypeTitle;
+    }
+
+    public void setOptions0(String options0) 
+    {
+        this.options0 = options0;
+    }
+
+    public String getOptions0() 
+    {
+        return options0;
+    }
+
+    public void setTitle0(String title0) 
+    {
+        this.title0 = title0;
+    }
+
+    public String getTitle0() 
+    {
+        return title0;
+    }
+
+    public void setTitle1(String title1) 
+    {
+        this.title1 = title1;
+    }
+
+    public String getTitle1() 
+    {
+        return title1;
+    }
+
+    public void setParse0(String parse0) 
+    {
+        this.parse0 = parse0;
+    }
+
+    public String getParse0() 
+    {
+        return parse0;
+    }
+
+    public void setAnswer0(String answer0) 
+    {
+        this.answer0 = answer0;
+    }
+
+    public String getAnswer0() 
+    {
+        return answer0;
+    }
+
+    public void setIsUpdate(Long isUpdate) 
+    {
+        this.isUpdate = isUpdate;
+    }
+
+    public Long getIsUpdate() 
+    {
+        return isUpdate;
+    }
+
+    public void setIsSubType(String isSubType) 
+    {
+        this.isSubType = isSubType;
+    }
+
+    public String getIsSubType() 
+    {
+        return isSubType;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("title", getTitle())
+            .append("optionA", getOptionA())
+            .append("optionB", getOptionB())
+            .append("optionC", getOptionC())
+            .append("optionD", getOptionD())
+            .append("optionE", getOptionE())
+            .append("optionF", getOptionF())
+            .append("optionG", getOptionG())
+            .append("answer1", getAnswer1())
+            .append("answer2", getAnswer2())
+            .append("qtpye", getQtpye())
+            .append("subjectId", getSubjectId())
+            .append("paperId", getPaperId())
+            .append("knowledgeId", getKnowledgeId())
+            .append("diff", getDiff())
+            .append("similarity", getSimilarity())
+            .append("parse", getParse())
+            .append("knowId", getKnowId())
+            .append("gradeId", getGradeId())
+            .append("knowledges", getKnowledges())
+            .append("area", getArea())
+            .append("year", getYear())
+            .append("paperTpye", getPaperTpye())
+            .append("source", getSource())
+            .append("fromSite", getFromSite())
+            .append("isSub", getIsSub())
+            .append("isNormal", getIsNormal())
+            .append("isKonw", getIsKonw())
+            .append("tiid", getTiid())
+            .append("md5", getMd5())
+            .append("isunique", getIsunique())
+            .append("md52", getMd52())
+            .append("createTime", getCreateTime())
+            .append("score", getScore())
+            .append("options", getOptions())
+            .append("number", getNumber())
+            .append("paperTypeTitle", getPaperTypeTitle())
+            .append("options0", getOptions0())
+            .append("title0", getTitle0())
+            .append("title1", getTitle1())
+            .append("parse0", getParse0())
+            .append("answer0", getAnswer0())
+            .append("isUpdate", getIsUpdate())
+            .append("isSubType", getIsSubType())
+            .toString();
+    }
+}

+ 52 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnStudent.java

@@ -0,0 +1,52 @@
+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_student
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnStudent extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 学生用户ID */
+    private Long studentId;
+
+    /** 定向Key */
+    @Excel(name = "定向Key")
+    private String directKey;
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setDirectKey(String directKey) 
+    {
+        this.directKey = directKey;
+    }
+
+    public String getDirectKey() 
+    {
+        return directKey;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("studentId", getStudentId())
+            .append("directKey", getDirectKey())
+            .toString();
+    }
+}

+ 68 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnTest.java

@@ -0,0 +1,68 @@
+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_test
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnTest extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 考卷批次 */
+    private String batchId;
+
+    /** 批次名称 */
+    @Excel(name = "批次名称")
+    private String name;
+
+    /** 创建人 */
+    @Excel(name = "创建人")
+    private Long creatorId;
+
+    public void setBatchId(String batchId) 
+    {
+        this.batchId = batchId;
+    }
+
+    public String getBatchId() 
+    {
+        return batchId;
+    }
+
+    public void setName(String name) 
+    {
+        this.name = name;
+    }
+
+    public String getName() 
+    {
+        return name;
+    }
+
+    public void setCreatorId(Long creatorId) 
+    {
+        this.creatorId = creatorId;
+    }
+
+    public Long getCreatorId() 
+    {
+        return creatorId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("batchId", getBatchId())
+            .append("name", getName())
+            .append("creatorId", getCreatorId())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 113 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnTestPaper.java

@@ -0,0 +1,113 @@
+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_test_paper
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnTestPaper extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 批次卷id */
+    private String id;
+
+    /** 批次id */
+    @Excel(name = "批次id")
+    private Long batchId;
+
+    /** 定向key */
+    @Excel(name = "定向key")
+    private String directKey;
+
+    /** 卷id */
+    @Excel(name = "卷id")
+    private Long paperId;
+
+    /** 试卷生成条件 */
+    @Excel(name = "试卷生成条件")
+    private String condions;
+
+    /** 创建人 */
+    @Excel(name = "创建人")
+    private Long creatorId;
+
+    public void setId(String id) 
+    {
+        this.id = id;
+    }
+
+    public String getId() 
+    {
+        return id;
+    }
+
+    public void setBatchId(Long batchId) 
+    {
+        this.batchId = batchId;
+    }
+
+    public Long getBatchId() 
+    {
+        return batchId;
+    }
+
+    public void setDirectKey(String directKey) 
+    {
+        this.directKey = directKey;
+    }
+
+    public String getDirectKey() 
+    {
+        return directKey;
+    }
+
+    public void setPaperId(Long paperId) 
+    {
+        this.paperId = paperId;
+    }
+
+    public Long getPaperId() 
+    {
+        return paperId;
+    }
+
+    public void setCondions(String condions) 
+    {
+        this.condions = condions;
+    }
+
+    public String getCondions() 
+    {
+        return condions;
+    }
+
+    public void setCreatorId(Long creatorId) 
+    {
+        this.creatorId = creatorId;
+    }
+
+    public Long getCreatorId() 
+    {
+        return creatorId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("batchId", getBatchId())
+            .append("directKey", getDirectKey())
+            .append("paperId", getPaperId())
+            .append("condions", getCondions())
+            .append("creatorId", getCreatorId())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

+ 143 - 0
ie-system/src/main/java/com/ruoyi/learn/domain/LearnTestStudent.java

@@ -0,0 +1,143 @@
+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_test_student
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public class LearnTestStudent extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 批次学生id */
+    private String id;
+
+    /** 批次id */
+    @Excel(name = "批次id")
+    private Long batchId;
+
+    /** 学生id */
+    @Excel(name = "学生id")
+    private Long studentId;
+
+    /** 定向标识学生可能有多个 */
+    @Excel(name = "定向标识学生可能有多个")
+    private String directKey;
+
+    /** 批次卷id */
+    @Excel(name = "批次卷id")
+    private Long paperId;
+
+    /** 学生班级 */
+    @Excel(name = "学生班级")
+    private Long classId;
+
+    /** 考卷ID */
+    @Excel(name = "考卷ID")
+    private Long examineeId;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Long status;
+
+    public void setId(String id) 
+    {
+        this.id = id;
+    }
+
+    public String getId() 
+    {
+        return id;
+    }
+
+    public void setBatchId(Long batchId) 
+    {
+        this.batchId = batchId;
+    }
+
+    public Long getBatchId() 
+    {
+        return batchId;
+    }
+
+    public void setStudentId(Long studentId) 
+    {
+        this.studentId = studentId;
+    }
+
+    public Long getStudentId() 
+    {
+        return studentId;
+    }
+
+    public void setDirectKey(String directKey) 
+    {
+        this.directKey = directKey;
+    }
+
+    public String getDirectKey() 
+    {
+        return directKey;
+    }
+
+    public void setPaperId(Long paperId) 
+    {
+        this.paperId = paperId;
+    }
+
+    public Long getPaperId() 
+    {
+        return paperId;
+    }
+
+    public void setClassId(Long classId) 
+    {
+        this.classId = classId;
+    }
+
+    public Long getClassId() 
+    {
+        return classId;
+    }
+
+    public void setExamineeId(Long examineeId) 
+    {
+        this.examineeId = examineeId;
+    }
+
+    public Long getExamineeId() 
+    {
+        return examineeId;
+    }
+
+    public void setStatus(Long status) 
+    {
+        this.status = status;
+    }
+
+    public Long getStatus() 
+    {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("batchId", getBatchId())
+            .append("studentId", getStudentId())
+            .append("directKey", getDirectKey())
+            .append("paperId", getPaperId())
+            .append("classId", getClassId())
+            .append("examineeId", getExamineeId())
+            .append("status", getStatus())
+            .append("createTime", getCreateTime())
+            .toString();
+    }
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPaper;
+
+/**
+ * 试卷Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnPaperMapper 
+{
+    /**
+     * 查询试卷
+     * 
+     * @param id 试卷主键
+     * @return 试卷
+     */
+    public LearnPaper selectLearnPaperById(Long id);
+
+    /**
+     * 查询试卷列表
+     * 
+     * @param learnPaper 试卷
+     * @return 试卷集合
+     */
+    public List<LearnPaper> selectLearnPaperList(LearnPaper learnPaper);
+
+    /**
+     * 新增试卷
+     * 
+     * @param learnPaper 试卷
+     * @return 结果
+     */
+    public int insertLearnPaper(LearnPaper learnPaper);
+
+    /**
+     * 修改试卷
+     * 
+     * @param learnPaper 试卷
+     * @return 结果
+     */
+    public int updateLearnPaper(LearnPaper learnPaper);
+
+    /**
+     * 删除试卷
+     * 
+     * @param id 试卷主键
+     * @return 结果
+     */
+    public int deleteLearnPaperById(Long id);
+
+    /**
+     * 批量删除试卷
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnPaperByIds(Long[] ids);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPaperQuestion;
+
+/**
+ * 试卷题关系Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnPaperQuestionMapper 
+{
+    /**
+     * 查询试卷题关系
+     * 
+     * @param id 试卷题关系主键
+     * @return 试卷题关系
+     */
+    public LearnPaperQuestion selectLearnPaperQuestionById(Long id);
+
+    /**
+     * 查询试卷题关系列表
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 试卷题关系集合
+     */
+    public List<LearnPaperQuestion> selectLearnPaperQuestionList(LearnPaperQuestion learnPaperQuestion);
+
+    /**
+     * 新增试卷题关系
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 结果
+     */
+    public int insertLearnPaperQuestion(LearnPaperQuestion learnPaperQuestion);
+
+    /**
+     * 修改试卷题关系
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 结果
+     */
+    public int updateLearnPaperQuestion(LearnPaperQuestion learnPaperQuestion);
+
+    /**
+     * 删除试卷题关系
+     * 
+     * @param id 试卷题关系主键
+     * @return 结果
+     */
+    public int deleteLearnPaperQuestionById(Long id);
+
+    /**
+     * 批量删除试卷题关系
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnPaperQuestionByIds(Long[] ids);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPaperReal;
+
+/**
+ * 真题卷Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnPaperRealMapper 
+{
+    /**
+     * 查询真题卷
+     * 
+     * @param id 真题卷主键
+     * @return 真题卷
+     */
+    public LearnPaperReal selectLearnPaperRealById(Long id);
+
+    /**
+     * 查询真题卷列表
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 真题卷集合
+     */
+    public List<LearnPaperReal> selectLearnPaperRealList(LearnPaperReal learnPaperReal);
+
+    /**
+     * 新增真题卷
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 结果
+     */
+    public int insertLearnPaperReal(LearnPaperReal learnPaperReal);
+
+    /**
+     * 修改真题卷
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 结果
+     */
+    public int updateLearnPaperReal(LearnPaperReal learnPaperReal);
+
+    /**
+     * 删除真题卷
+     * 
+     * @param id 真题卷主键
+     * @return 结果
+     */
+    public int deleteLearnPaperRealById(Long id);
+
+    /**
+     * 批量删除真题卷
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnPaperRealByIds(Long[] ids);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnQuestions;
+
+/**
+ * 试题Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnQuestionsMapper 
+{
+    /**
+     * 查询试题
+     * 
+     * @param id 试题主键
+     * @return 试题
+     */
+    public LearnQuestions selectLearnQuestionsById(Long id);
+
+    /**
+     * 查询试题列表
+     * 
+     * @param learnQuestions 试题
+     * @return 试题集合
+     */
+    public List<LearnQuestions> selectLearnQuestionsList(LearnQuestions learnQuestions);
+
+    /**
+     * 新增试题
+     * 
+     * @param learnQuestions 试题
+     * @return 结果
+     */
+    public int insertLearnQuestions(LearnQuestions learnQuestions);
+
+    /**
+     * 修改试题
+     * 
+     * @param learnQuestions 试题
+     * @return 结果
+     */
+    public int updateLearnQuestions(LearnQuestions learnQuestions);
+
+    /**
+     * 删除试题
+     * 
+     * @param id 试题主键
+     * @return 结果
+     */
+    public int deleteLearnQuestionsById(Long id);
+
+    /**
+     * 批量删除试题
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnQuestionsByIds(Long[] ids);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnStudent;
+
+/**
+ * 学生Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnStudentMapper 
+{
+    /**
+     * 查询学生
+     * 
+     * @param studentId 学生主键
+     * @return 学生
+     */
+    public LearnStudent selectLearnStudentByStudentId(Long studentId);
+
+    /**
+     * 查询学生列表
+     * 
+     * @param learnStudent 学生
+     * @return 学生集合
+     */
+    public List<LearnStudent> selectLearnStudentList(LearnStudent learnStudent);
+
+    /**
+     * 新增学生
+     * 
+     * @param learnStudent 学生
+     * @return 结果
+     */
+    public int insertLearnStudent(LearnStudent learnStudent);
+
+    /**
+     * 修改学生
+     * 
+     * @param learnStudent 学生
+     * @return 结果
+     */
+    public int updateLearnStudent(LearnStudent learnStudent);
+
+    /**
+     * 删除学生
+     * 
+     * @param studentId 学生主键
+     * @return 结果
+     */
+    public int deleteLearnStudentByStudentId(Long studentId);
+
+    /**
+     * 批量删除学生
+     * 
+     * @param studentIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnStudentByStudentIds(Long[] studentIds);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnTest;
+
+/**
+ * 试卷批次Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnTestMapper 
+{
+    /**
+     * 查询试卷批次
+     * 
+     * @param batchId 试卷批次主键
+     * @return 试卷批次
+     */
+    public LearnTest selectLearnTestByBatchId(String batchId);
+
+    /**
+     * 查询试卷批次列表
+     * 
+     * @param learnTest 试卷批次
+     * @return 试卷批次集合
+     */
+    public List<LearnTest> selectLearnTestList(LearnTest learnTest);
+
+    /**
+     * 新增试卷批次
+     * 
+     * @param learnTest 试卷批次
+     * @return 结果
+     */
+    public int insertLearnTest(LearnTest learnTest);
+
+    /**
+     * 修改试卷批次
+     * 
+     * @param learnTest 试卷批次
+     * @return 结果
+     */
+    public int updateLearnTest(LearnTest learnTest);
+
+    /**
+     * 删除试卷批次
+     * 
+     * @param batchId 试卷批次主键
+     * @return 结果
+     */
+    public int deleteLearnTestByBatchId(String batchId);
+
+    /**
+     * 批量删除试卷批次
+     * 
+     * @param batchIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnTestByBatchIds(String[] batchIds);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnTestPaper;
+
+/**
+ * 批次测试卷Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnTestPaperMapper 
+{
+    /**
+     * 查询批次测试卷
+     * 
+     * @param id 批次测试卷主键
+     * @return 批次测试卷
+     */
+    public LearnTestPaper selectLearnTestPaperById(String id);
+
+    /**
+     * 查询批次测试卷列表
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 批次测试卷集合
+     */
+    public List<LearnTestPaper> selectLearnTestPaperList(LearnTestPaper learnTestPaper);
+
+    /**
+     * 新增批次测试卷
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 结果
+     */
+    public int insertLearnTestPaper(LearnTestPaper learnTestPaper);
+
+    /**
+     * 修改批次测试卷
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 结果
+     */
+    public int updateLearnTestPaper(LearnTestPaper learnTestPaper);
+
+    /**
+     * 删除批次测试卷
+     * 
+     * @param id 批次测试卷主键
+     * @return 结果
+     */
+    public int deleteLearnTestPaperById(String id);
+
+    /**
+     * 批量删除批次测试卷
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnTestPaperByIds(String[] ids);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.mapper;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnTestStudent;
+
+/**
+ * 测试学生Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface LearnTestStudentMapper 
+{
+    /**
+     * 查询测试学生
+     * 
+     * @param id 测试学生主键
+     * @return 测试学生
+     */
+    public LearnTestStudent selectLearnTestStudentById(String id);
+
+    /**
+     * 查询测试学生列表
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 测试学生集合
+     */
+    public List<LearnTestStudent> selectLearnTestStudentList(LearnTestStudent learnTestStudent);
+
+    /**
+     * 新增测试学生
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 结果
+     */
+    public int insertLearnTestStudent(LearnTestStudent learnTestStudent);
+
+    /**
+     * 修改测试学生
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 结果
+     */
+    public int updateLearnTestStudent(LearnTestStudent learnTestStudent);
+
+    /**
+     * 删除测试学生
+     * 
+     * @param id 测试学生主键
+     * @return 结果
+     */
+    public int deleteLearnTestStudentById(String id);
+
+    /**
+     * 批量删除测试学生
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteLearnTestStudentByIds(String[] ids);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPaperQuestion;
+
+/**
+ * 试卷题关系Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnPaperQuestionService 
+{
+    /**
+     * 查询试卷题关系
+     * 
+     * @param id 试卷题关系主键
+     * @return 试卷题关系
+     */
+    public LearnPaperQuestion selectLearnPaperQuestionById(Long id);
+
+    /**
+     * 查询试卷题关系列表
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 试卷题关系集合
+     */
+    public List<LearnPaperQuestion> selectLearnPaperQuestionList(LearnPaperQuestion learnPaperQuestion);
+
+    /**
+     * 新增试卷题关系
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 结果
+     */
+    public int insertLearnPaperQuestion(LearnPaperQuestion learnPaperQuestion);
+
+    /**
+     * 修改试卷题关系
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 结果
+     */
+    public int updateLearnPaperQuestion(LearnPaperQuestion learnPaperQuestion);
+
+    /**
+     * 批量删除试卷题关系
+     * 
+     * @param ids 需要删除的试卷题关系主键集合
+     * @return 结果
+     */
+    public int deleteLearnPaperQuestionByIds(Long[] ids);
+
+    /**
+     * 删除试卷题关系信息
+     * 
+     * @param id 试卷题关系主键
+     * @return 结果
+     */
+    public int deleteLearnPaperQuestionById(Long id);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPaperReal;
+
+/**
+ * 真题卷Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnPaperRealService 
+{
+    /**
+     * 查询真题卷
+     * 
+     * @param id 真题卷主键
+     * @return 真题卷
+     */
+    public LearnPaperReal selectLearnPaperRealById(Long id);
+
+    /**
+     * 查询真题卷列表
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 真题卷集合
+     */
+    public List<LearnPaperReal> selectLearnPaperRealList(LearnPaperReal learnPaperReal);
+
+    /**
+     * 新增真题卷
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 结果
+     */
+    public int insertLearnPaperReal(LearnPaperReal learnPaperReal);
+
+    /**
+     * 修改真题卷
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 结果
+     */
+    public int updateLearnPaperReal(LearnPaperReal learnPaperReal);
+
+    /**
+     * 批量删除真题卷
+     * 
+     * @param ids 需要删除的真题卷主键集合
+     * @return 结果
+     */
+    public int deleteLearnPaperRealByIds(Long[] ids);
+
+    /**
+     * 删除真题卷信息
+     * 
+     * @param id 真题卷主键
+     * @return 结果
+     */
+    public int deleteLearnPaperRealById(Long id);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnPaper;
+
+/**
+ * 试卷Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnPaperService 
+{
+    /**
+     * 查询试卷
+     * 
+     * @param id 试卷主键
+     * @return 试卷
+     */
+    public LearnPaper selectLearnPaperById(Long id);
+
+    /**
+     * 查询试卷列表
+     * 
+     * @param learnPaper 试卷
+     * @return 试卷集合
+     */
+    public List<LearnPaper> selectLearnPaperList(LearnPaper learnPaper);
+
+    /**
+     * 新增试卷
+     * 
+     * @param learnPaper 试卷
+     * @return 结果
+     */
+    public int insertLearnPaper(LearnPaper learnPaper);
+
+    /**
+     * 修改试卷
+     * 
+     * @param learnPaper 试卷
+     * @return 结果
+     */
+    public int updateLearnPaper(LearnPaper learnPaper);
+
+    /**
+     * 批量删除试卷
+     * 
+     * @param ids 需要删除的试卷主键集合
+     * @return 结果
+     */
+    public int deleteLearnPaperByIds(Long[] ids);
+
+    /**
+     * 删除试卷信息
+     * 
+     * @param id 试卷主键
+     * @return 结果
+     */
+    public int deleteLearnPaperById(Long id);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnQuestions;
+
+/**
+ * 试题Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnQuestionsService 
+{
+    /**
+     * 查询试题
+     * 
+     * @param id 试题主键
+     * @return 试题
+     */
+    public LearnQuestions selectLearnQuestionsById(Long id);
+
+    /**
+     * 查询试题列表
+     * 
+     * @param learnQuestions 试题
+     * @return 试题集合
+     */
+    public List<LearnQuestions> selectLearnQuestionsList(LearnQuestions learnQuestions);
+
+    /**
+     * 新增试题
+     * 
+     * @param learnQuestions 试题
+     * @return 结果
+     */
+    public int insertLearnQuestions(LearnQuestions learnQuestions);
+
+    /**
+     * 修改试题
+     * 
+     * @param learnQuestions 试题
+     * @return 结果
+     */
+    public int updateLearnQuestions(LearnQuestions learnQuestions);
+
+    /**
+     * 批量删除试题
+     * 
+     * @param ids 需要删除的试题主键集合
+     * @return 结果
+     */
+    public int deleteLearnQuestionsByIds(Long[] ids);
+
+    /**
+     * 删除试题信息
+     * 
+     * @param id 试题主键
+     * @return 结果
+     */
+    public int deleteLearnQuestionsById(Long id);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnStudent;
+
+/**
+ * 学生Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnStudentService 
+{
+    /**
+     * 查询学生
+     * 
+     * @param studentId 学生主键
+     * @return 学生
+     */
+    public LearnStudent selectLearnStudentByStudentId(Long studentId);
+
+    /**
+     * 查询学生列表
+     * 
+     * @param learnStudent 学生
+     * @return 学生集合
+     */
+    public List<LearnStudent> selectLearnStudentList(LearnStudent learnStudent);
+
+    /**
+     * 新增学生
+     * 
+     * @param learnStudent 学生
+     * @return 结果
+     */
+    public int insertLearnStudent(LearnStudent learnStudent);
+
+    /**
+     * 修改学生
+     * 
+     * @param learnStudent 学生
+     * @return 结果
+     */
+    public int updateLearnStudent(LearnStudent learnStudent);
+
+    /**
+     * 批量删除学生
+     * 
+     * @param studentIds 需要删除的学生主键集合
+     * @return 结果
+     */
+    public int deleteLearnStudentByStudentIds(Long[] studentIds);
+
+    /**
+     * 删除学生信息
+     * 
+     * @param studentId 学生主键
+     * @return 结果
+     */
+    public int deleteLearnStudentByStudentId(Long studentId);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnTestPaper;
+
+/**
+ * 批次测试卷Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnTestPaperService 
+{
+    /**
+     * 查询批次测试卷
+     * 
+     * @param id 批次测试卷主键
+     * @return 批次测试卷
+     */
+    public LearnTestPaper selectLearnTestPaperById(String id);
+
+    /**
+     * 查询批次测试卷列表
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 批次测试卷集合
+     */
+    public List<LearnTestPaper> selectLearnTestPaperList(LearnTestPaper learnTestPaper);
+
+    /**
+     * 新增批次测试卷
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 结果
+     */
+    public int insertLearnTestPaper(LearnTestPaper learnTestPaper);
+
+    /**
+     * 修改批次测试卷
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 结果
+     */
+    public int updateLearnTestPaper(LearnTestPaper learnTestPaper);
+
+    /**
+     * 批量删除批次测试卷
+     * 
+     * @param ids 需要删除的批次测试卷主键集合
+     * @return 结果
+     */
+    public int deleteLearnTestPaperByIds(String[] ids);
+
+    /**
+     * 删除批次测试卷信息
+     * 
+     * @param id 批次测试卷主键
+     * @return 结果
+     */
+    public int deleteLearnTestPaperById(String id);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnTest;
+
+/**
+ * 试卷批次Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnTestService 
+{
+    /**
+     * 查询试卷批次
+     * 
+     * @param batchId 试卷批次主键
+     * @return 试卷批次
+     */
+    public LearnTest selectLearnTestByBatchId(String batchId);
+
+    /**
+     * 查询试卷批次列表
+     * 
+     * @param learnTest 试卷批次
+     * @return 试卷批次集合
+     */
+    public List<LearnTest> selectLearnTestList(LearnTest learnTest);
+
+    /**
+     * 新增试卷批次
+     * 
+     * @param learnTest 试卷批次
+     * @return 结果
+     */
+    public int insertLearnTest(LearnTest learnTest);
+
+    /**
+     * 修改试卷批次
+     * 
+     * @param learnTest 试卷批次
+     * @return 结果
+     */
+    public int updateLearnTest(LearnTest learnTest);
+
+    /**
+     * 批量删除试卷批次
+     * 
+     * @param batchIds 需要删除的试卷批次主键集合
+     * @return 结果
+     */
+    public int deleteLearnTestByBatchIds(String[] batchIds);
+
+    /**
+     * 删除试卷批次信息
+     * 
+     * @param batchId 试卷批次主键
+     * @return 结果
+     */
+    public int deleteLearnTestByBatchId(String batchId);
+}

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

@@ -0,0 +1,61 @@
+package com.ruoyi.learn.service;
+
+import java.util.List;
+import com.ruoyi.learn.domain.LearnTestStudent;
+
+/**
+ * 测试学生Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+public interface ILearnTestStudentService 
+{
+    /**
+     * 查询测试学生
+     * 
+     * @param id 测试学生主键
+     * @return 测试学生
+     */
+    public LearnTestStudent selectLearnTestStudentById(String id);
+
+    /**
+     * 查询测试学生列表
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 测试学生集合
+     */
+    public List<LearnTestStudent> selectLearnTestStudentList(LearnTestStudent learnTestStudent);
+
+    /**
+     * 新增测试学生
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 结果
+     */
+    public int insertLearnTestStudent(LearnTestStudent learnTestStudent);
+
+    /**
+     * 修改测试学生
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 结果
+     */
+    public int updateLearnTestStudent(LearnTestStudent learnTestStudent);
+
+    /**
+     * 批量删除测试学生
+     * 
+     * @param ids 需要删除的测试学生主键集合
+     * @return 结果
+     */
+    public int deleteLearnTestStudentByIds(String[] ids);
+
+    /**
+     * 删除测试学生信息
+     * 
+     * @param id 测试学生主键
+     * @return 结果
+     */
+    public int deleteLearnTestStudentById(String id);
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperQuestionServiceImpl.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.LearnPaperQuestionMapper;
+import com.ruoyi.learn.domain.LearnPaperQuestion;
+import com.ruoyi.learn.service.ILearnPaperQuestionService;
+
+/**
+ * 试卷题关系Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnPaperQuestionServiceImpl implements ILearnPaperQuestionService 
+{
+    @Autowired
+    private LearnPaperQuestionMapper learnPaperQuestionMapper;
+
+    /**
+     * 查询试卷题关系
+     * 
+     * @param id 试卷题关系主键
+     * @return 试卷题关系
+     */
+    @Override
+    public LearnPaperQuestion selectLearnPaperQuestionById(Long id)
+    {
+        return learnPaperQuestionMapper.selectLearnPaperQuestionById(id);
+    }
+
+    /**
+     * 查询试卷题关系列表
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 试卷题关系
+     */
+    @Override
+    public List<LearnPaperQuestion> selectLearnPaperQuestionList(LearnPaperQuestion learnPaperQuestion)
+    {
+        return learnPaperQuestionMapper.selectLearnPaperQuestionList(learnPaperQuestion);
+    }
+
+    /**
+     * 新增试卷题关系
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 结果
+     */
+    @Override
+    public int insertLearnPaperQuestion(LearnPaperQuestion learnPaperQuestion)
+    {
+        learnPaperQuestion.setCreateTime(DateUtils.getNowDate());
+        return learnPaperQuestionMapper.insertLearnPaperQuestion(learnPaperQuestion);
+    }
+
+    /**
+     * 修改试卷题关系
+     * 
+     * @param learnPaperQuestion 试卷题关系
+     * @return 结果
+     */
+    @Override
+    public int updateLearnPaperQuestion(LearnPaperQuestion learnPaperQuestion)
+    {
+        return learnPaperQuestionMapper.updateLearnPaperQuestion(learnPaperQuestion);
+    }
+
+    /**
+     * 批量删除试卷题关系
+     * 
+     * @param ids 需要删除的试卷题关系主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPaperQuestionByIds(Long[] ids)
+    {
+        return learnPaperQuestionMapper.deleteLearnPaperQuestionByIds(ids);
+    }
+
+    /**
+     * 删除试卷题关系信息
+     * 
+     * @param id 试卷题关系主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPaperQuestionById(Long id)
+    {
+        return learnPaperQuestionMapper.deleteLearnPaperQuestionById(id);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperRealServiceImpl.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.LearnPaperRealMapper;
+import com.ruoyi.learn.domain.LearnPaperReal;
+import com.ruoyi.learn.service.ILearnPaperRealService;
+
+/**
+ * 真题卷Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnPaperRealServiceImpl implements ILearnPaperRealService 
+{
+    @Autowired
+    private LearnPaperRealMapper learnPaperRealMapper;
+
+    /**
+     * 查询真题卷
+     * 
+     * @param id 真题卷主键
+     * @return 真题卷
+     */
+    @Override
+    public LearnPaperReal selectLearnPaperRealById(Long id)
+    {
+        return learnPaperRealMapper.selectLearnPaperRealById(id);
+    }
+
+    /**
+     * 查询真题卷列表
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 真题卷
+     */
+    @Override
+    public List<LearnPaperReal> selectLearnPaperRealList(LearnPaperReal learnPaperReal)
+    {
+        return learnPaperRealMapper.selectLearnPaperRealList(learnPaperReal);
+    }
+
+    /**
+     * 新增真题卷
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 结果
+     */
+    @Override
+    public int insertLearnPaperReal(LearnPaperReal learnPaperReal)
+    {
+        learnPaperReal.setCreateTime(DateUtils.getNowDate());
+        return learnPaperRealMapper.insertLearnPaperReal(learnPaperReal);
+    }
+
+    /**
+     * 修改真题卷
+     * 
+     * @param learnPaperReal 真题卷
+     * @return 结果
+     */
+    @Override
+    public int updateLearnPaperReal(LearnPaperReal learnPaperReal)
+    {
+        return learnPaperRealMapper.updateLearnPaperReal(learnPaperReal);
+    }
+
+    /**
+     * 批量删除真题卷
+     * 
+     * @param ids 需要删除的真题卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPaperRealByIds(Long[] ids)
+    {
+        return learnPaperRealMapper.deleteLearnPaperRealByIds(ids);
+    }
+
+    /**
+     * 删除真题卷信息
+     * 
+     * @param id 真题卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPaperRealById(Long id)
+    {
+        return learnPaperRealMapper.deleteLearnPaperRealById(id);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnPaperServiceImpl.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.LearnPaperMapper;
+import com.ruoyi.learn.domain.LearnPaper;
+import com.ruoyi.learn.service.ILearnPaperService;
+
+/**
+ * 试卷Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnPaperServiceImpl implements ILearnPaperService 
+{
+    @Autowired
+    private LearnPaperMapper learnPaperMapper;
+
+    /**
+     * 查询试卷
+     * 
+     * @param id 试卷主键
+     * @return 试卷
+     */
+    @Override
+    public LearnPaper selectLearnPaperById(Long id)
+    {
+        return learnPaperMapper.selectLearnPaperById(id);
+    }
+
+    /**
+     * 查询试卷列表
+     * 
+     * @param learnPaper 试卷
+     * @return 试卷
+     */
+    @Override
+    public List<LearnPaper> selectLearnPaperList(LearnPaper learnPaper)
+    {
+        return learnPaperMapper.selectLearnPaperList(learnPaper);
+    }
+
+    /**
+     * 新增试卷
+     * 
+     * @param learnPaper 试卷
+     * @return 结果
+     */
+    @Override
+    public int insertLearnPaper(LearnPaper learnPaper)
+    {
+        learnPaper.setCreateTime(DateUtils.getNowDate());
+        return learnPaperMapper.insertLearnPaper(learnPaper);
+    }
+
+    /**
+     * 修改试卷
+     * 
+     * @param learnPaper 试卷
+     * @return 结果
+     */
+    @Override
+    public int updateLearnPaper(LearnPaper learnPaper)
+    {
+        return learnPaperMapper.updateLearnPaper(learnPaper);
+    }
+
+    /**
+     * 批量删除试卷
+     * 
+     * @param ids 需要删除的试卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPaperByIds(Long[] ids)
+    {
+        return learnPaperMapper.deleteLearnPaperByIds(ids);
+    }
+
+    /**
+     * 删除试卷信息
+     * 
+     * @param id 试卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnPaperById(Long id)
+    {
+        return learnPaperMapper.deleteLearnPaperById(id);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnQuestionsServiceImpl.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.LearnQuestionsMapper;
+import com.ruoyi.learn.domain.LearnQuestions;
+import com.ruoyi.learn.service.ILearnQuestionsService;
+
+/**
+ * 试题Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnQuestionsServiceImpl implements ILearnQuestionsService 
+{
+    @Autowired
+    private LearnQuestionsMapper learnQuestionsMapper;
+
+    /**
+     * 查询试题
+     * 
+     * @param id 试题主键
+     * @return 试题
+     */
+    @Override
+    public LearnQuestions selectLearnQuestionsById(Long id)
+    {
+        return learnQuestionsMapper.selectLearnQuestionsById(id);
+    }
+
+    /**
+     * 查询试题列表
+     * 
+     * @param learnQuestions 试题
+     * @return 试题
+     */
+    @Override
+    public List<LearnQuestions> selectLearnQuestionsList(LearnQuestions learnQuestions)
+    {
+        return learnQuestionsMapper.selectLearnQuestionsList(learnQuestions);
+    }
+
+    /**
+     * 新增试题
+     * 
+     * @param learnQuestions 试题
+     * @return 结果
+     */
+    @Override
+    public int insertLearnQuestions(LearnQuestions learnQuestions)
+    {
+        learnQuestions.setCreateTime(DateUtils.getNowDate());
+        return learnQuestionsMapper.insertLearnQuestions(learnQuestions);
+    }
+
+    /**
+     * 修改试题
+     * 
+     * @param learnQuestions 试题
+     * @return 结果
+     */
+    @Override
+    public int updateLearnQuestions(LearnQuestions learnQuestions)
+    {
+        return learnQuestionsMapper.updateLearnQuestions(learnQuestions);
+    }
+
+    /**
+     * 批量删除试题
+     * 
+     * @param ids 需要删除的试题主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnQuestionsByIds(Long[] ids)
+    {
+        return learnQuestionsMapper.deleteLearnQuestionsByIds(ids);
+    }
+
+    /**
+     * 删除试题信息
+     * 
+     * @param id 试题主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnQuestionsById(Long id)
+    {
+        return learnQuestionsMapper.deleteLearnQuestionsById(id);
+    }
+}

+ 93 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnStudentServiceImpl.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.LearnStudentMapper;
+import com.ruoyi.learn.domain.LearnStudent;
+import com.ruoyi.learn.service.ILearnStudentService;
+
+/**
+ * 学生Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnStudentServiceImpl implements ILearnStudentService 
+{
+    @Autowired
+    private LearnStudentMapper learnStudentMapper;
+
+    /**
+     * 查询学生
+     * 
+     * @param studentId 学生主键
+     * @return 学生
+     */
+    @Override
+    public LearnStudent selectLearnStudentByStudentId(Long studentId)
+    {
+        return learnStudentMapper.selectLearnStudentByStudentId(studentId);
+    }
+
+    /**
+     * 查询学生列表
+     * 
+     * @param learnStudent 学生
+     * @return 学生
+     */
+    @Override
+    public List<LearnStudent> selectLearnStudentList(LearnStudent learnStudent)
+    {
+        return learnStudentMapper.selectLearnStudentList(learnStudent);
+    }
+
+    /**
+     * 新增学生
+     * 
+     * @param learnStudent 学生
+     * @return 结果
+     */
+    @Override
+    public int insertLearnStudent(LearnStudent learnStudent)
+    {
+        return learnStudentMapper.insertLearnStudent(learnStudent);
+    }
+
+    /**
+     * 修改学生
+     * 
+     * @param learnStudent 学生
+     * @return 结果
+     */
+    @Override
+    public int updateLearnStudent(LearnStudent learnStudent)
+    {
+        return learnStudentMapper.updateLearnStudent(learnStudent);
+    }
+
+    /**
+     * 批量删除学生
+     * 
+     * @param studentIds 需要删除的学生主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnStudentByStudentIds(Long[] studentIds)
+    {
+        return learnStudentMapper.deleteLearnStudentByStudentIds(studentIds);
+    }
+
+    /**
+     * 删除学生信息
+     * 
+     * @param studentId 学生主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnStudentByStudentId(Long studentId)
+    {
+        return learnStudentMapper.deleteLearnStudentByStudentId(studentId);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnTestPaperServiceImpl.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.LearnTestPaperMapper;
+import com.ruoyi.learn.domain.LearnTestPaper;
+import com.ruoyi.learn.service.ILearnTestPaperService;
+
+/**
+ * 批次测试卷Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnTestPaperServiceImpl implements ILearnTestPaperService 
+{
+    @Autowired
+    private LearnTestPaperMapper learnTestPaperMapper;
+
+    /**
+     * 查询批次测试卷
+     * 
+     * @param id 批次测试卷主键
+     * @return 批次测试卷
+     */
+    @Override
+    public LearnTestPaper selectLearnTestPaperById(String id)
+    {
+        return learnTestPaperMapper.selectLearnTestPaperById(id);
+    }
+
+    /**
+     * 查询批次测试卷列表
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 批次测试卷
+     */
+    @Override
+    public List<LearnTestPaper> selectLearnTestPaperList(LearnTestPaper learnTestPaper)
+    {
+        return learnTestPaperMapper.selectLearnTestPaperList(learnTestPaper);
+    }
+
+    /**
+     * 新增批次测试卷
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 结果
+     */
+    @Override
+    public int insertLearnTestPaper(LearnTestPaper learnTestPaper)
+    {
+        learnTestPaper.setCreateTime(DateUtils.getNowDate());
+        return learnTestPaperMapper.insertLearnTestPaper(learnTestPaper);
+    }
+
+    /**
+     * 修改批次测试卷
+     * 
+     * @param learnTestPaper 批次测试卷
+     * @return 结果
+     */
+    @Override
+    public int updateLearnTestPaper(LearnTestPaper learnTestPaper)
+    {
+        return learnTestPaperMapper.updateLearnTestPaper(learnTestPaper);
+    }
+
+    /**
+     * 批量删除批次测试卷
+     * 
+     * @param ids 需要删除的批次测试卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnTestPaperByIds(String[] ids)
+    {
+        return learnTestPaperMapper.deleteLearnTestPaperByIds(ids);
+    }
+
+    /**
+     * 删除批次测试卷信息
+     * 
+     * @param id 批次测试卷主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnTestPaperById(String id)
+    {
+        return learnTestPaperMapper.deleteLearnTestPaperById(id);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnTestServiceImpl.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.LearnTestMapper;
+import com.ruoyi.learn.domain.LearnTest;
+import com.ruoyi.learn.service.ILearnTestService;
+
+/**
+ * 试卷批次Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnTestServiceImpl implements ILearnTestService 
+{
+    @Autowired
+    private LearnTestMapper learnTestMapper;
+
+    /**
+     * 查询试卷批次
+     * 
+     * @param batchId 试卷批次主键
+     * @return 试卷批次
+     */
+    @Override
+    public LearnTest selectLearnTestByBatchId(String batchId)
+    {
+        return learnTestMapper.selectLearnTestByBatchId(batchId);
+    }
+
+    /**
+     * 查询试卷批次列表
+     * 
+     * @param learnTest 试卷批次
+     * @return 试卷批次
+     */
+    @Override
+    public List<LearnTest> selectLearnTestList(LearnTest learnTest)
+    {
+        return learnTestMapper.selectLearnTestList(learnTest);
+    }
+
+    /**
+     * 新增试卷批次
+     * 
+     * @param learnTest 试卷批次
+     * @return 结果
+     */
+    @Override
+    public int insertLearnTest(LearnTest learnTest)
+    {
+        learnTest.setCreateTime(DateUtils.getNowDate());
+        return learnTestMapper.insertLearnTest(learnTest);
+    }
+
+    /**
+     * 修改试卷批次
+     * 
+     * @param learnTest 试卷批次
+     * @return 结果
+     */
+    @Override
+    public int updateLearnTest(LearnTest learnTest)
+    {
+        return learnTestMapper.updateLearnTest(learnTest);
+    }
+
+    /**
+     * 批量删除试卷批次
+     * 
+     * @param batchIds 需要删除的试卷批次主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnTestByBatchIds(String[] batchIds)
+    {
+        return learnTestMapper.deleteLearnTestByBatchIds(batchIds);
+    }
+
+    /**
+     * 删除试卷批次信息
+     * 
+     * @param batchId 试卷批次主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnTestByBatchId(String batchId)
+    {
+        return learnTestMapper.deleteLearnTestByBatchId(batchId);
+    }
+}

+ 95 - 0
ie-system/src/main/java/com/ruoyi/learn/service/impl/LearnTestStudentServiceImpl.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.LearnTestStudentMapper;
+import com.ruoyi.learn.domain.LearnTestStudent;
+import com.ruoyi.learn.service.ILearnTestStudentService;
+
+/**
+ * 测试学生Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-09-18
+ */
+@Service
+public class LearnTestStudentServiceImpl implements ILearnTestStudentService 
+{
+    @Autowired
+    private LearnTestStudentMapper learnTestStudentMapper;
+
+    /**
+     * 查询测试学生
+     * 
+     * @param id 测试学生主键
+     * @return 测试学生
+     */
+    @Override
+    public LearnTestStudent selectLearnTestStudentById(String id)
+    {
+        return learnTestStudentMapper.selectLearnTestStudentById(id);
+    }
+
+    /**
+     * 查询测试学生列表
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 测试学生
+     */
+    @Override
+    public List<LearnTestStudent> selectLearnTestStudentList(LearnTestStudent learnTestStudent)
+    {
+        return learnTestStudentMapper.selectLearnTestStudentList(learnTestStudent);
+    }
+
+    /**
+     * 新增测试学生
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 结果
+     */
+    @Override
+    public int insertLearnTestStudent(LearnTestStudent learnTestStudent)
+    {
+        learnTestStudent.setCreateTime(DateUtils.getNowDate());
+        return learnTestStudentMapper.insertLearnTestStudent(learnTestStudent);
+    }
+
+    /**
+     * 修改测试学生
+     * 
+     * @param learnTestStudent 测试学生
+     * @return 结果
+     */
+    @Override
+    public int updateLearnTestStudent(LearnTestStudent learnTestStudent)
+    {
+        return learnTestStudentMapper.updateLearnTestStudent(learnTestStudent);
+    }
+
+    /**
+     * 批量删除测试学生
+     * 
+     * @param ids 需要删除的测试学生主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnTestStudentByIds(String[] ids)
+    {
+        return learnTestStudentMapper.deleteLearnTestStudentByIds(ids);
+    }
+
+    /**
+     * 删除测试学生信息
+     * 
+     * @param id 测试学生主键
+     * @return 结果
+     */
+    @Override
+    public int deleteLearnTestStudentById(String id)
+    {
+        return learnTestStudentMapper.deleteLearnTestStudentById(id);
+    }
+}

+ 126 - 0
ie-system/src/main/resources/mapper/learn/LearnPaperMapper.xml

@@ -0,0 +1,126 @@
+<?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.LearnPaperMapper">
+    
+    <resultMap type="LearnPaper" id="LearnPaperResult">
+        <result property="id"    column="id"    />
+        <result property="subjectId"    column="subjectId"    />
+        <result property="paperName"    column="paperName"    />
+        <result property="year"    column="year"    />
+        <result property="paperType"    column="paperType"    />
+        <result property="number"    column="number"    />
+        <result property="fenshu"    column="fenshu"    />
+        <result property="paperSource"    column="paperSource"    />
+        <result property="directKey"    column="direct_key"    />
+        <result property="tiid"    column="tiid"    />
+        <result property="osspath"    column="osspath"    />
+        <result property="filename"    column="filename"    />
+        <result property="relateId"    column="relate_id"    />
+        <result property="locations"    column="locations"    />
+        <result property="examineeTypes"    column="examineeTypes"    />
+        <result property="createTime"    column="createTime"    />
+    </resultMap>
+
+    <sql id="selectLearnPaperVo">
+        select id, subjectId, paperName, year, paperType, number, fenshu, paperSource, direct_key, tiid, osspath, filename, relate_id, locations, examineeTypes, createTime from learn_paper
+    </sql>
+
+    <select id="selectLearnPaperList" parameterType="LearnPaper" resultMap="LearnPaperResult">
+        <include refid="selectLearnPaperVo"/>
+        <where>  
+            <if test="subjectId != null "> and subjectId = #{subjectId}</if>
+            <if test="paperName != null  and paperName != ''"> and paperName like concat('%', #{paperName}, '%')</if>
+            <if test="year != null "> and year = #{year}</if>
+            <if test="paperType != null  and paperType != ''"> and paperType = #{paperType}</if>
+            <if test="number != null  and number != ''"> and number = #{number}</if>
+            <if test="fenshu != null "> and fenshu = #{fenshu}</if>
+            <if test="paperSource != null "> and paperSource = #{paperSource}</if>
+            <if test="directKey != null  and directKey != ''"> and direct_key = #{directKey}</if>
+            <if test="tiid != null  and tiid != ''"> and tiid = #{tiid}</if>
+            <if test="osspath != null  and osspath != ''"> and osspath = #{osspath}</if>
+            <if test="filename != null  and filename != ''"> and filename like concat('%', #{filename}, '%')</if>
+            <if test="relateId != null "> and relate_id = #{relateId}</if>
+            <if test="locations != null  and locations != ''"> and locations = #{locations}</if>
+            <if test="examineeTypes != null  and examineeTypes != ''"> and examineeTypes = #{examineeTypes}</if>
+            <if test="createTime != null "> and createTime = #{createTime}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnPaperById" parameterType="Long" resultMap="LearnPaperResult">
+        <include refid="selectLearnPaperVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnPaper" parameterType="LearnPaper" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_paper
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="subjectId != null">subjectId,</if>
+            <if test="paperName != null">paperName,</if>
+            <if test="year != null">year,</if>
+            <if test="paperType != null">paperType,</if>
+            <if test="number != null">number,</if>
+            <if test="fenshu != null">fenshu,</if>
+            <if test="paperSource != null">paperSource,</if>
+            <if test="directKey != null and directKey != ''">direct_key,</if>
+            <if test="tiid != null">tiid,</if>
+            <if test="osspath != null">osspath,</if>
+            <if test="filename != null">filename,</if>
+            <if test="relateId != null">relate_id,</if>
+            <if test="locations != null">locations,</if>
+            <if test="examineeTypes != null">examineeTypes,</if>
+            <if test="createTime != null">createTime,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="paperName != null">#{paperName},</if>
+            <if test="year != null">#{year},</if>
+            <if test="paperType != null">#{paperType},</if>
+            <if test="number != null">#{number},</if>
+            <if test="fenshu != null">#{fenshu},</if>
+            <if test="paperSource != null">#{paperSource},</if>
+            <if test="directKey != null and directKey != ''">#{directKey},</if>
+            <if test="tiid != null">#{tiid},</if>
+            <if test="osspath != null">#{osspath},</if>
+            <if test="filename != null">#{filename},</if>
+            <if test="relateId != null">#{relateId},</if>
+            <if test="locations != null">#{locations},</if>
+            <if test="examineeTypes != null">#{examineeTypes},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnPaper" parameterType="LearnPaper">
+        update learn_paper
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="subjectId != null">subjectId = #{subjectId},</if>
+            <if test="paperName != null">paperName = #{paperName},</if>
+            <if test="year != null">year = #{year},</if>
+            <if test="paperType != null">paperType = #{paperType},</if>
+            <if test="number != null">number = #{number},</if>
+            <if test="fenshu != null">fenshu = #{fenshu},</if>
+            <if test="paperSource != null">paperSource = #{paperSource},</if>
+            <if test="directKey != null and directKey != ''">direct_key = #{directKey},</if>
+            <if test="tiid != null">tiid = #{tiid},</if>
+            <if test="osspath != null">osspath = #{osspath},</if>
+            <if test="filename != null">filename = #{filename},</if>
+            <if test="relateId != null">relate_id = #{relateId},</if>
+            <if test="locations != null">locations = #{locations},</if>
+            <if test="examineeTypes != null">examineeTypes = #{examineeTypes},</if>
+            <if test="createTime != null">createTime = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnPaperById" parameterType="Long">
+        delete from learn_paper where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnPaperByIds" parameterType="String">
+        delete from learn_paper where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 76 - 0
ie-system/src/main/resources/mapper/learn/LearnPaperQuestionMapper.xml

@@ -0,0 +1,76 @@
+<?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.LearnPaperQuestionMapper">
+    
+    <resultMap type="LearnPaperQuestion" id="LearnPaperQuestionResult">
+        <result property="id"    column="id"    />
+        <result property="paperId"    column="paper_id"    />
+        <result property="questionId"    column="question_id"    />
+        <result property="seq"    column="seq"    />
+        <result property="score"    column="score"    />
+        <result property="createTime"    column="createTime"    />
+    </resultMap>
+
+    <sql id="selectLearnPaperQuestionVo">
+        select id, paper_id, question_id, seq, score, createTime from learn_paper_question
+    </sql>
+
+    <select id="selectLearnPaperQuestionList" parameterType="LearnPaperQuestion" resultMap="LearnPaperQuestionResult">
+        <include refid="selectLearnPaperQuestionVo"/>
+        <where>  
+            <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="questionId != null "> and question_id = #{questionId}</if>
+            <if test="seq != null "> and seq = #{seq}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="createTime != null "> and createTime = #{createTime}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnPaperQuestionById" parameterType="Long" resultMap="LearnPaperQuestionResult">
+        <include refid="selectLearnPaperQuestionVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnPaperQuestion" parameterType="LearnPaperQuestion" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_paper_question
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="paperId != null">paper_id,</if>
+            <if test="questionId != null">question_id,</if>
+            <if test="seq != null">seq,</if>
+            <if test="score != null">score,</if>
+            <if test="createTime != null">createTime,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="paperId != null">#{paperId},</if>
+            <if test="questionId != null">#{questionId},</if>
+            <if test="seq != null">#{seq},</if>
+            <if test="score != null">#{score},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnPaperQuestion" parameterType="LearnPaperQuestion">
+        update learn_paper_question
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="paperId != null">paper_id = #{paperId},</if>
+            <if test="questionId != null">question_id = #{questionId},</if>
+            <if test="seq != null">seq = #{seq},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="createTime != null">createTime = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnPaperQuestionById" parameterType="Long">
+        delete from learn_paper_question where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnPaperQuestionByIds" parameterType="String">
+        delete from learn_paper_question where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 121 - 0
ie-system/src/main/resources/mapper/learn/LearnPaperRealMapper.xml

@@ -0,0 +1,121 @@
+<?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.LearnPaperRealMapper">
+    
+    <resultMap type="LearnPaperReal" id="LearnPaperRealResult">
+        <result property="id"    column="id"    />
+        <result property="subjectId"    column="subjectId"    />
+        <result property="paperName"    column="paperName"    />
+        <result property="year"    column="year"    />
+        <result property="paperType"    column="paperType"    />
+        <result property="number"    column="number"    />
+        <result property="fenshu"    column="fenshu"    />
+        <result property="paperSource"    column="paperSource"    />
+        <result property="online"    column="online"    />
+        <result property="tiid"    column="tiid"    />
+        <result property="osspath"    column="osspath"    />
+        <result property="filename"    column="filename"    />
+        <result property="locations"    column="locations"    />
+        <result property="examineeType"    column="examineeType"    />
+        <result property="createTime"    column="createTime"    />
+    </resultMap>
+
+    <sql id="selectLearnPaperRealVo">
+        select id, subjectId, paperName, year, paperType, number, fenshu, paperSource, online, tiid, osspath, filename, locations, examineeType, createTime from learn_paper_real
+    </sql>
+
+    <select id="selectLearnPaperRealList" parameterType="LearnPaperReal" resultMap="LearnPaperRealResult">
+        <include refid="selectLearnPaperRealVo"/>
+        <where>  
+            <if test="subjectId != null "> and subjectId = #{subjectId}</if>
+            <if test="paperName != null  and paperName != ''"> and paperName like concat('%', #{paperName}, '%')</if>
+            <if test="year != null "> and year = #{year}</if>
+            <if test="paperType != null  and paperType != ''"> and paperType = #{paperType}</if>
+            <if test="number != null  and number != ''"> and number = #{number}</if>
+            <if test="fenshu != null "> and fenshu = #{fenshu}</if>
+            <if test="paperSource != null "> and paperSource = #{paperSource}</if>
+            <if test="online != null "> and online = #{online}</if>
+            <if test="tiid != null  and tiid != ''"> and tiid = #{tiid}</if>
+            <if test="osspath != null  and osspath != ''"> and osspath = #{osspath}</if>
+            <if test="filename != null  and filename != ''"> and filename like concat('%', #{filename}, '%')</if>
+            <if test="locations != null  and locations != ''"> and locations = #{locations}</if>
+            <if test="examineeType != null  and examineeType != ''"> and examineeType = #{examineeType}</if>
+            <if test="createTime != null "> and createTime = #{createTime}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnPaperRealById" parameterType="Long" resultMap="LearnPaperRealResult">
+        <include refid="selectLearnPaperRealVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnPaperReal" parameterType="LearnPaperReal" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_paper_real
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="subjectId != null">subjectId,</if>
+            <if test="paperName != null and paperName != ''">paperName,</if>
+            <if test="year != null">year,</if>
+            <if test="paperType != null">paperType,</if>
+            <if test="number != null">number,</if>
+            <if test="fenshu != null">fenshu,</if>
+            <if test="paperSource != null">paperSource,</if>
+            <if test="online != null">online,</if>
+            <if test="tiid != null">tiid,</if>
+            <if test="osspath != null">osspath,</if>
+            <if test="filename != null">filename,</if>
+            <if test="locations != null and locations != ''">locations,</if>
+            <if test="examineeType != null and examineeType != ''">examineeType,</if>
+            <if test="createTime != null">createTime,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="paperName != null and paperName != ''">#{paperName},</if>
+            <if test="year != null">#{year},</if>
+            <if test="paperType != null">#{paperType},</if>
+            <if test="number != null">#{number},</if>
+            <if test="fenshu != null">#{fenshu},</if>
+            <if test="paperSource != null">#{paperSource},</if>
+            <if test="online != null">#{online},</if>
+            <if test="tiid != null">#{tiid},</if>
+            <if test="osspath != null">#{osspath},</if>
+            <if test="filename != null">#{filename},</if>
+            <if test="locations != null and locations != ''">#{locations},</if>
+            <if test="examineeType != null and examineeType != ''">#{examineeType},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnPaperReal" parameterType="LearnPaperReal">
+        update learn_paper_real
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="subjectId != null">subjectId = #{subjectId},</if>
+            <if test="paperName != null and paperName != ''">paperName = #{paperName},</if>
+            <if test="year != null">year = #{year},</if>
+            <if test="paperType != null">paperType = #{paperType},</if>
+            <if test="number != null">number = #{number},</if>
+            <if test="fenshu != null">fenshu = #{fenshu},</if>
+            <if test="paperSource != null">paperSource = #{paperSource},</if>
+            <if test="online != null">online = #{online},</if>
+            <if test="tiid != null">tiid = #{tiid},</if>
+            <if test="osspath != null">osspath = #{osspath},</if>
+            <if test="filename != null">filename = #{filename},</if>
+            <if test="locations != null and locations != ''">locations = #{locations},</if>
+            <if test="examineeType != null and examineeType != ''">examineeType = #{examineeType},</if>
+            <if test="createTime != null">createTime = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnPaperRealById" parameterType="Long">
+        delete from learn_paper_real where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnPaperRealByIds" parameterType="String">
+        delete from learn_paper_real where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 270 - 0
ie-system/src/main/resources/mapper/learn/LearnQuestionsMapper.xml

@@ -0,0 +1,270 @@
+<?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.LearnQuestionsMapper">
+    
+    <resultMap type="LearnQuestions" id="LearnQuestionsResult">
+        <result property="id"    column="id"    />
+        <result property="title"    column="title"    />
+        <result property="optionA"    column="option_a"    />
+        <result property="optionB"    column="option_b"    />
+        <result property="optionC"    column="option_c"    />
+        <result property="optionD"    column="option_d"    />
+        <result property="optionE"    column="option_e"    />
+        <result property="optionF"    column="option_f"    />
+        <result property="optionG"    column="option_g"    />
+        <result property="answer1"    column="answer1"    />
+        <result property="answer2"    column="answer2"    />
+        <result property="qtpye"    column="qtpye"    />
+        <result property="subjectId"    column="subjectId"    />
+        <result property="paperId"    column="paperId"    />
+        <result property="knowledgeId"    column="knowledgeId"    />
+        <result property="diff"    column="diff"    />
+        <result property="similarity"    column="similarity"    />
+        <result property="parse"    column="parse"    />
+        <result property="knowId"    column="knowId"    />
+        <result property="gradeId"    column="gradeId"    />
+        <result property="knowledges"    column="knowledges"    />
+        <result property="area"    column="area"    />
+        <result property="year"    column="year"    />
+        <result property="paperTpye"    column="paperTpye"    />
+        <result property="source"    column="source"    />
+        <result property="fromSite"    column="fromSite"    />
+        <result property="isSub"    column="isSub"    />
+        <result property="isNormal"    column="isNormal"    />
+        <result property="isKonw"    column="isKonw"    />
+        <result property="tiid"    column="tiid"    />
+        <result property="md5"    column="md5"    />
+        <result property="isunique"    column="isunique"    />
+        <result property="md52"    column="md52"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="score"    column="score"    />
+        <result property="options"    column="options"    />
+        <result property="number"    column="number"    />
+        <result property="paperTypeTitle"    column="paperTypeTitle"    />
+        <result property="options0"    column="options0"    />
+        <result property="title0"    column="title0"    />
+        <result property="title1"    column="title1"    />
+        <result property="parse0"    column="parse0"    />
+        <result property="answer0"    column="answer0"    />
+        <result property="isUpdate"    column="isUpdate"    />
+        <result property="isSubType"    column="isSubType"    />
+    </resultMap>
+
+    <sql id="selectLearnQuestionsVo">
+        select id, title, option_a, option_b, option_c, option_d, option_e, option_f, option_g, answer1, answer2, qtpye, subjectId, paperId, knowledgeId, diff, similarity, parse, knowId, gradeId, knowledges, area, year, paperTpye, source, fromSite, isSub, isNormal, isKonw, tiid, md5, isunique, md52, create_time, score, options, number, paperTypeTitle, options0, title0, title1, parse0, answer0, isUpdate, isSubType from learn_questions
+    </sql>
+
+    <select id="selectLearnQuestionsList" parameterType="LearnQuestions" resultMap="LearnQuestionsResult">
+        <include refid="selectLearnQuestionsVo"/>
+        <where>  
+            <if test="title != null  and title != ''"> and title = #{title}</if>
+            <if test="optionA != null  and optionA != ''"> and option_a = #{optionA}</if>
+            <if test="optionB != null  and optionB != ''"> and option_b = #{optionB}</if>
+            <if test="optionC != null  and optionC != ''"> and option_c = #{optionC}</if>
+            <if test="optionD != null  and optionD != ''"> and option_d = #{optionD}</if>
+            <if test="optionE != null  and optionE != ''"> and option_e = #{optionE}</if>
+            <if test="optionF != null  and optionF != ''"> and option_f = #{optionF}</if>
+            <if test="optionG != null  and optionG != ''"> and option_g = #{optionG}</if>
+            <if test="answer1 != null  and answer1 != ''"> and answer1 = #{answer1}</if>
+            <if test="answer2 != null  and answer2 != ''"> and answer2 = #{answer2}</if>
+            <if test="qtpye != null  and qtpye != ''"> and qtpye = #{qtpye}</if>
+            <if test="subjectId != null "> and subjectId = #{subjectId}</if>
+            <if test="paperId != null "> and paperId = #{paperId}</if>
+            <if test="knowledgeId != null "> and knowledgeId = #{knowledgeId}</if>
+            <if test="diff != null "> and diff = #{diff}</if>
+            <if test="similarity != null "> and similarity = #{similarity}</if>
+            <if test="parse != null  and parse != ''"> and parse = #{parse}</if>
+            <if test="knowId != null "> and knowId = #{knowId}</if>
+            <if test="gradeId != null "> and gradeId = #{gradeId}</if>
+            <if test="knowledges != null  and knowledges != ''"> and knowledges = #{knowledges}</if>
+            <if test="area != null  and area != ''"> and area = #{area}</if>
+            <if test="year != null "> and year = #{year}</if>
+            <if test="paperTpye != null  and paperTpye != ''"> and paperTpye = #{paperTpye}</if>
+            <if test="source != null  and source != ''"> and source = #{source}</if>
+            <if test="fromSite != null  and fromSite != ''"> and fromSite = #{fromSite}</if>
+            <if test="isSub != null "> and isSub = #{isSub}</if>
+            <if test="isNormal != null "> and isNormal = #{isNormal}</if>
+            <if test="isKonw != null "> and isKonw = #{isKonw}</if>
+            <if test="tiid != null  and tiid != ''"> and tiid = #{tiid}</if>
+            <if test="md5 != null  and md5 != ''"> and md5 = #{md5}</if>
+            <if test="isunique != null "> and isunique = #{isunique}</if>
+            <if test="md52 != null  and md52 != ''"> and md52 = #{md52}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="options != null  and options != ''"> and options = #{options}</if>
+            <if test="number != null "> and number = #{number}</if>
+            <if test="paperTypeTitle != null  and paperTypeTitle != ''"> and paperTypeTitle = #{paperTypeTitle}</if>
+            <if test="options0 != null  and options0 != ''"> and options0 = #{options0}</if>
+            <if test="title0 != null  and title0 != ''"> and title0 = #{title0}</if>
+            <if test="title1 != null  and title1 != ''"> and title1 = #{title1}</if>
+            <if test="parse0 != null  and parse0 != ''"> and parse0 = #{parse0}</if>
+            <if test="answer0 != null  and answer0 != ''"> and answer0 = #{answer0}</if>
+            <if test="isUpdate != null "> and isUpdate = #{isUpdate}</if>
+            <if test="isSubType != null  and isSubType != ''"> and isSubType = #{isSubType}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnQuestionsById" parameterType="Long" resultMap="LearnQuestionsResult">
+        <include refid="selectLearnQuestionsVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnQuestions" parameterType="LearnQuestions" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_questions
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="title != null">title,</if>
+            <if test="optionA != null">option_a,</if>
+            <if test="optionB != null">option_b,</if>
+            <if test="optionC != null">option_c,</if>
+            <if test="optionD != null">option_d,</if>
+            <if test="optionE != null">option_e,</if>
+            <if test="optionF != null">option_f,</if>
+            <if test="optionG != null">option_g,</if>
+            <if test="answer1 != null">answer1,</if>
+            <if test="answer2 != null">answer2,</if>
+            <if test="qtpye != null">qtpye,</if>
+            <if test="subjectId != null">subjectId,</if>
+            <if test="paperId != null">paperId,</if>
+            <if test="knowledgeId != null">knowledgeId,</if>
+            <if test="diff != null">diff,</if>
+            <if test="similarity != null">similarity,</if>
+            <if test="parse != null">parse,</if>
+            <if test="knowId != null">knowId,</if>
+            <if test="gradeId != null">gradeId,</if>
+            <if test="knowledges != null">knowledges,</if>
+            <if test="area != null">area,</if>
+            <if test="year != null">year,</if>
+            <if test="paperTpye != null">paperTpye,</if>
+            <if test="source != null">source,</if>
+            <if test="fromSite != null">fromSite,</if>
+            <if test="isSub != null">isSub,</if>
+            <if test="isNormal != null">isNormal,</if>
+            <if test="isKonw != null">isKonw,</if>
+            <if test="tiid != null">tiid,</if>
+            <if test="md5 != null">md5,</if>
+            <if test="isunique != null">isunique,</if>
+            <if test="md52 != null">md52,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="score != null">score,</if>
+            <if test="options != null">options,</if>
+            <if test="number != null">number,</if>
+            <if test="paperTypeTitle != null">paperTypeTitle,</if>
+            <if test="options0 != null">options0,</if>
+            <if test="title0 != null">title0,</if>
+            <if test="title1 != null">title1,</if>
+            <if test="parse0 != null">parse0,</if>
+            <if test="answer0 != null">answer0,</if>
+            <if test="isUpdate != null">isUpdate,</if>
+            <if test="isSubType != null">isSubType,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="title != null">#{title},</if>
+            <if test="optionA != null">#{optionA},</if>
+            <if test="optionB != null">#{optionB},</if>
+            <if test="optionC != null">#{optionC},</if>
+            <if test="optionD != null">#{optionD},</if>
+            <if test="optionE != null">#{optionE},</if>
+            <if test="optionF != null">#{optionF},</if>
+            <if test="optionG != null">#{optionG},</if>
+            <if test="answer1 != null">#{answer1},</if>
+            <if test="answer2 != null">#{answer2},</if>
+            <if test="qtpye != null">#{qtpye},</if>
+            <if test="subjectId != null">#{subjectId},</if>
+            <if test="paperId != null">#{paperId},</if>
+            <if test="knowledgeId != null">#{knowledgeId},</if>
+            <if test="diff != null">#{diff},</if>
+            <if test="similarity != null">#{similarity},</if>
+            <if test="parse != null">#{parse},</if>
+            <if test="knowId != null">#{knowId},</if>
+            <if test="gradeId != null">#{gradeId},</if>
+            <if test="knowledges != null">#{knowledges},</if>
+            <if test="area != null">#{area},</if>
+            <if test="year != null">#{year},</if>
+            <if test="paperTpye != null">#{paperTpye},</if>
+            <if test="source != null">#{source},</if>
+            <if test="fromSite != null">#{fromSite},</if>
+            <if test="isSub != null">#{isSub},</if>
+            <if test="isNormal != null">#{isNormal},</if>
+            <if test="isKonw != null">#{isKonw},</if>
+            <if test="tiid != null">#{tiid},</if>
+            <if test="md5 != null">#{md5},</if>
+            <if test="isunique != null">#{isunique},</if>
+            <if test="md52 != null">#{md52},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="score != null">#{score},</if>
+            <if test="options != null">#{options},</if>
+            <if test="number != null">#{number},</if>
+            <if test="paperTypeTitle != null">#{paperTypeTitle},</if>
+            <if test="options0 != null">#{options0},</if>
+            <if test="title0 != null">#{title0},</if>
+            <if test="title1 != null">#{title1},</if>
+            <if test="parse0 != null">#{parse0},</if>
+            <if test="answer0 != null">#{answer0},</if>
+            <if test="isUpdate != null">#{isUpdate},</if>
+            <if test="isSubType != null">#{isSubType},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnQuestions" parameterType="LearnQuestions">
+        update learn_questions
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="title != null">title = #{title},</if>
+            <if test="optionA != null">option_a = #{optionA},</if>
+            <if test="optionB != null">option_b = #{optionB},</if>
+            <if test="optionC != null">option_c = #{optionC},</if>
+            <if test="optionD != null">option_d = #{optionD},</if>
+            <if test="optionE != null">option_e = #{optionE},</if>
+            <if test="optionF != null">option_f = #{optionF},</if>
+            <if test="optionG != null">option_g = #{optionG},</if>
+            <if test="answer1 != null">answer1 = #{answer1},</if>
+            <if test="answer2 != null">answer2 = #{answer2},</if>
+            <if test="qtpye != null">qtpye = #{qtpye},</if>
+            <if test="subjectId != null">subjectId = #{subjectId},</if>
+            <if test="paperId != null">paperId = #{paperId},</if>
+            <if test="knowledgeId != null">knowledgeId = #{knowledgeId},</if>
+            <if test="diff != null">diff = #{diff},</if>
+            <if test="similarity != null">similarity = #{similarity},</if>
+            <if test="parse != null">parse = #{parse},</if>
+            <if test="knowId != null">knowId = #{knowId},</if>
+            <if test="gradeId != null">gradeId = #{gradeId},</if>
+            <if test="knowledges != null">knowledges = #{knowledges},</if>
+            <if test="area != null">area = #{area},</if>
+            <if test="year != null">year = #{year},</if>
+            <if test="paperTpye != null">paperTpye = #{paperTpye},</if>
+            <if test="source != null">source = #{source},</if>
+            <if test="fromSite != null">fromSite = #{fromSite},</if>
+            <if test="isSub != null">isSub = #{isSub},</if>
+            <if test="isNormal != null">isNormal = #{isNormal},</if>
+            <if test="isKonw != null">isKonw = #{isKonw},</if>
+            <if test="tiid != null">tiid = #{tiid},</if>
+            <if test="md5 != null">md5 = #{md5},</if>
+            <if test="isunique != null">isunique = #{isunique},</if>
+            <if test="md52 != null">md52 = #{md52},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="score != null">score = #{score},</if>
+            <if test="options != null">options = #{options},</if>
+            <if test="number != null">number = #{number},</if>
+            <if test="paperTypeTitle != null">paperTypeTitle = #{paperTypeTitle},</if>
+            <if test="options0 != null">options0 = #{options0},</if>
+            <if test="title0 != null">title0 = #{title0},</if>
+            <if test="title1 != null">title1 = #{title1},</if>
+            <if test="parse0 != null">parse0 = #{parse0},</if>
+            <if test="answer0 != null">answer0 = #{answer0},</if>
+            <if test="isUpdate != null">isUpdate = #{isUpdate},</if>
+            <if test="isSubType != null">isSubType = #{isSubType},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnQuestionsById" parameterType="Long">
+        delete from learn_questions where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnQuestionsByIds" parameterType="String">
+        delete from learn_questions where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 58 - 0
ie-system/src/main/resources/mapper/learn/LearnStudentMapper.xml

@@ -0,0 +1,58 @@
+<?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.LearnStudentMapper">
+    
+    <resultMap type="LearnStudent" id="LearnStudentResult">
+        <result property="studentId"    column="student_id"    />
+        <result property="directKey"    column="direct_key"    />
+    </resultMap>
+
+    <sql id="selectLearnStudentVo">
+        select student_id, direct_key from learn_student
+    </sql>
+
+    <select id="selectLearnStudentList" parameterType="LearnStudent" resultMap="LearnStudentResult">
+        <include refid="selectLearnStudentVo"/>
+        <where>  
+            <if test="directKey != null  and directKey != ''"> and direct_key = #{directKey}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnStudentByStudentId" parameterType="Long" resultMap="LearnStudentResult">
+        <include refid="selectLearnStudentVo"/>
+        where student_id = #{studentId}
+    </select>
+
+    <insert id="insertLearnStudent" parameterType="LearnStudent">
+        insert into learn_student
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">student_id,</if>
+            <if test="directKey != null">direct_key,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="studentId != null">#{studentId},</if>
+            <if test="directKey != null">#{directKey},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnStudent" parameterType="LearnStudent">
+        update learn_student
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="directKey != null">direct_key = #{directKey},</if>
+        </trim>
+        where student_id = #{studentId}
+    </update>
+
+    <delete id="deleteLearnStudentByStudentId" parameterType="Long">
+        delete from learn_student where student_id = #{studentId}
+    </delete>
+
+    <delete id="deleteLearnStudentByStudentIds" parameterType="String">
+        delete from learn_student where student_id in 
+        <foreach item="studentId" collection="array" open="(" separator="," close=")">
+            #{studentId}
+        </foreach>
+    </delete>
+</mapper>

+ 65 - 0
ie-system/src/main/resources/mapper/learn/LearnTestMapper.xml

@@ -0,0 +1,65 @@
+<?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.LearnTestMapper">
+    
+    <resultMap type="LearnTest" id="LearnTestResult">
+        <result property="batchId"    column="batch_id"    />
+        <result property="name"    column="name"    />
+        <result property="creatorId"    column="creator_id"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectLearnTestVo">
+        select batch_id, name, creator_id, create_time from learn_test
+    </sql>
+
+    <select id="selectLearnTestList" parameterType="LearnTest" resultMap="LearnTestResult">
+        <include refid="selectLearnTestVo"/>
+        <where>  
+            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
+            <if test="creatorId != null "> and creator_id = #{creatorId}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnTestByBatchId" parameterType="String" resultMap="LearnTestResult">
+        <include refid="selectLearnTestVo"/>
+        where batch_id = #{batchId}
+    </select>
+
+    <insert id="insertLearnTest" parameterType="LearnTest" useGeneratedKeys="true" keyProperty="batchId">
+        insert into learn_test
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="name != null and name != ''">name,</if>
+            <if test="creatorId != null">creator_id,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="name != null and name != ''">#{name},</if>
+            <if test="creatorId != null">#{creatorId},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnTest" parameterType="LearnTest">
+        update learn_test
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="creatorId != null">creator_id = #{creatorId},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where batch_id = #{batchId}
+    </update>
+
+    <delete id="deleteLearnTestByBatchId" parameterType="String">
+        delete from learn_test where batch_id = #{batchId}
+    </delete>
+
+    <delete id="deleteLearnTestByBatchIds" parameterType="String">
+        delete from learn_test where batch_id in 
+        <foreach item="batchId" collection="array" open="(" separator="," close=")">
+            #{batchId}
+        </foreach>
+    </delete>
+</mapper>

+ 80 - 0
ie-system/src/main/resources/mapper/learn/LearnTestPaperMapper.xml

@@ -0,0 +1,80 @@
+<?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.LearnTestPaperMapper">
+    
+    <resultMap type="LearnTestPaper" id="LearnTestPaperResult">
+        <result property="id"    column="id"    />
+        <result property="batchId"    column="batch_id"    />
+        <result property="directKey"    column="direct_key"    />
+        <result property="paperId"    column="paper_id"    />
+        <result property="condions"    column="condions"    />
+        <result property="creatorId"    column="creator_id"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectLearnTestPaperVo">
+        select id, batch_id, direct_key, paper_id, condions, creator_id, create_time from learn_test_paper
+    </sql>
+
+    <select id="selectLearnTestPaperList" parameterType="LearnTestPaper" resultMap="LearnTestPaperResult">
+        <include refid="selectLearnTestPaperVo"/>
+        <where>  
+            <if test="batchId != null "> and batch_id = #{batchId}</if>
+            <if test="directKey != null  and directKey != ''"> and direct_key = #{directKey}</if>
+            <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="condions != null  and condions != ''"> and condions = #{condions}</if>
+            <if test="creatorId != null "> and creator_id = #{creatorId}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnTestPaperById" parameterType="String" resultMap="LearnTestPaperResult">
+        <include refid="selectLearnTestPaperVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnTestPaper" parameterType="LearnTestPaper" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_test_paper
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="batchId != null">batch_id,</if>
+            <if test="directKey != null and directKey != ''">direct_key,</if>
+            <if test="paperId != null">paper_id,</if>
+            <if test="condions != null and condions != ''">condions,</if>
+            <if test="creatorId != null">creator_id,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="batchId != null">#{batchId},</if>
+            <if test="directKey != null and directKey != ''">#{directKey},</if>
+            <if test="paperId != null">#{paperId},</if>
+            <if test="condions != null and condions != ''">#{condions},</if>
+            <if test="creatorId != null">#{creatorId},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnTestPaper" parameterType="LearnTestPaper">
+        update learn_test_paper
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="batchId != null">batch_id = #{batchId},</if>
+            <if test="directKey != null and directKey != ''">direct_key = #{directKey},</if>
+            <if test="paperId != null">paper_id = #{paperId},</if>
+            <if test="condions != null and condions != ''">condions = #{condions},</if>
+            <if test="creatorId != null">creator_id = #{creatorId},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnTestPaperById" parameterType="String">
+        delete from learn_test_paper where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnTestPaperByIds" parameterType="String">
+        delete from learn_test_paper where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 90 - 0
ie-system/src/main/resources/mapper/learn/LearnTestStudentMapper.xml

@@ -0,0 +1,90 @@
+<?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.LearnTestStudentMapper">
+    
+    <resultMap type="LearnTestStudent" id="LearnTestStudentResult">
+        <result property="id"    column="id"    />
+        <result property="batchId"    column="batch_id"    />
+        <result property="studentId"    column="student_id"    />
+        <result property="directKey"    column="direct_key"    />
+        <result property="paperId"    column="paper_id"    />
+        <result property="classId"    column="class_id"    />
+        <result property="examineeId"    column="examinee_id"    />
+        <result property="status"    column="status"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectLearnTestStudentVo">
+        select id, batch_id, student_id, direct_key, paper_id, class_id, examinee_id, status, create_time from learn_test_student
+    </sql>
+
+    <select id="selectLearnTestStudentList" parameterType="LearnTestStudent" resultMap="LearnTestStudentResult">
+        <include refid="selectLearnTestStudentVo"/>
+        <where>  
+            <if test="batchId != null "> and batch_id = #{batchId}</if>
+            <if test="studentId != null "> and student_id = #{studentId}</if>
+            <if test="directKey != null  and directKey != ''"> and direct_key = #{directKey}</if>
+            <if test="paperId != null "> and paper_id = #{paperId}</if>
+            <if test="classId != null "> and class_id = #{classId}</if>
+            <if test="examineeId != null "> and examinee_id = #{examineeId}</if>
+            <if test="status != null "> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectLearnTestStudentById" parameterType="String" resultMap="LearnTestStudentResult">
+        <include refid="selectLearnTestStudentVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertLearnTestStudent" parameterType="LearnTestStudent" useGeneratedKeys="true" keyProperty="id">
+        insert into learn_test_student
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="batchId != null">batch_id,</if>
+            <if test="studentId != null">student_id,</if>
+            <if test="directKey != null and directKey != ''">direct_key,</if>
+            <if test="paperId != null">paper_id,</if>
+            <if test="classId != null">class_id,</if>
+            <if test="examineeId != null">examinee_id,</if>
+            <if test="status != null">status,</if>
+            <if test="createTime != null">create_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="batchId != null">#{batchId},</if>
+            <if test="studentId != null">#{studentId},</if>
+            <if test="directKey != null and directKey != ''">#{directKey},</if>
+            <if test="paperId != null">#{paperId},</if>
+            <if test="classId != null">#{classId},</if>
+            <if test="examineeId != null">#{examineeId},</if>
+            <if test="status != null">#{status},</if>
+            <if test="createTime != null">#{createTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateLearnTestStudent" parameterType="LearnTestStudent">
+        update learn_test_student
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="batchId != null">batch_id = #{batchId},</if>
+            <if test="studentId != null">student_id = #{studentId},</if>
+            <if test="directKey != null and directKey != ''">direct_key = #{directKey},</if>
+            <if test="paperId != null">paper_id = #{paperId},</if>
+            <if test="classId != null">class_id = #{classId},</if>
+            <if test="examineeId != null">examinee_id = #{examineeId},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLearnTestStudentById" parameterType="String">
+        delete from learn_test_student where id = #{id}
+    </delete>
+
+    <delete id="deleteLearnTestStudentByIds" parameterType="String">
+        delete from learn_test_student where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>