实习项目|苍穹外卖|day9

news2024/11/15 17:39:57

实战作业。

用户端新增功能

1. 查询历史订单

接口设计

在这里插入图片描述
返回的是order+orderdetails(那我这里就先查order,再根据order_id查)

分页

pageHelper的使用:

//controller相关函数
    @GetMapping("/historyOrders")
    @ApiOperation("历史订单查询")//query 不用@RequestBody 
    public Result<PageResult> historyOrders(OrdersPageQueryDTO ordersPageQueryDTO){
        log.info("历史订单查询:{}", ordersPageQueryDTO);
        PageResult pageResult = orderService.historyOrders(ordersPageQueryDTO);
        return Result.success(pageResult);
//service实现类相关函数
    public PageResult historyOrders(OrdersPageQueryDTO ordersPageQueryDTO) {
        Long userId = BaseContext.getCurrentId();
        ordersPageQueryDTO.setUserId(userId);

        // 原型就是select * from employee limit 0, 10
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<OrderVO> page = orderMapper.pageQuery(ordersPageQueryDTO);
        long total = page.getTotal();
        List<OrderVO> results = page.getResult();
        for (OrderVO result : results) {
            Long orderId = result.getId();
            List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orderId);
            result.setOrderDetailList(orderDetailList);
        }

        return new PageResult(total, results);
    }
// mapper.xml
    <select id="pageQuery" resultType="com.sky.vo.OrderVO">
        select * from orders
        <where>
            <if test="status != null and status != ''">
                and status = #{status}
            </if>
        </where>
        order by order_time desc
    </select>

2.查询历史订单详情

已知orderId查询,与上一个功能类似。

3.取消订单

在这里插入图片描述
非常简单的修改状态+修改时间?
是不是要有逻辑判断啊?(什么状态下是可以取消的?)

3.再来一单

在这里插入图片描述

这里有一个难点,就是如何插入新的订单(好多信息,比如预计送达时间等等要怎么处理?)

管理端

1.订单搜索

个人觉得难点就在于,啊啊啊,好多条件用来搜索,sql语言怎么写啊!!!
service的逻辑不太清楚是不是以下这样的:

PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        Page<OrderVO> page = orderMapper.conditionSearch(ordersPageQueryDTO);

        long total = page.getTotal();
        List<OrderVO> result = page.getResult();

        for (OrderVO orderVO : result) {
            StringBuffer orderDishs = new StringBuffer();
            Long id = orderVO.getId();
            List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(id);
            for (OrderDetail orderDetail : orderDetails) {
                Long dishId = orderDetail.getDishId();//判断是不是菜品
                Dish dish;
                if(dishId != null){//是菜品,直接查询菜品表
                    dish = dishMapper.getById(dishId);
                    orderDishs.append(dish.toString());
                }else {//是套餐,查询套餐表//根据套餐ID,查下面的菜品ID,再查菜品信息
                    Long setmealId = orderDetail.getSetmealId();
                    List<SetmealDish> bySetmealId = setmealDishMapper.getBySetmealId(setmealId);
                    for (SetmealDish setmealDish : bySetmealId) {
                        dish = dishMapper.getById(setmealDish.getDishId());
                        orderDishs.append(dish.toString());
                    }
                }
                orderVO.setOrderDishes(orderDishs.toString());
            }

mapper

    <select id="conditionSearch" resultType="com.sky.vo.OrderVO">
        select * from orders
        <where>
            <if test="number != null and number != ''">
                and number = #{number}
            </if>
            <if test="phone != null and phone != ''">
                and phone = #{phone}
            </if>
            <if test="beginTime != null">
                and order_time &gt;= #{beginTime}
            </if>
            <if test="endTime != null">
                and order_time &lt;= #{endTime}
            </if>
            <if test="status != null and status != ''">
                and status = #{status}
            </if>
        </where>
        order by order_time desc
    </select>

2.各个状态的订单数量统计

    public OrderStatisticsVO statistics() {
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        Integer confirmed = orderMapper.countInStatus(Orders.CONFIRMED);
        Integer deliveryInProgress = orderMapper.countInStatus(Orders.DELIVERY_IN_PROGRESS);
        Integer  toBeConfirmed = orderMapper.countInStatus(Orders.TO_BE_CONFIRMED);
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);
        orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
        
        return orderStatisticsVO;
    }

