入门级node+uni-app开发即时通讯聊天室(3)用户的搜索以及好友添加(二)

前言:这篇介绍到好友的添加与好友状态的实时渲染,写代码之前,我们先经过缜密的思考再动手,尽管这样子写出来的代码也并不会是最好的一次。但至少只要你大体上摸准了它的脉搏之后的细节修改也只是在大厦下填填补补而不至于推到大厦再重来。那我们仔细观察上面的数据。再观察下我们的数据表。
在这里插入图片描述
rel_status 字段我们用于对好友之间的关系进行判断,参照QQ微信等的设计,当我们第一次没点进去之前有多少条未处理的请求我们就显示一个数字几,那么这里其实就隐含了两个状态,一个是未处理状态,一个是已处理状态。同时假设我们已经点了进去我们不一定会点击添加好友。但他仍然是已处理状态(即我们返回之后已经不会再有tips提示);假如是被请求方被申请了好友,他们添加了好友,那他们就是已是好友状态。还有一个状态是你是申请方添加别人为好友。
所以我们得规范下rel_status的定义,方便对他进行数据的匹配与展示。当然你的定义不一定要全随我,我这里只是提供一种思路。
rel_status: 取值范围 0 - 4 (0表示双方已经为好友,1表示当前用户与朋友是申请方与接受方的关系,2表示当前用户与朋友是接收方与申请方的关系,3表示未处理的当前用户与朋友是申请方与接收方的关系,4表示未处理的当前用户与朋友是接收方与申请方的关系)

代入一个流程,我们看看这样子定义是否会有问题:我们的首页渲染的tips应该是 rel_status 为 3 或者4 同时 user_id 是发送方或者接收方的数据条数。当我们点击进去的时候,将这些数据的rel_status 分别更新为1 或 2。等等,如果这样子做你考虑到如何将他分别更新 1 或 2了吗?你将使用两条更改语句!(将rel_status为3 更新 为rel_status 为 1,将rel_status为4更新为2),到这里的时候我们应该能意识到我们的表的结构并不理想,其中的1234的关键变量在于处理和未处理的关系,我们可以通过生成这一个状态的变量,就可以通过一条语句去判断他的消息的未读数。

经过思考,我们决定rel_status定义(*0表示当前用户与朋友是申请方与接受方的关系,1表示当前用户与朋友是接收方与申请方的关系,2表示双方已经为好友。)同时在数据库里添加新的字段,handle_status(0表示未处理,1表示已处理)用于表示当前的消息是否已经被处理。

我们再代入进流程,首页渲染时,我们只需要count当前用户 在自己是被请求的状态这个handle_status为0 的数目 ,当进入好友请求组件的时候,我们将当前的用户作为接收方的所有handle_status为0改变为1;

好,至此我们准备的思路已经大体上可以编写代码了,上面的主要就是对数据库的表的结构进行优化,这也是我第一次写的不够好的地方,状态太过耦合,只用一个状态去表示这个稍微复杂点的好友的各种状态显得逻辑太过混乱,总之:通过一个状态去表达两种以上的复杂状态明显是会造成逻辑混乱的,同时也会造成冗余,为了使我们的代码更加优雅,我们使用handle_status表示这个请求是否被处理,而这个其实就是是否被看见(进入处理的页面(或者是进行明显会造成‘处理’这种结果的操作),我们就可以更新数据库了)

在这里插入图片描述
观察我们的页面,我们现在需要做的是在他们渲染的时候同时判断他们之间的关系,然后实时把他渲染成相应的按钮。乍一看这不要查询两次吗?他们的关系存储在friend表,而用户的信息在user表。仅凭我前面的教程理解了之后自己解决这个实时渲染其实也不太有问题(你能做到的)。这并不算太难。但是我希望能在这里就把连接查询告诉给你。我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据。

mysql连接查询
mysql连接查询有三种,一种是inner join(内连接),一种是左连接,一种是右连接。
在这里插入图片描述
在这里插入图片描述
右连接我想我就不必放了。但其实这里我们需要理解的是,所谓的内连接就是两个表的交集(怎么理解?比如我user表的user_id 与friend表的user_id 相连,他们的数据条数肯定是相同的,假如我们查找所有,那两个表的所有字段由friend表跟user表都会在一张表上返回),而假如是左连接,由于我们有的用户不一定有请求添加好友等等的操作,此时左连接仍然返回左边这张user表的所有字段而通过user_id查找不到的则返回空。 现在不太理解也没关系,随着代码跟文字慢慢理解。
mysql 连接 语句
select 字段 from table1 as t1 join table2 as t2 on t1.id = t2.id
当然你仍然可以在这个基础上添加条件查询。

