前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅。最终成果github地址:https://github.com/66Web/react-antd-zhaoping,欢迎star。


一、聊天信息根据用户分组

  • 从redux中获取到chatmsg:其中包含了所有与当前用户有关的聊天信息
  • 与不同的用户聊天信息的chatid不同:根据chatid可将数据分到不同的数组

    //按照聊天用户分组,根据 chatid
    const msgGroup = {}
    this.props.chat.chatmsg.forEach(v=>{
    msgGroup[v.chatid] = msgGroup[v.chatid] || []
    msgGroup[v.chatid].push(v)
    })
  • Object.values():返回数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名

  • 将分好组的聊天信息,通过Object.values()获得新的二维数组

    const chatList = Object.values(msgGroup)  

二、聊天列表展示

  • 获取【最后一条聊天信息】
  1. 定义一个方法返回数组的最后一个值:每个用户的聊天信息自动按照create_time排序,最后即最新

    getLast = (arr) => {
    return arr[arr.length-1]
    }
  2. 遍历用户信息二维数组,获得每一个用户的聊天信息数组,调用方法获取最后一条信息

    {chatList.map(v=>{
    // console.log(v)
    const lastItem = this.getLast(v)   
  • 获取【对方用户】的用户名及头像
  1. 从redux中获取到当前用户的userid,以及存储所有用户name和avatar的userinfo
  2. 遍历获得每一个用户的聊天信息数组后,判断聊天信息的from是否为当前userid,如果是则将to赋给targetId,否则赋from
    const Item = List.Item
    const Brief = Item.Brief
    const userid = this.props.user._id
    const userinfo = this.props.chat.users //其它代码
    const targetId = v[0].from==userid?v[0].to:v[0].from
    return (
    <List key={lastItem._id}>
    <Item
    thumb={require(`../img/${userinfo[targetId].avatar}.png`)}
    arrow="horizontal"
    onClick={()=>{
    this.props.history.push(`/chat/${targetId}`)
    }}
    >
    {lastItem.content}
    <Brief>{userinfo[targetId].name}</Brief>
    </Item>
    </List>
    )
  • 获取【未读消息数】:过滤显示read为false,且to时当前用户userid的聊天信息数组的length数

    const unreadNum = v.filter(v=>!v.read&&v.to==userid).length
    
    extra={<Badge text={unreadNum}></Badge>}
    

      

三、最新消息排序

  • 给二维数组进行排序:比较不同用户聊天信息的最后一条的create_time,最大者最新,优先显示

    //用户信息数组的数组、排序
    const chatList = Object.values(msgGroup).sort((a, b)=>{
    const a_last = this.getLast(a).create_time
    const b_last = this.getLast(b).create_time
    return b_last - a_last
    })

      

四、消息未读数更新

  • 获取当前聊天的目标用户【to】,发送给后端更新数据库中的未读消息
  1. chat.js中:为了在当前打开的聊天页面中【伪同步】标识消息已读,在componentWillUnmount时更新消息

    componentWillUnmount(){
    const to = this.props.match.params.user
    this.props.readMsg(to)
    }  
  2. chat.redux.js中:定义readMsg(from),通过axios.post发送请求,将目标用户的userid【to】传给后端(更新条件:聊天信息中只有from为【to】,即目标用户发来的才算未读)

    //操作数据的方法
    export function readMsg(from){
    return (dispatch, getState)=>{
    axios.post('/user/readmsg',{from})
    .then(res=>{
    console.log(res)
    })
    }
    }
  • user.js中:处理标识已读的后端请求/readmsg,更新数据库中的聊天信息

  1. 更新条件一:聊天信息的to为当前用户的userid,从req.cookies中获取到

  2. 更新条件二:聊天信息的from为目标用户的userid,从req.body中获取到

  3. 满足条件时:将聊天信息的read字段,设置为true,标识已读

  4. mongodb的更新操作默认只更新第一条,设置{'multi':true}可同时更新多条

  5. 更新成功后:返回更新成功的数据条数doc.nModified

    //标识已读
    Router.post('/readmsg', function(req, res){
    const userid = req.cookies.userid
    const {from} = req.body
    console.log(userid, from)
    Chat.update({from, to:userid},
    {'$set':{read:true}},
    {'multi':true},function(err, doc){
    if(!err){
    return res.json({code:0, num:doc.nModified})
    }
    return res.json({code:1, msg:'修改失败'})
    })
    })

  • chat.redux.js中:将数据库中标识已读之后的聊天信息数据存入redux中

    //action type
    const MSG_READ = 'MSG_READ' //标识已读 //reducer中:只标识当前用户与目标用户的聊天信息中from为目标用户的信息
    case MSG_READ:
    const {from, num} = action.payload
    return {...state, chatmsg:state.chatmsg.map(v=>({...v, read:from==v.from?true:v.read})) , unread:state.unread-num} //action creator
    function msgRead({from, to, num}){
    return {type:MSG_READ, payload:{from, to, num}}
    } //readMsg方法中:成功获取后端返回的数据后,触发action将数据存入redux
    axios.post('/user/readmsg',{from})
    .then(res=>{
    const userid = getState().user._id
    if(res.status==200&&res.data.code==0){
    dispatch(msgRead({userid, from, num:res.data.num}))
    }
    })

注:项目来自慕课网

【招聘App】—— React/Nodejs/MongoDB全栈项目:消息列表的更多相关文章

  1. 【招聘App】—— React/Nodejs/MongoDB全栈项目:登录注册

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  2. 【招聘App】—— React/Nodejs/MongoDB全栈项目:socket.io&聊天实现

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  3. 【招聘App】—— React/Nodejs/MongoDB全栈项目:信息完善&用户列表

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  4. 【招聘App】—— React/Nodejs/MongoDB全栈项目:项目准备

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  5. 【招聘App】—— React/Nodejs/MongoDB全栈项目:个人中心&退出登录

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  6. 全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口

    通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 首页书籍信息 先来回顾一下首页书籍都有哪些信息: 从下面的图片可以看 ...

  7. 全栈项目|小书架|服务器端-NodeJS+Koa2 实现书籍详情接口

    通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 书籍详情分析 书籍详情页面如下: 从上图可以分析出详情页面大概有以下 ...

  8. 全栈项目|小书架|服务器开发-NodeJS 使用 JWT 实现登录认证

    通过这篇 全栈项目|小书架|服务器开发-JWT 详解 文章我们对JWT有了深入的了解,那么接下来介绍JWT如何在项目中使用. 安装 $ npm install jsonwebtoken 生成 Toke ...

  9. Vue、Node全栈项目~面向小白的博客系统~

    个人博客系统 前言 ❝ 代码质量问题轻点喷(去年才学的前端),有啥建议欢迎联系我,联系方式见最下方,感谢! 页面有啥bug也可以反馈给我,感谢! 这是一套包含前后端代码的个人博客系统,欢迎各位提出建议 ...

随机推荐

  1. time_t转化成日期格式小工具

    time_t转化成日期格式小工具下载  http://files.cnblogs.com/files/lansan0701/TimeTool.zip

  2. 虚拟机VMware 安装CentOS6.5

    对linux完全小白的情况下,也能依据下面的文章,一步一步安装使用成功! CentOS 6.5 下载http://www.linuxdown.net/CentOS/2014/0928/3371.htm ...

  3. Python selenium.webdriver.chrome.options.Options() Examples

    The following are 27 code examples for showing how to use selenium.webdriver.chrome.options.Options( ...

  4. python读取doc

    import os, time, fnmatch from docx import Document class search: def __init__(self, path, search_str ...

  5. 使用Python获取计算机名,ip地址,mac地址等等

    获取计算机名 # 获取计算机名,常用的方法有三种 import os import socket # method one name = socket.gethostname() print(name ...

  6. selenium 下拉框处理

    web应用中有很多时候我们会遇见<select></select>标签的下列列表框,一般是无法直接去操作下列列表中的选择的.selenium webdriver 提供了专门操作 ...

  7. 使用bottle进行web开发(5):Generating Content

    在纯粹的 WSGI中,你的应用能返回的数据类型是十分有限的,你必须返回可迭代的字符串,你能返回字符串是因为字符串是可以迭代的,但是这导致服务器将你的内容按一字符一字符的传送,这个时候,Unicode ...

  8. [BZOJ1491][NOI2007]社交网络 floyd

    1491: [NOI2007]社交网络 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2196  Solved: 1170[Submit][Status ...

  9. [BZOJ1494][NOI2007]生成树计数 状压dp 并查集

    1494: [NOI2007]生成树计数 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 793  Solved: 451[Submit][Status][ ...

  10. 清理tomcat缓存

    解决方案:删除work目录的内容,注意不能删除work目录,不然会出现404错误 rm -rf /usr/local/tomcat/work/*