『博客开发日记』之获取通知列表接口的实现

本文最后更新于 2026年5月28日 晚上

获取通知列表接口的实现


获取通知列表接口的需求

这是前台获取通知列表的接口

前台仅展示已发布通知;未登录用户只能看全体通知,登录用户还能看发给自己的指定通知

如果是指定用户的话通知只能是指定的用户才能看到

按发布时间倒序排序

分页查询

查询发布人的名字并回填

如果当前用户已登录,再查询并回填阅读状态

未读优先,已读在后;同状态下保持发布时间倒序


代码实现

前期准备

用 EasyCode 插件生成需要的文件


在 NoticeController 中添加接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 前台通知相关接口
*/
@RestController
@Api(tags = "通知", description = "前台通知相关接口")
public class NoticeController
{
@Autowired
private NoticeService noticeService;

@GetMapping("/notice/list")
@SystemLog(businessName = "获取通知列表接口")
@ApiOperation(value = "获取通知列表接口", notes = "分页查询通知列表", response = PageVo.class)
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页号", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "int", paramType = "query")
})
public ResponseResult<PageVo> getNoticeList(Integer pageNum, Integer pageSize)
{
return noticeService.getNoticeList(pageNum, pageSize);
}

}


创建 BlogNoticeListVo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 前台通知Vo
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@ApiModel(description = "前台通知列表响应对象")
public class BlogNoticeListVo
{
@ApiModelProperty(value = "通知id", example = "6")
private Long id;

@ApiModelProperty(value = "通知标题", example = "这里是标题")
private String title;

@ApiModelProperty(value = "通知内容", example = "这里是内容")
private String content;

@ApiModelProperty(value = "通知类型(关联字典编码:notice_type)", example = "系统维护")
private Integer type;

@ApiModelProperty(value = "通知等级(字典code:notice_level)", example = "M")
private String level;

@TableField(exist = false)
@ApiModelProperty(value = "读取状态(0: 未读, 1: 已读)", example = "0")
private String isRead;

@ApiModelProperty(value = "发布人名字", example = "云梦泽")
private String publisherName;

@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "发布时间", example = "2024-01-01 12:00:00")
private Date publishTime;
}


添加常量

1
2
3
4
/**
* 目标类型:指定用户
*/
public static final String TARGET_TYPE_IS_SPECIFIED = "2";

在 NoticeServiceImpl 中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
@Autowired
private SysNoticeUserService sysNoticeUserService;

@Autowired
private SysUserService sysUserService;

//获取通知列表
@Override
public ResponseResult<PageVo> getNoticeList(Integer pageNum, Integer pageSize)
{
Long userId = SecurityUtils.getUserId();

//前台仅展示已发布通知;未登录用户只能看全体通知,登录用户还能看发给自己的指定通知
LambdaQueryWrapper<SysNotice> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysNotice::getStatus, SystemConstants.NOTICE_STATUS_PUBLISHED)
.eq(SysNotice::getDelFlag, SystemConstants.STATUS_NORMAL);
if (userId == null) {
queryWrapper.eq(SysNotice::getTargetType, SystemConstants.TARGET_TYPE_IS_ALL);
} else {
queryWrapper.and(wrapper -> wrapper
.eq(SysNotice::getTargetType, SystemConstants.TARGET_TYPE_IS_ALL)
.or(orWrapper -> orWrapper
.eq(SysNotice::getTargetType, SystemConstants.TARGET_TYPE_IS_SPECIFIED)
.apply("find_in_set({0}, target_user_ids)", userId)));
}

//按发布时间倒序排序
queryWrapper.orderByDesc(SysNotice::getPublishTime);

//分页查询
Page<SysNotice> page = new Page<>(pageNum, pageSize);
this.page(page, queryWrapper);

List<SysNotice> noticeList = page.getRecords();

//实体转换为Vo
List<BlogNoticeListVo> noticeListVos = BeanCopyUtils.copyBeanList(noticeList, BlogNoticeListVo.class);

