3.5 私信列表和发送私信

本文档详述了私信系统的实现过程,包括创建消息实体类、数据库操作、服务层和控制器的编写,以及前端页面的交互优化。重点在于查询用户会话列表、私信分页显示及未读消息计数。同时,提供了发送私信和更新消息状态的接口,并展示了相关JavaScript代码处理。
摘要由CSDN通过智能技术生成



# 私信列表

在这里插入图片描述

小id放前

1、创建message表对应的实体类

public class Message {
    private int id;
    private int fromId;   //发送者id
    private int toId;     //接受者id
    private String conversationId;   //会话id  小的id在前面  111_112 和112_111属于同一个会话
    private String content;   //内容
    private int status;   //状态
    }0表示未读  1表示已读  2表示删除
    private Date createTime;

2、编写Message数据层方法

  • 当前用户的会话列表需要分页显示 ,因此需要分页的属性offset,limit;
  • 查询数据库中属于当前用户id的所有会话,形成会话列表;
  • 查询当前用户的会话数量,为分页做准备
  • 每一个会话里又有很多内容信息,因此也需要进行分页,需要相关参数;
  • 根据会话id查找得到相应的私信列表;
  • 查询当前会话包含的私信数量;
  • 需要在页面显示未读消息的数量包括会话未读数量和私信未读数量,因此需要传入用户id和会话id,根据选择传入相应的值
@Mapper
public interface MessageMapper {
    // 查询当前用户的会话列表,针对每个会话只返回一条最新的私信.
    List<Message> selectConversations(int userId, int offset, int limit);

    // 查询当前用户的会话数量.
    int selectConversationCount(int userId);

    // 查询某个会话所包含的私信列表.
    List<Message> selectLetters(String conversationId, int offset, int limit);

    // 查询某个会话所包含的私信数量.
    int selectLetterCount(String conversationId);

    // 查询未读私信的数量
    int selectLetterUnreadCount(int userId, String conversationId);
}

3、编写Mapper对应xml文件

  • 首先查找status不等于2并且发送者id不等于1的有效信息 等于1的是系统消息
  • 传入的userid 可能是from也可能是to
  • 根据conversation_id排序 选择同组conversation_id中最大的一条信息表示是最新的消息
