欢迎光临
我们一直在努力

# 苍穹外卖day09--以为订单模块只是CRUD,结果被业务逻辑狠狠干碎了(附百度地图API接入教程)

苍穹外卖day09–以为订单模块只是CRUD,结果被业务逻辑狠狠干碎了(附百度地图API接入教程)

文章目录

  • 苍穹外卖day09–以为订单模块只是CRUD,结果被业务逻辑狠狠干碎了(附百度地图API接入教程)
    • 前言
      • 用户端订单模块接口设计与开发
        • 共性问题–不要相信前端传过来的数据
        • 查询历史订单–对产品原型分析不够
        • 查询订单详情–没啥问题
        • 取消订单、再来一单–业务分析能力较差
      • 管理端订单模块接口设计与开发
        • 订单搜索–没啥问题
        • 各个状态的订单数量统计–一般般
        • 查询订单详情–没问题
        • 接单、拒单、取消、派送、完成订单
      • 调用百度地图API
        • 申请百度地图AK
        • 在配置文件中添加商家地址以及AK
        • 在用户下单接口中添加校验逻辑
    • 消失的day08
    • 总结

前言

day9的要求是完成用户端以及管理端订单模块的接口。

我是先自行分析,然后与AI讨论并设计接口,理解之后,让AI根据黑马的答案以及接口文档开发代码。

在整个过程中,代码能力提升应该不大,毕竟都是AI写的,自己只是过了一遍,但是真的发现了自己很多业务方面的问题。

这篇文章将总结自己的问题。在这里插入图片描述

用户端订单模块接口设计与开发

共性问题–不要相信前端传过来的数据

在一开始,我设计所有的接口的时候,都让前端传递了个userId,但是呢userId是不用传递的,因为JWT 拦截器已经把 userId 解析出来放进 BaseContext了。

但是,仅仅只有这一个原因吗? 并不是

其实前端传递过来的数据并不可信,为什么?

假设我们不是通过前端点击传递的,而是通过postman、浏览器开发者工具等传递,会发生什么?

一个用户登录了自己的账号,然后直接把请求参数里面的userId改成别的,然后发送请求,可以直接得到他人的数据。

这就叫做越权漏洞。

其实不仅只有userId不通过前端传递,前面我们所写的接口,比如通过id查询地址,以及后面要补充的根据id取消订单,这个id如果要通过前端传递,就要进行订单归属的校验。

假设我们知道了别人的订单id,然后我们通过postman发送取消订单的请求并传入该id,那么会直接取消他人订单。

而校验订单归属其实很简单,只需要校验用户是否为当前用户,也就是在查询方法后加上:

// 校验订单是否属于当前登录用户
if (!orders.getUserId().equals(BaseContext.getCurrentId())) {
throw new OrderBusinessException(MessageConstant.ORDER_BELONG_TO_OTHERS);
}

查询历史订单–对产品原型分析不够

在查询历史订单这个接口中,前端传递订单状态(等),后端不止返回订单。不要根据接口名为订单,就简单返回一个订单。

从页面原型看出,还需要返回菜品的名字、图片、总价等。

因此需要返回的是Orders+OrderDetails的VO

而对于查询这种操作,数据量可能很大,因此前端必须传Page以及PageSize进行分页查询。

因此后端返回的是PageResult,总数+VO集合。

查询订单详情–没啥问题

查询订单详情就没什么问题了,前端传过来订单id,后端直接返回Orders+OrderDetails。

取消订单、再来一单–业务分析能力较差

像取消订单、再下一单,这种前端传递和后端响应数据都很少的,那就要仔细思考一下业务逻辑了。

先说取消订单,首先要明白,什么状态下可以取消? 取消之后是否需要退款?

如果已接单,那么不允许取消,抛出异常。

如果处于已付款,待接单情况下取消,那么要调用微信支付退款接口。然后将支付状态修改为退款,订单状态修改为已取消。

还需要设置取消原因、取消时间,最后更新订单字段。

接着说再来一单,再来一单的逻辑是:把上次点的东西 重新放进购物车,而不是直接返回上次的订单,因为订单状态,支付状态等,完全不对。

利用Stream流里的map方法,把订单详情里面对象变成购物车对象。

利用copyProperties方法,最后记得补充上购物车中userId以及创建时间的字段。