首先我们应该处理上个章节我们写的用户方法,通过这个连接查询再去获取一下rel_status。然后通过这个rel_status 去判断 实时渲染。这个语句可能会让你有点吃力,我稍微解释一下这么写的原因:使用左连接确保即使右边无匹配的值,我们也可以将user表的数据返回。假如匹配的数据存在我们应该确保返回的数据当前的用户ID是作为别人的朋友ID而存在的,意思是:我们查询的是查询中的用户ID与我们当前(作为他的朋友)的ID的关系 实在觉得一时理解困难就先跳过吧,随着教程的深入,连接查询的使用增多你会越来越理解。哦对了,注意下join里的写法,是使用了ES6的模板字符串。分号不要写错了。
在这里插入图片描述

在前端先处理一下根据好友状态渲染相应的按钮块,这里不要搞混,展示在页面的用户如果被我们申请,我们通过接口返回他的状态应该是0(查询语句中排除了自己作为friends表的user_id 的数据),详情参考上面的定义。
在这里插入图片描述

添加好友的处理应该有四种逻辑,一种是双方都不是好友,一种是对方已经请求了你,一种是你请求对方,一种是双方都是好友。别着急,我们一个一个来。申请中我们就不必对他添加事件了,我们先在加好友这添加事件。名字随你起。

1.双方都不是好友 你请求对方

那我们这里的操作就应该是将他们分别添加进表,同时将请求方的handle_status作为1 插入表明是他们之间的状态请求方已经处理,而被请求方的handle_status应该为0。我们还得明白一个概念:事务控制 ,要么这两条插入语句全部执行,要么就都不执行。就拿经典的银行转账例子解释一下为什么加入控制把。
银行转账的实质就是把你的钱扣掉,给别人的钱加钱,假如程序在把你的钱扣掉了的时候出错了,他下面的给别人加钱的操作执行不了,这么一想你是不是很生气?一来二算你亏了2倍的钱。所以对于复数级的数据库操作我们加入事务控制对程序是保险的,程序假如在这一系列的数据库操作过程中产生了错误,它会回滚这个操作,回到你执行这整个流程之前的状态。

先到后台写方法,到dao层加入文件trans.js ,同时router目录下加入文件trans.js
dao层如下
在这里插入图片描述
router 如下
在这里插入图片描述
别忘记在主启动文件中添加依赖

前端方法如下:
在这里插入图片描述
其中const {} 使用的是ES6的解构赋值,如果不懂建议去搜索。对之后的代码编写很有帮助,其余就不多做解释了,自己看注释把。

2.对方已经请求了你

那么此时对方查找到的你的rel_status 应该是0,你作为接受请求方(此时通过接口查找对方的rel_status为1)。当你点击添加好友时,就证明你同意对方的申请了。这里你也可以根据rel_status对加好友添加条件渲染的控制。我是直接给他合并了。那么回到代码,我们应该做的只是将两个用户的rel_status 更新为2就行,同时为了人性化一点我们也给接受申请方发送一条提示把。

mysql 更新语句
UPDATE table_name SET field1=new-value1, field2=new-value2
跟insert 一样的,我们也可以不用写每个字段,使用ali-mysql-client时直接传入一个json对象就行。这次我们不用更新两次,因为我们知道user_id跟friend_id是相互的。我们只需要把user_id与friend_id传进去后端就好。但记得,当他们添加完好友之后,接受申请方得给申请方发条信息。

在这里插入图片描述

db.sql('update `friends` set rel_status = 2,handle_status = 1 where (user_id = ? and friend_id = ?) or (friend_id = ? and user_id = ?)').params([userId,friendId,userId,friendId]).execute();

更新处理状态,好友状态,使用or运算符表示 这两种情况都修改,传入参数,执行sql语句。

router\trans文件如下:

在这里插入图片描述
前端代码如下:

在这里插入图片描述
至此搜索页面的好友的添加就已经完全的实现了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值