3.查询订单详情

与用户端共用一个service实现。

4.接单

改变订单状态。

5.拒单

这里面有逻辑我不是很清晰,拒单算作取消订单还是完成订单?

6.取消订单

和拒单几乎一样

7.派送订单

8.完成订单

在这里插入图片描述

        //这里自己设置一个状态检测吧,并不是任何状态都可以

        Orders order = orderMapper.getById(id);
        if (order.getStatus() != Orders.DELIVERY_IN_PROGRESS){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }else{
            order.setStatus(Orders.COMPLETED);
            order.setDeliveryTime(LocalDateTime.now());
            orderMapper.update(order);
        }

已有功能优化

优化用户下单功能,加入校验逻辑,如果用户的收货地址距离商家门店超出配送范围(配送范围为5公里内),则下单失败。

提示:

​ 1. 基于百度地图开放平台实现(https://lbsyun.baidu.com/)

​ 2. 注册账号—>创建应用获取AK(服务端应用)—>调用接口

  1. 相关接口

    https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

    https://lbsyun.baidu.com/index.php?title=webapi/directionlite-v1

  2. 商家门店地址可以配置在配置文件中,例如:

    sky:
      shop:
        address: 北京市海淀区上地十街10号
    

自己的分析

我要知道我门店的位置(给的提示是写在配置里面,那应该是有对应的类了,那就可以直接依赖注入使用),要知道用户的位置(用户提交订单里面的地址提取出来!)。然后计算。

package com.sky.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "sky.shop")
@Data
public class ShopProperties {

    private String address;
    
}

API学习:地理编码+骑行路线规划

直接用百度的代码,感觉还是不行,这样代码风格不统一,自己阅读起来也很难受。

  1. 如何获取application.yam中的配置:@Value注解 更多方法
  2. 如何使用HttpClient:基于老师已给的HttpClientUtil进行的,直接doGet。
  3. 解析api调用返回的String报错。JSON.parseObject(str)。报错信息
    @Value("${sky.shop.address}")
    String shopAddress;

    @Value("${sky.baidumap.AK}")
    String Ak;

    @Value("${sky.baidumap.geocodingUrl}")
    String geocodingUrl;

    @Value("${sky.baidumap.distanceUrl}")
    String distanceUrl;
  1. 我现在纠结的点在于如何反馈,能够让客户端知道是距离问题导致的。

对答案

原本计划两天前就完成的,但是电脑出了些问题,如今重装了系统,一切恢复如常。还是一句话:有用的东西装D盘,所以基本上就是下下几个版本号错误的软件,重新安装一下mysql(数据都保存在D盘,简单恢复一下就好),就没多大事!!!

实战内容

完成用户端历史订单模块、商家端订单管理模块相关业务新功能开发和已有功能优化,具体任务列表如下:

1. 新功能开发

用户端历史订单模块:

  • 查询历史订单
  • 查询订单详情
  • 取消订单 //考虑不足,没有考虑到订单是否存在;没有理清状态改变。待接单状态下要退钱,退完钱要更新到取消状态。