<select id="selectConversations" resultType="Message">
    select <include refid="selectFields"></include>
    from message
    where id in (
        select max(id) from message
        where status != 2
        and from_id != 1
        and (from_id = #{userId} or to_id = #{userId})
        group by conversation_id
    )
    order by id desc
    limit #{offset}, #{limit}
</select>

4、编写MessageService

@Service
public class MessageService {
    @Autowired(required = false)
    private MessageMapper messageMapper;

    @Autowired
    private SensitiveFilter sensitiveFilter;

    public List<Message> findConversations(int userId, int offset, int limit) {
        return messageMapper.selectConversations(userId, offset, limit);
    }

    public int findConversationCount(int userId) {
        return messageMapper.selectConversationCount(userId);
    }

    public List<Message> findLetters(String conversationId, int offset, int limit) {
        return messageMapper.selectLetters(conversationId, offset, limit);
    }

    public int findLetterCount(String conversationId) {
        return messageMapper.selectLetterCount(conversationId);
    }

    public int findLetterUnreadCount(int userId, String conversationId) {
        return messageMapper.selectLetterUnreadCount(userId, conversationId);
    }
}

5、编写MessageController

//会话列表
@RequestMapping(value = "",method = RequestMethod.GET)
public String getLetterList(Model model, Page page) {
    //获取当前用户信息
    User user = hostHolder.getUser();
    //设置分页信息
    page.setLimit(5);
    page.setPath("/letter/list");
    page.setRows(messageService.findConversationCount(user.getId()));

    //查询到的会话列表
    List<Message> conversationList=messageService.findConversations(
            user.getId(),page.getOffset(),page.getLimit());
    //使用list集合类型是map来存储遍历得到的每一个会话的信息
    List<Map<String,Object>> conversations=new ArrayList<>();
    if(conversationList!=null)
    {
        for (Message message:conversationList)
        {
            Map<String, Object> map = new HashMap<>();
            //放入消息对象
            map.put("conversation", message);
            //放入每一个会话中的消息数量
            map.put("letterCount", messageService.findLetterCount(message.getConversationId()));
            //放入未读消息数量
            map.put("unreadCount", messageService.findLetterUnreadCount(user.getId(), message.getConversationId()));
            //放入目标用户信息来显示相应的用户名头像等信息
            //如果当前用户对象和fromid一样,说明应该显示接受对象信息,反之一样
            int targetId = user.getId() == message.getFromId() ? message.getToId() : message.getFromId();
            map.put("target", userService.queryUserById(targetId));

            conversations.add(map);
        }

    }
    model.addAttribute("conversations", conversations);

    // 查询当前用户所有会话中未读消息数量
    int AllLetterUnreadCount = messageService.findLetterUnreadCount(user.getId(),null);
    model.addAttribute("AllLetterUnreadCount", AllLetterUnreadCount);

    return "/site/letter";

}


//私信:每一个会话中的详细消息
//查找私信列表   需要传入会话的id
@RequestMapping(path = "/letter/detail/{conversationId}", method = RequestMethod.GET)
public String getLetterDetail(@PathVariable("conversationId") String conversationId, Page page, Model model) {
    // 分页信息
    page.setLimit(5);
    page.setPath("/letter/detail/" + conversationId);
    page.setRows(messageService.findLetterCount(conversationId));

    // 私信列表
    List<Message> letterList = messageService.findLetters(
            conversationId, page.getOffset(), page.getLimit());
    List<Map<String, Object>> letters = new ArrayList<>();
    if (letterList != null) {
        for (Message message : letterList) {
            Map<String, Object> map = new HashMap<>();

            //放入每一条信息对象
            map.put("letter", message);
            //放入发送者用户信息
            map.put("fromUser", userService.queryUserById(message.getFromId()));
            letters.add(map);
        }
    }
    model.addAttribute("letters", letters);

    // 会话中需要显示来自谁的私信
    // 私信目标 用户信息
    model.addAttribute("target", getLetterTarget(conversationId));
    

    return "/site/letter-detail";
}

//把会话id拆分,如果当前用户id和id0一样说明,id1是相应的目标
private User getLetterTarget(String conversationId) {
    String[] ids = conversationId.split("_");
    int id0 = Integer.parseInt(ids[0]);
    int id1 = Integer.parseInt(ids[1]);

    if (hostHolder.getUser().getId() == id0) {
        return userService.queryUserById(id1);
    } else {
        return userService.queryUserById(id0);
    }
}

6、修改页面

<!-- 私信列表 -->
<ul class="list-unstyled">
   <li class="media pb-3 pt-3 mb-3 border-bottom position-relative"  th:each="map:${conversations}">
      <span class="badge badge-danger" th:text="${map.unreadCount}"  th:if="${map.unreadCount!=0}">3</span>
      <a href="profile.html">
         <img th:src="${map.target.headerUrl}" class="mr-4 rounded-circle user-header" alt="用户头像" >
      </a>
      <div class="media-body">
         <h6 class="mt-0 mb-3">
            <span class="text-success" th:utext="${map.target.username}">落基山脉下的闲人</span>
            <span class="float-right text-muted font-size-12"  th:text="${#dates.format(map.conversation.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-28 14:13:25</span>
         </h6>
         <div>
            <a th:href="@{|/letter/detail/${map.conversation.conversationId}|}"  th:utext="${map.conversation.content}">米粉车, 你来吧!</a>
            <ul class="d-inline font-size-12 float-right">
               <li class="d-inline ml-2"><a href="#" class="text-primary">共<i th:text="${map.letterCount}">5</i>条会话</a></li>
            </ul>
         </div>
      </div>
   </li>
</ul>

发送私信

增加新增消息和修改消息状态的方法

//发送消息
@RequestMapping(value = "/letter/send",method = RequestMethod.POST)
@ResponseBody
public String sendLetter(String toName, String content) {
    User target = userService.queryUserByName(toName);
    if (target == null) {
        return CommunityUtil.getJSONString(1, "目标用户不存在!");
    }

    Message message = new Message();
    message.setFromId(hostHolder.getUser().getId());
    message.setToId(target.getId());
    if (message.getFromId() < message.getToId()) {
        message.setConversationId(message.getFromId() + "_" + message.getToId());
    } else {
        message.setConversationId(message.getToId() + "_" + message.getFromId());
    }
    message.setContent(content);
    message.setCreateTime(new Date());
    messageService.addMessage(message);

    return CommunityUtil.getJSONString(0);
}

修改js页面

$(function(){
   $("#sendBtn").click(send_letter);
   $(".close").click(delete_msg);
});

function send_letter() {
   $("#sendModal").modal("hide");

   var toName = $("#recipient-name").val();
   var content = $("#message-text").val();
   $.post(
      CONTEXT_PATH + "/letter/send",
      {"toName":toName,"content":content},
      function(data) {
         data = $.parseJSON(data);
         if(data.code == 0) {
            $("#hintBody").text("发送成功!");
         } else {
            $("#hintBody").text(data.msg);
         }

         $("#hintModal").modal("show");
         setTimeout(function(){
            $("#hintModal").modal("hide");
            location.reload();
         }, 2000);
      }
   );
}

function delete_msg() {
   // TODO 删除数据
   $(this).parents(".media").remove();
}

把未读的私信设置为已读

//获取当前用户的私信中该用户属于接收方并且私信状态为0的帖子
private List<Integer> getLetterIds(List<Message> letterList) {
    List<Integer> ids = new ArrayList<>();

    if (letterList != null) {
        for (Message message : letterList) {
            if (hostHolder.getUser().getId() == message.getToId() && message.getStatus() == 0) {
                ids.add(message.getId());
            }
        }
    }

    return ids;
}
// 设置已读
List<Integer> ids = getLetterIds(letterList);
if (!ids.isEmpty()) {
    messageService.updateStatus(ids,1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值