微信小程序客户端登陆
一 总体流程
前段携带code发送请求给后端,后端利用微信小程序相关api解析这个code,获取能唯一认证登陆身份的openid。接着先到数据库查询是否有这个id,如果没有就保存用户信息实现注册,并返回token到前端,如果有就直接返回token到前端
二 前置准备
因为我们要用到微信相关api,所以我们需要用到微信的客户端。微信客户端需要我们微信小程序的id以及密钥,我们需要将他放到配置文件里面。
首先我们要设置好配置类和配置文件。
我们要在nacos中的设置关于微信小程序中的配置
然后设置配置类读取信息
再将微信小程序客户端注册到spring容器内
乘客端登录:获取登录用户信息接口
总体流程
web端从请求头获取token,先判断是否是登陆状态:如果redis有对应的数据就是登陆。远程调用,传入id,获取用户信息并返回。service根据远程调用传来的id查询数据库中乘客的信息并返回。
乘客端登录:登录校验
一 分析过程
1 如何判断是否登录状态?
-- 判断请求头里面是否包含token字符串
-- 根据token查询redis
2 如何实现?
-- 原始方式:在需要判断登录的controller进行上面判断(token和redis)
-- 如果使用原始方式,功能肯定可以实现的,但是造成有大量重复代码
-- 对这样方式进行优化
3 如何优化?
-- 使用 自定义注解+ aop 进行优化
二 具体实现
首先先创建一个注解,用于加在要登陆校验的方法上,实现登陆校验。然后创建一个切面类,去实现登陆校验:判断请求头是否有token,根据token查询redis是否存在。如果不存在就是没有登陆。如果存在就查询数据库,将用户的id存到threadlocal里面。
乘客端登录:获取微信手机号
因为我们是在微信小程序实现登陆的,我们是直接登陆,不需要去输入个人的信息,那么我们的个人信息来源于我们的微信。我们需要通过微信小程序解析一下微信传过来的相关参数来获取我们的用户信息。
在这里我们用微信小程序的api来解析微信传过来的code来获取微信的信息,获取电话号码,然后存到我们的数据库中
司机端登录与认证
总体流程
司机端登陆
和乘客端的很像,这里就直接赋值粘贴
获取登录司机信息
也是和乘客端很像,就cv了
腾讯云对象存储上传接口
1 主要概述
* 我们项目基于腾讯云对象存储服务COS,存储司机认证相关资料(身份证、驾驶证)
* 要使用腾讯云对象存储服务,首先进行开通,注册腾讯云之后,开通就可以了
* 使用对象存储服务,可以在控制台里面进行操作,也可以使用Java代码进行操作,这些操作,腾讯云官方提供详细文档说明,按照文档就方便进行操作
* 官方文档地址
https://cloud.tencent.com/document/product/436/10199
2 开发流程
当我们司机端点击开始接单的时候,我们会要求司机录取自己的个人信息。比如说身份证,驾驶证等。
我们乘客接收到这些图片的path之后,会将图片存储到腾讯云中,好方便我们后面利用腾讯云来实现验证照片合法性的功能。
我们web端接收到前端传来的文件本身和他的地址,将文件本身和他的地址作为参数远程调用service,然后service将他们存储到腾讯云cos存储桶里面
每上传一张照片就调用一次接口,接口一次只能上传一张照片
腾讯云身份证认证接口
1 需求
司机注册成功之后,应该引导他去做实名认证,这就需要用到腾讯云身份证识别和云存储功能了
2 流程
web端获取上传的文件之后远程调用service来验证上传的文件,这里也就是身份证。service端获取到身份证后调用腾讯的api来实现认证并返回认证的信息
腾讯云驾驶证识别接口
流程和上面一样的
获取司机的认证信息
1 需求分析
司机进行操作首先进行登录,登录成功之后,进行认证,跳转到认证页面完成认证
* **查看认证信息**,进入到认证页面时候,回显证件信息
2 具体实现
我们登陆校验会获取司机的id存到threadLocal中,我们可以获取司机id远程调用service获取司机认证信息。service根据id查询数据库,并且填充没有信息的字段
3 BUG:文件上传使用openfeign要加参数
bug:
feign 传 MultipartFile Error converting request body 序列化 错误
feign 传 MultipartFile Error converting request body 序列化 错误-CSDN博客
在请求注解中加入参数
修改司机认证信息
1 功能分析
**认证状态:**
0:未认证 【刚注册完为未认证状态】
1:审核中 【提交了认证信息后变为审核中】
2:认证通过 【后台审核通过】
-1:认证未通过【后台审核不通过】
* **第一次登录时候,完成用户注册,注册时候,当前认证状态值是0(未认证)**
* **上传认证信息(填写认证资料)之后,进行提交,提交之后,当前认证状态值1(审核中)**
* **司机端提交审核资料之后,后台管理员对提交资料进行审核,审核通过,认证状态值2,审核没有通过,认证状态值-1**
**司机开启接单的条件:**
1、登录
2、认证通过
3、建立了腾讯云人员库人员
4、当日验证了人脸识别
2 流程
就是前端将司机要修改的信息传到后端,后端做修改操作。
开通人脸识别
新注册的司机进行人脸信息采集,类似于在公司里面进行人脸录入,每天进行人脸打卡
实现思路
前端传入司机的id和司机人脸的图片到后端,后端创建一个人脸模型进人员库中管理.人员库要提前创建,并且将人员库的id在后端配置好,使用。
预估订单数据
预估驾驶线路
开发腾讯地图服务接口
* 封装地图服务接口:代驾路线距离,线路规划,时间
* 修改Nacos配置文件,修改腾讯位置服务key
实现思路
前端传开始代驾的经纬度和结束代驾的经纬度到后端,后端调用腾讯云的api计算最佳路线。
预估订单金额
乘客选择了出发和结束的地点,计算预估金额是多少,根据约定规则进行金额计算。
预估订单数据接口
前面计算了预估驾驶线路与预估订单金额,当前就可以编写web端乘客端预估订单数据接口了。
我们前端订单数据传入后端,后端进入web层。web的service调用预估驾驶线路与预估订单金额,获取预估订单的信息,实现预估订单的接口
乘客下单(一)
乘客下单时,我们拿到的订单费用都是预估费用,不是实际费用,因此下单时我们不插入账单信息,实际的账单信息是在代驾结束后产生的,实际的代驾里程会根据代驾过程中实时上传的金纬度计算获取,代驾过程中可能还要产生一些未知的费用,如:等时费、停车费、路桥费等。
主要实现:保存订单信息到数据库;查询订单状态,供前端轮训查到司机接单后跳转页面
保存订单信息
我们在司机结束订单之后会根据实际情况计算相应的金额,路线等信息,我们要先将这部分信息保存到数据库中
乘客端查询订单状态
乘客下完单后,订单状态为1,乘客端小程序会轮询订单状态,当订单状态为2时,说明已经有司机接单了,那么页面进行跳转,进行下一步操作
乘客下单(二)
前面我们创建了订单,但是略过了寻找附近适合接单的司机。接下来完善这部分功能
搜索附近司机
假设司机端的小程序实时把自己的GPS定位上传,然后定位信息缓存到Redis里面。咱们怎么能利用Redis计算出,上车点方圆几公里的司机都有谁呢?这就需要使用Redis的Geo功能。
既然Redis的GEO命令可以帮我们提取出某个坐标点指定距离以内的景点,如果Redis里面缓存的是司机的定位信息,那么我们用代驾单的起点坐标来查询附近几公里以内的司机,是不是也可以?而且Redis的Geo计算是在内存中完成的,比MySQL的Geo计算快了上千倍。
实现流程
司机开启接单服务后,司机端小程序就会实时上传经纬度信息到后端。后端将这些位置信息储存到redis的GEO。
关闭接单服务我们就要清空GEO数据,我们在web端定义一个删除的方法。供后续的api使用
获取司机个性化设置消息
司机针对接单,有一些个性化设置,只有满足了这些条件,才可以接单,如:“实时更新司机位置信息”,只有开启了接单服务,接口才可以更新数据
**说明:**
service_status:服务状态,司机开启了接单,才能进行接单后的一些列操作;
order_distance:订单程设置,如:order_distance=0(不限制);order_distance=50(只接代驾里程在50公里范围内的订单);
accept_distance:接单里程设置,司机起始点距离司机的位置,如:accept_distance=3(只接收3公里范围内的订单);
is_auto_accept:是否自动接单,开启后,系统自动抢单,不需要手动点接单按钮;
实现
定义一个接口,前端调用该接口。接口查询司机的个性化设置后返回给web。我们司机端web对上面搜索附近司机进行修改,获取了司机的个性化信息,判断司机是否接单。如果司机开始接单之后,才上传司机的位置信息
搜索附近适合接单的司机
需求
司机端的小程序开启接单服务后,开始实时上传司机的定位信息到redis的GEO缓存,前面乘客已经下单,现在乘客端就要查找附近适合接单的司机,如果有对应的司机,那就给司机发送新订单消息。
流程
乘客端通过对个性化信息的获取,来获取附近适合接单的司机
任务调度
前面乘客端已经下单了,附近的司机我们也能搜索了,接下来我们就要看怎么把这两件事给关联上?
乘客下单,搜索附近的司机,但是可能当时附近有司机,也有可能当时附近没有司机,乘客下单的一个等待时间为15分钟(15分钟后系统自动取消订单),那么下单与搜索司机怎么关联上呢?答案肯定是任务调度。
乘客下单了,然后启动一个任务调度,每隔1分钟执行一次搜索附近司机的任务调度,只要在15分钟内没有司机接单,那么就必须一直查找附近适合的司机,直到15分钟内有司机接单为止。
任务调度搜索到满足条件的司机后,会在服务器端给司机建立一个临时队列(1分钟过期),把新订单数据放入队列,司机小程序端开启接单服务后,每隔几秒轮询获取临时队列里面的新订单数据,在小程序前端进行语音播报,司机即可进行抢单操作。
流程
我们乘客下单,要搜索附近合适的司机。我们在dispatch服务中去做这些逻辑。
在乘客下单时,会请求我们的dispatch来开启调度服务。dispatch会判断该订单是否有调度服务。如果没有就用代码创建我们的任务。任务主要内容是查询附近合适的司机,将订单信息放在为每一个司机创建的一分钟临时的订单队列里面。
司机接单
1 需求
* 乘客下单之后,新订单信息已经在司机临时队列
* 下面司机可以开始进行接单了
首先,司机登录,认证(身份证、驾驶证、创建人脸模型)
第二,司机进行人脸识别(每天司机接单之前都需要进行人脸识别)
第三,司机开始接单了,更新司机接单状态
第四,当司机开始接单之后,删除司机之前存储到Redis里面位置信息
第五,当司机开始接单之后,清空司机临时队列新订单信息
判断司机在当日是否人脸识别
前端发请求给后端,后端在threadlocal中得到司机的id,查询数据库,返回司机在当日是否人脸识别的结果给前端
人脸识别接口
* 之前创建人脸识别模型,基于之前创建人脸模型完成当前识别功能。这个人脸模型是司机当时人脸输入的时候创建的。
前面我们已经做了人员库人员信息录入,现在我们要做人脸验证,为了防止司机作弊,我们还要对司机上传的人脸信息做人脸静态活体检测。
人脸静态活体检测可用于对用户上传的静态图片进行防翻拍活体检测,以判断是否是翻拍图片。
* 找到腾讯云文档1:照片比对
https://console.cloud.tencent.com/api/explorer?Product=iai&Version=2020-03-03&Action=VerifyFace
* 找到腾讯云文档2:人脸静态活体检测
https://console.cloud.tencent.com/api/explorer?Product=iai&Version=2020-03-03&Action=DetectLiveFace
实现
在判断司机当日人脸识别情况之后,我们对司机进行人脸识别。前端将司机的id和图片传到后端。后端调用腾讯云两个api来实现司机的人脸识别,并返回人脸识别成功与否给前端
开启接单服务web接口
调用前面所写的端口,完成开始接单服务的功能
停止接单服务web接口
前端发送停止接单的请求,后端修改司机的信息,比如接单状态等。
司机抢单
当前司机已经开启接单服务了,实时轮流司机服务器端临时队列,只要有合适的新订单产生,那么就会轮回获取新订单数据,进行语音播放,如果司机对这个订单感兴趣就可以抢单,大家注意,同一个新订单会放入满足条件的所有司机的临时队列,谁先抢到就是谁的。
我们前端传入司机的id和订单的id,后端基于redisson在司机抢到单之后修改订单的状态和司机的状态,将抢单的成功与否传给前端
订单执行(一)
乘客端查找当前订单
无论是司机端,还是乘客端,遇到页面切换,重新登录小程序等,只要回到首页面,查看当前是否有正在执行订单,如果有跳转到当前订单执行页面
* 之前这个接口已经开发,为了测试,临时跳过去,默认没有当前订单的
实现
前端发送请求后端,后端从threadlocal得到乘客的id,根据乘客id查询订单数据库,看是否有正在执行的订单。
司机端查找当前订单
和乘客端一致
获取订单信息
进入首页,在有执行中订单的情况下,我们需要获取订单信息,才能加载订单的信息。
实现
前端传入订单的id到后端,后端根据订单的id查询订单的信息。司机和乘客端都是一样
司机端司乘同显
司机端司乘同显要简单一些,司机的地点就是司乘同显的起始点,代驾起点就是司乘同显的终点,知道起点与终点,我们就可以计算出最佳线路,根据最佳线路在小程序地图组件上一渲染就可以了
实现
前面我们在地图微服务已经实现过了“计算最佳驾驶线路”接口,这里只需要在提供司机端web接口即可。前端传入司机的经纬度和目的地的经纬度,调用接口计算最佳路线。
更新司机位置到Redis缓存
司机赶往代驾点,会实时更新司机的经纬度位置到Redis缓存,这样乘客端才能看见司机的动向,司机端更新,乘客端获取。
实现
前端将司机的id和经纬度传给后端,后端储存到redis中
获取司机基本信息
乘客端进入司乘同显页面,需要加载司机的基本信息,显示司机的姓名、头像及驾龄等信息
实现
前端传入订单的id到后端,后端获取乘客的id,先判断是否是这个乘客的订单,在调用司机端的接口来查询司机的信息
乘客端获取司机经纬度位置
乘客端要实时了解司机代驾的动向。乘客端的事成同显,显示司机的驾驶路线,也就是两点之间的最佳路线。我们前端传入起始和终止的坐标到后端,我们后端再调用腾讯云的api来计算最佳的路线
司机到达起始点
司机到达代驾起始点,司机手动触发“到达乘客起点”按钮,更新订单状态
* 司机到达代驾起始点之后,更新当前代驾订单数据
* 更新订单状态:司机到达
* 更新订单到达时间
实现
前端传入订单的id和司机的id,我们后端获取后修改该订单的状态和到达时间
司机更新代驾车辆信息
司机到达代驾起始点,联系了乘客,见到了代驾车辆,要拍照与录入车辆信息