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,359 @@
<?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.NotificationLogMapper">
<!-- 通知发送历史分页字段映射。 -->
<resultMap id="NotificationLogResultMap"
type="com.roomroot.jwgl.vo.notificationlog.NotificationLogVO">
<id column="id" property="id"/>
<result column="sendTime" property="sendTime"/>
<result column="title" property="title"/>
<result column="category" property="category"/>
<result column="noticeStatus" property="noticeStatus"/>
<result column="readCount" property="readCount"/>
<result column="recipientCount" property="recipientCount"/>
<result column="receivedCount" property="receivedCount"/>
<result column="readerCount" property="readerCount"/>
</resultMap>
<!-- 通知发送日志详情字段映射,继承列表中的发送与阅读统计字段。 -->
<resultMap id="NotificationLogDetailResultMap"
type="com.roomroot.jwgl.vo.notificationlog.NotificationLogDetailVO"
extends="NotificationLogResultMap">
<result column="content" property="content"/>
<result column="createTime" property="createTime"/>
<result column="priority" property="priority"/>
<result column="remark" property="remark"/>
<result column="all" property="all"/>
</resultMap>
<!-- 通知日志接收对象和阅读明细字段映射。 -->
<resultMap id="NotificationLogRecipientResultMap"
type="com.roomroot.jwgl.vo.notificationlog.NotificationLogRecipientVO">
<id column="id" property="id"/>
<result column="accountId" property="accountId"/>
<result column="loginName" property="loginName"/>
<result column="userName" property="userName"/>
<result column="received" property="received"/>
<result column="receivedTime" property="receivedTime"/>
<result column="read" property="read"/>
<result column="readTime" property="readTime"/>
</resultMap>
<!-- 通知日志发送与阅读汇总统计字段映射。 -->
<resultMap id="NotificationLogStatisticsResultMap"
type="com.roomroot.jwgl.vo.notificationlog.NotificationLogStatisticsVO">
<result column="notificationCount" property="notificationCount"/>
<result column="successNotificationCount"
property="successNotificationCount"/>
<result column="partialNotificationCount"
property="partialNotificationCount"/>
<result column="failedNotificationCount"
property="failedNotificationCount"/>
<result column="recipientCount" property="recipientCount"/>
<result column="receivedCount" property="receivedCount"/>
<result column="readerCount" property="readerCount"/>
</resultMap>
<!--
第一步:按通知编号和账户编号汇总重复接收记录。
第二步:每个账户分别确定是否成功接收、是否阅读和首次接收时间。
第三步:按通知汇总接收对象、成功接收、已阅读人数和首次发送时间。
-->
<sql id="NotificationRecipientStatisticsSql">
SELECT
recipient_status."noticeId",
COUNT(1) AS "recipientCount",
NVL(SUM(recipient_status."received"), 0)
AS "receivedCount",
NVL(SUM(recipient_status."read"), 0)
AS "readerCount",
MIN(recipient_status."receivedTime")
AS "firstReceivedTime"
FROM (
SELECT
recipient."通告编号" AS "noticeId",
recipient."用户编号" AS "accountId",
MAX(
CASE
WHEN recipient."已接收" = 1 THEN 1
ELSE 0
END
) AS "received",
MAX(
CASE
WHEN recipient."已阅读" = 1 THEN 1
ELSE 0
END
) AS "read",
MIN(
CASE
WHEN recipient."已接收" = 1
THEN recipient."接收时间"
ELSE NULL
END
) AS "receivedTime"
FROM "通告用户信息" recipient
GROUP BY
recipient."通告编号",
recipient."用户编号"
) recipient_status
GROUP BY recipient_status."noticeId"
</sql>
<!--
第一步:应用标题、类别和发送时间范围条件。
第二步:根据接收对象数和成功接收数匹配综合发送状态。
第三步:列表、汇总和导出统一复用该筛选规则。
-->
<sql id="NotificationLogFilterSql">
<where>
<!-- 通知标题使用不区分英文字母大小写的包含查询。 -->
<if test="query.title != null">
AND LOWER(notice."标题") LIKE
'%' || LOWER(#{query.title}) || '%'
</if>
<!-- 通知类别使用精确匹配。 -->
<if test="query.category != null">
AND notice."类别" = #{query.category}
</if>
<!-- 发送开始时间包含所选时间点。 -->
<if test="query.sendStartTime != null">
AND NVL(statistics."firstReceivedTime",
notice."发布时间")
&gt;= #{query.sendStartTime}
</if>
<!-- 发送结束时间包含所选时间点。 -->
<if test="query.sendEndTime != null">
AND NVL(statistics."firstReceivedTime",
notice."发布时间")
&lt;= #{query.sendEndTime}
</if>
<!-- 全部接收对象均接收成功时匹配发送成功。 -->
<if test='query.sendStatus == "发送成功"'>
AND statistics."recipientCount" &gt; 0
AND statistics."receivedCount"
= statistics."recipientCount"
</if>
<!-- 仅部分接收对象接收成功时匹配部分成功。 -->
<if test='query.sendStatus == "部分成功"'>
AND statistics."receivedCount" &gt; 0
AND statistics."receivedCount"
&lt; statistics."recipientCount"
</if>
<!-- 没有接收对象接收成功时匹配发送失败。 -->
<if test='query.sendStatus == "发送失败"'>
AND statistics."receivedCount" = 0
</if>
</where>
</sql>
<!--
第一步:按通知编号和账户编号汇总历史接收记录,避免重复账户造成统计重复。
第二步:按通知汇总接收对象、成功接收、已阅读人数和首次接收时间。
第三步:只保留已经实际产生接收记录的通知,并按照页面条件筛选和稳定排序。
-->
<select id="selectNotificationLogPage"
resultMap="NotificationLogResultMap">
SELECT
notice."编号" AS "id",
NVL(statistics."firstReceivedTime",
notice."发布时间") AS "sendTime",
notice."标题" AS "title",
notice."类别" AS "category",
notice."状态" AS "noticeStatus",
NVL(notice."阅读次数", 0) AS "readCount",
statistics."recipientCount" AS "recipientCount",
statistics."receivedCount" AS "receivedCount",
statistics."readerCount" AS "readerCount"
FROM "通告表" notice
INNER JOIN (
<include refid="NotificationRecipientStatisticsSql"/>
) statistics
ON statistics."noticeId" = notice."编号"
<include refid="NotificationLogFilterSql"/>
ORDER BY
"sendTime" DESC,
notice."编号" DESC
</select>
<!--
第一步:根据通知编号定位已经产生接收记录的通知。
第二步:查询通知正文、创建信息和发布范围。
第三步:同时返回与列表一致的发送、接收和阅读统计。
-->
<select id="selectNotificationLogDetail"
resultMap="NotificationLogDetailResultMap">
SELECT
notice."编号" AS "id",
NVL(statistics."firstReceivedTime",
notice."发布时间") AS "sendTime",
notice."标题" AS "title",
notice."类别" AS "category",
notice."状态" AS "noticeStatus",
NVL(notice."阅读次数", 0) AS "readCount",
statistics."recipientCount" AS "recipientCount",
statistics."receivedCount" AS "receivedCount",
statistics."readerCount" AS "readerCount",
notice."内容" AS "content",
notice."创建时间" AS "createTime",
notice."优先级" AS "priority",
notice."备注" AS "remark",
notice."全体" AS "all"
FROM "通告表" notice
INNER JOIN (
<include refid="NotificationRecipientStatisticsSql"/>
) statistics
ON statistics."noticeId" = notice."编号"
WHERE notice."编号" = #{id}
</select>
<!--
第一步:按账户汇总指定通知可能存在的重复接收记录。
第二步:关联登录信息,返回登录账号和接收人姓名。
第三步:在分组结果上筛选接收与阅读状态并执行稳定排序。
-->
<select id="selectNotificationLogRecipientPage"
resultMap="NotificationLogRecipientResultMap">
SELECT
MIN(recipient."编号") AS "id",
recipient."用户编号" AS "accountId",
account."账号" AS "loginName",
account."用户姓名" AS "userName",
MAX(
CASE
WHEN recipient."已接收" = 1 THEN 1
ELSE 0
END
) AS "received",
MIN(
CASE
WHEN recipient."已接收" = 1
THEN recipient."接收时间"
ELSE NULL
END
) AS "receivedTime",
MAX(
CASE
WHEN recipient."已阅读" = 1 THEN 1
ELSE 0
END
) AS "read",
MIN(
CASE
WHEN recipient."已阅读" = 1
THEN recipient."阅读时间"
ELSE NULL
END
) AS "readTime"
FROM "通告用户信息" recipient
LEFT JOIN "登录信息表" account
ON account."编号" = recipient."用户编号"
WHERE recipient."通告编号" = #{query.id}
<if test="query.keyword != null">
AND (
LOWER(NVL(account."账号", '')) LIKE
'%' || LOWER(#{query.keyword}) || '%'
OR LOWER(NVL(account."用户姓名", '')) LIKE
'%' || LOWER(#{query.keyword}) || '%'
)
</if>
GROUP BY
recipient."用户编号",
account."账号",
account."用户姓名"
HAVING 1 = 1
<if test="query.received != null">
AND MAX(
CASE
WHEN recipient."已接收" = 1 THEN 1
ELSE 0
END
) =
<choose>
<when test="query.received">1</when>
<otherwise>0</otherwise>
</choose>
</if>
<if test="query.read != null">
AND MAX(
CASE
WHEN recipient."已阅读" = 1 THEN 1
ELSE 0
END
) =
<choose>
<when test="query.read">1</when>
<otherwise>0</otherwise>
</choose>
</if>
ORDER BY
"received" ASC,
"read" ASC,
"readTime" DESC,
"userName" ASC,
"loginName" ASC,
"accountId" ASC
</select>
<!--
第一步:复用列表条件筛选全部符合条件的通知发送日志。
第二步:分别统计三类发送结果和接收、阅读总人数。
第三步:派生失败人数、未读人数和阅读率由工具类统一计算。
-->
<select id="selectNotificationLogStatistics"
resultMap="NotificationLogStatisticsResultMap">
SELECT
COUNT(1) AS "notificationCount",
NVL(SUM(
CASE
WHEN filtered."recipientCount" &gt; 0
AND filtered."receivedCount"
= filtered."recipientCount"
THEN 1
ELSE 0
END
), 0) AS "successNotificationCount",
NVL(SUM(
CASE
WHEN filtered."receivedCount" &gt; 0
AND filtered."receivedCount"
&lt; filtered."recipientCount"
THEN 1
ELSE 0
END
), 0) AS "partialNotificationCount",
NVL(SUM(
CASE
WHEN filtered."receivedCount" = 0 THEN 1
ELSE 0
END
), 0) AS "failedNotificationCount",
NVL(SUM(filtered."recipientCount"), 0)
AS "recipientCount",
NVL(SUM(filtered."receivedCount"), 0)
AS "receivedCount",
NVL(SUM(filtered."readerCount"), 0)
AS "readerCount"
FROM (
SELECT
notice."编号" AS "id",
statistics."recipientCount" AS "recipientCount",
statistics."receivedCount" AS "receivedCount",
statistics."readerCount" AS "readerCount"
FROM "通告表" notice
INNER JOIN (
<include refid="NotificationRecipientStatisticsSql"/>
) statistics
ON statistics."noticeId" = notice."编号"
<include refid="NotificationLogFilterSql"/>
) filtered
</select>
</mapper>