//查询发布人的名字并回填
List<Long> publisherIds = noticeList.stream()
.map(SysNotice::getPublisherId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
Map<Long, String> publisherNameMap = new HashMap<>();
if (!publisherIds.isEmpty()) {
List<SysUser> publisherList = sysUserService.listByIds(publisherIds);
publisherNameMap = publisherList.stream()
.collect(Collectors.toMap(SysUser::getId, user -> StringUtils.hasText(user.getNickname()) ? user.getNickname() : user.getUsername(), (oldVal, newVal) -> oldVal));
}

//查询指定接收人的名字并回填
Map<Long, String> targetUserNameMap = new HashMap<>();
List<Long> targetUserIds = noticeList.stream()
.filter(notice -> SystemConstants.TARGET_TYPE_IS_SPECIFIED.equals(notice.getTargetType()))
.map(SysNotice::getTargetUserIds)
.filter(StringUtils::hasText)
.flatMap(targetUserIdsStr -> Arrays.stream(targetUserIdsStr.split(",")))
.map(String::trim)
.filter(StringUtils::hasText)
.map(Long::valueOf)
.distinct()
.collect(Collectors.toList());
if (!targetUserIds.isEmpty()) {
List<SysUser> targetUserList = sysUserService.listByIds(targetUserIds);
targetUserNameMap = targetUserList.stream()
.collect(Collectors.toMap(SysUser::getId, user -> StringUtils.hasText(user.getNickname()) ? user.getNickname() : user.getUsername(), (oldVal, newVal) -> oldVal));
}

//将接收人名字集合封装进 VO
for (int i = 0; i < noticeList.size(); i++)
{
SysNotice notice = noticeList.get(i);
BlogNoticeListVo noticeListVo = noticeListVos.get(i);
noticeListVo.setPublisherName(publisherNameMap.get(notice.getPublisherId()));
noticeListVo.setTargetUserIds(notice.getTargetUserIds());
if (SystemConstants.TARGET_TYPE_IS_SPECIFIED.equals(notice.getTargetType()) && StringUtils.hasText(notice.getTargetUserIds())) {
List<String> targetNames = Arrays.stream(notice.getTargetUserIds().split(","))
.map(String::trim)
.filter(StringUtils::hasText)
.map(Long::valueOf)
.map(targetUserNameMap::get)
.filter(StringUtils::hasText)
.collect(Collectors.toList());
noticeListVo.setTargetName(targetNames);
}
}

//默认未读
for (BlogNoticeListVo noticeListVo : noticeListVos) {
noticeListVo.setIsRead(SystemConstants.NOTICE_NOT_READ);
}

//如果当前用户已登录,再查询并回填阅读状态
if (userId != null && !noticeList.isEmpty()) {
List<Long> noticeIds = noticeList.stream().map(SysNotice::getId).collect(Collectors.toList());
List<SysNoticeUser> noticeUserList = sysNoticeUserService.list(new LambdaQueryWrapper<SysNoticeUser>()
.eq(SysNoticeUser::getUserId, userId)
.in(SysNoticeUser::getNoticeId, noticeIds));

Map<Long, String> noticeReadMap = noticeUserList.stream()
.collect(Collectors.toMap(SysNoticeUser::getNoticeId, SysNoticeUser::getIsRead, (oldVal, newVal) -> oldVal));

for (BlogNoticeListVo noticeListVo : noticeListVos) {
noticeListVo.setIsRead(noticeReadMap.getOrDefault(noticeListVo.getId(), SystemConstants.NOTICE_NOT_READ));
}

//未读优先,已读在后;同状态下保持发布时间倒序
noticeListVos.sort(Comparator.comparing((BlogNoticeListVo vo) -> SystemConstants.NOTICE_IS_READ.equals(vo.getIsRead()))
.thenComparing(BlogNoticeListVo::getPublishTime, Comparator.nullsLast(Comparator.reverseOrder())));
}

PageVo pageVo = new PageVo(noticeListVos, page.getTotal());
return ResponseResult.okResult(pageVo);
}





PS:该系列只做为作者学习开发项目做的笔记用

不一定符合读者来学习,仅供参考


预告

后续会记录博客的开发过程

每次学习会做一份笔记来进行发表

“一花一世界,一叶一菩提”


版权所有 © 2026 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『博客开发日记』之获取通知列表接口的实现
http://example.com/2026/05/28/『博客开发日记』之获取通知列表接口的实现/
作者
云梦泽
发布于
2026年5月28日
更新于
2026年5月28日
许可协议