sky-take-out/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java

468 lines
16 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.sky.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.common.constant.MessageConstant;
import com.sky.common.context.BaseContext;
import com.sky.common.exception.AddressBookBusinessException;
import com.sky.common.exception.OrderBusinessException;
import com.sky.common.exception.ShoppingCartBusinessException;
import com.sky.common.result.PageResult;
import com.sky.common.utils.WeChatPayUtil;
import com.sky.mapper.*;
import com.sky.pojo.dto.*;
import com.sky.pojo.entity.*;
import com.sky.pojo.vo.OrderPaymentVO;
import com.sky.pojo.vo.OrderStatisticsVO;
import com.sky.pojo.vo.OrderSubmitVO;
import com.sky.pojo.vo.OrderVO;
import com.sky.service.OrderService;
import com.sky.service.utils.CheckOutOfRangeUtils;
import com.sky.service.utils.OrderServiceImplUtils;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 订单
*/
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Autowired
WebSocketServer webSocketServer;
@Autowired
OrderServiceImplUtils orderServiceImplUtils;
@Autowired
CheckOutOfRangeUtils checkOutOfRangeUtils;
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderDetailMapper orderDetailMapper;
@Autowired
private ShoppingCartMapper shoppingCartMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private AddressBookMapper addressBookMapper;
@Autowired
private WeChatPayUtil weChatPayUtil;
/**
* 用户下单
*
* @param ordersSubmitDTO ordersSubmitDTO
* @return OrderSubmitVO
*/
@Transactional
public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
// 异常情况的处理(收货地址为空、购物车为空)
AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
if (addressBook == null) {
throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
}
// 判断是否超出范围
String address = addressBook.getProvinceName() + addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail();
checkOutOfRangeUtils.checkOutOfRange(address, 1L);
Long userId = BaseContext.getUserId();
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.setUserId(userId);
// 查询当前用户的购物车数据
List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
if (shoppingCartList == null || shoppingCartList.isEmpty()) {
throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
}
// 构造订单数据
Orders order = new Orders();
BeanUtils.copyProperties(ordersSubmitDTO, order);
order.setPhone(addressBook.getPhone());
order.setAddress(addressBook.getDetail());
order.setConsignee(addressBook.getConsignee());
order.setNumber(String.valueOf(System.currentTimeMillis()));
order.setUserId(userId);
order.setStatus(Orders.PENDING_PAYMENT);
order.setPayStatus(Orders.UN_PAID);
order.setOrderTime(LocalDateTime.now());
// 向订单表插入1条数据
orderMapper.insert(order);
// 订单明细数据
List<OrderDetail> orderDetailList = new ArrayList<>();
for (ShoppingCart cart : shoppingCartList) {
OrderDetail orderDetail = new OrderDetail();
BeanUtils.copyProperties(cart, orderDetail);
orderDetail.setOrderId(order.getId());
orderDetailList.add(orderDetail);
}
// 向明细表插入n条数据
orderDetailMapper.insertBatch(orderDetailList);
// 清理购物车中的数据
shoppingCartMapper.deleteByUserId(userId);
// 封装返回结果
return OrderSubmitVO.builder()
.id(order.getId())
.orderNumber(order.getNumber())
.orderAmount(order.getAmount())
.orderTime(order.getOrderTime())
.build();
}
/**
* 订单支付
*/
public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
// 当前登录用户id
Long userId = BaseContext.getUserId();
User user = userMapper.getById(userId);
Orders orders = orderMapper.getByNumber(ordersPaymentDTO.getOrderNumber());
// 调用微信支付接口,生成预支付交易单
JSONObject jsonObject = weChatPayUtil.pay(
ordersPaymentDTO.getOrderNumber(), // 商户订单号
new BigDecimal(orders.getAmount().toString()), // 支付金额,单位 元
"苍穹外卖订单", // 商品描述
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"));
return vo;
}
/**
* 支付成功,修改订单状态
*
* @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);
// 通过客户端浏览器推送消息
HashMap<String, Object> map = new HashMap<>();
map.put("type", 1);// 1 来单提醒 2 客户催单
map.put("orderId", ordersDB.getId());
map.put("content", "订单号" + outTradeNo);
String jsonString = JSON.toJSONString(map);
webSocketServer.sendToAllClient(jsonString);
}
/**
* 历史订单
*
* @param pageNum 当前页
* @param pageSize 一页大小
* @param status 订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
* @return 订单列表
*/
@Override
public PageResult pageQuery4User(int pageNum, int pageSize, Integer status) {
// 设置分页
PageHelper.startPage(pageNum, pageSize);
OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO();
ordersPageQueryDTO.setStatus(status);
ordersPageQueryDTO.setUserId(BaseContext.getUserId());
// 分页条件查询
Page<Orders> page = orderMapper.pageQuery(ordersPageQueryDTO);
List<OrderVO> list = new ArrayList<>();
// 查询出订单明细并封装入OrderVO进行响应
if (page != null && page.getTotal() > 0) {
for (Orders orders : page) {
Long orderId = orders.getId();// 订单id
// 查询订单明细
List<OrderDetail> 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 订单id
*/
@Override
public void reminder(Long id) {
Orders ordersDB = orderMapper.getById(id);
if (ordersDB == null) {
throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
}
HashMap map = new HashMap<>();
map.put("type", 2);
map.put("orderId", id);
map.put("content", "订单号" + ordersDB.getNumber());
webSocketServer.sendToAllClient(JSON.toJSONString(map));
}
/**
* 查询订单详情
*
* @param id 订单id
* @return 订单详情
*/
@Override
public OrderVO details(Long id) {
// 查询订单
Orders orders = orderMapper.getById(id);
// 查询订单详情列表
List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
// 封装 OrderVO
OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(orders, orderVO);
orderVO.setOrderDetailList(orderDetailList);
return orderVO;
}
/**
* 取消订单
*
* @param id 订单id
*/
@Override
public void cancel(Long id) {
// 查找数据库
Orders ordersDB = orderMapper.getById(id);
// 如果存在则继续
if (ordersDB == null) {
throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
}
// 如果订单状态>2抛出异常 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
if (ordersDB.getStatus() > 2) {
throw new OrderBusinessException(MessageConstant.ORDER_STATUS_NOT_OP);
}
// 订单处于待接单状态下取消,需要进行退款
Orders orders = new Orders();
BeanUtils.copyProperties(ordersDB, orders);
orders.setId(id);
if (orders.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
// 调用微信退款...
orders.setPayStatus(OrderVO.REFUND);
}
// 更新订单状态、时间、原因等
orders.setStatus(Orders.CANCELLED);
orders.setCancelReason("用户取消");
orders.setCancelTime(LocalDateTime.now());
orderMapper.update(orders);
}
/**
* 取消订单-商家
*
* @param dto 订单
*/
@Override
public void cancelBusiness(OrdersCancelDTO dto) {
Orders ordersDB = orderMapper.getById(dto.getId());
// 订单不存在
if (ordersDB == null) {
throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
}
Orders orders = new Orders();
orders.setCancelTime(LocalDateTime.now());
orders.setCancelReason(dto.getCancelReason());
orders.setId(dto.getId());
orders.setStatus(Orders.CANCELLED);
// 更新数据
orderMapper.update(orders);
}
/**
* 再来一单
*
* @param id 订单id
*/
@Override
public void repetition(Long id) {
// TODO 是否超出范围
// 查询当前用户id
Long userId = BaseContext.getUserId();
// 根据订单id查询当前订单详情
List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
// 将订单详情对象转换为购物车对象
List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(orderDetail -> {
ShoppingCart shoppingCart = new ShoppingCart();
BeanUtils.copyProperties(orderDetail, shoppingCart, "id");
shoppingCart.setUserId(userId);
shoppingCart.setCreateTime(LocalDateTime.now());
return shoppingCart;
}).collect(Collectors.toList());
// 将购物车对象批量添加到数据库
shoppingCartMapper.insertBatch(shoppingCartList);
}
/**
* 订单搜索
*
* @param dto 订单详情
* @return 分页数据
*/
@Override
public PageResult<OrderVO> conditionSearch(OrdersPageQueryDTO dto) {
PageHelper.startPage(dto.getPage(), dto.getPageSize());
Page<Orders> page = orderMapper.pageQuery(dto);
// 部分订单状态需要额外返回订单菜品信息将Orders转化为OrderVO
List<OrderVO> orderVOList = orderServiceImplUtils.getOrderVOList(page);
return new PageResult<>(page.getTotal(), orderVOList);
}
/**
* 各个状态的订单数量统计
*
* @return OrderStatisticsVO
*/
@Override
public OrderStatisticsVO statistics() {
// 根据状态,分别查询出待接单、待派送、派送中的订单数量
// 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
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 dto 接单请求
*/
@Override
public void confirm(OrdersConfirmDTO dto) {
// 订单状态 1待付款 2待接单 3 已接单 4 派送中 5 已完成 6 已取消 7 退款
Orders orders = Orders.builder().status(Orders.CONFIRMED).id(dto.getId()).build();
// 接单判断是否超出范围
checkOutOfRangeUtils.checkOutOfRange(orders.getAddress(), 3L);
orderMapper.update(orders);
}
/**
* 拒单
*
* @param dto 拒单请求
*/
@Override
public void rejection(OrdersRejectionDTO dto) {
Orders ordersDB = orderMapper.getById(dto.getId());
// 订单为空不存在
if (ordersDB == null) {
throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
}
// 订单状态为2才可以拒单
if (!ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
throw new OrderBusinessException(MessageConstant.ORDER_STATUS_NOT_OP);
}
// 拒单需要退款根据订单id更新订单状态、拒单原因、取消时间
Orders orders = Orders.builder()
.status(Orders.CANCELLED)
.cancelReason(dto.getRejectionReason())
.orderTime(LocalDateTime.now())
.id(ordersDB.getId())
.build();
orderMapper.update(orders);
}
/**
* 派送订单
*
* @param id 订单id
*/
@Override
public void delivery(Long id) {
Orders ordersDB = orderMapper.getById(id);
// 订单不能再
if (ordersDB == null) {
throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
}
// 状态为3
if (!ordersDB.getStatus().equals(Orders.CONFIRMED)) {
throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
}
Orders orders = Orders.builder()
.id(ordersDB.getId())
.status(Orders.DELIVERY_IN_PROGRESS)
.orderTime(LocalDateTime.now()).build();
orderMapper.update(orders);
}
/**
* 完成订单
*
* @param id 订单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()
.id(ordersDB.getId())
// 更新订单状态,状态转为完成
.status(Orders.COMPLETED)
.deliveryTime(LocalDateTime.now())
.build();
orderMapper.update(orders);
}
}