最后调用collect方法把所有对象封装成list集合,然后添加到购物车中。

管理端订单模块接口设计与开发

订单搜索–没啥问题

就是一个简单的分页查询,老生常谈了,没啥问题。

各个状态的订单数量统计–一般般

这个也没太大问题,就是要知道,我们没有点击任何按钮,但是这个订单数量统计已经出来了。

因此前端不需要任何参数传递,当访问这个页面的时候就相当于发送了一次请求,然后后端返回对应数据。

查询订单详情–没问题

和用户端一样的,返回Orders+OrderDetails的VO。

接单、拒单、取消、派送、完成订单

这里整体框架非常简单,就是传id,后端不用返回什么东西,但是具体的业务逻辑,分的还是比较细的,需要认真想一下。

先问自己三个问题:

前置状态是什么? (谁能点这个按钮 → 要不要校验状态)

钱动了吗? (已支付的单子往回退 → 要不要退款)

要留痕吗? (取消/拒单 → 要不要记原因和时间)

比如:

  • 接单/拒单/取消前端传 @RequestBody DTO,因为拒单和取消除了 id 还要带原因。

  • 拒单必须校验 状态=2,不是待接单就抛OrderBusinessException (ORDER_STATUS_ERROR) 而且如果用户已支付(payStatus=1),要先调weChatPayUtil.refund(…) 退款,再把订单改成已取消

  • 取消订单也需要判断是否支付,支付了要退款

  • 派送订单需要校验订单状态为3

  • 完成订单需要校验订单状态为4

调用百度地图API

用户下单时,如果用户的收货地址距离商家门店超出配送范围(5公里内),则下单失败。

接下来我们就详细介绍,如何实现该逻辑。

申请百度地图AK

打开 https://lbsyun.baidu.com/ 注册并登录

进入 控制台 → 应用管理 → 我的应用 → 创建应用

应用类型选择服务端,IP白名单填0.0.0.0/0

创建成功之后得到AK。

在配置文件中添加商家地址以及AK

sky:
shop:
address: 北京市海淀区上地十街10号
baidu:
ak: 你的百度地图AK

在用户下单接口中添加校验逻辑

//商家门店地址
@Value("${sky.shop.address}")
private String shopAddress;

//百度地图AK
@Value("${sky.baidu.ak}")
private String ak;

先把配置文件里的属性注入。

//拼接用户完整收货地址
StringBuilder userAddress = new StringBuilder();
if (addressBook.getProvinceName() != null) {
userAddress.append(addressBook.getProvinceName());
}
if (addressBook.getCityName() != null) {
userAddress.append(addressBook.getCityName());
}
if (addressBook.getDistrictName() != null) {
userAddress.append(addressBook.getDistrictName());
}
if (addressBook.getDetail() != null) {
userAddress.append(addressBook.getDetail());
}

根据前端传过来的数据,把用户完整地址拼接好。

核心校验部分,map集合里面装着一些调用百度地图API所需要的参数。

然后分别用地址编码接口,把商家地址以及用户收货地址转换成经纬度坐标。

有了坐标之后,调用百度地图轻量路线规划接口,计算距离。随后进行业务逻辑的判断。

消失的day08

在文章结尾我想说一下为什么第八天的日记我没写,因为第八天只有两个模块,一个是开发用户下单接口,一个是调用微信小程序支付API。

调用微信小程序支付API呢,因为没有企业资质,并不太好实践,所以只是看看了课,如果以后要用到,用AI开发也是极快的,所以没有写。

而对于用户下单模块呢,其实也没有想象中的那么难,也就是根据产品原型明确DTO与VO,对数据库里的Orders以及OrderDetails有一个清晰认识。

最后加上业务层:查询地址是否为空,购物车是否为空,最后向Orders以及OrderDetails插入数据,并清空购物车即可。

总结

感觉第九天的日记应该是真正算的上日记了,因为前几天其实更像是一种笔记,而第九天真正记录了自己的一些错误,业务能力也得到了提高,也真正接触到了调用第三方API,很好很好,继续加油。

赞(0)
未经允许不得转载:171主机测评 » # 苍穹外卖day09--以为订单模块只是CRUD,结果被业务逻辑狠狠干碎了(附百度地图API接入教程)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址