package com.peanut.modules.book.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.peanut.common.utils.PageUtils; import com.peanut.common.utils.R; import com.peanut.config.Constants; import com.peanut.config.DelayQueueConfig; import com.peanut.modules.book.entity.*; import com.peanut.modules.book.service.*; import com.peanut.modules.book.vo.request.BuyOrderListRequestVo; import com.peanut.modules.book.vo.request.ModifyOrderAddressRequestVo; import com.peanut.modules.book.vo.request.ProductRequestVo; import com.peanut.modules.book.vo.request.ProductTransportVo; import com.peanut.modules.book.vo.response.BuyOrderResponseVo; import com.peanut.modules.book.vo.response.ExpressQueryResponseVo; import com.peanut.modules.book.vo.ShippingAddressRequestVo; import com.peanut.modules.book.vo.UserAddressVo; import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo; import com.peanut.modules.pay.weChatPay.service.WxpayService; import com.peanut.modules.sys.entity.SysConfigEntity; import com.peanut.modules.sys.service.SysConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.MessagePostProcessor; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; /** * 订单表 * * @author yl * @email yl328572838@163.com * @date 2022-08-29 15:27:44 */ @Slf4j @RestController @RequestMapping("book/buyOrder") public class BuyOrderController { @Autowired private BuyOrderService buyOrderService; @Autowired private ShopProductService shopProductService; @Autowired private BuyOrderDetailService buyOrderDetailService; @Autowired private CouponService couponService; @Autowired private CouponHistoryService couponHistoryService; @Autowired private OrderCartService orderCartService; @Autowired private MyUserService myUserService; @Autowired private TransactionDetailsService transactionDetailsService; @Autowired private UserEbookBuyService userEbookBuyService; @Autowired private WxpayService wxpayService; @Autowired private RabbitTemplate rabbitTemplate; @Autowired private ShopProductBookService shopProductBookService; @Autowired private ExpressOrderService expressOrderService; @Autowired private UserAddressService userAddressService; @Autowired private ExpressFeeService expressFeeService; @Autowired private SysConfigService sysConfigService; @RequestMapping(value = "/decomposeShipment", method = RequestMethod.GET) public R decomposeShipment(@RequestParam("userId") Integer userId) { Map> result = buyOrderService.decomposeShipment(userId); return R.ok().put("result", result); } // TODO 新版本上线后废弃 @RequestMapping("/list") public R list(@RequestParam Map params) throws Exception { PageUtils page = buyOrderService.list(params); return R.ok().put("page", page); } /** * 订单列表 * * @param requestVo request value object * @return R */ @RequestMapping(path = "/orderList", method = RequestMethod.POST) public R orderList(@RequestBody BuyOrderListRequestVo requestVo) { PageUtils page = buyOrderService.orderList(requestVo); return R.ok().put("result", page); } /** * 订单详情 * * @param orderSn 订单号 * @return R */ @RequestMapping(path = "/orderDetail", method = RequestMethod.GET) public R orderDetail(@RequestParam("orderSn") String orderSn) { BuyOrderResponseVo buyOrderResponseVo = buyOrderService.orderDetail(orderSn); return R.ok().put("result", buyOrderResponseVo); } /** * 下单 * * @param buyOrder 订单 * @return R */ @RequestMapping("/buySave") @Transactional public R buySave(@RequestBody BuyOrder buyOrder) throws IOException { // 获取订单详情 List buyOrderDetails = buyOrder.getProducts(); // 订单总金额 BigDecimal totalPrice = new BigDecimal(0); // 遍历商品总价计算 for (BuyOrderDetail buyOrderDetail : buyOrderDetails) { Integer productId = buyOrderDetail.getProductId(); int quantity = buyOrderDetail.getQuantity(); ShopProduct product = shopProductService.getById(productId); BigDecimal price = getRealPrice(product); if (!handleStock(buyOrderDetail, product)) { return R.error(500, "库存不足"); } totalPrice = totalPrice.add(price.multiply(BigDecimal.valueOf(quantity))); buyOrderDetail.setProductName(product.getProductName()); buyOrderDetail.setProductPrice(product.getPrice()); int originWeight = product.getWeight(); int originWeightIntValue = originWeight / 100; int originWeightDecimalValue = originWeightIntValue % 100; buyOrderDetail.setWeight(BigDecimal.valueOf(originWeightIntValue).add(BigDecimal.valueOf(originWeightDecimalValue).divide(new BigDecimal(100), MathContext.DECIMAL64))); buyOrderDetail.setProductUrl(product.getProductImages()); buyOrderDetail.setOrderStatus(Constants.ORDER_STATUS_TO_BE_PAID); } totalPrice = totalPrice.subtract(useCouponAmount(buyOrder)); totalPrice = totalPrice.add(getShoppingAmount(buyOrder)); String orderSn = IdWorker.getTimeId().substring(0, 32); buyOrder.setOrderSn(orderSn); buyOrder.setPaymentDate(new Date()); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("id", buyOrder.getAddressId()); UserAddress userAddress = userAddressService.getOne(queryWrapper); UserAddressVo vo = new UserAddressVo(); vo = userAddressService.getAddressName(vo, userAddress.getRegionCode()); buyOrder.setProvince(vo.getProvince()); buyOrder.setCity(vo.getCity()); buyOrder.setDistrict(vo.getCounty()); buyOrder.setAddress(vo.getDetailAddress()); buyOrderService.save(buyOrder); for (BuyOrderDetail buyOrderDetail : buyOrderDetails) { buyOrderDetail.setOrderId(buyOrder.getOrderId()); buyOrderDetail.setUserId(buyOrder.getUserId()); if (Constants.BUY_TYPE_CART.equals(buyOrder.getBuyType())) { handleBuyCart(buyOrder, buyOrderDetail); } } buyOrderDetailService.saveBatch(buyOrderDetails); // 1. 虚拟币支付 if (Constants.PAYMENT_METHOD_VIRTUAL.equals(buyOrder.getPaymentMethod())) { buyOrder.setOrderStatus(Constants.ORDER_STATUS_TO_BE_SHIPPED); MyUserEntity user = this.myUserService.getById(buyOrder.getUserId()); if (usePeanutCoin(user, totalPrice)) { // 更新订单状态 buyOrderService.updateOrderStatus(user.getId(), buyOrder.getOrderSn(), "0"); recordTransaction(buyOrder, user, totalPrice); addEbookToUser(buyOrderDetails, buyOrder); } else { return R.error(500, "花生币余额不足!"); } } // 2. 微信支付 if (Constants.PAYMENT_METHOD_WECHAT_PAY.equals(buyOrder.getPaymentMethod())) { rabbitTemplate.convertAndSend( DelayQueueConfig.ORDER_TO_BE_PAY_EXCHANGE, DelayQueueConfig.ORDER_TO_BE_PAY_ROUTING_KEY, buyOrder.getOrderId(), messagePostProcessor() ); WechatPaymentInfo paymentInfo = new WechatPaymentInfo(); paymentInfo.setOrderSn(orderSn); paymentInfo.setBuyOrderId(buyOrder.getOrderId()); paymentInfo.setTotalAmount(totalPrice); wxpayService.prepay(paymentInfo); } Map result = new HashMap<>(); result.put("orderSn", buyOrder.getOrderSn()); result.put("money", totalPrice); return R.ok(result); } @RequestMapping(path = "/calculateTransportPrice", method = RequestMethod.POST) public R getTransportPrice(@RequestBody ProductTransportVo vo) { String regionCode = vo.getRegionCode(); List products = vo.getProducts(); BigDecimal totalWeight = new BigDecimal(0); for (ProductRequestVo product : products) { ShopProduct shopProduct = shopProductService.getById(product.getProductId()); BigDecimal weight = BigDecimal.valueOf(Double.valueOf(shopProduct.getWeight()) / 1000.0); totalWeight = totalWeight.add(weight.multiply(new BigDecimal(product.getQuantity()))); } totalWeight = totalWeight.setScale(0, RoundingMode.UP); QueryWrapper configQueryWrapper = new QueryWrapper<>(); configQueryWrapper.eq("param_key", "DEFAULT_EXPRESS"); SysConfigEntity config = sysConfigService.getOne(configQueryWrapper); BigDecimal expressFee = expressFeeService.calculateExpressFee(config.getParamValue(), totalWeight, regionCode); return R.ok().put("result", expressFee); } /** * 列表 */ @RequestMapping("/getMyOrderList") public R getMyOrderList(@RequestParam Map params) { PageUtils page = buyOrderService.getMyOrderList(params); return R.ok().put("page", page); } /** * 修改 */ @RequestMapping("/update") public R update(@RequestBody BuyOrder buyOrder) { buyOrderService.updateById(buyOrder); return R.ok(); } /** * 删除 */ @RequestMapping("/delete") public R delete(@RequestBody Integer[] orderIds) { buyOrderService.removeByIds(Arrays.asList(orderIds)); return R.ok(); } /** * app 端 取消订单 */ @RequestMapping("/appDelete") @Transactional public R appDelete(@RequestParam("orderId") Integer orderId) { //1. 判断订单状态 BuyOrder byId = buyOrderService.getById(orderId); if (byId != null) { //2. 判断当前订单是否存在优惠券 进行 回显 Integer couponId = byId.getCouponId(); if (couponId != null) { CouponHistoryEntity byId1 = couponHistoryService.getById(couponId); byId1.setUseStatus(0); couponHistoryService.updateById(byId1); } // 库存回滚 List buyOrderDetailEntities = buyOrderDetailService.getBaseMapper().selectList(new QueryWrapper() .eq("order_id", byId.getOrderId())); for (BuyOrderDetail buyOrderDetailEntity : buyOrderDetailEntities) { Integer productId = buyOrderDetailEntity.getProductId(); ShopProduct product = shopProductService.getById(productId); product.setProductStock(product.getProductStock() + buyOrderDetailEntity.getQuantity()); shopProductService.updateById(product); } buyOrderService.removeById(orderId); } return R.ok(); } /** * 充值专用订单生成接口 */ @RequestMapping("/rechargeSave") @Transactional public R rechargeSave(@RequestBody BuyOrder buyOrder) throws IOException { String timeId = IdWorker.getTimeId().substring(0, 32); buyOrder.setOrderSn(timeId); buyOrderService.save(buyOrder); //下单微信支付预付款订单 BuyOrder buyOrderEntity = buyOrderService.getBaseMapper().selectOne(new LambdaQueryWrapper().eq(BuyOrder::getOrderSn, timeId)); WechatPaymentInfo paymentInfo = new WechatPaymentInfo(); paymentInfo.setOrderSn(buyOrderEntity.getOrderSn()); paymentInfo.setBuyOrderId(Integer.valueOf(buyOrderEntity.getProductId())); paymentInfo.setTotalAmount(buyOrderEntity.getRealMoney()); wxpayService.prepay(paymentInfo); return R.ok().put("orderSn", timeId); } /** * 获取订单详情 * TODO 新版本上线后删除 * * @param orderId * @return */ @RequestMapping("/getOrderDetail") public R getOrderDetail(@RequestParam Integer orderId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(BuyOrder::getOrderId, orderId); BuyOrder one = buyOrderService.getOne(wrapper); if (one.equals(null)) { return R.error("order error:order is null"); } //添加用户信息 one.setUser(myUserService.getById(one.getUserId())); //添加商品信息 LambdaQueryWrapper wrapper1 = new LambdaQueryWrapper<>(); wrapper1.eq(BuyOrderDetail::getOrderId, orderId); List buyOrderDetailEntities = buyOrderDetailService.getBaseMapper().selectList(wrapper1); one.setProducts(buyOrderDetailEntities); return R.ok().put("detail", one); } /** * 获取订单详情 * * @param orderId 订单 ID * @return R */ @RequestMapping(value = "/getOrderInfo", method = RequestMethod.GET) public R appGetOrderInfo(@RequestParam("orderId") Integer orderId) { BuyOrder buyOrder = buyOrderService.getById(orderId); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("order_id", orderId); List buyOrderDetailList = buyOrderDetailService.list(queryWrapper); for (BuyOrderDetail buyOrderDetail : buyOrderDetailList) { ShopProduct prod = shopProductService.getById(buyOrderDetail.getProductId()); if (prod != null) { buyOrderDetail.setImage(prod.getProductImages()); } } return R.ok().put("result", buyOrder); } @RequestMapping(value = "/modifyOrderAddress", method = RequestMethod.POST) public R modifyOrderAddress(@RequestBody ShippingAddressRequestVo addressRequestVo) { BuyOrder buyOrder = buyOrderService.getById(addressRequestVo.getOrderId()); buyOrder.setProvince(addressRequestVo.getProvince()); buyOrder.setCity(addressRequestVo.getCity()); buyOrder.setDistrict(addressRequestVo.getCounty()); buyOrder.setShippingUser(addressRequestVo.getName()); buyOrder.setUserPhone(addressRequestVo.getMobile()); buyOrderService.updateById(buyOrder); return R.ok(); } /** * 查询订单快递 * * @param orderId 订单号 * @return R */ @RequestMapping(value = "/queryExpress", method = RequestMethod.GET) public R queryExpress(@RequestParam("orderId") Integer orderId) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("order_id", orderId); List buyOrderDetailList = buyOrderDetailService.list(queryWrapper); List result = new ArrayList<>(); for (BuyOrderDetail buyOrderDetail : buyOrderDetailList) { ExpressQueryResponseVo vo = new ExpressQueryResponseVo(); vo.setOrderDetailId(buyOrderDetail.getId()); ExpressQueryResponse expressQueryResponse = expressOrderService.queryExpressOrder(buyOrderDetail.getExpressCompanyCode(), buyOrderDetail.getExpressBillNo()); vo.setLogisticCode(expressQueryResponse.getLogisticCode()); vo.setTraces(expressQueryResponse.getTraces()); result.add(vo); } return R.ok().put("result", result); } /** * 检查可合并的订单信息 * * @return */ @RequestMapping("/checkOrder") public R checkOrder(@RequestParam Map params) { Page page = buyOrderService.checkOrder(params); return R.ok().put("page", page); } /** * 检查传来的orderId 是否有可合并的其他订单信息 * * @param orderIds * @return */ @RequestMapping("/checkMerge") public R checkMerge(@RequestBody Integer[] orderIds) { List list = buyOrderService.checkOrder(orderIds); return R.ok().put("list", list); } /** * 分包发货 * * @param expressCompanyCode 快递公司编码 * @param buyOrderDetailId 订单详情列表 * @return R */ @RequestMapping(value = "/delivery", method = RequestMethod.POST) public R delivery(@RequestParam("expressCompanyCode") String expressCompanyCode, @RequestBody List buyOrderDetailId) throws Exception { buyOrderService.delivery(expressCompanyCode, buyOrderDetailId); return R.ok(); } /** * 获取商品实际价格 * * @param product 商品信息 * @return 商品实际价格 */ private BigDecimal getRealPrice(ShopProduct product) { BigDecimal activityPrice = product.getActivityPrice(); return (activityPrice == null || activityPrice.equals(BigDecimal.ZERO)) ? product.getPrice() : activityPrice; } /** * 处理商品库存 * * @param buyOrderDetail * @param product * @return */ private boolean handleStock(BuyOrderDetail buyOrderDetail, ShopProduct product) { int quantity = buyOrderDetail.getQuantity(); if (product.getProductStock() - quantity < 0) { return false; } product.setProductStock(product.getProductStock() - quantity); product.setSumSales(product.getSumSales() + quantity); shopProductService.updateById(product); return true; } /** * 使用优惠券 * * @param buyOrder * @return */ private BigDecimal useCouponAmount(BuyOrder buyOrder) { Integer couponId = buyOrder.getCouponId(); if (couponId != null) { CouponHistoryEntity couponHistory = couponHistoryService.getById(couponId); couponHistory.setUseStatus(1); couponHistory.setUseTime(new Date()); couponHistory.setOrderId(Long.valueOf(buyOrder.getOrderId())); couponHistory.setOrderSn(buyOrder.getOrderSn()); CouponEntity coupon = couponService.getById(couponHistory.getCouponId()); return coupon.getCouponAmount(); } return BigDecimal.ZERO; } @RequestMapping("/modifyConsigneeAddress") public R modifyConsigneeAddress(@RequestBody ModifyOrderAddressRequestVo requestVo) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("order_sn", requestVo.getOrderSn()); BuyOrder buyOrder = buyOrderService.getOne(queryWrapper); buyOrder.setShippingUser(requestVo.getConsigneeName()); buyOrder.setUserPhone(requestVo.getConsigneeMobile()); buyOrder.setProvince(requestVo.getProvince()); buyOrder.setCity(requestVo.getCity()); buyOrder.setDistrict(requestVo.getCounty()); buyOrder.setAddress(requestVo.getAddress()); buyOrder.setAddressModified(1); buyOrderService.updateById(buyOrder); return R.ok(); } /** * 计算运费 * * @param buyOrder * @return */ private BigDecimal getShoppingAmount(BuyOrder buyOrder) { return buyOrder.getOrderMoney() == null ? BigDecimal.ZERO : buyOrder.getShippingMoney(); } /** * 使用虚拟币支付 * * @param user * @param totalPrice * @return */ private boolean usePeanutCoin(MyUserEntity user, BigDecimal totalPrice) { if (user.getPeanutCoin().compareTo(totalPrice) >= 0) { user.setPeanutCoin(user.getPeanutCoin().subtract(totalPrice)); this.myUserService.updateById(user); return true; } return false; } /** * 交易记录 * * @param buyOrder * @param user * @param totalPrice */ private void recordTransaction(BuyOrder buyOrder, MyUserEntity user, BigDecimal totalPrice) { TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity(); transactionDetailsEntity.setRemark("订单编号为 - " + buyOrder.getOrderSn()); transactionDetailsEntity.setUserId(user.getId()); transactionDetailsEntity.setUserName(user.getNickname()); transactionDetailsEntity.setChangeAmount(totalPrice.negate()); transactionDetailsEntity.setUserBalance(user.getPeanutCoin()); transactionDetailsEntity.setTel(user.getTel()); transactionDetailsEntity.setOrderType("购买商品"); transactionDetailsService.save(transactionDetailsEntity); } /** * 给用户添加电子书 * * @param products * @param buyOrder */ private void addEbookToUser(List products, BuyOrder buyOrder) { List productIds = products.stream().map(BuyOrderDetail::getProductId).collect(Collectors.toList()); for (Integer productId : productIds) { List collect = shopProductBookService.getBaseMapper().selectList(new LambdaQueryWrapper() .eq(ShopProductBookEntity::getProductId, productId) .eq(ShopProductBookEntity::getDelFlag, 0)).stream().map(ShopProductBookEntity::getBookId).collect(Collectors.toList()); userEbookBuyService.addBookForUser(buyOrder.getUserId(), collect); } } /** * 购物车 * * @param buyOrder * @param buyOrderDetail */ private void handleBuyCart(BuyOrder buyOrder, BuyOrderDetail buyOrderDetail) { List orderCartList = orderCartService.getBaseMapper().selectList(new QueryWrapper() .eq("user_id", buyOrder.getUserId()).eq("product_id", buyOrderDetail.getProductId())); if (orderCartList.size() > 0) { List collect = orderCartList.stream().map(OrderCartEntity::getCartId).collect(Collectors.toList()); orderCartService.removeByIds(collect); } } private MessagePostProcessor messagePostProcessor() { return message -> { //设置有效期30分钟 message.getMessageProperties().setExpiration(String.valueOf(30 * 60 * 1000)); return message; }; } }