Files
nuttyreading-java/src/main/java/com/peanut/modules/book/controller/BuyOrderController.java
2023-10-19 17:22:35 +08:00

552 lines
21 KiB
Java

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.ProductRequestVo;
import com.peanut.modules.book.vo.request.ProductTransportVo;
import com.peanut.modules.book.vo.response.BuyOrderListResponseVo;
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;
/**
* 订单列表
*
* @param params
* @return
* @throws Exception
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> 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) {
List<BuyOrderListResponseVo> response = buyOrderService.orderList(requestVo);
return R.ok().put("result", response);
}
/**
* 下单
*
* @param buyOrder 订单
* @return R
*/
@RequestMapping("/buySave")
@Transactional
public R buySave(@RequestBody BuyOrder buyOrder) throws IOException {
// 获取订单详情
List<BuyOrderDetail> 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<UserAddress> 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<String, Object> 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<ProductRequestVo> 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<SysConfigEntity> 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<String, Object> 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<BuyOrderDetail> buyOrderDetailEntities = buyOrderDetailService.getBaseMapper().selectList(new QueryWrapper<BuyOrderDetail>()
.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<BuyOrder>().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);
}
/**
* 获取订单详情
*
* @param orderId
* @return
*/
@RequestMapping("/getOrderDetail")
public R getOrderDetail(@RequestParam Integer orderId) {
LambdaQueryWrapper<BuyOrder> 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<BuyOrderDetail> wrapper1 = new LambdaQueryWrapper<>();
wrapper1.eq(BuyOrderDetail::getOrderId, orderId);
List<BuyOrderDetail> 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<BuyOrderDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_id", orderId);
List<BuyOrderDetail> 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<BuyOrderDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_id", orderId);
List<BuyOrderDetail> buyOrderDetailList = buyOrderDetailService.list(queryWrapper);
List<ExpressQueryResponseVo> 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<String, Object> 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<Integer> 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;
}
/**
* 计算运费
*
* @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<BuyOrderDetail> products, BuyOrder buyOrder) {
List<Integer> productIds = products.stream().map(BuyOrderDetail::getProductId).collect(Collectors.toList());
for (Integer productId : productIds) {
List<Integer> collect = shopProductBookService.getBaseMapper().selectList(new LambdaQueryWrapper<ShopProductBookEntity>()
.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<OrderCartEntity> orderCartList = orderCartService.getBaseMapper().selectList(new QueryWrapper<OrderCartEntity>()
.eq("user_id", buyOrder.getUserId()).eq("product_id", buyOrderDetail.getProductId()));
if (orderCartList.size() > 0) {
List<Integer> 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;
};
}
}