From af63e0cceafaa31a6a3d4f4452cbd018db56fd64 Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Wed, 10 Jan 2024 22:02:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=AE=B6=E7=AB=AF=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sky/controller/admin/OrderController.java | 125 ++++++++ .../sky/controller/admin/orderController.java | 11 - .../main/java/com/sky/mapper/OrderMapper.java | 7 + .../java/com/sky/service/OrderService.java | 54 +++- .../sky/service/impl/OrderServiceImpl.java | 283 +++++++++++++++++- sky-server/src/main/resources/application.yml | 6 +- .../src/main/resources/mapper/OrderMapper.xml | 7 + 7 files changed, 471 insertions(+), 22 deletions(-) create mode 100644 sky-server/src/main/java/com/sky/controller/admin/OrderController.java delete mode 100644 sky-server/src/main/java/com/sky/controller/admin/orderController.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..ab59c35 --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/admin/OrderController.java @@ -0,0 +1,125 @@ +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.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.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RestController("adminOrderController") +@RequestMapping("/admin/order") +@Api(tags = "管理端订单接口") +@Slf4j +public class OrderController { + @Resource + private OrderService orderService; + + /** + * 订单搜索 + * + * @param ordersPageQueryDTO OrdersPageQueryDTO + * @return PageResult + */ + @ApiOperation("订单搜索") + @GetMapping("/conditionSearch") + public Result conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) { + // 条件搜索订单 + PageResult pageResult = orderService.conditionSearch(ordersPageQueryDTO); + return Result.success(pageResult); + } + + /** + * 各个状态的订单数量统计 + * + * @return + */ + @ApiOperation("各个状态的订单数量统计") + @GetMapping("/statistics") + public Result statistics() { + OrderStatisticsVO orderStatisticsVO = orderService.statistics(); + return Result.success(orderStatisticsVO); + } + + /** + * 订单详情 + * + * @param id + * @return + */ + @ApiOperation("查询订单详情") + @GetMapping("/details/{id}") + public Result details(@PathVariable("id") Long id) { + OrderVO orderVO = orderService.detail(id); + return Result.success(orderVO); + } + + /** + * 接单 + * + * @return + */ + @ApiOperation("接单") + @PutMapping("/confirm") + public Result confirm(@RequestBody OrdersConfirmDTO ordersConfirmDTO) { + orderService.confirm(ordersConfirmDTO); + return Result.success(); + } + + /** + * 拒单 + * + * @return + */ + @PutMapping("/rejection") + @ApiOperation("拒单") + public Result rejection(@RequestBody OrdersRejectionDTO ordersRejectionDTO) throws Exception { + orderService.rejection(ordersRejectionDTO); + return Result.success(); + } + + /** + * 取消订单 + * + * @return + */ + @PutMapping("/cancel") + @ApiOperation("取消订单") + public Result cancel(@RequestBody OrdersCancelDTO ordersCancelDTO) throws Exception { + orderService.cancel(ordersCancelDTO); + return Result.success(); + } + + /** + * 派送订单 + * + * @return + */ + @PutMapping("/delivery/{id}") + @ApiOperation("派送订单") + public Result delivery(@PathVariable("id") Long id) { + orderService.delivery(id); + return Result.success(); + } + + /** + * 完成订单 + * + * @return + */ + @PutMapping("/complete/{id}") + @ApiOperation("完成订单") + public Result complete(@PathVariable("id") Long id) { + orderService.complete(id); + return Result.success(); + } +} 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 deleted file mode 100644 index a94a5bc..0000000 --- a/sky-server/src/main/java/com/sky/controller/admin/orderController.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.sky.controller.admin; - -import io.swagger.annotations.Api; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController("adminOrderController") -@RequestMapping("/admin/order") -@Api(tags = "管理端订单接口") -public class orderController { -} 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 99c3517..50edd24 100644 --- a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java @@ -63,4 +63,11 @@ public interface OrderMapper { * @return Orders */ Orders useCancelById(Long id); + + /** + * 根据状态统计订单数量 + * + * @param status + */ + Integer countStatus(Integer status); } 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 d1e7d9d..23b1f6c 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,9 @@ package com.sky.service; -import com.sky.dto.OrdersPaymentDTO; -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; @@ -69,4 +69,54 @@ public interface OrderService { * @param id 订单id */ void repetition(Long id); + + /** + * 条件搜索订单 + * + * @param ordersPageQueryDTO OrdersPageQueryDTO + * @return PageResult + */ + PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO); + + /** + * 各个状态的订单数量统计 + * + * @return + */ + OrderStatisticsVO statistics(); + + /** + * 接单 + * + * @param ordersConfirmDTO + */ + void confirm(OrdersConfirmDTO ordersConfirmDTO); + + /** + * 拒单 + * + * @param ordersRejectionDTO + */ + void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception; + + /** + * 商家取消订单 + * + * @param ordersCancelDTO + */ + void cancel(OrdersCancelDTO ordersCancelDTO) throws Exception; + + /** + * 派送订单 + * + * @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 c34850b..bb46133 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,13 +1,14 @@ package com.sky.service.impl; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; +import com.github.xiaoymin.knife4j.core.util.CollectionUtils; import com.sky.constant.MessageConstant; import com.sky.context.BaseContext; -import com.sky.dto.OrdersPageQueryDTO; -import com.sky.dto.OrdersPaymentDTO; -import com.sky.dto.OrdersSubmitDTO; +import com.sky.dto.*; import com.sky.entity.*; import com.sky.exception.AddressBookBusinessException; import com.sky.exception.OrderBusinessException; @@ -15,22 +16,23 @@ import com.sky.exception.ShoppingCartBusinessException; import com.sky.mapper.*; import com.sky.result.PageResult; import com.sky.service.OrderService; +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 com.sky.websocket.WebSocketServer; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +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.*; import java.util.stream.Collectors; @Service @@ -50,6 +52,10 @@ public class OrderServiceImpl implements OrderService { private WeChatPayUtil weChatPayUtil; @Resource private WebSocketServer webSocketServer; + @Value("${sky.shop.address}") + private String shopAddress; + @Value("${sky.baidu.ak}") + private String ak; /** * 用户下单 @@ -66,7 +72,7 @@ public class OrderServiceImpl implements OrderService { // 抛出异常,购物车为空 throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL); } - + checkOutOfRange(addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail()); // 1. 查询当前用户的购物车数据 ShoppingCart shoppingCart = new ShoppingCart(); Long currentId = BaseContext.getCurrentId(); @@ -298,6 +304,267 @@ public class OrderServiceImpl implements OrderService { // 将购物车对象批量添加到数据库 shoppingCartMapper.insertBatch(shoppingCartList); } + + /** + * 条件搜索订单 + * + * @param ordersPageQueryDTO OrdersPageQueryDTO + * @return PageResult + */ + 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 ordersList = page.getResult(); + if (!CollectionUtils.isEmpty(ordersList)) { + for (Orders orders : ordersList) { + // 将共同字段复制到OrderVO + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders, orderVO); + String orderDishes = getOrderDishesStr(orders); + + // 将订单菜品信息封装到orderVO中,并添加到orderVOList + orderVO.setOrderDishes(orderDishes); + orderVOList.add(orderVO); + } + } + return orderVOList; + } + + /** + * 根据订单id获取菜品信息字符串 + * + * @param orders Orders + * @return String + */ + private String getOrderDishesStr(Orders orders) { + // 查询订单菜品详情信息(订单中的菜品和数量) + List orderDetailList = orderDetailMapper.getByOrderId(orders.getId()); + + // 将每一条订单菜品信息拼接为字符串(格式:宫保鸡丁*3;) + List orderDishList = orderDetailList.stream().map(x -> { + return x.getName() + "*" + x.getNumber() + ";"; + }).collect(Collectors.toList()); + + // 将该订单对应的所有菜品信息拼接在一起 + return String.join("", orderDishList); + } + + /** + * 各个状态的订单数量统计 + * + * @return + */ + 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.setToBeConfirmed(toBeConfirmed); + orderStatisticsVO.setConfirmed(confirmed); + orderStatisticsVO.setDeliveryInProgress(deliveryInProgress); + return orderStatisticsVO; + } + + /** + * 接单 + * + * @param ordersConfirmDTO + */ + public void confirm(OrdersConfirmDTO ordersConfirmDTO) { + Orders orders = Orders.builder() + .id(ordersConfirmDTO.getId()) + .status(Orders.CONFIRMED) + .build(); + + orderMapper.update(orders); + } + + /** + * 拒单 + * + * @param ordersRejectionDTO + */ + public void rejection(OrdersRejectionDTO ordersRejectionDTO) throws Exception { + // 根据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 (Objects.equals(payStatus, Orders.PAID)) { + // 用户已支付,需要退款 + String refund = "dasda"; + 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 + */ + 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); + } + + // 管理端取消订单需要退款,根据订单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 + */ + 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 = new Orders(); + orders.setId(ordersDB.getId()); + // 更新订单状态,状态转为派送中 + orders.setStatus(Orders.DELIVERY_IN_PROGRESS); + + orderMapper.update(orders); + } + + /** + * 完成订单 + * + * @param id + */ + 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 = new Orders(); + orders.setId(ordersDB.getId()); + // 更新订单状态,状态转为完成 + orders.setStatus(Orders.COMPLETED); + orders.setDeliveryTime(LocalDateTime.now()); + + 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 = 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("超出配送范围"); + } + } } diff --git a/sky-server/src/main/resources/application.yml b/sky-server/src/main/resources/application.yml index c3bc3d7..5abdb10 100644 --- a/sky-server/src/main/resources/application.yml +++ b/sky-server/src/main/resources/application.yml @@ -65,4 +65,8 @@ sky: api-v3-key: ${sky.wechat.apiV3Key} we-chat-pay-cert-file-path: ${sky.wechat.weChatPayCertFilePath} notify-url: ${sky.wechat.notifyUrl} - refund-notify-url: ${sky.wechat.refundNotifyUrl} \ No newline at end of file + refund-notify-url: ${sky.wechat.refundNotifyUrl} + shop: + address: 江苏省无锡市江阴市渡江二村13栋 + baidu: + ak: sUMa2pGqc6z2gYbQyeRVMQuyinKWjmKP \ No newline at end of file diff --git a/sky-server/src/main/resources/mapper/OrderMapper.xml b/sky-server/src/main/resources/mapper/OrderMapper.xml index f779779..a15c249 100644 --- a/sky-server/src/main/resources/mapper/OrderMapper.xml +++ b/sky-server/src/main/resources/mapper/OrderMapper.xml @@ -102,4 +102,11 @@ from orders where id = #{id}; + + +