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,275 @@
<?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.OperationLogMapper">
<!--
将操作日志、登录记录和登录账户字段显式映射为列表 VO。
不使用旧实体的自动映射,避免继承公共字段和历史属性名影响查询。
-->
<resultMap id="OperationLogResultMap"
type="com.roomroot.jwgl.vo.operationlog.OperationLogVO">
<id column="id" property="id"/>
<result column="loginRecordId" property="loginRecordId"/>
<result column="operationAt" property="operationAt"/>
<result column="operationContent" property="operationContent"/>
<result column="url" property="url"/>
<result column="accountId" property="accountId"/>
<result column="loginName" property="loginName"/>
<result column="operatorName" property="operatorName"/>
<result column="unifiedAccount" property="unifiedAccount"/>
<result column="loginAt" property="loginAt"/>
<result column="ipAddress" property="ipAddress"/>
<result column="intranetIpAddress" property="intranetIpAddress"/>
<result column="transactionId" property="transactionId"/>
</resultMap>
<!--
详情 VO 继承列表 VO 的公共审计字段,因此复用已有显式字段映射。
后续增加仅详情使用的字段时,继续在当前结果映射中补充。
-->
<resultMap id="OperationLogDetailResultMap"
type="com.roomroot.jwgl.vo.operationlog.OperationLogDetailVO"
extends="OperationLogResultMap">
</resultMap>
<!--
第一步:使用业务层生成的 UUID 保存操作日志主键。
第二步:关联当前请求所属的登录记录,并保存服务端生成的操作时间。
第三步:只写入经过业务层规范化的操作内容和请求地址。
-->
<insert id="insertOperationLog">
INSERT INTO "操作日志表" (
"编号", "登录记录编号", "操作时间", "操作内容", "Url"
) VALUES (
#{id}, #{loginRecordId}, #{operationAt},
#{operationContent}, #{url}
)
</insert>
<!--
第一步:操作日志通过左连接关联登录记录,取得本次登录的时间、IP和事务标识。
第二步:登录记录通过左连接关联登录信息,关联数据缺失时仍保留历史操作日志。
第三步:按照时间、操作人、模块、内容和地址组合筛选。
第四步:按操作时间和日志编号倒序排列,保证分页顺序稳定。
-->
<select id="selectOperationLogPage"
resultMap="OperationLogResultMap">
SELECT
o."编号" AS "id",
o."登录记录编号" AS "loginRecordId",
o."操作时间" AS "operationAt",
o."操作内容" AS "operationContent",
o."Url" AS "url",
l."登录信息编号" AS "accountId",
a."账号" AS "loginName",
a."用户姓名" AS "operatorName",
a."统一账号" AS "unifiedAccount",
l."登录时间" AS "loginAt",
l."IP地址" AS "ipAddress",
l."内网IP" AS "intranetIpAddress",
l."事务ID" AS "transactionId"
FROM "操作日志表" o
LEFT JOIN "登录记录表" l
ON l."编号" = o."登录记录编号"
LEFT JOIN "登录信息表" a
ON a."编号" = l."登录信息编号"
<where>
<!-- 开始时间采用大于等于条件,包含边界时刻。 -->
<if test="startTime != null">
AND o."操作时间" &gt;= #{startTime}
</if>
<!-- 结束时间采用小于等于条件,包含边界时刻。 -->
<if test="endTime != null">
AND o."操作时间" &lt;= #{endTime}
</if>
<!-- 操作人关键字同时匹配账号、姓名和统一账号。 -->
<if test="operatorKeyword != null">
AND (
LOWER(NVL(a."账号", '')) LIKE
'%' || LOWER(#{operatorKeyword}) || '%'
OR LOWER(NVL(a."用户姓名", '')) LIKE
'%' || LOWER(#{operatorKeyword}) || '%'
OR LOWER(NVL(a."统一账号", '')) LIKE
'%' || LOWER(#{operatorKeyword}) || '%'
)
</if>
<!-- 操作内容使用不区分英文字母大小写的包含查询。 -->
<if test="contentKeyword != null">
AND LOWER(NVL(o."操作内容", '')) LIKE
'%' || LOWER(#{contentKeyword}) || '%'
</if>
<!-- 请求地址使用不区分英文字母大小写的包含查询。 -->
<if test="urlKeyword != null">
AND LOWER(NVL(o."Url", '')) LIKE
'%' || LOWER(#{urlKeyword}) || '%'
</if>
<!--
旧操作日志表没有模块字段,因此根据现有控制器地址识别模块。
模块名称已经在业务层完成白名单校验,此处只负责转换为地址条件。
-->
<if test="module != null">
<choose>
<when test='module == "部别管理"'>
AND LOWER(NVL(o."Url", '')) LIKE '%/department/%'
</when>
<when test='module == "隶属关系设置"'>
AND (
LOWER(NVL(o."Url", '')) LIKE
'%/research-office-affiliation/%'
OR LOWER(NVL(o."Url", '')) LIKE
'%/teaching-class-affiliation/%'
)
</when>
<when test='module == "部别人员管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/department-personnel/%'
</when>
<when test='module == "字典设置"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/dictionary-setting/%'
</when>
<when test='module == "账户管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/account-management/%'
</when>
<when test='module == "操作日志管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/operation-log/%'
</when>
<when test='module == "通知公告管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/notice-announcement/%'
</when>
<when test='module == "培养方案管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/training/%'
</when>
<when test='module == "学科专业管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/discipline/%'
</when>
<when test='module == "教研室与教员管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/faculty/%'
</when>
<when test='module == "课程教学管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/course-teaching/%'
</when>
<when test='module == "学员档案管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/student-records/%'
</when>
<when test='module == "教学楼管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/build/%'
</when>
<when test='module == "教室管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/classroom/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/classroom/jxcdl/%'
</when>
<when test='module == "教学场地历管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/classroom/jxcdl/%'
</when>
<when test='module == "教室输出课程表管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/classroomlesson/%'
</when>
<when test='module == "学期校历管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/xqxlb/%'
</when>
<when test='module == "教材管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/teachingmaterial/%'
</when>
<when test='module == "教材库存管理"'>
AND LOWER(NVL(o."Url", '')) LIKE
'%/teachingstock/%'
</when>
<otherwise>
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/department/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/research-office-affiliation/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/teaching-class-affiliation/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/department-personnel/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/dictionary-setting/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/account-management/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/operation-log/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/notice-announcement/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/training/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/discipline/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/faculty/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/course-teaching/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/student-records/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/build/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/classroom/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/classroomlesson/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/xqxlb/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/teachingmaterial/%'
AND LOWER(NVL(o."Url", '')) NOT LIKE
'%/teachingstock/%'
</otherwise>
</choose>
</if>
</where>
ORDER BY o."操作时间" DESC, o."编号" DESC
</select>
<!--
第一步:根据操作日志主键精确查询唯一日志。
第二步:使用左连接补充登录记录和账户信息,避免历史关联数据缺失时
连操作日志本身也无法查看。
第三步:只返回审计展示所需字段,不查询密码等敏感账户信息。
-->
<select id="selectOperationLogById"
resultMap="OperationLogDetailResultMap">
SELECT
o."编号" AS "id",
o."登录记录编号" AS "loginRecordId",
o."操作时间" AS "operationAt",
o."操作内容" AS "operationContent",
o."Url" AS "url",
l."登录信息编号" AS "accountId",
a."账号" AS "loginName",
a."用户姓名" AS "operatorName",
a."统一账号" AS "unifiedAccount",
l."登录时间" AS "loginAt",
l."IP地址" AS "ipAddress",
l."内网IP" AS "intranetIpAddress",
l."事务ID" AS "transactionId"
FROM "操作日志表" o
LEFT JOIN "登录记录表" l
ON l."编号" = o."登录记录编号"
LEFT JOIN "登录信息表" a
ON a."编号" = l."登录信息编号"
WHERE o."编号" = #{id}
</select>
</mapper>