From 21bfc4430b83d33b4930650a2206c845a5e3d474 Mon Sep 17 00:00:00 2001 From: zvv <508748680@qq.com> Date: Sun, 5 Apr 2026 18:57:29 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A2=E5=8D=95=E7=8A=B6=E6=80=81=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E5=A4=84=E7=90=86=20+=20day09=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sky/controller/admin/OrderController.java | 134 +++++ .../sky/controller/user/OrderController.java | 73 ++- .../com/sky/mapper/OrderDetailMapper.java | 10 + .../main/java/com/sky/mapper/OrderMapper.java | 54 ++ .../com/sky/mapper/ShoppingCartMapper.java | 7 + .../main/java/com/sky/mapper/UserMapper.java | 5 + .../java/com/sky/service/OrderService.java | 103 +++- .../sky/service/impl/OrderServiceImpl.java | 510 +++++++++++++++++- .../src/main/java/com/sky/task/OrderTask.java | 71 +++ sky-server/src/main/resources/application.yml | 4 + .../src/main/resources/mapper/OrderMapper.xml | 56 ++ .../resources/mapper/ShoppingCartMapper.xml | 11 +- 12 files changed, 1021 insertions(+), 17 deletions(-) create mode 100644 sky-server/src/main/java/com/sky/controller/admin/OrderController.java create mode 100644 sky-server/src/main/java/com/sky/task/OrderTask.java diff --git a/sky-server/src/main/java/com/sky/controller/admin/OrderController.java b/sky-server/src/main/java/com/sky/controller/admin/OrderController.java new file mode 100644 index 0000000..0d16dce --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/admin/OrderController.java @@ -0,0 +1,134 @@ +package com.sky.controller.admin; + + +import com.sky.dto.OrdersCancelDTO; +import com.sky.dto.OrdersConfirmDTO; +import com.sky.dto.OrdersPageQueryDTO; +import com.sky.dto.OrdersRejectionDTO; +import com.sky.entity.OrderDetail; +import com.sky.result.PageResult; +import com.sky.result.Result; +import com.sky.service.OrderService; +import com.sky.vo.OrderStatisticsVO; +import com.sky.vo.OrderVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController("adminOrderController") +@Slf4j +@Api("订单管理接口") +@RequestMapping("/admin/order") +public class OrderController { + + @Autowired + private OrderService orderService; + + + /** + * 订单搜索 + * @param ordersPageQueryDTO + * @return + */ + @GetMapping("/conditionSearch") + @ApiOperation("订单搜索") + public Result conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO){ + PageResult pageResult = orderService.conditionSearch(ordersPageQueryDTO); + return Result.success(pageResult); + } + + /** + * 各个状态的订单数量统计 + * @return + */ + @GetMapping("/statistics") + @ApiOperation("各个状态的订单数量统计") + public Result statistics(){ + OrderStatisticsVO orderStatisticsVO = orderService.statistics(); + return Result.success(orderStatisticsVO); + + } + + + /** + * 根据订单id查询订单详情 + * @param id + * @return + */ + @GetMapping("/details/{id}") + @ApiOperation("查询订单详情") + public Result details(@PathVariable Long id){ + OrderVO orderVO = orderService.details(id); + return Result.success(orderVO); + } + + + /** + * 接单 + * @param ordersConfirmDTO + * @return + */ + @PutMapping("/confirm") + @ApiOperation("接单") + public Result confirm(@RequestBody OrdersConfirmDTO ordersConfirmDTO){ + orderService.confirm(ordersConfirmDTO); + return Result.success(); + } + + + /** + * 将待接单的订单拒单 + * @param ordersRejectionDTO + * @return + */ + @PutMapping("/rejection") + @ApiOperation("拒单") + public Result rejection(@RequestBody OrdersRejectionDTO ordersRejectionDTO){ + orderService.rejection(ordersRejectionDTO); + return Result.success(); + } + + + /** + * 将当派送的订单 取消订单 + * @param ordersCancelDTO + * @return + */ + @PutMapping("/cancel") + @ApiOperation("取消订单") + public Result cancel(@RequestBody OrdersCancelDTO ordersCancelDTO){ + orderService.cancel(ordersCancelDTO); + return Result.success(); + } + + + /** + * 派送订单 + * @param id + * @return + */ + @PutMapping("/delivery/{id}") + @ApiOperation("派送订单") + public Result delivery(@PathVariable Long id){ + orderService.delivery(id); + return Result.success(); + } + + + /** + * 完成订单 + * @param id + * @return + */ + @PutMapping("/complete/{id}") + @ApiOperation("完成订单") + public Result complete(@PathVariable Long id){ + orderService.complete(id); + return Result.success(); + } + +} diff --git a/sky-server/src/main/java/com/sky/controller/user/OrderController.java b/sky-server/src/main/java/com/sky/controller/user/OrderController.java index 89e81bf..4c4f9e3 100644 --- a/sky-server/src/main/java/com/sky/controller/user/OrderController.java +++ b/sky-server/src/main/java/com/sky/controller/user/OrderController.java @@ -1,18 +1,19 @@ package com.sky.controller.user; +import com.sky.dto.OrdersPaymentDTO; import com.sky.dto.OrdersSubmitDTO; +import com.sky.result.PageResult; import com.sky.result.Result; import com.sky.service.OrderService; +import com.sky.vo.OrderPaymentVO; import com.sky.vo.OrderSubmitVO; +import com.sky.vo.OrderVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController("userOrderController") @@ -32,4 +33,68 @@ public class OrderController { OrderSubmitVO orderSubmitVO = orderService.submitOrder(ordersSubmitDTO); return Result.success(orderSubmitVO); } + + + /** + * 订单支付 + * + * @param ordersPaymentDTO + * @return + */ + @PutMapping("/payment") + @ApiOperation("订单支付") + public Result payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception { + log.info("订单支付:{}", ordersPaymentDTO); + OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO); + log.info("生成预支付交易单:{}", orderPaymentVO); + return Result.success(orderPaymentVO); + } + + + @GetMapping("/historyOrders") + @ApiOperation("历史订单查询") + public Result page(int page, int pageSize, Integer status){ + PageResult pageResult = orderService.pageQuery4User(page, pageSize, status); + return Result.success(pageResult); + } + + + /** + * 查询订单详情 + * @param id + * @return + */ + @GetMapping("/orderDetail/{id}") + @ApiOperation("查询订单详情") + public Result details(@PathVariable Long id){ + OrderVO orderVO = orderService.details(id); + return Result.success(orderVO); + } + + + /** + * 用户取消订单 + * @param id + * @return + */ + @PutMapping("/cancel/{id}") + @ApiOperation("取消订单") + public Result cancel(@PathVariable Long id){ + orderService.userCancelById(id); + + return Result.success(); + } + + + /** + * 再来一单 + * @param id + * @return + */ + @PostMapping("/repetition/{id}") + @ApiOperation("再来一单") + public Result repetition(@PathVariable Long id){ + orderService.repetition(id); + return Result.success(); + } } diff --git a/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java b/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java index 76aba24..26b9a1e 100644 --- a/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java @@ -3,6 +3,7 @@ package com.sky.mapper; import com.sky.entity.OrderDetail; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; import java.util.List; @@ -15,4 +16,13 @@ public interface OrderDetailMapper { * @param orderDetailList */ void insertBatch(List orderDetailList); + + + /** + * 根据订单id 查询订单明细 + * @param id + * @return + */ + @Select("select * from order_detail where order_id = #{orderId}") + List getByOrderId(Long id); } diff --git a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java index 0581a37..7df2d1c 100644 --- a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java @@ -1,8 +1,14 @@ package com.sky.mapper; +import com.github.pagehelper.Page; +import com.sky.dto.OrdersPageQueryDTO; import com.sky.entity.Orders; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.time.LocalDateTime; +import java.util.List; @Mapper public interface OrderMapper { @@ -12,4 +18,52 @@ public interface OrderMapper { * @param orders */ void insert(Orders orders); + + /** + * 根据订单号查询订单 + * @param orderNumber + */ + @Select("select * from orders where number = #{orderNumber}") + Orders getByNumber(String orderNumber); + + /** + * 修改订单信息 + * @param orders + */ + void update(Orders orders); + + + /** + * 分页条件查询 并按照下单时间排序 + * @param ordersPageQueryDTO + * @return + */ + Page pageQuery(OrdersPageQueryDTO ordersPageQueryDTO); + + + /** + * 根据id查询订单 + * @param id + * @return + */ + @Select("select * from orders where id = #{id}") + Orders getById(Long id); + + + /** + * 根据状态统计订单数量 + * @param toBeConfirmed + * @return + */ + @Select("select count(*) from orders where status = #{status}") + Integer countStatus(Integer toBeConfirmed); + + /** + * 根据订单状态和下单时间查询订单 + * @param status + * @param orderTime + * @return + */ + @Select("select * from orders where status = #{status} and order_time < #{orderTime}") + List getByStatusAndOrderTimeLT(Integer status, LocalDateTime orderTime); } diff --git a/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java b/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java index eac2e3c..bf09d1f 100644 --- a/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java @@ -42,4 +42,11 @@ public interface ShoppingCartMapper { */ @Delete("delete from shopping_cart where user_id = #{userId}") void deleteByUserId(Long userId); + + + /** + * 批量插入购物车数据 + * @param shoppingCartList + */ + void insertBatch(List shoppingCartList); } diff --git a/sky-server/src/main/java/com/sky/mapper/UserMapper.java b/sky-server/src/main/java/com/sky/mapper/UserMapper.java index 1f15f6f..fe0a862 100644 --- a/sky-server/src/main/java/com/sky/mapper/UserMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/UserMapper.java @@ -22,4 +22,9 @@ public interface UserMapper { * @param user */ void insert(User user); + + + + @Select("select * from user where id = #{id}") + User getById(Long userId); } diff --git a/sky-server/src/main/java/com/sky/service/OrderService.java b/sky-server/src/main/java/com/sky/service/OrderService.java index 5bc6a12..a3b7fbb 100644 --- a/sky-server/src/main/java/com/sky/service/OrderService.java +++ b/sky-server/src/main/java/com/sky/service/OrderService.java @@ -1,9 +1,11 @@ package com.sky.service; -import com.sky.dto.OrdersSubmitDTO; +import com.sky.dto.*; +import com.sky.result.PageResult; +import com.sky.vo.OrderPaymentVO; +import com.sky.vo.OrderStatisticsVO; import com.sky.vo.OrderSubmitVO; - - +import com.sky.vo.OrderVO; public interface OrderService { @@ -14,4 +16,99 @@ public interface OrderService { * @return */ OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO); + + + /** + * 订单支付 + * @param ordersPaymentDTO + * @return + */ + OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception; + + /** + * 支付成功,修改订单状态 + * @param outTradeNo + */ + void paySuccess(String outTradeNo); + + + /** + * 用户订单分页查询 + * @param page + * @param pageSize + * @param status + * @return + */ + PageResult pageQuery4User(int page, int pageSize, Integer status); + + + /** + * 查询订单详情 + * @param id + * @return + */ + OrderVO details(Long id); + + + /** + * 用户取消订单 + * @param id + */ + void userCancelById(Long id); + + /** + * 再来一单 + * @param id + */ + void repetition(Long id); + + + /** + * 订单搜索 + * @param ordersPageQueryDTO + * @return + */ + PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO); + + + /** + * 各个状态的订单数量统计 + * @return + */ + OrderStatisticsVO statistics(); + + + /** + * 接单 + * @param ordersConfirmDTO + */ + void confirm(OrdersConfirmDTO ordersConfirmDTO); + + + /** + * 拒单 + * @param ordersRejectionDTO + */ + void rejection(OrdersRejectionDTO ordersRejectionDTO); + + + /** + * 取消订单 + * @param ordersCancelDTO + */ + void cancel(OrdersCancelDTO ordersCancelDTO); + + + /** + * 派送订单 + * @param id + */ + void delivery(Long id); + + + /** + * 完成订单 + * @param id + */ + void complete(Long id); } diff --git a/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java index d971587..5c21914 100644 --- a/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java +++ b/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java @@ -1,35 +1,53 @@ package com.sky.service.impl; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; import com.sky.constant.MessageConstant; import com.sky.context.BaseContext; -import com.sky.dto.OrdersSubmitDTO; -import com.sky.entity.AddressBook; -import com.sky.entity.OrderDetail; -import com.sky.entity.Orders; -import com.sky.entity.ShoppingCart; +import com.sky.dto.*; +import com.sky.entity.*; import com.sky.exception.AddressBookBusinessException; +import com.sky.exception.OrderBusinessException; import com.sky.exception.ShoppingCartBusinessException; -import com.sky.mapper.AddressBookMapper; -import com.sky.mapper.OrderDetailMapper; -import com.sky.mapper.OrderMapper; -import com.sky.mapper.ShoppingCartMapper; +import com.sky.mapper.*; +import com.sky.result.PageResult; import com.sky.result.Result; import com.sky.service.OrderService; import com.sky.service.UserService; +import com.sky.utils.HttpClientUtil; +import com.sky.utils.WeChatPayUtil; +import com.sky.vo.OrderPaymentVO; +import com.sky.vo.OrderStatisticsVO; import com.sky.vo.OrderSubmitVO; +import com.sky.vo.OrderVO; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.xmlbeans.impl.xb.xmlconfig.Extensionconfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Service public class OrderServiceImpl implements OrderService { + private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class); @Autowired private OrderMapper orderMapper; @Autowired @@ -38,6 +56,16 @@ public class OrderServiceImpl implements OrderService { private AddressBookMapper addressBookMapper; @Autowired private ShoppingCartMapper shoppingCartMapper; + @Autowired + private WeChatPayUtil weChatPayUtil; + @Autowired + private UserMapper userMapper; + @Autowired + private OrderService orderService; + @Value("${sky.shop.address}") + private String shopAddress; + @Value("${sky.baidu.ak}") + private String ak; /** * 用户下单 @@ -56,6 +84,9 @@ public class OrderServiceImpl implements OrderService { throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL); } + //检查用户的收货地址是否超出配送范围 + checkOutOfRange(addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail()); + //购物车为空 Long userId = BaseContext.getCurrentId(); @@ -75,6 +106,7 @@ public class OrderServiceImpl implements OrderService { orders.setNumber(String.valueOf(System.currentTimeMillis())); //使用时间戳作为订单号 orders.setPhone(addressBook.getPhone()); orders.setConsignee(addressBook.getConsignee()); + orders.setAddress(addressBook.getDetail()); orders.setUserId(userId); orderMapper.insert(orders); @@ -103,4 +135,464 @@ public class OrderServiceImpl implements OrderService { return orderSubmitVO; } + + + /** + * 订单支付 + * + * @param ordersPaymentDTO + * @return + */ + public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception { + /* + // 当前登录用户id + Long userId = BaseContext.getCurrentId(); + User user = userMapper.getById(userId); + + //调用微信支付接口,生成预支付交易单 + JSONObject jsonObject = weChatPayUtil.pay( + ordersPaymentDTO.getOrderNumber(), //商户订单号 + new BigDecimal(0.01), //支付金额,单位 元 + "苍穹外卖订单", //商品描述 + user.getOpenid() //微信用户的openid + ); + + if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) { + throw new OrderBusinessException("该订单已支付"); + } + + OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class); + vo.setPackageStr(jsonObject.getString("package")); + + */ + + log.info("跳过微信支付,支付成功"); + paySuccess(ordersPaymentDTO.getOrderNumber()); + + return new OrderPaymentVO(); + } + + /** + * 支付成功,修改订单状态 + * + * @param outTradeNo + */ + public void paySuccess(String outTradeNo) { + + // 根据订单号查询订单 + Orders ordersDB = orderMapper.getByNumber(outTradeNo); + + // 根据订单id更新订单的状态、支付方式、支付状态、结账时间 + Orders orders = Orders.builder() + .id(ordersDB.getId()) + .status(Orders.TO_BE_CONFIRMED) + .payStatus(Orders.PAID) + .checkoutTime(LocalDateTime.now()) + .build(); + + orderMapper.update(orders); + } + + + /** + * 用户订单分页查询 + * @param pageNum + * @param pageSize + * @param status + * @return + */ + @Override + public PageResult pageQuery4User(int pageNum, int pageSize, Integer status) { + //设置分页 + PageHelper.startPage(pageNum, pageSize); + + OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO(); + ordersPageQueryDTO.setUserId(BaseContext.getCurrentId()); + ordersPageQueryDTO.setStatus(status); + + //分页条件查询 + Page page = orderMapper.pageQuery(ordersPageQueryDTO); + + List list = new ArrayList<>(); + + //查询出订单明细,并封装入OrderVO进行响应 + if(page != null && page.getTotal() > 0){ + for(Orders orders: page){ + Long orderId = orders.getId(); //订单id + + //查询订单明细 + List orderDetails = orderDetailMapper.getByOrderId(orderId); + + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders,orderVO); + orderVO.setOrderDetailList(orderDetails); + + list.add(orderVO); + } + } + return new PageResult(page.getTotal(), list); + } + + + /** + * 查询订单详情 + * @param id + * @return + */ + @Override + public OrderVO details(Long id) { + + //根据id查询订单 + Orders orders = orderMapper.getById(id); + + //查询该订单对应的菜品/套餐的明细 + //查询该订单对应的菜品/套餐的明细 + List orderDetailList = orderDetailMapper.getByOrderId(orders.getId()); + + //将该订单及其详情封装到OrderVO并返回 + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders,orderVO); + orderVO.setOrderDetailList(orderDetailList); + + return orderVO; + } + + + /** + * 用户取消订单 + * @param id + */ + @Override + public void userCancelById(Long id) { + + Orders ordersDB = orderMapper.getById(id); + 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.setStatus(Orders.REFUND); + } + + //更新订单状态 取消原因 取消时间 + orders.setStatus(Orders.CANCELLED); + orders.setCancelReason("用户取消"); + orders.setCancelTime(LocalDateTime.now()); + orderMapper.update(orders); + } + + + /** + * 再来一单 + * @param id + */ + @Override + public void repetition(Long id) { + + //查询当前用户id + Long userId = BaseContext.getCurrentId(); + + //根据订单id查询当前订单详情 + List orderDetailList = orderDetailMapper.getByOrderId(id); + + //将订单详情对象转换为购物车对象 + List 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); + + } + + + /** + * 订单搜索 + * @param ordersPageQueryDTO + * @return + */ + @Override + public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) { + PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize()); + Page page = orderMapper.pageQuery(ordersPageQueryDTO); + + //部分订单状态需要额外返回订单菜品信息,将Orders转换为OrderVO + List orderVOList = getOrderVOList(page); + + return new PageResult(page.getTotal(), orderVOList); + } + + private List getOrderVOList(Page page){ + //需要返回订单菜品信息 自定义OrderVO响应结果 + List orderVOList = new ArrayList<>(); + + List orderList = page.getResult(); + if(orderList != null && orderList.size() > 0){ + for(Orders orders: orderList){ + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders,orderVO); + +/* // ========== 统一拒单原因和取消原因 ========== + if (orderVO.getCancelReason() == null && orderVO.getRejectionReason() != null) { + orderVO.setCancelReason(orderVO.getRejectionReason()); + }*/ + String orderDishes = getOrderDishesStr(orders); + + //将订单菜品信息封装到orderVO中 并添加到orderVOList + orderVO.setOrderDishes(orderDishes); + orderVOList.add(orderVO); + } + } + return orderVOList; + } + + /** + * 根据订单id获取菜品信息字符串 + * @param orders + * @return + */ + private String getOrderDishesStr(Orders orders){ + // 查询订单菜品详情信息(订单中的菜品和数量) + List orderDetailList = orderDetailMapper.getByOrderId(orders.getId()); + + // 将每一条订单菜品信息拼接为字符串(格式:宫保鸡丁*3;) + List orderDishList = orderDetailList.stream().map(x ->{ + String orderDish = x.getName() + "*" + x.getNumber() + ";"; + return orderDish; + }).collect(Collectors.toList()); + + // 将该订单对应的所有菜品信息拼接在一起 + return String.join("",orderDishList); + } + + + + + /** + * 各个状态的订单数量统计 + * @return + */ + @Override + public OrderStatisticsVO statistics() { + //根据状态 分别查询出待接单、待派送、派送中的订单数量 + Integer toBeConfirmed = orderMapper.countStatus(Orders.TO_BE_CONFIRMED); + Integer confirmed = orderMapper.countStatus(Orders.CONFIRMED); + Integer deliveryInProgress = orderMapper.countStatus(Orders.DELIVERY_IN_PROGRESS); + + //将查询出的数量封装到orderStatisticsVO中响应 + OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO(); + orderStatisticsVO.setConfirmed(confirmed); + orderStatisticsVO.setToBeConfirmed(toBeConfirmed); + orderStatisticsVO.setDeliveryInProgress(deliveryInProgress); + + return orderStatisticsVO; + } + + + /** + * 接单 + * @param ordersConfirmDTO + */ + @Override + public void confirm(OrdersConfirmDTO ordersConfirmDTO) { + Orders orders = Orders.builder() + .id(ordersConfirmDTO.getId()) + .status(Orders.CONFIRMED) + .build(); + orderMapper.update(orders); + } + + + /** + * 拒单 + * @param ordersRejectionDTO + */ + @Override + public void rejection(OrdersRejectionDTO ordersRejectionDTO) { + //根据id查询订单 + Orders ordersDB = orderMapper.getById(ordersRejectionDTO.getId()); + + // 订单只有存在且状态为2(待接单)才可以拒单 + if(ordersDB == null || !ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + + /* + //支付状态 + Integer payStatus = ordersDB.getPayStatus(); + if(payStatus == Orders.PAID){ + //用户已支付 需要退款 + String refund = weChatPayUtil.refund( + ordersDB.getNumber(), + ordersDB.getNumber(), + new BigDecimal(0.01), + new BigDecimal(0.01)); + log.info("申请退款:{}", refund); + } + */ + + // 拒单需要退款,根据订单id更新订单状态、拒单原因、取消时间 + Orders orders = new Orders(); + orders.setId(ordersDB.getId()); + orders.setStatus(Orders.CANCELLED); + orders.setRejectionReason(ordersRejectionDTO.getRejectionReason()); + orders.setCancelTime(LocalDateTime.now()); + + orderMapper.update(orders); + } + + + /** + * 商家取消订单 + * @param ordersCancelDTO + */ + @Override + public void cancel(OrdersCancelDTO ordersCancelDTO) { + //根据id查询订单 + Orders ordersDB = orderMapper.getById(ordersCancelDTO.getId()); + + //管理端取消订单需要退款 根据订单id更新订单状态、取消原因、取消时间 + Orders orders = new Orders(); + orders.setId(ordersCancelDTO.getId()); + orders.setStatus(Orders.CANCELLED); + orders.setCancelReason(ordersCancelDTO.getCancelReason()); + orders.setCancelTime(LocalDateTime.now()); + orderMapper.update(orders); + } + + + /** + * 派送订单 + * @param id + */ + @Override + public void delivery(Long id) { + // 根据id查询订单 + Orders ordersDB = orderMapper.getById(id); + + // 校验订单是否存在,并且状态为3(待派送 已接单) + if(ordersDB == null || !ordersDB.getStatus().equals(Orders.CONFIRMED)){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + + // 更新订单状态,状态转为派送中 + Orders orders = Orders.builder() + .status(Orders.DELIVERY_IN_PROGRESS) + .id(ordersDB.getId()) + .build(); + orderMapper.update(orders); + } + + + /** + * 完成订单 + * @param id + */ + @Override + public void complete(Long id) { + // 根据id查询订单 + Orders ordersDB = orderMapper.getById(id); + + // 校验订单是否存在,并且状态为4 派送中 + if(ordersDB == null || !ordersDB.getStatus().equals(Orders.DELIVERY_IN_PROGRESS)){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + + // 更新订单状态,状态转为完成 + Orders orders = Orders.builder() + .status(Orders.COMPLETED) + .id(ordersDB.getId()) + .deliveryTime(LocalDateTime.now()) + .build(); + orderMapper.update(orders); + } + + + /** + * 检查客户的收货地址是否超出配送范围 + * @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 = JSONObject.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 shopLat = lat + "," + lng; + + map.put("address", address); + + //获取用户收获地址的经纬度坐标 + String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map); + jsonObject = JSONObject.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", shopLat); + map.put("destination", userLngLat); + map.put("steps_info", "0"); + + //路线规划 + String json = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map); + jsonObject = JSONObject.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"); + //配送距离超过5000米 + if(distance > 5000){ + throw new OrderBusinessException("超出配送范围"); + } + + } + } diff --git a/sky-server/src/main/java/com/sky/task/OrderTask.java b/sky-server/src/main/java/com/sky/task/OrderTask.java new file mode 100644 index 0000000..b2985bb --- /dev/null +++ b/sky-server/src/main/java/com/sky/task/OrderTask.java @@ -0,0 +1,71 @@ +package com.sky.task; + + +import com.sky.entity.Orders; +import com.sky.mapper.OrderMapper; +import com.sky.service.OrderService; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.annotations.Select; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 定时任务类 定时处理任务状态 + */ + +@Component +@Slf4j +@EnableScheduling +public class OrderTask { + + @Autowired + private OrderMapper orderMapper; + + + + /** + * 处理超时订单的方法 + */ + @Scheduled(cron = "0 * * * * ?") //每分钟触发一次 + //@Scheduled(cron = "1/5 * * * * ?") + public void processTimeOutOrder(){ + log.info("定时处理超时订单:{}", LocalDateTime.now()); + LocalDateTime time = LocalDateTime.now().plusMinutes(-15); + + //select * from orders where status = ? and order_time < (当前时间 - 15分钟) + List ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time); + if(ordersList != null && ordersList.size()>0){ + for(Orders orders : ordersList){ + orders.setStatus(Orders.CANCELLED); + orders.setCancelReason("订单超时,自动取消"); + orders.setCancelTime(LocalDateTime.now()); + orderMapper.update(orders); + } + } + } + + + /** + * 处理一直在派送中的订单 + */ + @Scheduled(cron = "0 0 1 * * ?") //每天凌晨一点触发一次 + //@Scheduled(cron = "0/5 * * * * ?") + public void processDeliveryOrder() { + log.info("定时处理一直在派送中的订单:{}", LocalDateTime.now()); + + //处理上一天的待派送状态的订单 + LocalDateTime time = LocalDateTime.now().plusMinutes(-60); + List ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, time); + if (ordersList != null && ordersList.size() > 0) { + for (Orders orders : ordersList) { + orders.setStatus(Orders.COMPLETED); + orderMapper.update(orders); + } + } + } +} diff --git a/sky-server/src/main/resources/application.yml b/sky-server/src/main/resources/application.yml index f232fff..f60a5b1 100644 --- a/sky-server/src/main/resources/application.yml +++ b/sky-server/src/main/resources/application.yml @@ -54,3 +54,7 @@ sky: wechat: appid: ${sky.wechat.appid} secret: ${sky.wechat.secret} + shop: + address: 山西省晋中市太古区山西农业大学 + baidu: + ak: MAXYV7FMGffoKTRsrd35RXhjHTWxSEkw diff --git a/sky-server/src/main/resources/mapper/OrderMapper.xml b/sky-server/src/main/resources/mapper/OrderMapper.xml index 94d940a..7319f59 100644 --- a/sky-server/src/main/resources/mapper/OrderMapper.xml +++ b/sky-server/src/main/resources/mapper/OrderMapper.xml @@ -11,4 +11,60 @@ #{payMethod}, #{payStatus}, #{amount}, #{remark}, #{phone}, #{address}, #{consignee}, #{estimatedDeliveryTime}, #{deliveryStatus}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus}) + + + + update orders + + + cancel_reason=#{cancelReason}, + + + rejection_reason=#{rejectionReason}, + + + cancel_time=#{cancelTime}, + + + pay_status=#{payStatus}, + + + pay_method=#{payMethod}, + + + checkout_time=#{checkoutTime}, + + + status = #{status}, + + + delivery_time = #{deliveryTime} + + + where id = #{id} + + diff --git a/sky-server/src/main/resources/mapper/ShoppingCartMapper.xml b/sky-server/src/main/resources/mapper/ShoppingCartMapper.xml index 49e7101..90fc6c5 100644 --- a/sky-server/src/main/resources/mapper/ShoppingCartMapper.xml +++ b/sky-server/src/main/resources/mapper/ShoppingCartMapper.xml @@ -3,7 +3,6 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > - + + + + insert into shopping_cart (name, image, user_id, dish_id, setmeal_id, dish_flavor, number, amount, create_time) + values + + (#{sc.name}, #{sc.image}, #{sc.userId}, #{sc.dishId}, #{sc.setmealId}, #{sc.dishFlavor}, #{sc.number}, #{sc.amount}, #{sc.createTime}) + + +