feat: 提交课表冲突检查相关功能模块

This commit is contained in:
dengxiaoyue
2026-08-21 14:39:03 +08:00
parent 179b12e3bf
commit f190c29e05
857 changed files with 10838 additions and 5 deletions
@@ -0,0 +1,230 @@
<?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.roomroot.jwgl.mapper.SSKCBXYDMapper">
<select id="selectBySskcbh" resultType="com.roomroot.jwgl.entity.SSKCBXYD">
SELECT * FROM "实施_课程表_学员队" WHERE "实施_课程表编号" = #{sskcbh}
</select>
<delete id="deleteBySskcbbh">
DELETE FROM "实施_课程表_学员队" WHERE "实施_课程表编号" = #{sskcbbh}
</delete>
<resultMap id="ScheduleResultMap" type="com.roomroot.jwgl.vo.elective.ClassScheduleVO">
<id column="编号" property="bh"/>
<result column="实施_课程编号" property="sskcbh"/>
<result column="日期" property="rq"/>
<result column="节次" property="jc"/>
<result column="教学内容" property="jxnr"/>
<result column="教学方法" property="jxff"/>
<result column="年度" property="nd"/>
<result column="学员队编号" property="xydbh"/>
<result column="课名称" property="kcmc"/>
</resultMap>
<select id="selectScheduleByXydbh" resultMap="ScheduleResultMap">
SELECT
s."编号", s."实施_课程编号", s."日期", s."节次",
s."教学内容", s."教学方法", s."年度",
t."学员队编号",
k."课名称"
FROM "实施_课程表" s
JOIN "实施_课程表_学员队" t ON t."实施_课程表编号" = s."编号"
<!--
修正:三层关联 SSKCB → 实施_课程 → 课表
- 类型转换:c."编号" 是 VARBINARY,s."实施_课程编号" 是 CHAR,必须 CAST 才能匹配上
- 科目关联:KB.科目代码 = SSKC.科目编号
-->
LEFT JOIN "实施_课程" c ON CAST(c."编号" AS CHAR(36)) = s."实施_课程编号"
LEFT JOIN "课表" k ON k."科目代码" = c."科目编号"
WHERE t."学员队编号" = #{xydbh}
<if test="nd != null">
AND s."年度" = #{nd}
</if>
ORDER BY s."日期", s."节次"
</select>
<!-- ============================================================ -->
<!-- 课表冲突检查 - 维度1:教学班时间冲突明细查询 -->
<!-- 检查逻辑:同一班次 + 同一日期 + 同一节次,出现 >1 个不同课次 -->
<!-- 用到的表: -->
<!-- 1. 实施_课程表 SSKCB → 日期(RQ)/节次(JC)/年度/删除状态(SCZT=0正常) -->
<!-- 2. 实施_课程表_学员队 SSKCBXYD → 学员队编号(班次编号) -->
<!-- 3. 学员队表(或班次表) XYDB → 翻译班次中文名 -->
<!-- 4. 课表 KB → 翻译课程名称 -->
<!-- ============================================================ -->
<select id="selectTeamConflictDetails"
resultType="com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO">
SELECT
/* 固定维度编码:教学班时间冲突 */
'TEAM_CONFLICT' AS dimension_code,
'教学班时间冲突' AS dimension_title,
/* 发生冲突的资源(班次)*/
g."学员队编号" AS resource_id,
COALESCE(x."学员队名称", g."学员队编号") AS resource_name,
/* 冲突日期节次(统一从主表 SSKCB(s) 取)*/
g."日期" AS rq,
g."节次" AS jc,
/* 占用课次数(同一班次同一时间有多少门课) */
g."占用课次数" AS occupied_lesson_count,
/* 冲突课程名称拼接 */
g."课程名称列表" AS course_names,
/* 冲突课次编号拼接(前端跳转用)*/
g."课次编号列表" AS conflict_sskcb_bhs,
/* 冲突原因说明 */
'教学班次【' || COALESCE(x."学员队名称", g."学员队编号") || '】在 '
|| TO_CHAR(g."日期", 'YYYY-MM-DD') || ' 第' || CAST(g."节次" AS VARCHAR) || '节'
|| ' 被同时安排 ' || CAST(g."占用课次数" AS VARCHAR) || ' 门课程:'
|| COALESCE(g."课程名称列表", '(课次号:' || g."课次编号列表" || ')')
AS reason,
/* =========================================================
* 以下为 UI 明细表格新增的 5 个字段(对应截图8列)
* 列别名统一用"下划线命名" → MyBatis resultType 自动转驼峰匹配 VO 属性
* ========================================================= */
/* 冲突号:日期8位_节次2位补0_资源编号(学员队编号)*/
TO_CHAR(g."日期", 'YYYYMMDD')
|| '_' || LPAD(CAST(g."节次" AS VARCHAR), 2, '0')
|| '_' || g."学员队编号" AS conflict_no,
/* 班次名称列表(该冲突涉及的所有学员队/班次) */
COALESCE(g.xyd_names_list, '(无)') AS xyd_names,
/* 教员姓名列表(含【主/辅】标注)*/
COALESCE(g.teacher_names_list, '(无)') AS teacher_names,
/* 场地/教室名称列表 */
COALESCE(g.classroom_names_list, '(无)') AS classroom_names,
/* 责任单位(班次的所属单位)*/
COALESCE(g.responsible_dept_list, '(无)')AS responsible_dept
FROM (
/*
* 内层子查询:按班次+日期+节次 GROUP BY,筛选 COUNT(DISTINCT 课次) > 1 的冲突组
*
* 新增:除原有课程信息 JOIN 外,再 LEFT JOIN 三类业务信息用于明细展示(均加 DISTINCT,避免 JOIN 膨胀影响聚合)
* ① 班次+责任单位:SSKCB 再次 JOIN SSKCBXYD + 学员队表(拿到所有涉及班次的名称和所属单位)
* ② 教员:SSKCB → SSKCBFZJY + 教员表(带【主】【辅】标注)
* ③ 场地/教室:SSKCB → SSKCBJS + 教室表
*/
SELECT
t."学员队编号",
s."日期",
s."节次",
COUNT(DISTINCT s."编号") AS "占用课次数",
/* 原有用字段:课程名、课次号 */
WM_CONCAT(DISTINCT k."课名称") AS "课程名称列表",
WM_CONCAT(DISTINCT s."编号") AS "课次编号列表",
/* ========== 新增 4 个聚合字段(对应 UI 明细 4 列)========== */
/* 1. 班次名称列表:一个课次可能多个班上,DISTINCT 去重再拼接 */
WM_CONCAT(DISTINCT xyd_info."学员队名称") AS xyd_names_list,
/* 2. 教员姓名列表:带【主】【辅】角色区分 */
WM_CONCAT(DISTINCT
CASE fz_info."主教员" WHEN 1 THEN '【主】' ELSE '【辅】' END
|| jy_info."教员姓名"
) AS teacher_names_list,
/* 3. 场地/教室名称列表 */
WM_CONCAT(DISTINCT js_info."教室名称") AS classroom_names_list,
/* 4. 责任单位:学员队表所属单位字段聚合(DISTINCT 去重)*/
WM_CONCAT(DISTINCT xyd_info."所属单位") AS responsible_dept_list
FROM "实施_课程表" s
/* 维度过滤用:主关联"教学班(学员队)" —— 教学班冲突就是按这个维度 GROUP BY */
INNER JOIN "实施_课程表_学员队" t ON t."实施_课程表编号" = s."编号"
/* 课表信息三层关联 */
LEFT JOIN "实施_课程" c ON CAST(c."编号" AS CHAR(36)) = s."实施_课程编号"
LEFT JOIN "课表" k ON k."科目代码" = c."科目编号"
/* ========== 新增 JOIN:聚合该冲突课次涉及的所有班次/教员/教室信息 ========== */
LEFT JOIN "实施_课程表_学员队" xyd_link ON xyd_link."实施_课程表编号" = s."编号"
LEFT JOIN "学员队表" xyd_info ON xyd_info."学员队编号" = xyd_link."学员队编号"
LEFT JOIN "实施_课程表_辅助教员" fz_info ON fz_info."实施_课程表编号" = s."编号"
LEFT JOIN "教员表" jy_info ON jy_info."教员编号" = fz_info."辅助教员编号"
LEFT JOIN "实施_课程表_教室" js_link ON js_link."实施_课程表编号" = s."编号"
LEFT JOIN "教室表" js_info ON js_info."教室编号" = js_link."教室编号"
WHERE s."删除状态" = 0
AND s."年度" = #{nd}
GROUP BY t."学员队编号", s."日期", s."节次"
HAVING COUNT(DISTINCT s."编号") > 1
) g
/* 翻译班次中文名(学员队表) */
LEFT JOIN "学员队表" x ON x."学员队编号" = g."学员队编号"
ORDER BY g."日期", g."节次", g."学员队编号"
</select>
<!-- ============================================================ -->
<!-- 课表冲突检查 - 维度2:教学班必修与选修时间冲突 -->
<!-- 检查逻辑:同一班次同一日期节次,同时出现"必修"和"选修"两类课程 -->
<!-- 用到的表: -->
<!-- 1. 实施_课程表 SSKCB → 日期/节次/年度/删除状态 -->
<!-- 2. 实施_课程表_学员队 SSKCBXYD → 班次编号 -->
<!-- 3. 课表 KB → 课程类型(必修/选修/考查) -->
<!-- 4. 学员队表 XYDB → 翻译班次中文名 -->
<!-- ============================================================ -->
<select id="selectElectiveRequiredConflictDetails"
resultType="com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO">
SELECT
'ELECTIVE_REQUIRED_CONFLICT' AS dimension_code,
'教学班必修与选修时间冲突' AS dimension_title,
g."学员队编号" AS resource_id,
COALESCE(x."学员队名称", g."学员队编号") AS resource_name,
/* 日期节次统一取自主表 s */
g."日期" AS rq,
g."节次" AS jc,
(g."必修课次数" + g."选修课次数") AS occupied_lesson_count,
(g."必修课程名" || ';' || g."选修课程名") AS course_names,
(g."必修课次编号" || ',' || g."选修课次编号") AS conflict_sskcb_bhs,
'教学班次【' || COALESCE(x."学员队名称", g."学员队编号") || '】在 '
|| TO_CHAR(g."日期", 'YYYY-MM-DD') || ' 第' || CAST(g."节次" AS VARCHAR) || '节'
|| ' 同时安排了必修课:' || COALESCE(g."必修课程名", '(无)')
|| ' 与 选修课:' || COALESCE(g."选修课程名", '(无)')
AS reason,
/* ========== UI 明细新增 5 字段 ========== */
/* 冲突号:日期8位_节次2位_学员队编号 */
TO_CHAR(g."日期", 'YYYYMMDD')
|| '_' || LPAD(CAST(g."节次" AS VARCHAR), 2, '0')
|| '_' || g."学员队编号" AS conflict_no,
COALESCE(g.xyd_names_list, '(无)') AS xyd_names,
COALESCE(g.teacher_names_list, '(无)') AS teacher_names,
COALESCE(g.classroom_names_list, '(无)') AS classroom_names,
COALESCE(g.responsible_dept_list, '(无)')AS responsible_dept
FROM (
/*
* 按班次+日期+节次分组,分别统计"必修课"和"选修课"
* 新增 JOIN:同维度1,LEFT JOIN 班次/教员/教室三类信息(WM_CONCAT DISTINCT 聚合)
*/
SELECT
t."学员队编号",
s."日期",
s."节次",
COUNT(DISTINCT CASE WHEN k."课程类型" = '必修' THEN s."编号" END) AS "必修课次数",
COUNT(DISTINCT CASE WHEN k."课程类型" = '选修' THEN s."编号" END) AS "选修课次数",
WM_CONCAT(DISTINCT CASE WHEN k."课程类型" = '必修' THEN k."课名称" END) AS "必修课程名",
WM_CONCAT(DISTINCT CASE WHEN k."课程类型" = '选修' THEN k."课名称" END) AS "选修课程名",
WM_CONCAT(DISTINCT CASE WHEN k."课程类型" = '必修' THEN s."编号" END) AS "必修课次编号",
WM_CONCAT(DISTINCT CASE WHEN k."课程类型" = '选修' THEN s."编号" END) AS "选修课次编号",
/* ========== 新增 4 个聚合字段 ========== */
WM_CONCAT(DISTINCT xyd_info."学员队名称") AS xyd_names_list,
WM_CONCAT(DISTINCT
CASE fz_info."主教员" WHEN 1 THEN '【主】' ELSE '【辅】' END
|| jy_info."教员姓名"
) AS teacher_names_list,
WM_CONCAT(DISTINCT js_info."教室名称") AS classroom_names_list,
WM_CONCAT(DISTINCT xyd_info."所属单位") AS responsible_dept_list
FROM "实施_课程表" s
INNER JOIN "实施_课程表_学员队" t ON t."实施_课程表编号" = s."编号"
LEFT JOIN "实施_课程" c ON CAST(c."编号" AS CHAR(36)) = s."实施_课程编号"
LEFT JOIN "课表" k ON k."科目代码" = c."科目编号"
/* ========== 新增 JOIN:三类业务信息 ========== */
LEFT JOIN "实施_课程表_学员队" xyd_link ON xyd_link."实施_课程表编号" = s."编号"
LEFT JOIN "学员队表" xyd_info ON xyd_info."学员队编号" = xyd_link."学员队编号"
LEFT JOIN "实施_课程表_辅助教员" fz_info ON fz_info."实施_课程表编号" = s."编号"
LEFT JOIN "教员表" jy_info ON jy_info."教员编号" = fz_info."辅助教员编号"
LEFT JOIN "实施_课程表_教室" js_link ON js_link."实施_课程表编号" = s."编号"
LEFT JOIN "教室表" js_info ON js_info."教室编号" = js_link."教室编号"
WHERE s."删除状态" = 0
AND s."年度" = #{nd}
GROUP BY t."学员队编号", s."日期", s."节次"
/* 关键:只有必修 >0 并且 选修 >0 才算冲突 */
HAVING COUNT(DISTINCT CASE WHEN k."课程类型" = '必修' THEN s."编号" END) > 0
AND COUNT(DISTINCT CASE WHEN k."课程类型" = '选修' THEN s."编号" END) > 0
) g
/* 修正:学员队表主键是「学员队编号」,不是「编号」 */
LEFT JOIN "学员队表" x ON x."学员队编号" = g."学员队编号"
ORDER BY g."日期", g."节次"
</select>
</mapper>