// 校验订单是否存在
        if (ordersDB == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
        if (ordersDB.getStatus() > 2) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        Orders orders = new Orders();
        orders.setId(ordersDB.getId());

        // 订单处于待接单状态下取消,需要进行退款
        if (ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
            //调用微信支付退款接口
//            weChatPayUtil.refund(
//                    ordersDB.getNumber(), //商户订单号
//                    ordersDB.getNumber(), //商户退款单号
//                    new BigDecimal(0.01),//退款金额,单位 元
//                    new BigDecimal(0.01));//原订单金额

            //支付状态修改为 退款
            orders.setPayStatus(Orders.REFUND);
        }

        // 更新订单状态、取消原因、取消时间
        orders.setStatus(Orders.CANCELLED);
  • 再来一单 //答案思路是把数据库的数据转为购物车对象:
public void repetition(Long id) {
        // 查询当前用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单id查询当前订单详情
        List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);

        // 将订单详情对象转换为购物车对象
        List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(x -> {
            ShoppingCart shoppingCart = new ShoppingCart();

            // 将原订单详情里面的菜品信息重新复制到购物车对象中
            BeanUtils.copyProperties(x, shoppingCart, "id");
            shoppingCart.setUserId(userId);
            shoppingCart.setCreateTime(LocalDateTime.now());

            return shoppingCart;
        }).collect(Collectors.toList());

        // 将购物车对象批量添加到数据库
        shoppingCartMapper.insertBatch(shoppingCartList);
    }

商家端订单管理模块:(校验订单是否存在,和退款都是没有考虑到的。)

  • 订单搜索 (好奇怪,答案里的代码里没有考虑套餐的问题?答:直接套餐名*数量)
  • 各个状态的订单数量统计
  • 查询订单详情
  • 接单
  • 拒单 (没考虑已付款要退钱的问题。)
  • 取消订单
  • 派送订单
  • 完成订单
2. 已有功能优化

优化用户下单功能,加入校验逻辑,如果用户的收货地址距离商家门店超出配送范围(配送范围为5公里内),则下单失败。

提示:

