【招聘App】—— React/Nodejs/MongoDB全栈项目:消息列表
前言:最近在学习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)
二、聊天列表展示
- 获取【最后一条聊天信息】
- 定义一个方法返回数组的最后一个值:每个用户的聊天信息自动按照create_time排序,最后即最新
getLast = (arr) => {
return arr[arr.length-1]
} 遍历用户信息二维数组,获得每一个用户的聊天信息数组,调用方法获取最后一条信息
{chatList.map(v=>{
// console.log(v)
const lastItem = this.getLast(v)
- 获取【对方用户】的用户名及头像
- 从redux中获取到当前用户的userid,以及存储所有用户name和avatar的userinfo
- 遍历获得每一个用户的聊天信息数组后,判断聊天信息的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】,发送给后端更新数据库中的未读消息
- chat.js中:为了在当前打开的聊天页面中【伪同步】标识消息已读,在componentWillUnmount时更新消息
componentWillUnmount(){
const to = this.props.match.params.user
this.props.readMsg(to)
} 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,更新数据库中的聊天信息
更新条件一:聊天信息的to为当前用户的userid,从req.cookies中获取到
更新条件二:聊天信息的from为目标用户的userid,从req.body中获取到
满足条件时:将聊天信息的read字段,设置为true,标识已读
mongodb的更新操作默认只更新第一条,设置{'multi':true}可同时更新多条
更新成功后:返回更新成功的数据条数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全栈项目:消息列表的更多相关文章
- 【招聘App】—— React/Nodejs/MongoDB全栈项目:登录注册
前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...
- 【招聘App】—— React/Nodejs/MongoDB全栈项目:socket.io&聊天实现
前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...
- 【招聘App】—— React/Nodejs/MongoDB全栈项目:信息完善&用户列表
前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...
- 【招聘App】—— React/Nodejs/MongoDB全栈项目:项目准备
前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...
- 【招聘App】—— React/Nodejs/MongoDB全栈项目:个人中心&退出登录
前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...
- 全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口
通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 首页书籍信息 先来回顾一下首页书籍都有哪些信息: 从下面的图片可以看 ...
- 全栈项目|小书架|服务器端-NodeJS+Koa2 实现书籍详情接口
通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 书籍详情分析 书籍详情页面如下: 从上图可以分析出详情页面大概有以下 ...
- 全栈项目|小书架|服务器开发-NodeJS 使用 JWT 实现登录认证
通过这篇 全栈项目|小书架|服务器开发-JWT 详解 文章我们对JWT有了深入的了解,那么接下来介绍JWT如何在项目中使用. 安装 $ npm install jsonwebtoken 生成 Toke ...
- Vue、Node全栈项目~面向小白的博客系统~
个人博客系统 前言 ❝ 代码质量问题轻点喷(去年才学的前端),有啥建议欢迎联系我,联系方式见最下方,感谢! 页面有啥bug也可以反馈给我,感谢! 这是一套包含前后端代码的个人博客系统,欢迎各位提出建议 ...
随机推荐
- sql文格式替换
SELECT COUNT(1)FROM TAB1 TWHERE T.IS_DEL <> 0 将以上SQL格式替换为代码中的格式 sql.AppendLine(" SELECT & ...
- HashMap/Hashtable/ConcurrentHashMap区别
HashMap:每个隔间都没锁门,有人想上厕所,管理员指给他一个隔间,里面没人的话正常用,里面有人的话把这个人赶出来然后用. 优点,每个人进来不耽误都能用:缺点,每一个上厕所的人都有被中途赶出来的危险 ...
- springmvc Converter
以下,来自于Springmvc指南第二版,第93页. Spring的Converter是可以将一种类型转为另一种类型. 例如用户输入的date类型可能有多种格式. 比如:在controller中接收一 ...
- Ubunt 服务教程集锦
1.Ubuntu管理服务安装(强烈推荐最好用Xshell和Xftp): 序号 服务名 介绍 教程地址 windows客户端 1 VNC 可以图形界面管理Ubuntu ubuntu安装vncserver ...
- 【C++】复制构造函数
参考资料:黄邦勇帅(里面对于临时变量的说法我不是很理解,感觉里面的解释有问题) 用到复制构造函数的情况: 1.函数值传递 2.返回对象 3.用一个对象初始化另一个对象 重点注意下面两种情况: ① 只调 ...
- KVM(二)CPU 和内存虚拟化
1. 为什么需要 CPU 虚拟化 X86 操作系统是设计在直接运行在裸硬件设备上的,因此它们自动认为它们完全占有计算机硬件.x86 架构提供四个特权级别给操作系统和应用程序来访问硬件. Ring 是指 ...
- MySQL的事务理解
在学习事务这一概念前,我们需要需要构思一个场景 场景构思 假设该场景发生于一个银行转账背景下,月中,又到了发工资的日子.学校打算给A老师发放一个月的工资.(此处,我们假设转账都是由人工操作的),整个过 ...
- AC日记——codeforces Ancient Berland Circus 1c
1C - Ancient Berland Circus 思路: 求出三角形外接圆: 然后找出三角形三条边在小数意义下的最大公约数; 然后n=pi*2/fgcd; 求出面积即可: 代码: #includ ...
- Codeforces 651 C. Watchmen-曼哈顿距离和欧几里得距离
C. Watchmen time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...
- HDU 2673 (排序)
Acmer in HDU-ACM team are ambitious, especially shǎ崽, he can spend time in Internet bar doing proble ...