feat(system): 添加公告通知已读记录功能
- 新增 SysNoticeRead 实体类用于存储公告/通知已读记录 - 实现 SysNoticeReadMapper 数据访问层接口及 XML 映射文件 - 创建 ISysNoticeReadService 服务接口及实现类 - 添加数据库表 sys_notice_read 存储用户阅读状态 - 添加发布状态字段到公告表支持公告发布控制 - 实现前端 NoticePanel 组件支持未读标记和阅读状态显示 - 提供标记已读、批量标记、未读数量统计等功能 - 优化公告列表按已读状态和时间排序显示
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package com.core.system.domain;
|
||||
|
||||
import com.core.common.core.domain.BaseEntity;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
|
||||
/**
|
||||
* 公告/通知已读记录 sys_notice_read
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public class SysNoticeRead extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 阅读ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long readId;
|
||||
|
||||
/** 公告/通知ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long noticeId;
|
||||
|
||||
/** 用户ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long userId;
|
||||
|
||||
/** 阅读时间 */
|
||||
private String readTime;
|
||||
|
||||
public Long getReadId() {
|
||||
return readId;
|
||||
}
|
||||
|
||||
public void setReadId(Long readId) {
|
||||
this.readId = readId;
|
||||
}
|
||||
|
||||
public Long getNoticeId() {
|
||||
return noticeId;
|
||||
}
|
||||
|
||||
public void setNoticeId(Long noticeId) {
|
||||
this.noticeId = noticeId;
|
||||
}
|
||||
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getReadTime() {
|
||||
return readTime;
|
||||
}
|
||||
|
||||
public void setReadTime(String readTime) {
|
||||
this.readTime = readTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.core.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.core.system.domain.SysNoticeRead;
|
||||
|
||||
/**
|
||||
* 公告/通知已读记录 Mapper接口
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public interface SysNoticeReadMapper {
|
||||
|
||||
/**
|
||||
* 查询公告/通知已读记录
|
||||
*
|
||||
* @param readId 阅读ID
|
||||
* @return 公告/通知已读记录
|
||||
*/
|
||||
public SysNoticeRead selectNoticeReadById(Long readId);
|
||||
|
||||
/**
|
||||
* 查询用户的已读公告/通知ID列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 已读公告/通知ID列表
|
||||
*/
|
||||
public List<Long> selectReadNoticeIdsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 查询公告/通知的已读用户数量
|
||||
*
|
||||
* @param noticeId 公告/通知ID
|
||||
* @return 已读用户数量
|
||||
*/
|
||||
public int countReadByNoticeId(Long noticeId);
|
||||
|
||||
/**
|
||||
* 新增公告/通知已读记录
|
||||
*
|
||||
* @param noticeRead 公告/通知已读记录
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertNoticeRead(SysNoticeRead noticeRead);
|
||||
|
||||
/**
|
||||
* 删除公告/通知已读记录
|
||||
*
|
||||
* @param readId 阅读ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeReadById(Long readId);
|
||||
|
||||
/**
|
||||
* 批量删除公告/通知已读记录
|
||||
*
|
||||
* @param readIds 需要删除的阅读ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteNoticeReadByIds(Long[] readIds);
|
||||
|
||||
/**
|
||||
* 检查用户是否已阅读公告/通知
|
||||
*
|
||||
* @param noticeId 公告/通知ID
|
||||
* @param userId 用户ID
|
||||
* @return 是否已阅读
|
||||
*/
|
||||
public boolean checkNoticeRead(Long noticeId, Long userId);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.core.system.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.system.domain.SysNotice;
|
||||
import com.core.system.domain.SysNoticeRead;
|
||||
|
||||
/**
|
||||
* 公告/通知已读记录 服务层
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public interface ISysNoticeReadService {
|
||||
|
||||
/**
|
||||
* 查询用户的未读公告/通知数量
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 未读数量
|
||||
*/
|
||||
public int getUnreadCount(Long userId);
|
||||
|
||||
/**
|
||||
* 标记公告/通知为已读
|
||||
*
|
||||
* @param noticeId 公告/通知ID
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
public AjaxResult markAsRead(Long noticeId, Long userId);
|
||||
|
||||
/**
|
||||
* 批量标记公告/通知为已读
|
||||
*
|
||||
* @param noticeIds 公告/通知ID列表
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
public AjaxResult markAllAsRead(Long[] noticeIds, Long userId);
|
||||
|
||||
/**
|
||||
* 查询用户的已读公告/通知ID列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 已读公告/通知ID列表
|
||||
*/
|
||||
public List<Long> selectReadNoticeIdsByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 查询带已读状态的公告列表
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @param userId 用户ID
|
||||
* @return 公告集合
|
||||
*/
|
||||
public List<SysNotice> selectNoticeListWithReadStatus(SysNotice notice, Long userId);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.core.system.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.core.system.domain.SysNotice;
|
||||
import com.core.system.domain.SysNoticeRead;
|
||||
import com.core.system.mapper.SysNoticeMapper;
|
||||
import com.core.system.mapper.SysNoticeReadMapper;
|
||||
import com.core.system.service.ISysNoticeReadService;
|
||||
|
||||
/**
|
||||
* 公告/通知已读记录 服务层实现
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
@Service
|
||||
public class SysNoticeReadServiceImpl implements ISysNoticeReadService {
|
||||
|
||||
@Autowired
|
||||
private SysNoticeReadMapper noticeReadMapper;
|
||||
|
||||
@Autowired
|
||||
private SysNoticeMapper noticeMapper;
|
||||
|
||||
/**
|
||||
* 查询用户的未读公告/通知数量
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 未读数量
|
||||
*/
|
||||
@Override
|
||||
public int getUnreadCount(Long userId) {
|
||||
// 查询所有状态为正常(0)的公告/通知
|
||||
SysNotice notice = new SysNotice();
|
||||
notice.setStatus("0");
|
||||
List<SysNotice> allNotices = noticeMapper.selectNoticeList(notice);
|
||||
|
||||
// 查询用户已读的公告/通知ID
|
||||
List<Long> readNoticeIds = noticeReadMapper.selectReadNoticeIdsByUserId(userId);
|
||||
|
||||
// 计算未读数量
|
||||
int unreadCount = 0;
|
||||
for (SysNotice n : allNotices) {
|
||||
if (!readNoticeIds.contains(n.getNoticeId())) {
|
||||
unreadCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return unreadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记公告/通知为已读
|
||||
*
|
||||
* @param noticeId 公告/通知ID
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult markAsRead(Long noticeId, Long userId) {
|
||||
// 检查是否已读
|
||||
boolean isRead = noticeReadMapper.checkNoticeRead(noticeId, userId);
|
||||
if (isRead) {
|
||||
return AjaxResult.success("已标记为已读");
|
||||
}
|
||||
|
||||
// 插入已读记录
|
||||
SysNoticeRead noticeRead = new SysNoticeRead();
|
||||
noticeRead.setNoticeId(noticeId);
|
||||
noticeRead.setUserId(userId);
|
||||
|
||||
int result = noticeReadMapper.insertNoticeRead(noticeRead);
|
||||
if (result > 0) {
|
||||
return AjaxResult.success("标记成功");
|
||||
}
|
||||
return AjaxResult.error("标记失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量标记公告/通知为已读
|
||||
*
|
||||
* @param noticeIds 公告/通知ID列表
|
||||
* @param userId 用户ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult markAllAsRead(Long[] noticeIds, Long userId) {
|
||||
int successCount = 0;
|
||||
for (Long noticeId : noticeIds) {
|
||||
boolean isRead = noticeReadMapper.checkNoticeRead(noticeId, userId);
|
||||
if (!isRead) {
|
||||
SysNoticeRead noticeRead = new SysNoticeRead();
|
||||
noticeRead.setNoticeId(noticeId);
|
||||
noticeRead.setUserId(userId);
|
||||
noticeReadMapper.insertNoticeRead(noticeRead);
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
return AjaxResult.success("成功标记" + successCount + "条记录为已读");
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户的已读公告/通知ID列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 已读公告/通知ID列表
|
||||
*/
|
||||
@Override
|
||||
public List<Long> selectReadNoticeIdsByUserId(Long userId) {
|
||||
return noticeReadMapper.selectReadNoticeIdsByUserId(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询带已读状态的公告列表
|
||||
*
|
||||
* @param notice 公告信息
|
||||
* @param userId 用户ID
|
||||
* @return 公告集合
|
||||
*/
|
||||
@Override
|
||||
public List<SysNotice> selectNoticeListWithReadStatus(SysNotice notice, Long userId) {
|
||||
// 这里可以扩展为在查询结果中添加已读状态标记
|
||||
// 暂时返回普通列表
|
||||
return noticeMapper.selectNoticeList(notice);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?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.core.system.mapper.SysNoticeReadMapper">
|
||||
|
||||
<resultMap type="SysNoticeRead" id="SysNoticeReadResult">
|
||||
<result property="readId" column="read_id"/>
|
||||
<result property="noticeId" column="notice_id"/>
|
||||
<result property="userId" column="user_id"/>
|
||||
<result property="readTime" column="read_time"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectNoticeReadById" parameterType="Long" resultMap="SysNoticeReadResult">
|
||||
select read_id, notice_id, user_id, read_time
|
||||
from sys_notice_read
|
||||
where read_id = #{readId}
|
||||
</select>
|
||||
|
||||
<select id="selectReadNoticeIdsByUserId" parameterType="Long" resultType="Long">
|
||||
select notice_id
|
||||
from sys_notice_read
|
||||
where user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<select id="countReadByNoticeId" parameterType="Long" resultType="int">
|
||||
select count(1)
|
||||
from sys_notice_read
|
||||
where notice_id = #{noticeId}
|
||||
</select>
|
||||
|
||||
<select id="checkNoticeRead" resultType="boolean">
|
||||
select count(1) > 0
|
||||
from sys_notice_read
|
||||
where notice_id = #{noticeId} and user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<insert id="insertNoticeRead" parameterType="SysNoticeRead">
|
||||
insert into sys_notice_read (
|
||||
read_id,
|
||||
notice_id,
|
||||
user_id,
|
||||
read_time
|
||||
) values (
|
||||
(SELECT COALESCE(MAX(read_id), 0) + 1 FROM sys_notice_read),
|
||||
#{noticeId},
|
||||
#{userId},
|
||||
now()
|
||||
)
|
||||
</insert>
|
||||
|
||||
<delete id="deleteNoticeReadById" parameterType="Long">
|
||||
delete from sys_notice_read where read_id = #{readId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteNoticeReadByIds" parameterType="Long">
|
||||
delete from sys_notice_read where read_id in
|
||||
<foreach item="readId" collection="array" open="(" separator="," close=")">
|
||||
#{readId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user