feat: 提交课表冲突检查相关功能模块
This commit is contained in:
@@ -2,6 +2,7 @@ package com.roomroot.jwgl.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.roomroot.jwgl.entity.SSKCBFZJY;
|
||||
import com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -13,4 +14,12 @@ public interface SSKCBFZJYMapper extends BaseMapper<SSKCBFZJY> {
|
||||
List<SSKCBFZJY> selectBySskcbh(@Param("sskcbh") String sskcbh);
|
||||
|
||||
int deleteBySskcbbh(@Param("sskcbbh") String sskcbbh);
|
||||
|
||||
/**
|
||||
* 【课表冲突检查】教员时间冲突明细查询。
|
||||
*
|
||||
* @param nd 年度
|
||||
* @return 教员时间冲突明细列表
|
||||
*/
|
||||
List<TimetableConflictDetailVO> selectTeacherConflictDetails(@Param("nd") Integer nd);
|
||||
}
|
||||
@@ -3,11 +3,112 @@
|
||||
<mapper namespace="com.roomroot.jwgl.mapper.SSKCBFZJYMapper">
|
||||
|
||||
<select id="selectBySskcbh" resultType="com.roomroot.jwgl.entity.SSKCBFZJY">
|
||||
SELECT * FROM 实施_课程表_辅助教员 WHERE 实施_课程表编号 = #{sskcbh}
|
||||
SELECT * FROM "实施_课程表_辅助教员" WHERE "实施_课程表编号" = #{sskcbh}
|
||||
</select>
|
||||
|
||||
<delete id="deleteBySskcbbh">
|
||||
DELETE FROM 实施_课程表_辅助教员 WHERE 实施_课程表编号 = #{sskcbbh}
|
||||
DELETE FROM "实施_课程表_辅助教员" WHERE "实施_课程表编号" = #{sskcbbh}
|
||||
</delete>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 课表冲突检查 - 维度3:教员时间冲突明细查询 -->
|
||||
<!-- 检查逻辑:同一教员(主讲+辅讲统一查)在同一日期节次,被安排多个课次 -->
|
||||
<!-- 用到的表: -->
|
||||
<!-- 1. 实施_课程表 SSKCB → 日期/节次/年度/删除状态 -->
|
||||
<!-- 2. 实施_课程表_辅助教员 SSKCBFZJY → 教员编号(FZJYBH) -->
|
||||
<!-- 3. 教员表/教研室人员表 JYB/JYSX → 翻译教员姓名 -->
|
||||
<!-- 4. 课表 KB → 翻译课程名称 -->
|
||||
<!-- ============================================================ -->
|
||||
<select id="selectTeacherConflictDetails"
|
||||
resultType="com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO">
|
||||
SELECT
|
||||
/* 固定维度编码:教员时间冲突 */
|
||||
'TEACHER_CONFLICT' AS dimension_code,
|
||||
'教员时间冲突' AS dimension_title,
|
||||
/* 发生冲突的资源(教员)*/
|
||||
g."辅助教员编号" AS resource_id,
|
||||
COALESCE(j."教员姓名", g."辅助教员编号") AS resource_name,
|
||||
/* 冲突日期节次:统一取自主表 s */
|
||||
g."日期" AS rq,
|
||||
g."节次" AS jc,
|
||||
/* 占用课次数:同一教员同一时间排了几门不同的课 */
|
||||
g."占用课次数" AS occupied_lesson_count,
|
||||
/* 冲突课程名 + 主讲/辅讲标注 */
|
||||
g."课程名称列表" AS course_names,
|
||||
/* 冲突课次编号列表,逗号分隔 */
|
||||
g."课次编号列表" AS conflict_sskcb_bhs,
|
||||
/* 中文原因 */
|
||||
'教员【' || COALESCE(j."教员姓名", g."辅助教员编号") || '】在 '
|
||||
|| TO_CHAR(g."日期", 'YYYY-MM-DD') || ' 第' || CAST(g."节次" AS VARCHAR) || '节'
|
||||
|| ' 被同时安排 ' || CAST(g."占用课次数" AS VARCHAR) || ' 门课程:'
|
||||
|| COALESCE(g."课程名称列表", '(课次号:' || 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 (
|
||||
/*
|
||||
* 内层:按教员编号+日期+节次 GROUP BY,筛选出现>1课次的冲突
|
||||
*
|
||||
* 关键修正:
|
||||
* 1. 关联链路:SSKCB → 实施_课程 c → 课表 k;必须 CAST(c.编号 AS CHAR(36))
|
||||
* 2. 主讲/辅讲字段:真实列名「主教员」(1主/0辅)
|
||||
* 3. 日期节次:统一取主表 s
|
||||
*
|
||||
* 新增 JOIN(同维度1/2):为明细表格聚合"该冲突课次涉及的所有班次/教员/场地"
|
||||
* - INNER JOIN f 是"维度过滤主关联"(只保留该教员的课次做分组)
|
||||
* - 额外 LEFT JOIN xyd/fz/js 三层是"聚合展示用"(把同一冲突组涉及的所有信息都拼出来)
|
||||
*/
|
||||
SELECT
|
||||
f."辅助教员编号",
|
||||
s."日期",
|
||||
s."节次",
|
||||
COUNT(DISTINCT s."编号") AS "占用课次数",
|
||||
/* 原课程名称列表(课程名 + 主/辅标注)*/
|
||||
WM_CONCAT(DISTINCT
|
||||
CASE f."主教员" WHEN 1 THEN '【主】' ELSE '【辅】' END
|
||||
|| COALESCE(k."课名称", '未命名课程')
|
||||
) AS "课程名称列表",
|
||||
WM_CONCAT(DISTINCT s."编号") 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
|
||||
/* 维度过滤主关联:只看该教员的课次(GROUP BY 维度)*/
|
||||
INNER JOIN "实施_课程表_辅助教员" f ON f."实施_课程表编号" = 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 f."辅助教员编号", s."日期", s."节次"
|
||||
HAVING COUNT(DISTINCT s."编号") > 1
|
||||
) g
|
||||
/* 翻译教员姓名:教员表主键「教员编号」,姓名字段「教员姓名」 */
|
||||
LEFT JOIN "教员表" j ON j."教员编号" = g."辅助教员编号"
|
||||
ORDER BY g."日期", g."节次", g."辅助教员编号"
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -2,6 +2,7 @@ package com.roomroot.jwgl.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.roomroot.jwgl.entity.SSKCBJS;
|
||||
import com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -13,4 +14,12 @@ public interface SSKCBJSMapper extends BaseMapper<SSKCBJS> {
|
||||
List<SSKCBJS> selectBySskcbh(@Param("sskcbh") String sskcbh);
|
||||
|
||||
int deleteBySskcbbh(@Param("sskcbbh") String sskcbbh);
|
||||
|
||||
/**
|
||||
* 【课表冲突检查】教室时间冲突明细查询。
|
||||
*
|
||||
* @param nd 年度
|
||||
* @return 教室时间冲突明细列表
|
||||
*/
|
||||
List<TimetableConflictDetailVO> selectClassroomConflictDetails(@Param("nd") Integer nd);
|
||||
}
|
||||
@@ -3,11 +3,108 @@
|
||||
<mapper namespace="com.roomroot.jwgl.mapper.SSKCBJSMapper">
|
||||
|
||||
<select id="selectBySskcbh" resultType="com.roomroot.jwgl.entity.SSKCBJS">
|
||||
SELECT * FROM 实施_课程表_教室 WHERE 实施_课程表编号 = #{sskcbh}
|
||||
SELECT * FROM "实施_课程表_教室" WHERE "实施_课程表编号" = #{sskcbh}
|
||||
</select>
|
||||
|
||||
<delete id="deleteBySskcbbh">
|
||||
DELETE FROM 实施_课程表_教室 WHERE 实施_课程表编号 = #{sskcbbh}
|
||||
DELETE FROM "实施_课程表_教室" WHERE "实施_课程表编号" = #{sskcbbh}
|
||||
</delete>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 课表冲突检查 - 维度4:教室(教学场地)时间冲突明细查询 -->
|
||||
<!-- 检查逻辑:同一教室同一日期节次,被安排多个不同课次 -->
|
||||
<!-- 用到的表: -->
|
||||
<!-- 1. 实施_课程表 SSKCB → 日期/节次/年度/删除状态 -->
|
||||
<!-- 2. 实施_课程表_教室 SSKCBJS → 教室编号(JSBH) -->
|
||||
<!-- 3. 教室表 JSB → 翻译教室中文名 -->
|
||||
<!-- 4. 课表 KB → 翻译课程名称 -->
|
||||
<!-- ============================================================ -->
|
||||
<select id="selectClassroomConflictDetails"
|
||||
resultType="com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO">
|
||||
SELECT
|
||||
/* 固定维度编码:教室时间冲突 */
|
||||
'CLASSROOM_CONFLICT' AS dimension_code,
|
||||
'教室时间冲突' AS dimension_title,
|
||||
/* 发生冲突的资源(教室)*/
|
||||
g."教室编号" AS resource_id,
|
||||
/* 翻译教室名称(教室表主键「教室编号」,名称「教室名称」)*/
|
||||
COALESCE(r."教室名称", g."教室编号") AS resource_name,
|
||||
/* 冲突的日期节次:统一取自主表 s */
|
||||
g."日期" AS rq,
|
||||
g."节次" AS jc,
|
||||
/* 同一教室同一时间占用课次数 */
|
||||
g."占用课次数" AS occupied_lesson_count,
|
||||
/* 冲突的课程名称列表 */
|
||||
g."课程名称列表" AS course_names,
|
||||
/* 冲突的课次编号列表 */
|
||||
g."课次编号列表" AS conflict_sskcb_bhs,
|
||||
/* 中文原因 */
|
||||
'教室【' || COALESCE(r."教室名称", g."教室编号") || '】在 '
|
||||
|| TO_CHAR(g."日期", 'YYYY-MM-DD') || ' 第' || CAST(g."节次" AS VARCHAR) || '节'
|
||||
|| ' 被同时安排 ' || CAST(g."占用课次数" AS VARCHAR) || ' 门课程:'
|
||||
|| COALESCE(g."课程名称列表", '(课次号:' || 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 (
|
||||
/*
|
||||
* 内层:按教室编号+日期+节次 GROUP BY,筛选 COUNT(DISTINCT 课次) > 1
|
||||
*
|
||||
* 关键修正:
|
||||
* 1. 三层关联 JOIN:SSKCB → 实施_课程 → 课表;CAST(ss.编号 AS CHAR(36))
|
||||
* 2. 日期节次统一取主表 s
|
||||
*
|
||||
* 新增 JOIN(同其他维度):聚合该冲突课次的班次/教员/场地所有明细信息
|
||||
* - INNER JOIN c 作为"维度过滤主关联"(只保留该教室的课次做分组)
|
||||
* - xyd_link/fz_info/js_link 作为"聚合展示用"JOIN(WM_CONCAT DISTINCT)
|
||||
*/
|
||||
SELECT
|
||||
c."教室编号",
|
||||
s."日期",
|
||||
s."节次",
|
||||
COUNT(DISTINCT s."编号") AS "占用课次数",
|
||||
WM_CONCAT(DISTINCT k."课名称") AS "课程名称列表",
|
||||
WM_CONCAT(DISTINCT s."编号") 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 "实施_课程表_教室" c ON c."实施_课程表编号" = s."编号"
|
||||
/* 课表信息三层关联(ss=实施_课程别名,避免与聚合JOIN的别名冲突)*/
|
||||
LEFT JOIN "实施_课程" ss ON CAST(ss."编号" AS CHAR(36)) = s."实施_课程编号"
|
||||
LEFT JOIN "课表" k ON k."科目代码" = ss."科目编号"
|
||||
/* ========== 新增 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 c."教室编号", s."日期", s."节次"
|
||||
HAVING COUNT(DISTINCT s."编号") > 1
|
||||
) g
|
||||
/* 修正:教室表主键是「教室编号」,不是「编号」 */
|
||||
LEFT JOIN "教室表" r ON r."教室编号" = g."教室编号"
|
||||
ORDER BY g."日期", g."节次", g."教室编号"
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -3,6 +3,7 @@ package com.roomroot.jwgl.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.roomroot.jwgl.entity.SSKCBXYD;
|
||||
import com.roomroot.jwgl.vo.elective.ClassScheduleVO;
|
||||
import com.roomroot.jwgl.vo.timetableconflict.TimetableConflictDetailVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -17,4 +18,20 @@ public interface SSKCBXYDMapper extends BaseMapper<SSKCBXYD> {
|
||||
|
||||
/** 查询班次关联的课程表(联表) */
|
||||
List<ClassScheduleVO> selectScheduleByXydbh(@Param("xydbh") String xydbh, @Param("nd") Integer nd);
|
||||
|
||||
/**
|
||||
* 【课表冲突检查】教学班时间冲突明细查询。
|
||||
*
|
||||
* @param nd 年度(学期过滤)
|
||||
* @return 教学班时间冲突明细列表
|
||||
*/
|
||||
List<TimetableConflictDetailVO> selectTeamConflictDetails(@Param("nd") Integer nd);
|
||||
|
||||
/**
|
||||
* 【课表冲突检查】教学班必修与选修时间冲突明细查询。
|
||||
*
|
||||
* @param nd 年度
|
||||
* @return 必修选修冲突明细列表
|
||||
*/
|
||||
List<TimetableConflictDetailVO> selectElectiveRequiredConflictDetails(@Param("nd") Integer nd);
|
||||
}
|
||||
@@ -30,7 +30,13 @@
|
||||
k."课名称"
|
||||
FROM "实施_课程表" s
|
||||
JOIN "实施_课程表_学员队" t ON t."实施_课程表编号" = s."编号"
|
||||
LEFT JOIN "课表" k ON k."课编号" = 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}
|
||||
@@ -38,4 +44,187 @@
|
||||
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>
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.roomroot.jwgl.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.roomroot.jwgl.entity.TimetableConflictResult;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课表冲突检查结果 Mapper。
|
||||
* <p>
|
||||
* 对应表:课表_冲突检查结果。
|
||||
* 继承 MyBatis-Plus BaseMapper 自动获得 insert / selectList / delete 等 CRUD 方法;
|
||||
* 额外保留 2 个便捷方法:按年度+批次号清理、按年度+维度编码查最新批次。
|
||||
* </p>
|
||||
*
|
||||
* @author management
|
||||
*/
|
||||
@Mapper
|
||||
public interface TimetableConflictResultMapper extends BaseMapper<TimetableConflictResult> {
|
||||
|
||||
/**
|
||||
* 按年度 + 检查批次号清理历史记录(DELETE,非逻辑删除)。
|
||||
* <p>
|
||||
* 等价于 MP 的 delete(new LambdaQueryWrapper<TimetableConflictResult>()
|
||||
* .eq(TimetableConflictResult::getNd, nd)
|
||||
* .eq(TimetableConflictResult::getJcpch, jcpch));
|
||||
* 这里提供 XML 版本只是为了在"批处理前后先清旧批次"场景更直观,
|
||||
* 不实现也行,Service 层用 MP wrapper 即可。
|
||||
* </p>
|
||||
*
|
||||
* @param nd 年度
|
||||
* @param jcpch 检查批次号
|
||||
* @return 删除条数
|
||||
*/
|
||||
int deleteByNdAndJcpch(@Param("nd") Integer nd, @Param("jcpch") String jcpch);
|
||||
|
||||
/**
|
||||
* 查询指定年度的所有检查批次号(倒序,最新排第一)。
|
||||
* <p>
|
||||
* 给前端"查看某次检查历史"的下拉框用。
|
||||
* </p>
|
||||
*
|
||||
* @param nd 年度
|
||||
* @return 批次号列表
|
||||
*/
|
||||
List<String> selectJcpchListByNd(@Param("nd") Integer nd);
|
||||
|
||||
/**
|
||||
* 【默认走 MP BaseMapper】等价说明:
|
||||
* <ul>
|
||||
* <li>insert(entity) → 单条插入一条冲突结果</li>
|
||||
* <li>insertBatch(entityList) → 需要 Service 层自己循环或用 MP IService 的 saveBatch,
|
||||
* 此处 BaseMapper 没有批量方法。</li>
|
||||
* <li>selectList(wrapper) → 按年度/维度/批次号查询明细列表</li>
|
||||
* <li>delete(wrapper) → 按条件 delete(reset 场景清该年度所有)</li>
|
||||
* </ul>
|
||||
*
|
||||
* 另:以下 2 个方法只是接口声明,提供语义化 API;
|
||||
* 若不准备写 TimetableConflictResultMapper.xml 实现,
|
||||
* 调用方请直接使用 MP BaseMapper 默认方法即可(推荐,更省事)。
|
||||
*/
|
||||
default int deleteByNd(Integer nd) {
|
||||
return delete(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimetableConflictResult>()
|
||||
.eq(TimetableConflictResult::getNd, nd));
|
||||
}
|
||||
|
||||
default List<TimetableConflictResult> listByNdAndJcpch(Integer nd, String jcpch) {
|
||||
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<TimetableConflictResult> qw
|
||||
= new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
|
||||
qw.eq(TimetableConflictResult::getNd, nd);
|
||||
if (jcpch != null && !jcpch.isEmpty()) {
|
||||
qw.eq(TimetableConflictResult::getJcpch, jcpch);
|
||||
}
|
||||
qw.orderByAsc(TimetableConflictResult::getRq)
|
||||
.orderByAsc(TimetableConflictResult::getJc)
|
||||
.orderByAsc(TimetableConflictResult::getWdbm);
|
||||
return selectList(qw);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user