​ 1. 基于百度地图开放平台实现(https://lbsyun.baidu.com/)

​ 2. 注册账号—>创建应用获取AK(服务端应用)—>调用接口

  1. 相关接口

    https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding

    https://lbsyun.baidu.com/index.php?title=webapi/directionlite-v1

  2. 商家门店地址可以配置在配置文件中,例如:

    sky:
      shop:
        address: 北京市海淀区上地十街10号
    

实战要求

  1. 根据产品原型进行需求分析和接口设计
  2. 根据接口设计进行代码实现
  3. 分别通过swagger接口文档和前后端联调进行功能测试
  4. 分组实战(具体任务分工由组长分配)

主要的问题是:如何从配置中获取信息@value。如何访问接口(doGet,doPost,map)。如何解析得到的返回值(难,至今没搞懂,出了问题是照着答案抄的。)

@Value("${sky.shop.address}")
    private String shopAddress;

    @Value("${sky.baidu.ak}")
    private String ak;

    /**
     * 检查客户的收货地址是否超出配送范围
     * @param address
     */
    private void checkOutOfRange(String address) {
        Map map = new HashMap();
        map.put("address",shopAddress);
        map.put("output","json");
        map.put("ak",ak);

        //获取店铺的经纬度坐标
        String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);

        JSONObject jsonObject = JSON.parseObject(shopCoordinate);
        if(!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("店铺地址解析失败");
        }

        //数据解析
        JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
        String lat = location.getString("lat");
        String lng = location.getString("lng");
        //店铺经纬度坐标
        String shopLngLat = lat + "," + lng;

        map.put("address",address);
        //获取用户收货地址的经纬度坐标
        String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);

        jsonObject = JSON.parseObject(userCoordinate);
        if(!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("收货地址解析失败");
        }

        //数据解析
        location = jsonObject.getJSONObject("result").getJSONObject("location");
        lat = location.getString("lat");
        lng = location.getString("lng");
        //用户收货地址经纬度坐标
        String userLngLat = lat + "," + lng;

        map.put("origin",shopLngLat);
        map.put("destination",userLngLat);
        map.put("steps_info","0");

        //路线规划
        String json = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map);

        jsonObject = JSON.parseObject(json);
        if(!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("配送路线规划失败");
        }

        //数据解析
        JSONObject result = jsonObject.getJSONObject("result");
        JSONArray jsonArray = (JSONArray) result.get("routes");
        Integer distance = (Integer) ((JSONObject) jsonArray.get(0)).get("distance");

        if(distance > 5000){
            //配送距离超过5000米
            throw new OrderBusinessException("超出配送范围");
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2134120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线性回归_梯度下降法

from numpy import * import matplotlib.pyplot as plt1.导入数据 # 1.导入数据 # 模型 y wx b points genfromtxt(linear_regress_lsm_data.csv, delimiter,) length len(points) print(point count %d%length) x array(points[:, 0]) y array(points[:, 1]) plt.scatt…

浅谈工业配电系统中漏电产生的成因以及应对方案

摘要 在现代工业厂房的配电系统中&#xff0c;绝缘检测仪作为保障电气设备安全运行的重要工具&#xff0c;发挥着关键作用。本文探讨了绝缘检测仪在工业厂房配电系统中的应用背景、工作原理、具体应用以及其对设备维护与安全管理的影响。通过分析绝缘检测仪在实际操作中的优势…

数据结构修炼——顺序表和链表的区别与联系?从入门到进阶!

目录 一、线性表二、顺序表2.1 概念及结构2.2 接口实现2.3 一些思考以及顺序表的缺点 三、链表3.1 概念及结构3.2 链表的分类3.3 链表的实现3.3.1 无头单向非循环链表3.3.2 带头双向循环链表 四、顺序表和链表的区别 一、线性表 线性表&#xff08;linear list&#xff09;是n…

初级练习[3]:Hive SQL子查询应用

目录 环境准备看如下链接 子查询 查询所有课程成绩均小于60分的学生的学号、姓名 查询没有学全所有课的学生的学号、姓名 解释: 没有学全所有课,也就是该学生选修的课程数 < 总的课程数。 查询出只选修了三门课程的全部学生的学号和姓名 环境准备看如下链接 环境准备h…

【蓝桥杯省赛真题53】Scratch游乐场 蓝桥杯scratch图形化编程 中小学生蓝桥杯省赛真题讲解

目录 scratch游乐场 一、题目要求 编程实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、python资料 scratch游…

Upstage 将发布新一代 LLM “Solar Pro “预览版

Solar Pro 是最智能的 LLM&#xff0c;经过优化可在单 GPU 上运行&#xff0c;性能超过微软、Meta 和谷歌等科技巨头的模型。 加州圣何塞2024年9月11日电 /美通社/ – Upstage 今天宣布发布其下一代大型语言模型 (LLM) Solar Pro 的预览版。加州圣何塞2024年9月11日电 /美通社…

ElementUI大坑Notification修改样式

默认<style lang"scss" scoped>局部样式&#xff0c;尝试用deep透传也无效 实践成功方法&#xff1a;单独写一个style <style> .el-notification{position: absolute !important;top: 40% !important;left: 40% !important; } </style> 也支持自…

无头服务(Headless Service)

无头服务 ​ 无头服务&#xff08;Headless Service&#xff09;是 Kubernetes 中的一种特殊服务类型&#xff0c;主要用于提供稳定的网络标识&#xff0c;而不需要通过负载均衡来分配流量。它允许直接访问 Pod&#xff0c;而不经过集群内的负载均衡器&#xff0c;并且通常用于…

C# net跨平台上位机开发(avalonia)附demo源码

介绍: 目前微软还没有跨平台桌面程序的开发框架。github上有一个团队开始自行研发跨平台桌面框架,其中一款叫avalonia。avalonia 采用 Xaml+C#,类似于wpf,可运行于.netframework,.netcore,是相对比较成熟的.net跨平台桌面应用技术。下面介绍如何创建 avalonia项目;如何在…

mysql_getshell的几种方法

mysql_getshell 一、mysql的--os-shell 利用原理 --os-shell就是使用udf提权获取WebShell。也是通过into oufile向服务器写入两个文件&#xff0c;一个可以直接执行系统命令&#xff0c;一个进行上传文件。此为sqlmap的一个命令&#xff0c;利用这条命令的先决条件&#xff1a;…

PMP--一模--解题--41-50

文章目录 14.敏捷--方法--回顾--回顾是最重要的一个实践&#xff0c;原因是它能让团队学习、改进和调整其过程。41、 [单选] 新项目中的所有团队成员都希望通过尽快交付价值来获得客户的信任。项目经理了解到一个资源已经在其他项目中与发起人一起工作。某资源似乎在使用个人影…

ICM20948 DMP代码详解(20)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;19&#xff09; 本回继续对inv_icm20948_read_mems_reg函数的其余内容进行解析。为了便于理解和回顾&#xff0c;再次贴出inv_icm20948_read_mems_reg函数源码&#xff0c;在EMD-Core\sources\Invn\Devices\Drivers\I…

在docker中安装 zendesk/maxwell 失败,解决方法

文章目录 1、拉取镜像失败2、一键设置镜像加速&#xff1a;修改文件 /etc/docker/daemon.json&#xff08;如果不存在则创建&#xff09;3、保存好之后 执行以下两条命令 1、拉取镜像失败 [rootlocalhost docker]# docker pull zendesk/maxwell Using default tag: latest Err…

有奖直播 | onsemi IPM 助力汽车电气革命及电子化时代冷热管理

在全球汽车行业向电气化和智能化转型的浪潮中&#xff0c;功率管理技术的创新和应用成为了关键驱动力。作为全球领先的半导体解决方案供应商&#xff0c;onsemi&#xff08;安森美&#xff09;致力于通过其先进的智能功率模块&#xff08;IPM&#xff09;技术&#xff0c;推动汽…

Java许可政策再变,Oracle JDK 17 免费期将结束!

原文地址&#xff1a;https://www.infoworld.com/article/3478122/get-ready-for-more-java-licensing-changes.html Oracle JDK 17的许可协议将于9月变更回Oracle Technology Network License Agreement&#xff0c;这将迫使用户重新评估他们的使用策略。 有句老话说&#xf…

【MyBatis---快速学习和复习】

学习视频&#xff08;强推&#xff09;&#xff1a;【MyBatis视频零基础入门到进阶&#xff0c;MyBatis全套视频教程源码级深入详解】 https://www.bilibili.com/video/BV1JP4y1Z73S/?p134&share_sourcecopy_web&vd_source4d877b7310d01a59f27364f1080e3382 MyBatis中…

【算法】-单调队列

目录 什么是单调队列 区域内最大值 区域内最小值 什么是单调队列 说到单调队列&#xff0c;其实就是一个双端队列&#xff0c; 顾名思义&#xff0c;单调队列的重点分为「单调」和「队列」。「单调」指的是元素的「规律」——递增&#xff08;或递减&#xff09;。「队列」指…

Python精选200Tips:126-130

Those who know are not as good as those who love, and those who love are not as good as those who enjoy 126 PyInstaller - 将 Python 程序打包成独立可执行文件的工具示例:图像变为灰度图像项目结构代码文件打包步骤运行可执行文件127 PyYAML - YAML 解析和生成工具示…

【机器学习(六)】分类和回归任务-LightGBM算法-Sentosa_DSML社区版

文章目录 一、算法概念二、算法原理&#xff08;一&#xff09;Histogram&#xff08;二&#xff09;GOSS1、信息增益2、近似误差 &#xff08;三&#xff09;EFB 三、算法优缺点&#xff08;一&#xff09;优点&#xff08;二&#xff09;缺点 四、LightGBM分类任务实现对比&a…

计算机毕业设计 财会信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…