发出信息的实现
- 创建信息数据库
create table tbl_message
(
id bigint auto_increment,
notifier bigint not null comment '发出消息的人',
receiver bigint not null comment '接收消息的人',
outerId bigint not null comment '信息所对应的Id,如评论的Id。做外键',
type int not null comment '消息的类型:收到评论,点赞,系统通知等',
time_create bigint not null,
status int default 0 not null comment '0:未读;1:已读',
notifier_name varchar(100) null,
outer_title varchar(256) null,
constraint tbl_message_pk
primary key (id)
);
生成mapper
<table tableName="tbl_message" domainObjectName="Message"></table>
运行指令
2. 创建信息类型的枚举和信息状态的枚举、
信息类型
package com.july.community.enums;
public enum MessageTypeEnum {
REPLY_QUESTION(1,"回复了问题"),
REPLY_COMMENT(2,"回复了评论");
private int type;
private String name;
public int getType() {
return type;
}
public String getName() {
return name;
}
MessageTypeEnum(int type, String name) {
this.type = type;
this.name = name;
}
}
信息状态
package com.july.community.enums;
public enum MessageStatusEnum {
UNREAD(0),
READ(1);
private int status;
public int getStatus() {
return status;
}
MessageStatusEnum(int status) {
this.status = status;
}
public static String nameOfType(int type){
for (MessageTypeEnum messageTypeEnum :MessageTypeEnum.values()){
if (messageTypeEnum.getType() == type){
return messageTypeEnum.getName();
}
}
return "";
}
}
- 编写逻辑
package com.july.community.service;
public class CommentService {
@Autowired
private MessageMapper messageMapper;
public void insert(Comment comment) {
if (comment.getType() == CommentTypeEnum.COMMENT.getType()){
//评论的回复
...
//发出信息通知提醒
createMessage(comment, parentComment.getCommentator(), MessageTypeEnum.REPLY_COMMENT);
}else{
//问题的回复
...
//发出信息通知提醒
createMessage(comment, parentQuestion.getCreator(), MessageTypeEnum.REPLY_QUESTION);
}
...
}
//发出信息通知提醒
private void createMessage(Comment comment, Long receiver, MessageTypeEnum messageType) {
Message message = new Message();
message.setNotifier(comment.getCommentator());
message.setReceiver(receiver);
message.setOuterid(comment.getParentId());
message.setStatus(MessageStatusEnum.UNREAD.getStatus());
message.setType(messageType.getType());
message.setTimeCreate(System.currentTimeMillis());
messageMapper.insert(message);
}
}
展示通知内容
- 构建MessageDTO
package com.july.community.dto;
import com.july.community.model.User;
import lombok.Data;
@Data
public class MessageDTO {
private Long id;
private Long timeCreate;
private Integer status;
private Long notifiedId;
private String notifierName;
private String outerTitle;
private Long outerid;
private String typeName;
private Integer type;
}
- 编写controller
在profileController中
@Autowired
private MessageService messageService;
@GetMapping("/profile/{action}")
public String profile(@PathVariable(name = "action") String action,
Model model,
@RequestParam(name = "page",defaultValue = "1") Integer page,
@RequestParam(name = "size",defaultValue = "5") Integer size ,
HttpServletRequest request){
...
else if("replies".equals(action)){
//我的信息
//获取信息数据
PaginationDTO paginationDTO = messageService.getList(user.getId(), page, size);
model.addAttribute("pagination",paginationDTO);
model.addAttribute("sectionName","最新回复");
}
}
- 编写MessageService
package com.july.community.service;
@Service
public class MessageService {
@Autowired
private MessageMapper messageMapper;
@Autowired
private UserMapper userMapper;
public PaginationDTO getList(Long userId, Integer page, Integer size) {
PaginationDTO<MessageDTO> paginationDTO = new PaginationDTO<>();
MessageExample example = new MessageExample();
example.createCriteria().andReceiverEqualTo(userId);
example.setOrderByClause("time_create desc");
Integer totalCount = (int) messageMapper.countByExample(example);
paginationDTO.setPagination(totalCount, page, size);
Integer totalPage = paginationDTO.getTotalPage();
//限定页码范围
if (page < 1) {
page = 1;
}
if (page > totalPage && totalPage != 0) {
page = totalPage;
}
//获取message所有对象
Integer offset = size * (page - 1);
MessageExample messageExample = new MessageExample();
messageExample.createCriteria().andReceiverEqualTo(userId);
List<Message> messages = messageMapper.selectByExampleWithRowbounds(messageExample,
new RowBounds(offset, size));//该list存从数据库中查到的message对象
if (messages.size() == 0){
return paginationDTO;
}
List<MessageDTO> messageDTOS = new ArrayList<>(); //该list存要返回的messageDTO对象
//循环获取
for (Message message : messages) {
MessageDTO messageDTO = new MessageDTO();
BeanUtils.copyProperties(message,messageDTO);
messageDTO.setTypeName(MessageTypeEnum.nameOfType(message.getType()));
messageDTOS.add(messageDTO);
}
paginationDTO.setData(messageDTOS);
return paginationDTO;
}
//获取用户未读信息数
public Long unreadCount(Long receiverId) {
MessageExample example = new MessageExample();
example.createCriteria().andReceiverEqualTo(receiverId);
return messageMapper.countByExample(example);
}
}
注:此处已经修改分页PaginationDTO为泛型,以实现复用
public class PaginationDTO<T> {
private List<T> data; //问题列表
- 前端
profile.html
<!--我的信息的部分-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" th:if="${section == 'replies'}">
<div class="media" th:each="message : ${pagination.data}">
<div class="media-body">
<p class="media-heading">
<span th:text="${message.notifierName + ' ' +message.type+ ' '}"></span>
<a th:href="@{'/message/'+${message.id}}"
th:text="${message.outerTitle}"></a>
</p>
</div>
</div>
</div>
...
<a href="/profile/replies"
th:class="${section == 'replies'}? 'active list-group-item' : 'list-group-item'">
<span class="badge" th:text="${session.unreadCount}"></span>
最新回复</a>
navigation.html
<li><a href="/profile/replies">信息<span class="badge" th:text="${session.unreadCount}"></span></a></li>
- 导航栏通知数显示
在SessionInterceptor中进行编写
if(users.size() != 0){ //若找到了这个用户信息
...
//获取该用户的未读信息数
Long unreadCount = messageService.unreadCount(users.get(0).getId());
//写入session
request.getSession().setAttribute("unreadCount",unreadCount);
}
信息点击后跳转并消除未读
- 创建messageController
package com.july.community.controller;
@Controller
public class MessageController {
@Autowired
private MessageService messageService;
@GetMapping("/message/{id}")
public String profile(@PathVariable(name = "id") Long id,
HttpServletRequest request) {
//验证登录状态
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
return "redirect:/";
}
//获取点击的信息
MessageDTO messageDTO = messageService.getMessageDTO(id, user);
if (MessageTypeEnum.REPLY_COMMENT.getType() == messageDTO.getType()
|| MessageTypeEnum.REPLY_QUESTION.getType() == messageDTO.getType()) {
//跳转到相应的问题页面
return "redirect:/question/" + messageDTO.getOuterid();
} else {
return "redirect:/";
}
}
}
- 编写messageService中已读方法
//获取点击的信息
public MessageDTO getMessageDTO(Long id, User user) {
//获取点击的问题
Message message = messageMapper.selectByPrimaryKey(id);
if (message == null){
throw new CustomizeException(CustomizeErrorCode.MESSAGE_NOT_FOUND);
}
//核对查看权限
if (message.getReceiver() != user.getId()){
throw new CustomizeException(CustomizeErrorCode.READ_MESSAGE_FAIL);
}
//标记为已读
message.setStatus(MessageStatusEnum.READ.getStatus());
messageMapper.updateByPrimaryKey(message);
//获取这条回复,得到其所对应的问题
MessageDTO messageDTO= new MessageDTO();
BeanUtils.copyProperties(message,messageDTO);
messageDTO.setTypeName(MessageTypeEnum.nameOfType(message.getType()));
return messageDTO;
}