Update: 完善考试与试卷重构方案

新增内容:
1. 试卷完整业务操作清单(65项操作)
   - 试卷管理操作(17项)
   - 试卷题目操作(12项)
   - 发放范围limitation操作(16项)🔴重点
   - 考试执行操作(12项)
   - 补考/重考操作(8项)

2. 发放范围迁移详细方案
   - 数据结构说明
   - 完整迁移SQL
   - 迁移验证SQL

确保数据拆分后不影响班级/课程关联等业务流程
This commit is contained in:
liyuchen 2026-04-17 07:55:36 +08:00
parent 2779536eb3
commit cfc83209be

View File

@ -9,9 +9,129 @@
---
## 二、目标数据模型
## 二、试卷完整业务操作清单
### 2.1 核心表结构设计
> **重要**:确保数据拆分后不影响以下所有业务流程
### 2.1 试卷管理操作17项
| 操作类型 | 操作名称 | 涉及的数据库表/SQL | 影响分析 |
|---------|---------|-------------------|---------|
| **CRUD** | 试卷列表查询 | `et_exam_exampaper_and_editexampaper` | 需拆分为 paper + examinations |
| **CRUD** | 试卷新增 | INSERT 到视图 | 需改为 INSERT 到 `et_exam_paper` |
| **CRUD** | 试卷编辑 | UPDATE 视图 | 需改为 UPDATE `et_exam_paper` |
| **CRUD** | 试卷删除 | DELETE + 级联删除 | 需保留级联逻辑 |
| **CRUD** | 试卷详情查看 | JOIN 查询 | 需重新设计 JOIN |
| **预览** | 试卷预览 | `preview()` / `previewPage()` | 不涉及业务拆分 |
| **导入** | 试卷导入 | `fileImport()` | 不涉及业务拆分 |
### 2.2 试卷题目操作12项
| 操作类型 | 操作名称 | 涉及的SQL ID | 影响分析 |
|---------|---------|-------------|---------|
| **题目查询** | 获取试卷题目列表 | `getExampaperEditList` | 需改为 JOIN `et_exam_paper_question` |
| **题目统计** | 获取各题型数量 | `getCount` | 需改为统计 `et_exam_paper_question` |
| **历史问卷** | 保存历史问卷 | `insertHistoryExam` | 需复制到新试卷 |
| **随机组卷** | 随机添加试题 | `insertRandExam` | 需 INSERT 到 `et_exam_paper_question` |
| **序号更新** | 更新题目序号 | `updateRandExamNum` | 需更新 `et_exam_paper_question.num` |
| **题目查询** | 返回试卷信息 | `getExampaperReturn` | 需查询 `et_exam_paper` |
| **题目数量** | 获取题目数量 | `getQuestionNum` | 需 COUNT `et_exam_paper_question` |
| **题型数量** | 获取各题型数量 | `getNumber` | 需按 type_num 统计 |
| **序号修改** | 修改题目序号 | `updateOtherNumber` | 需更新 `et_exam_paper_question.num` |
| **单题修改** | 修改单题序号 | `updateNewNumber` | 需更新 `et_exam_paper_question.num` |
| **题目删除** | 删除试卷题目 | `DeleteExamQuestion` | 需 DELETE `et_exam_paper_question` |
### 2.3 发放范围limitation操作16项🔴 关键
> **这是与班级/课程关联的核心模块,必须完整保留**
| 操作类型 | 操作名称 | 涉及的SQL/URL | 关键字段 |
|---------|---------|--------------|---------|
| **发放范围** | 查询发放范围列表 | `limitationUrl` | `exam_id`, `limitation` |
| **全所发放** | 设置全所发放 | `saveLimitationUrl` (limitation=1) | 需关联 examination |
| **部门发放** | 添加部门发放范围 | `departmentAddUrl` | 需关联 examination |
| **人员发放** | 添加人员发放范围 | `saveLimitationUrl` (limitation=3) | 需关联 examination |
| **班级发放** | 添加班级发放范围 | `saveClassUrl` | `et_exam_limitation_class` |
| **课程发放** | 添加课程发放范围 | `saveCourseUrl` | `et_exam_limitation_course` |
| **删除发放** | 删除发放范围 | `deleteLimitationUrl` | 需 DELETE + 级联 |
| **删除其他** | 删除其他发放范围 | `deleteOtherUrl` | 需 DELETE + 级联 |
| **班级人员** | 获取班级人员列表 | `classComboxUrl` | 需关联 `v_class_user` |
| **课程人员** | 获取课程人员列表 | `courseComboxUrl` | 需关联课程学员 |
| **更新班级** | 更新班级对应人的exam_id | `updateClassUrl` | 需关联 examination |
| **更新课程** | 更新课程对应人的exam_id | `updateCourseUrl` | 需关联 examination |
| **更新limitation** | 更新limitation的exam_id | `updateLimitationUrl` | 需关联 examination |
| **删除limitation** | 依据试卷id删除limitation | `deleteLimitationExampaperUrl` | 需关联 examination |
| **删除人员** | 删除课程班级对应的人 | `deletePersonUrl` | 需关联 examination |
| **人员导入** | 发放范围人员导入 | `personImportUrl` | 需关联 examination |
### 2.4 考试执行操作12项
| 操作类型 | 操作名称 | 涉及的SQL/URL | 影响分析 |
|---------|---------|-------------|---------|
| **答题查询** | 获取考试题目列表 | `getExamTestList` | 需改为 JOIN examination |
| **成绩查询** | 获取考试成绩列表 | `getExamResultList` | 需 JOIN examination |
| **判卷列表** | 获取待判卷列表 | `getExamMarkList` | 需 JOIN examination |
| **成绩统计** | 获取个人成绩统计 | `getExamScoreList` | 需 JOIN examination |
| **提交查询** | 查询未提交用户 | `getIsNotSubmitList` | 需关联 examination |
| **机构详情** | 获取机构学员详情 | `getInstitutionDetail` | 需关联 examination |
| **部门详情** | 获取部门学员详情 | `getDepartmentDetail` | 需关联 examination |
| **个人详情** | 获取个人考试详情 | `getPersonDetail` | 需关联 examination |
| **班级详情** | 获取班级考试详情 | `getClassDetail` | 需关联 examination |
| **课程详情** | 获取课程考试详情 | `getCourseDetail` | 需关联 examination |
| **自动判卷** | 自动评分 | `updateUserScore` | 需 JOIN examination |
| **补考推送** | 推送补考人员 | `insertInstituteResit` 等 | 需关联 examination |
### 2.5 补考/重考操作8项
| 操作类型 | 操作名称 | 涉及的SQL ID | 关键逻辑 |
|---------|---------|-------------|---------|
| **插入补考** | 插入机构补考 | `insertInstituteResit` | 需创建新 examination |
| **插入补考** | 插入部门补考 | `insertDepartmentResit` | 需创建新 examination |
| **插入补考** | 插入个人补考 | `insertPersonResit` | 需创建新 examination |
| **插入补考** | 插入班级补考 | `insertClassResit` | 需创建新 examination |
| **插入补考** | 插入课程补考 | `insertCourseResit` | 需创建新 examination |
| **保存补考试卷** | 保存原试卷试题至补考 | `saveResitPaper` | 需复制 paper_question |
| **删除补考** | 删除临时试卷 | `deleteTemporaryExam` | 需关联 examination |
| **更新补考ID** | 更新补考exam_id | `updateLimitationExamId` | 需关联 examination |
### 2.6 发放范围类型详解
```
limitation 字段含义:
├── 1 = 全所(所有人员)
├── 2 = 部门(指定部门及下属人员)
├── 3 = 人员(指定个人)
├── 4 = 班级(指定班级的人员)→ 关联 et_exam_limitation_class
└── 5 = 课程(指定课程的人员)→ 关联 et_exam_limitation_course
```
### 2.7 关键业务流程依赖关系
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 试卷发放范围业务流程 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 用户操作 后端处理 数据库操作 │
│ ───────── ──────── ────────── │
│ │
│ 选择"班级发放" ──────► saveLimitationUrl ──────► INSERT et_exam_limitation │
│ │ │ (limitation=4) │
│ ▼ ▼ │
│ 选择班级 ─────────► saveClassUrl ──────► INSERT et_exam_limitation_class │
│ │ │ (展开班级人员) │
│ ▼ ▼ │
│ 点击发布 ─────────► updateClassUrl ──────► UPDATE et_exam_limitation_class │
│ │ SET exam_id = 正式ID │
│ ▼ │
│ 发布成功 ──────► 班级学员可看到考试 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
### 3.1 核心表结构设计
```
┌─────────────────────────────────────────────────────────────────────────────┐
@ -55,7 +175,7 @@
└─────────────────────────────────────────────────────────────────────────────┘
```
### 2.2 新旧表字段对照
### 3.2 新旧表字段对照
| 新表 et_exam_paper | 来自 | 新表 et_exam_examinations | 来自 |
|-------------------|------|--------------------------|------|
@ -75,9 +195,9 @@
---
## 、详细重构方案
## 、详细重构方案
### 3.1 第一阶段:数据库层重构
### 4.1 第一阶段:数据库层重构
#### 3.1.1 创建新表
@ -239,7 +359,7 @@ SET ut.exam_id = eq.edit_id;
---
### 3.2 第二阶段SQL 映射层重构
### 4.2 第二阶段SQL 映射层重构
#### 3.2.1 新建映射文件
@ -315,7 +435,7 @@ SET ut.exam_id = eq.edit_id;
---
### 3.3 第三阶段Java 控制器层重构
### 4.3 第三阶段Java 控制器层重构
#### 3.3.1 新增控制器
@ -345,7 +465,7 @@ public class ExamExaminationController {
---
### 3.4 第四阶段:前端页面重构
### 4.4 第四阶段:前端页面重构
#### 3.4.1 页面拆分
@ -521,7 +641,128 @@ SELECT
(SELECT COUNT(*) FROM et_exam_usertest WHERE exam_id IS NOT NULL) AS user_answer_count;
```
### 6.3 迁移后验证
### 6.3 发放范围迁移(班级/课程关联)🔴 重点
> 这是用户特别关心的业务场景,必须确保迁移后不影响现有功能
#### 6.3.1 发放范围数据结构
```
当前结构(存在问题):
et_exam_limitation (exam_id 实际是试卷ID)
├── et_exam_limitation_class (exam_id 关联到试卷)
└── et_exam_limitation_course (exam_id 关联到试卷)
重构后结构:
et_exam_examination_limitation (exam_id 关联到考试ID)
├── et_exam_limitation_class (exam_id 关联到考试ID)
└── et_exam_limitation_course (exam_id 关联到考试ID)
```
#### 6.3.2 迁移 SQL
```sql
-- 1. 迁移 et_exam_limitation 表
-- 注意exam_id 在原表中指向试卷,现在需要改为指向考试
-- 由于原表中 exam_id = 试卷ID重构后 exam_id = 考试ID
-- 而考试ID = 试卷ID首次迁移时1:1映射
INSERT INTO et_exam_examination_limitation (
id, exam_id, limitation, user, user_id
)
SELECT
id,
exam_id, -- 考试ID原试卷ID
limitation, -- 发放范围类型
user, -- 用户/部门名称
user_id -- 用户ID/部门代码
FROM et_exam_limitation
WHERE exam_id IS NOT NULL;
-- 2. 迁移 et_exam_limitation_class 表
-- 展开班级人员到 et_exam_examination_limitation
INSERT INTO et_exam_examination_limitation (
id, exam_id, limitation, user, user_id
)
SELECT
md5(UUID()) AS id,
exam_id AS exam_id, -- 考试ID原试卷ID
4 AS limitation, -- 班级类型
class_person AS user, -- 班级人员姓名
class_person_id AS user_id -- 班级人员ID
FROM et_exam_limitation_class
WHERE exam_id IS NOT NULL;
-- 3. 迁移 et_exam_limitation_course 表
-- 展开课程人员到 et_exam_examination_limitation
INSERT INTO et_exam_examination_limitation (
id, exam_id, limitation, user, user_id
)
SELECT
md5(UUID()) AS id,
exam_id AS exam_id, -- 考试ID原试卷ID
5 AS limitation, -- 课程类型
course_person AS user, -- 课程人员姓名
course_person_id AS user_id -- 课程人员ID
FROM et_exam_limitation_course
WHERE exam_id IS NOT NULL;
```
#### 6.3.3 迁移验证 SQL
```sql
-- 验证1发放范围数据完整性
SELECT
'原limitation' AS source_table,
COUNT(*) AS record_count
FROM et_exam_limitation
UNION ALL
SELECT
'原limitation_class' AS source_table,
COUNT(*) AS record_count
FROM et_exam_limitation_class
UNION ALL
SELECT
'原limitation_course' AS source_table,
COUNT(*) AS record_count
FROM et_exam_limitation_course
UNION ALL
SELECT
'新examination_limitation' AS source_table,
COUNT(*) AS record_count
FROM et_exam_examination_limitation;
-- 验证2各类型发放范围数量
SELECT
limitation AS 类型,
CASE limitation
WHEN 1 THEN '全所'
WHEN 2 THEN '部门'
WHEN 3 THEN '人员'
WHEN 4 THEN '班级'
WHEN 5 THEN '课程'
END AS 类型名称,
COUNT(*) AS 数量
FROM et_exam_examination_limitation
GROUP BY limitation
ORDER BY limitation;
-- 验证3检查 exam_id 是否都能关联到有效的考试记录
SELECT
el.exam_id,
COUNT(*) AS limitation_count,
CASE
WHEN e.id IS NOT NULL THEN '有效'
ELSE '孤立数据'
END AS status
FROM et_exam_examination_limitation el
LEFT JOIN et_exam_examinations e ON el.exam_id = e.id
GROUP BY el.exam_id, e.id;
```
### 6.4 迁移后验证
```sql
-- 1. 数据完整性检查