苍穹外卖 项目记录 day10 商户端(PC端)订单管理

文章目录

  • 订单搜索
  • 各状态订单数量统计
  • 查询订单详情
  • 接单
  • 拒单
  • 取消订单
  • 派送订单
  • 完成订单
  • 校验收货地址是否超出配送范围


订单搜索

业务规则:

  • 输入订单号/手机号进行搜索,支持模糊搜索
  • 根据订单状态进行筛选
  • 下单时间进行时间筛选
  • 搜索内容为空,提示未找到相关订单
  • 搜索结果页,展示包含搜索关键词的内容
  • 分页展示搜索到的订单数据

/admin/order/conditionSearch GET

@Autowired
private OrderService orderService;/*** 订单搜索* @param ordersPageQueryDTO* @return*/
@GetMapping("/conditionSearch")
@ApiOperation("订单搜索")
public Result<PageResult> conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO){PageResult pageResult = orderService.conditionSearch(ordersPageQueryDTO);return Result.success(pageResult);
}/*** 条件搜索订单分页查询* @param ordersPageQueryDTO* @return*/
PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO);/*** 订单条件搜索* @param ordersPageQueryDTO* @return*/
@Override
public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());Page<Orders> page = orderMapper.pageQuery(ordersPageQueryDTO);//部分订单状态需要返回订单菜品信息 将Orders转化为OrderVOList<OrderVO> orderVOList = getOrderVOList(page);return new PageResult(page.getTotal(),orderVOList);
}Page<Orders> pageQuery(OrdersPageQueryDTO ordersPageQueryDTO);<!-- 查询订单列表 --><select id="pageQuery" resultType="com.sky.entity.Orders">select * from orders<where><if test="number != null and number!=''">and number like concat('%',#{number},'%')</if><if test="phone != null and phone!=''">and phone like concat('%',#{phone},'%')</if><if test="userId != null">and user_id = #{userId}</if><if test="status != null">and status = #{status}</if><if test="beginTime != null">and order_time &gt;= #{beginTime}</if><if test="endTime != null">and order_time &lt;= #{endTime}</if></where>order by order_time desc</select>

各状态订单数量统计

/admin/order/statistics GET

OrderController.java

/***  统计各个状态的订单数量* @return*/
@GetMapping("/statistics")
@ApiOperation("各个状态订单数量统计")
public Result<OrderStatisticsVO> statistics(){OrderStatisticsVO orderStatisticsVO = orderService.statistics();return Result.success(orderStatisticsVO);
}

OrderService.java

/*** 各个状态的订单数量统计* @return*/
OrderStatisticsVO statistics();

OrderServiceImpl.java

/*** 各个状态订单数量统计* @return*/@Overridepublic OrderStatisticsVO statistics() {//根据状态 分别查询待接单  待派送  派送中的订单数量Integer toBeConfirmed = orderMapper.countSatus(Orders.TO_BE_CONFIRMED);Integer confirmed = orderMapper.countSatus(Orders.CONFIRMED);Integer deliveryInProgress = orderMapper.countSatus(Orders.DELIVERY_IN_PROGRESS);//将查询出的数据封装岛orderStatisticsVO对象中OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();orderStatisticsVO.setToBeConfirmed(toBeConfirmed);orderStatisticsVO.setConfirmed(confirmed);orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);return orderStatisticsVO;}

OrderMapper.java

/*** 根据状态统计订单数量* @param status* @return*/
@Select("select count(id) from orders where status = #{status}")
Integer countSatus(Integer status);

查询订单详情

业务规则:

  • 订单详情页面需要展示订单基本信息(状态、订单号、下单时间、收货人、电话、收货地址、金额等)
  • 订单详情页面需要展示订单明细数据(商品名称、数量、单价)

/admin/order/detail/{id} GET

/*** 查询订单详情* @param id* @return*/
@GetMapping("/details/{id}")
@ApiOperation("查询订单详情")
public Result<OrderVO> details(@PathVariable("id") Long id){OrderVO orderVO = orderService.details(id);return Result.success(orderVO);
}

OrderService.java

OrderVO details(Long id);

OrderSeviceImpl.java

/**** 查询订单详情* @param id* @return*/public OrderVO details(Long id) {//根据id查询订单Orders orders = orderMapper.getById(id);//查询该订单对应得菜品/套餐明显List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());// 将该订单及其详情封装到OrderVO并返回OrderVO  orderVO = new OrderVO();BeanUtils.copyProperties(orders,orderVO);orderVO.setOrderDetailList(orderDetailList);return orderVO;
}

OrderDetailMapper.java

/*** 根据订单id查询订单明细* @param orderId* @return*/
@Select("select * from order_detail where order_id = #{orderId}")
List<OrderDetail> getByOrderId(Long orderId);

接单

  • 商家接单其实就是将订单的状态修改为“已接单”

admin/order/confirm PUT

OrderController.java

@PutMapping("/confirm")
@ApiOperation("接单")
public Result confirm(@RequestBody OrdersConfirmDTO ordersConfirmDTO) {orderService.confirm(ordersConfirmDTO);return Result.success();
}

OrderService.java

void confirm(OrdersConfirmDTO ordersConfirmDTO);

OrderServiceImp.java

public void confirm(OrdersConfirmDTO ordersConfirmDTO) {Orders orders = Orders.builder().id(ordersConfirmDTO.getId()).status(Orders.CONFIRMED).build();orderMapper.update(orders);
}

OrderMapper.java

   /*** 修改订单信息* @param orders*/void update(Orders orders);

OrderMapper.xml

<update id="update" parameterType="com.sky.entity.Orders">update orders<set><if test="cancelReason != null and cancelReason!='' ">cancel_reason=#{cancelReason},</if><if test="rejectionReason != null and rejectionReason!='' ">rejection_reason=#{rejectionReason},</if><if test="cancelTime != null">cancel_time=#{cancelTime},</if><if test="payStatus != null">pay_status=#{payStatus},</if><if test="payMethod != null">pay_method=#{payMethod},</if><if test="checkoutTime != null">checkout_time=#{checkoutTime},</if><if test="status != null">status = #{status},</if><if test="deliveryTime != null">delivery_time = #{deliveryTime}</if></set>where id = #{id}
</update>

拒单

admin/order/rejection PUT

@PutMapping("/rejection")
@ApiOperation("拒单")
public Result rejection(@RequestBody OrdersRejectionDTO ordersRejectionDTO) throws Exception {orderService.rejection(ordersRejectionDTO);return Result.success();
}
void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception;
@Override
public void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception {//根据id查询订单Orders orderDB = orderMapper.getById(ordersRejectionDTO.getId());//订单只有存在且状态为2 待接单才可以拒单//处理业务异常if(orderDB == null || !orderDB.getStatus().equals(Orders.TO_BE_CONFIRMED)){throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);}//支付状态Integer payStatus = orderDB.getPayStatus();if(payStatus == Orders.PAID){//用户已支付需要退款  伪造订单支付 跳过微信退款//String refund = weChatPayUtil.refund(//        orderDB.getNumber(),//        orderDB.getNumber(),//        new BigDecimal(0.01),//        new BigDecimal(0.01));Log.info("退款结果:{}",refund);//支付状态修改为 退款orderDB.setPayStatus(Orders.REFUND);}//管理端取消订单需要退款 根据订单id更新订单状态 取消原因 取消时间Orders orders = new Orders();orders.setId(orderDB.getId());orders.setStatus(Orders.CANCELLED);orders.setCancelReason(ordersRejectionDTO.getRejectionReason());orders.setCancelTime(LocalDateTime.now());orderMapper.update(orders);
}

取消订单

业务规则:

  • 取消订单其实就是将订单状态修改为“已取消”
  • 商家取消订单时需要指定取消原因
  • 商家取消订单时,如果用户已经完成了支付,需要为用户退款

admin/order/cancel PUT

@PutMapping("/cancel")
@ApiOperation("取消订单")
public Result cancel(@RequestBody OrdersCancelDTO ordersCancelDTO) throws Exception{orderService.cancel(ordersCancelDTO);return Result.success();
}
void cancel(OrdersCancelDTO ordersCancelDTO) throws Exception;
public void cancel(OrdersCancelDTO ordersCancelDTO) throws Exception{//根据id查询订单Orders ordersDB = orderMapper.getById(ordersCancelDTO.getId());//支付状态Integer payStatus = ordersDB.getPayStatus();if (payStatus == 1) {//用户已支付,需要退款//String refund = weChatPayUtil.refund(//        ordersDB.getNumber(),//        ordersDB.getNumber(),//        new BigDecimal(0.01),//        new BigDecimal(0.01));//log.info("申请退款:{}", refund);ordersDB.setPayStatus(Orders.REFUND);}// 管理端取消订单需要退款,根据订单id更新订单状态、取消原因、取消时间Orders orders = new Orders();orders.setId(ordersCancelDTO.getId());orders.setStatus(Orders.CANCELLED);orders.setCancelReason(ordersCancelDTO.getCancelReason());orders.setCancelTime(LocalDateTime.now());orderMapper.update(orders);
}

派送订单

  • 派送订单其实就是将订单状态修改为“派送中”
  • 只有状态为“待派送”的订单可以执行派送订单操作
@PutMapping("/delivery/{id}")
@ApiOperation("派送订单")
public Result delivery(@PathVariable("id") Long id) {orderService.delivery(id);return Result.success();
}
 void delivery(Long id);
@Override
public void delivery(Long id) {// 根据id查询订单Orders ordersDB = orderMapper.getById(id);// 校验订单是否存在,并且状态为3if (ordersDB == null || !ordersDB.getStatus().equals(Orders.CONFIRMED)) {throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);}Orders orders = new Orders();orders.setId(ordersDB.getId());// 更新订单状态,状态转为派送中orders.setStatus(Orders.DELIVERY_IN_PROGRESS);orderMapper.update(orders);
}

完成订单

@PutMapping("/complete/{id}")
@ApiOperation("完成订单")
public Result complete(@PathVariable("id") Long id) {orderService.complete(id);return Result.success();
}
void complete(Long id);
@Override
public void complete(Long id) {// 根据id查询订单Orders ordersDB = orderMapper.getById(id);// 校验订单是否存在,并且状态为4if (ordersDB == null || !ordersDB.getStatus().equals(Orders.DELIVERY_IN_PROGRESS)) {throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);}Orders orders = new Orders();orders.setId(ordersDB.getId());// 更新订单状态,状态转为完成orders.setStatus(Orders.COMPLETED);orders.setDeliveryTime(LocalDateTime.now());orderMapper.update(orders);
}

校验收货地址是否超出配送范围

百度开放地图

登录百度地图开放平台:https://lbsyun.baidu.com/

进入控制台,创建应用,获取AK:

控制台 | 百度地图开放平台 (baidu.com)

配置application.yml

shop:
address: ${sky.shop.address}
baidu:
ak: ${sky.baidu.ak}

OrderServiceImpl,注入上面的配置项:

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

OrderServiceImpl.java

/*** 检查客户的收货地址是否超出配送范围* @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("超出配送范围");}
}
//检查用户收获地址是否超出配送范围
checkOutOfRange(addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail());

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

three.js+WebGL踩坑经验合集(6.2):负缩放,负定矩阵和行列式的关系(3D版本)

本篇将紧接上篇的2D版本对3D版的负缩放矩阵进行解读。 (6.1):负缩放&#xff0c;负定矩阵和行列式的关系&#xff08;2D版本&#xff09; 既然three.js对3D版的负缩放也使用行列式进行判断&#xff0c;那么&#xff0c;2D版的结论用到3D上其实是没毛病的&#xff0c;THREE.Li…

反向代理模块jmh

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当…

软件工程经济学-日常作业+大作业

目录 一、作业1 作业内容 解答 二、作业2 作业内容 解答 三、作业3 作业内容 解答 四、大作业 作业内容 解答 1.建立层次结构模型 (1)目标层 (2)准则层 (3)方案层 2.构造判断矩阵 (1)准则层判断矩阵 (2)方案层判断矩阵 3.层次单排序及其一致性检验 代码 …

【回溯】目标和 字母大小全排列

文章目录 494. 目标和解题思路&#xff1a;回溯784. 字母大小写全排列解题思路&#xff1a;回溯 494. 目标和 494. 目标和 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式…

告别复杂,拥抱简洁:用plusDays(7)代替plus(7, ChronoUnit.DAYS)

前言 你知道吗?有时候代码里的一些小细节看起来很简单,却可能成为你调试时的大麻烦。在 Java 中,我们用 LocalDateTime 进行日期和时间的操作时,发现一个小小的替代方法可以让代码更简洁,功能更强大。这不,今天我们就来探讨如何用 LocalDateTime.now().plusDays(7) 替代…

《苍穹外卖》项目学习记录-Day10订单状态定时处理

利用Cron表达式生成器生成Cron表达式 1.处理超时订单 查询订单表把超时的订单查询出来&#xff0c;也就是订单的状态为待付款&#xff0c;下单的时间已经超过了15分钟。 //select * from orders where status ? and order_time < (当前时间 - 15分钟) 遍历集合把数据库…

【深度分析】微软全球裁员计划不影响印度地区,将继续增加当地就业机会

当微软的裁员刀锋掠过全球办公室时&#xff0c;班加罗尔的键盘声却愈发密集——这场资本迁徙背后&#xff0c;藏着数字殖民时代最锋利的生存法则。 表面是跨国公司的区域战略调整&#xff0c;实则是全球人才市场的地壳运动。微软一边在硅谷裁撤年薪20万美金的高级工程师&#x…

Linux中 端口被占用如何解决

lsof命令查找 查找被占用端口 lsof -i :端口号 #示例 lsof -i :8080 lsof -i :3306 netstat命令查找 查找被占用端口 netstat -tuln | grep 端口号 #示例 netstat -tuln | grep 3306 netstat -tuln | grep 6379 ss命令查找 查找被占用端口 ss -tunlp | grep 端口号 #示例…

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记

qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记 文章目录 qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记1.例程运行效果2.例程缩略图3.项目文件列表4.main.qml5.main.cpp6.CMakeLists.txt 1.例程运行效果 运行该项目需要自己准备一个模型文件 2.例程缩略图…

高性能消息队列Disruptor

定义一个事件模型 之后创建一个java类来使用这个数据模型。 /* <h1>事件模型工程类&#xff0c;用于生产事件消息</h1> */ no usages public class EventMessageFactory implements EventFactory<EventMessage> { Overridepublic EventMessage newInstance(…

Spring Boot项目如何使用MyBatis实现分页查询

写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油&#xff0c;冲鸭&#x…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.27 线性代数王国:矩阵分解实战指南

1.27 线性代数王国&#xff1a;矩阵分解实战指南 #mermaid-svg-JWrp2JAP9qkdS2A7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JWrp2JAP9qkdS2A7 .error-icon{fill:#552222;}#mermaid-svg-JWrp2JAP9qkdS2A7 .erro…

EasyExcel使用详解

文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…

FIDL:Flutter与原生通讯的新姿势,不局限于基础数据类型

void initUser(User user); } 2、执行命令./gradlew assembleDebug&#xff0c;生成IUserServiceStub类和fidl.json文件 3、打开通道&#xff0c;向Flutter公开方法 FidlChannel.openChannel(getFlutterEngine().getDartExecutor(), new IUserServiceStub() { Override void…

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析

87.(3)攻防世界 web simple_php

之前做过&#xff0c;回顾 12&#xff0c;攻防世界simple_php-CSDN博客 进入靶场 <?php // 显示当前 PHP 文件的源代码&#xff0c;方便调试或查看代码结构 // __FILE__ 是 PHP 的一个魔术常量&#xff0c;代表当前文件的完整路径和文件名 show_source(__FILE__);// 包含…

x86-64数据传输指令

关于汇编语言一些基础概念的更详细的介绍&#xff0c;可移步MIPS指令集&#xff08;一&#xff09;基本操作_mips指令 sw-CSDN博客 该指令集中一个字2字节。 该架构有16个64位寄存器&#xff0c;名字都以%r开头&#xff0c;每个寄存器的最低位字节&#xff0c;低1~2位字节&…

网络工程师 (8)存储管理

一、页式存储基本原理 &#xff08;一&#xff09;内存划分 页式存储首先将内存物理空间划分成大小相等的存储块&#xff0c;这些块通常被称为“页帧”或“物理页”。每个页帧的大小是固定的&#xff0c;例如常见的页帧大小有4KB、8KB等&#xff0c;这个大小由操作系统决定。同…

全程Kali linux---CTFshow misc入门(25-37)

第二十五题&#xff1a; 提示&#xff1a;flag在图片下面。 直接检查CRC&#xff0c;检测到错误&#xff0c;就直接暴力破解。 暴力破解CRC的python代码。 import binascii import struct def brute_force_ihdr_crc(filename): # 读取文件二进制数据 with open(filen…

MySQL数据库(二)- SQL

目录 ​编辑 一 DDL (一 数据库操作 1 查询-数据库&#xff08;所有/当前&#xff09; 2 创建-数据库 3 删除-数据库 4 使用-数据库 (二 表操作 1 创建-表结构 2 查询-所有表结构名称 3 查询-表结构内容 4 查询-建表语句 5 添加-字段名数据类型 6 修改-字段数据类…