From cfc83209be8cee521a695e79d31efe2ff5d448d4 Mon Sep 17 00:00:00 2001 From: liyuchen Date: Fri, 17 Apr 2026 07:55:36 +0800 Subject: [PATCH] =?UTF-8?q?Update:=20=E5=AE=8C=E5=96=84=E8=80=83=E8=AF=95?= =?UTF-8?q?=E4=B8=8E=E8=AF=95=E5=8D=B7=E9=87=8D=E6=9E=84=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增内容: 1. 试卷完整业务操作清单(65项操作) - 试卷管理操作(17项) - 试卷题目操作(12项) - 发放范围limitation操作(16项)🔴重点 - 考试执行操作(12项) - 补考/重考操作(8项) 2. 发放范围迁移详细方案 - 数据结构说明 - 完整迁移SQL - 迁移验证SQL 确保数据拆分后不影响班级/课程关联等业务流程 --- EXAM_PAPER_REFACTOR_PLAN.md | 259 ++++++++++++++++++++++++++++++++++-- 1 file changed, 250 insertions(+), 9 deletions(-) diff --git a/EXAM_PAPER_REFACTOR_PLAN.md b/EXAM_PAPER_REFACTOR_PLAN.md index a7d7b51..e0909f1 100644 --- a/EXAM_PAPER_REFACTOR_PLAN.md +++ b/EXAM_PAPER_REFACTOR_PLAN.md @@ -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. 数据完整性检查