项目9-网页聊天室5(会话管理之获取会话信息)

1.会话管理

此处谈到的会话(虽然也是叫做 session),这个会话是特指在聊天过程中,产生的"业务上的会话”而不是 servlet/spring 里面内置的会话,会话是计算机中一个非常广义的概念

【每次你发起一个聊天,都相当于创建了一个会话

这个会话里就包含了一些"人"和一些"消息
比如我和 同学A 聊天, 就产生一 会话

我再和同学 B 聊天, 也会产生一个会话,】

【此处的会话要想管理起来,势必要放到数据库中进行保存.(持久化存储)】

2.会话的数据库设计 

【实体】

  • 会话
  • 用户
  • 消息

会话 和 用户【多对多】
一个会话里会包含多个用户,
一个用户也能出现在多个会话中。 

会话 和 消息 【一对多】
一个会话里会包含多条消息条消息只能从属于一个会话,

2.1 会话表

先创建一个会话表

-- 会话表
drop table if exists message_session;
create table message_session (
sessionId int primary key auto_increment,
-- 上次访问时间
lastTime datetime
);
insert into message_session values(1, now());
insert into message_session values(2, now());

2.2 会话和用户的关联表

-- 会话-⽤⼾ 关联表
drop table if exists message_session_user;
create table message_session_user (
sessionId int,
userId int
);
insert into message_session_user values(1, 1), (1, 2);
insert into message_session_user values(2, 1), (2, 3);

后续写到消息功能的时候,再来考虑消息表和会话之间的关联
一个会话里,可以有两个用户,也可以有多个用户!

有两个用户的会话,称为"单聊”有多个用户的会话,称为"群聊”

3.会话管理的核心内容 

1.获取会话信息
2.新增会话

3.1 获取会话信息

1.约定前后端接口

2.前端操作 


针对会话的标题这里,只是简化处理了,此处就只是单纯的使用了第0个会话中的用户的名字作为了会话标题.
暂时没有考虑群聊的情况.
如果想考虑群聊,需要给会话表新增个属性,会话的标题,
会话的最后一条消息,可能比较长,但是会话预览的部分,不适合显示太长内容就可以根据长度,进行一个截断操作.
判定下消息长度是否超过 10.如果超过, 就只取前 10 个字符,作为预览结果.
当用户点击会话列表中的元素的时候,
1.把当前会话设置成"高亮"/active 状态
2.获取到该会话中的历史消息,并且显示到右侧区域

如何实现设置高亮的效果,
1)先获取到所有的会话的li标签了
2)循环遍历这些li标签.
3)依次对比,看现在这个li标签是否是正在点击的标签,如果是,就给 className 属性设置成 selected; 如果不是,就清空 className

4.后端代码

结果表示当前用户(用户的登录状态),有哪些会话每个会话都包含哪些好友信息 

4.1 MODEL

要求与约定的响应报文一致

@Data
public class MessageSession {
    private Integer sessionId;
    private List<Friend> friends;
    private String lastMessage;
}

4.2 MAPPER

package com.example.demo.mapper;

import com.example.demo.model.Friend;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;


@Mapper
public interface MessageSessionMapper {
    //1.根据 userId 获取到该用户都在哪些会话中存在。返回结果是一组 sessionId
    List<Integer> getSessionIdsByUserId(Integer usenId);
    //2.根据 sessionId 再来查询这个会话都包含了哪些用户.(刨除最初的自己)
    List<Friend> getFriendBySessionId(Integer sessionId,Integer selfUserId);
}
<?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.example.demo.mapper.MessageSessionMapper">
<!--    给定一个用户看当前包含哪些sessionId-->
<!--    降序排序-->
    <select id="getSessionIdsByUserId" resultType="java.lang.Integer">
        select sessionId from message_session
        where sessionId in
        (select sessionId from message_session_user where userId=#{userId})
        order by lastTime desc
    </select>

<!--    给会话id看包含哪些好友-->
    <select id="getFriendBySessionId" resultType="com.example.demo.model.Friend">
<!--        与friend类相互匹配-->
        select userId as friendId,username as friendName from user
        where userId in
        (select userId from message_session_user where sessionId = #{sessionId} and userId!=#{selfUserId})
    </select>
</mapper>

4.3 CONTROLLER

package com.example.demo.controller;

import com.example.demo.config.Result;
import com.example.demo.constant.Constant;
import com.example.demo.mapper.MessageSessionMapper;
import com.example.demo.model.MessageSession;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping("/session")
public class MessageSessionController {
    @Autowired
    private MessageSessionMapper messageSessionMapper;
    @RequestMapping("/getSessionMessage")
    public Result getSessionMessage(HttpSession httpSession){
        //0.先构造返回的数据
        List<MessageSession> messageSessionList=new ArrayList<>();
        //1.获取到当前用户的userId(从spring的session 中获取)
        User user=(User) httpSession.getAttribute(Constant.USERINFO_SESSION_KEY);
        Integer userId= user.getUserId();
        //拦截器已经做了相关操作
        // 2.根据userId 查询数据库,查出来有哪些会话id
        List<Integer> sessionId=messageSessionMapper.getSessionIdsByUserId(userId);
        // 3.遍历会话id,查询出每个会话里涉及到的好友都有谁
        for(Integer userIds:sessionId){
            /*public class MessageSession {
                private Integer sessionId;
                private List<Friend> friends;
                private String lastMessage;
            }*/

            MessageSession messageSession=new MessageSession();
            messageSession.setSessionId(userIds);
            messageSession.setFriends(messageSessionMapper.getFriendBySessionId(userIds,userId));
            // 4.遍历会话id,查询出每个会话的最后一条消息
            messageSession.setLastMessage("最后一条消息");
            // 最终目标就是构造出一个MessageSession 对象数组
            messageSessionList.add(messageSession);
        }
        return Result.success(messageSessionList);
    }

}

4.4 POSTMAN测试

成功!!!

5.前端代码

<!-- 会话列表 -->
                <ul class="list" id="session-list">
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li class="selected">
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                    <li>
                        <h3>lisi</h3>
                        <p>晚上吃啥</p>
                    </li>
                </ul>
function getSessionList() {
    $.ajax({
        type: 'get',
        url: '/session/getSessionMessage',
        success: function(result) {
            body=result.data;
            // 1. 清空之前的会话列表
            let sessionListUL = document.querySelector('#session-list');
            sessionListUL.innerHTML = '';
            // 2. 遍历响应的数组, 针对结果来构造页面
            for (let session of body) {
                // 针对 lastMessage 的长度进行截断处理
                if (session.lastMessage.length > 10) {
                    session.lastMessage = session.lastMessage.substring(0, 10) + '...';
                }
                // 构造一个li标签
                let li = document.createElement('li');
                // 会话id保存起来,以备后用
                // 把会话 id 保存到 li 标签的自定义属性中. 
                li.setAttribute('message-session-id', session.sessionId);
                li.innerHTML = '<h3>' + session.friends[0].friendName + '</h3>' 
                    + '<p>' + session.lastMessage + '</p>';
                sessionListUL.appendChild(li);

                // 给 li 标签新增点击事件
                li.onclick = function() {
                    // 这个写法, 就能保证, 点击哪个 li 标签
                    // 此处对应的 clickSession 函数的参数就能拿到哪个 li 标签. 
                    clickSession(li);
                }
            }
        }
    });
}

getSessionList();

测试!!!

成功!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值