SpringBoot-实现回复通知的功能

发出信息的实现

  1. 创建信息数据库
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 "";
    }
}

  1. 编写逻辑
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);
    }
}

展示通知内容

  1. 构建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;
}

  1. 编写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","最新回复");
            }
}
  1. 编写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; //问题列表
  1. 前端
    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>
  1. 导航栏通知数显示
    在SessionInterceptor中进行编写
if(users.size() != 0){ //若找到了这个用户信息
                        ...
                        //获取该用户的未读信息数
                        Long unreadCount = messageService.unreadCount(users.get(0).getId());
                        //写入session
                        request.getSession().setAttribute("unreadCount",unreadCount);
                    }

信息点击后跳转并消除未读

  1. 创建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:/";
        }
    }
}

  1. 编写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;
    }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值