From 6786006ed172208ec14dd6417dceb95e0faca64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9D=BE?= <8605635+zhang3064194730@user.noreply.gitee.com> Date: Wed, 20 Nov 2024 16:50:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=201.=E7=BE=8E=E5=9B=A2=E6=A0=B8=E9=94=80?= =?UTF-8?q?=E5=88=B8=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=202.=E9=80=80?= =?UTF-8?q?=E6=AC=BE=E6=94=AF=E6=8C=81=E4=BC=98=E6=83=A0=E5=88=B8=E7=A7=AF?= =?UTF-8?q?=E5=88=86=E9=80=80=E6=AC=BE=EF=BC=8C=E9=87=91=E9=A2=9D=E6=AF=94?= =?UTF-8?q?=E4=BE=8B=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ThirdPartyCouponController.java | 31 +++++ .../cashier/dto/shoptable/UpdateCartDTO.java | 2 + .../ysk/cashier/pojo/order/TbCashierCart.java | 4 + .../ysk/cashier/pojo/order/TbOrderDetail.java | 5 +- .../cn/ysk/cashier/resp/PhpCommonResp.java | 11 ++ .../service/ThirdPartyCouponService.java | 9 ++ .../impl/ThirdPartyCouponServiceImpl.java | 38 ++++++ .../impl/shopimpl/TbShopTableServiceImpl.java | 116 ++++++++++++++---- 8 files changed, 192 insertions(+), 24 deletions(-) create mode 100644 eladmin-system/src/main/java/cn/ysk/cashier/controller/ThirdPartyCouponController.java create mode 100644 eladmin-system/src/main/java/cn/ysk/cashier/resp/PhpCommonResp.java create mode 100644 eladmin-system/src/main/java/cn/ysk/cashier/service/ThirdPartyCouponService.java create mode 100644 eladmin-system/src/main/java/cn/ysk/cashier/service/impl/ThirdPartyCouponServiceImpl.java diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/controller/ThirdPartyCouponController.java b/eladmin-system/src/main/java/cn/ysk/cashier/controller/ThirdPartyCouponController.java new file mode 100644 index 00000000..a7579669 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/controller/ThirdPartyCouponController.java @@ -0,0 +1,31 @@ +package cn.ysk.cashier.controller; + +import cn.ysk.cashier.service.ThirdPartyCouponService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 三方团购券 + */ +@RestController +@RequestMapping("/api/thirdPartyCoupon") +public class ThirdPartyCouponController { + + private final ThirdPartyCouponService thirdPartyCouponService; + + public ThirdPartyCouponController(ThirdPartyCouponService thirdPartyCouponService) { + this.thirdPartyCouponService = thirdPartyCouponService; + } + + /** + * 获取美团绑定链接 + * @return 美团绑定链接 + */ + @GetMapping + public ResponseEntity getBindUrl() { + return ResponseEntity.ok(thirdPartyCouponService.getBindUrl()); + } +} diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/dto/shoptable/UpdateCartDTO.java b/eladmin-system/src/main/java/cn/ysk/cashier/dto/shoptable/UpdateCartDTO.java index 97b094c0..b7db4dfd 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/dto/shoptable/UpdateCartDTO.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/dto/shoptable/UpdateCartDTO.java @@ -22,5 +22,7 @@ public class UpdateCartDTO { private String note; private Boolean isPack; private Boolean isGift; + // 是否打印 + private Boolean isPrint; } diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbCashierCart.java b/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbCashierCart.java index 56264e2f..905e6d15 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbCashierCart.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbCashierCart.java @@ -15,6 +15,7 @@ */ package cn.ysk.cashier.pojo.order; +import cn.ysk.cashier.mybatis.entity.TbActivateOutRecord; import lombok.Data; import cn.hutool.core.bean.BeanUtil; import io.swagger.annotations.ApiModelProperty; @@ -173,6 +174,8 @@ public class TbCashierCart implements Serializable { private String unit; private BigDecimal discountSaleAmount; private String discountSaleNote; + private Boolean isPrint; + private String useCouponInfo; public void copy(TbCashierCart source) { BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true)); @@ -211,4 +214,5 @@ public class TbCashierCart implements Serializable { } } + } diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbOrderDetail.java b/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbOrderDetail.java index fa7c253c..dad7060d 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbOrderDetail.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/pojo/order/TbOrderDetail.java @@ -15,6 +15,7 @@ */ package cn.ysk.cashier.pojo.order; +import cn.ysk.cashier.mybatis.entity.TbActivateOutRecord; import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; import cn.hutool.core.bean.BeanUtil; @@ -133,9 +134,11 @@ public class TbOrderDetail implements Serializable { private Integer isMember; private Integer isTemporary; private String discountSaleNote; - + private Boolean isPrint; + private String useCouponInfo; public void copy(TbOrderDetail source){ BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); } + } diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/resp/PhpCommonResp.java b/eladmin-system/src/main/java/cn/ysk/cashier/resp/PhpCommonResp.java new file mode 100644 index 00000000..afe66147 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/resp/PhpCommonResp.java @@ -0,0 +1,11 @@ +package cn.ysk.cashier.resp; + +import lombok.Data; + +@Data +public class PhpCommonResp { + private String code; + private String msg; + private long time; + private T data; +} diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/service/ThirdPartyCouponService.java b/eladmin-system/src/main/java/cn/ysk/cashier/service/ThirdPartyCouponService.java new file mode 100644 index 00000000..9fc82d46 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/service/ThirdPartyCouponService.java @@ -0,0 +1,9 @@ +package cn.ysk.cashier.service; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +public interface ThirdPartyCouponService { + + String getBindUrl(); +} diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/ThirdPartyCouponServiceImpl.java b/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/ThirdPartyCouponServiceImpl.java new file mode 100644 index 00000000..50f50a69 --- /dev/null +++ b/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/ThirdPartyCouponServiceImpl.java @@ -0,0 +1,38 @@ +package cn.ysk.cashier.service.impl; + +import cn.ysk.cashier.exception.BadRequestException; +import cn.ysk.cashier.resp.PhpCommonResp; +import cn.ysk.cashier.service.ThirdPartyCouponService; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class ThirdPartyCouponServiceImpl implements ThirdPartyCouponService { + + @Value("${phpServer}") + private String phpServerUrl; + + public ThirdPartyCouponServiceImpl(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + private final RestTemplate restTemplate; + + private T getData(String url, Object data) { + PhpCommonResp resp = restTemplate.getForEntity(phpServerUrl + url, PhpCommonResp.class).getBody(); + if (resp == null) { + throw new BadRequestException("请求php服务器失败"); + } + + if (!"1".equals(resp.getCode())) { + throw new BadRequestException(resp.getMsg()); + } + + return (T) resp.getData(); + } + + @Override + public String getBindUrl() { + return getData("/meituan/getuisdkurl", null); + } +} diff --git a/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/shopimpl/TbShopTableServiceImpl.java b/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/shopimpl/TbShopTableServiceImpl.java index 632c3cc5..5bdc5a10 100644 --- a/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/shopimpl/TbShopTableServiceImpl.java +++ b/eladmin-system/src/main/java/cn/ysk/cashier/service/impl/shopimpl/TbShopTableServiceImpl.java @@ -2,6 +2,7 @@ package cn.ysk.cashier.service.impl.shopimpl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; @@ -454,6 +455,7 @@ public class TbShopTableServiceImpl implements TbShopTableService { tbCashierCart.setSalePrice(tbCashierCart.getSalePrice()); tbCashierCart.setTotalAmount(updateCartDTO.getNum().multiply(tbCashierCart.getSalePrice())); tbCashierCart.setNote(updateCartDTO.getNote()); + tbCashierCart.setIsPrint(updateCartDTO.getIsPrint()); if (updateCartDTO.getIsPack() != null) { if (!updateCartDTO.getIsPack()) { @@ -1308,13 +1310,12 @@ public class TbShopTableServiceImpl implements TbShopTableService { // 创建结余购物车 balanceCart = BeanUtil.copyProperties(cashierCart, TbCashierCart.class); - BigDecimal num = balanceNum; balanceCart.setUserCouponId(null); balanceCart.setId(null); balanceCart.setNumber(balanceNum); balanceCart.setTotalNumber(balanceNum); - balanceCart.setPackFee(singlePackFee.multiply(num)); - balanceCart.setTotalAmount(cashierCart.getTotalAmountByNum(balanceNum).add(singlePackFee.multiply(num))); + balanceCart.setPackFee(singlePackFee.multiply(balanceNum)); + balanceCart.setTotalAmount(cashierCart.getTotalAmountByNum(balanceNum).add(singlePackFee.multiply(balanceNum))); balanceCartList.add(balanceCart); } else { currentUseNum =cashierCart.getNumber(); @@ -1334,6 +1335,7 @@ public class TbShopTableServiceImpl implements TbShopTableService { tbActivateOutRecord.setCreateTime(DateUtil.date()); tbActivateOutRecord.setRefNum(0); outRecords.add(tbActivateOutRecord); + cashierCart.setUseCouponInfo(JSONObject.toJSONString(tbActivateOutRecord)); couponVo.setFinalDiscountAmount(discountAmount); // 优惠券未消耗完毕 @@ -1526,6 +1528,7 @@ public class TbShopTableServiceImpl implements TbShopTableService { } + /** * 根据商品优惠券 * @@ -1609,6 +1612,9 @@ public class TbShopTableServiceImpl implements TbShopTableService { orderDetail.setIsTemporary(cashierCart.getIsTemporary()); orderDetail.setOrderId(orderInfo == null ? null : orderInfo.getId()); orderDetail.setIsMember(cashierCart.getIsMember()); + orderDetail.setIsPrint(cashierCart.getIsPrint()); + orderDetail.setUseCouponInfo(cashierCart.getUseCouponInfo()); + priceDTO.getOrderDetailList().add(orderDetail); } return priceDTO; @@ -2138,6 +2144,34 @@ public class TbShopTableServiceImpl implements TbShopTableService { return orderInfo.getOrderAmount(); } + /** + * 根据折扣设置订单信息 + */ + private BigDecimal resetAmountByDiscount(PayDTO payDTO, TbOrderInfo orderInfo) { + List cashierCarts = mpCashierCartService.selectByOrderIdAndState(orderInfo.getId()); + List detailList = mpOrderDetailService.selectByOrderId(orderInfo.getId()); + BigDecimal discount = BigDecimal.valueOf(payDTO.getDiscount()); + cashierCarts.forEach(item -> { + item.setTotalAmount(item.getTotalAmount().multiply(discount).setScale(2, RoundingMode.HALF_UP)); + }); + + detailList.forEach(item -> { + item.setPriceAmount(item.getPriceAmount().multiply(discount).setScale(2, RoundingMode.HALF_UP)); + }); + + mpCashierCartService.updateBatchById(cashierCarts); + mpOrderDetailService.updateBatchById(detailList); + BigDecimal oldAmount = orderInfo.getOrderAmount(); + BigDecimal finalAmount = orderInfo.getOrderAmount().multiply(BigDecimal.valueOf(payDTO.getDiscount())).setScale(2, RoundingMode.HALF_UP); + BigDecimal discountAmount = oldAmount.subtract(finalAmount); + orderInfo.setDiscountAmount(discountAmount); + orderInfo.setOrderAmount(finalAmount); + orderInfo.setAmount(finalAmount); + orderInfo.setSettlementAmount(finalAmount); + mpOrderInfoService.updateById(orderInfo); + return finalAmount; + } + @Override // @Transactional public Object pay(PayDTO payDTO) { @@ -2157,8 +2191,6 @@ public class TbShopTableServiceImpl implements TbShopTableService { payDTO.setVipUserId(orderInfo.getMemberId() != null ? Integer.valueOf(orderInfo.getMemberId()) : null); } - - if (ObjectUtil.isEmpty(orderInfo)) { throw new BadRequestException("订单不存在"); } @@ -2172,17 +2204,20 @@ public class TbShopTableServiceImpl implements TbShopTableService { payDTO.setDiscount((double) 1); } - // 计算优惠券积分折扣信息 BigDecimal finalAmount = null; + // 计算订单折扣信息 + if (payDTO.getDiscount() != 1) { + finalAmount = resetAmountByDiscount(payDTO, orderInfo); + }else { + finalAmount = orderInfo.getOrderAmount(); + } + + // 计算优惠券积分折扣信息 if (payDTO.getVipUserId() != null) { // 计算商品券折扣 finalAmount = calcDiscountAndUpdateInfo(payDTO, orderInfo); } - if (finalAmount == null) { - finalAmount = orderInfo.getOrderAmount().multiply(BigDecimal.valueOf(payDTO.getDiscount())).setScale(2, RoundingMode.HALF_UP); - } - boolean isOnline = false; switch (payDTO.getPayType()) { @@ -2671,15 +2706,15 @@ public class TbShopTableServiceImpl implements TbShopTableService { throw new BadRequestException("订单明细数量不一致"); } + HashMap data = new HashMap<>(); BigDecimal returnAmount = BigDecimal.ZERO; BigDecimal packAMount = BigDecimal.ZERO; BigDecimal saleAmount = BigDecimal.ZERO; ArrayList remainOrderDetailList = new ArrayList<>(); for (TbOrderDetail orderDetail : detailList) { - if (orderDetail.getUserCouponId() != null) { - throw new BadRequestException("选择了优惠券抵扣商品,无法退款"); - } + // 退款数量 BigDecimal returnNum = returnNumMap.get(orderDetail.getId().toString()); + // 剩余数量 BigDecimal remainNum = orderDetail.getNum().subtract(returnNum); if (remainNum.compareTo(BigDecimal.ZERO) < 0) { throw new BadRequestException("{}最多可退数量为: {}", orderDetail.getProductName(), orderDetail.getNum()); @@ -2700,14 +2735,6 @@ public class TbShopTableServiceImpl implements TbShopTableService { remainOrderDetailList.add(remainOrderDetail); } - returnAmount = returnAmount.add(orderDetail.getPriceAmount() - .divide(orderDetail.getNum(), 2, RoundingMode.DOWN) - .multiply(returnNum)); - saleAmount = saleAmount.add(orderDetail.getPrice()); - packAMount = packAMount.add(orderDetail.getPackAmount() - .divide(orderDetail.getNum(), 2, RoundingMode.DOWN) - .multiply(returnNum)); - BigDecimal returnPackFee = packFee.multiply(returnNum); orderDetail.setNum(returnNum); orderDetail.setPriceAmount(returnNum.multiply(orderDetail.getPrice()) @@ -2716,6 +2743,34 @@ public class TbShopTableServiceImpl implements TbShopTableService { orderDetail.setRefundNumber(returnNum); // orderDetail.setStatus(isOnline ? "refunding" : "refund"); orderDetail.setStatus("refund"); + // 优惠券抵扣商品直接退券 + if (StrUtil.isNotBlank(orderDetail.getUseCouponInfo())) { + data.put("isCouponDiscount", true); + TbActivateOutRecord outRecord = JSONObject.parseObject(orderDetail.getUseCouponInfo(), TbActivateOutRecord.class); + outRecord.setRefNum(returnNum.intValue()); + shopCouponService.refund(CollUtil.newArrayList(outRecord)); + // 使用了满减或积分,获取普通付款商品计算退款比例,退部分现金 + }else if (oldOrderInfo.getFullCouponDiscountAmount().compareTo(BigDecimal.ZERO) > 0 || oldOrderInfo.getPointsDiscountAmount().compareTo(BigDecimal.ZERO) > 0){ + // 计算当前商品占比 + BigDecimal ratio = calcDetailRatio(orderDetail); + BigDecimal realAmount = orderDetail.getPriceAmount().multiply(ratio); + returnAmount = returnAmount.add(realAmount + .divide(orderDetail.getNum(), 2, RoundingMode.DOWN) + .multiply(returnNum)); + saleAmount = saleAmount.add(orderDetail.getPrice()); + packAMount = packAMount.add(orderDetail.getPackAmount() + .divide(orderDetail.getNum(), 2, RoundingMode.DOWN) + .multiply(returnNum)); + + }else { + returnAmount = returnAmount.add(orderDetail.getPriceAmount() + .divide(orderDetail.getNum(), 2, RoundingMode.DOWN) + .multiply(returnNum)); + saleAmount = saleAmount.add(orderDetail.getPrice()); + packAMount = packAMount.add(orderDetail.getPackAmount() + .divide(orderDetail.getNum(), 2, RoundingMode.DOWN) + .multiply(returnNum)); + } } if (returnAmount.compareTo(BigDecimal.ZERO) <= 0) { @@ -2757,12 +2812,23 @@ public class TbShopTableServiceImpl implements TbShopTableService { updateStockAndRecord(detailList); mpOrderDetailService.updateBatchById(detailList); - HashMap data = new HashMap<>(); data.put("returnOrder", returnOrder); data.put("returnAmount", returnAmount); return data; } + private BigDecimal calcDetailRatio(TbOrderDetail orderDetail) { + List detailList = mpOrderDetailService.selectByOrderIdAndState(orderDetail.getId(), TableConstant.OrderInfo.Status.CLOSED); + BigDecimal totalAmount = BigDecimal.ZERO; + for (TbOrderDetail item : detailList) { + if (item.getUserCouponId() == null) { + totalAmount = totalAmount.add(item.getPriceAmount()); + } + } + + return orderDetail.getPriceAmount().divide(totalAmount, 2, RoundingMode.HALF_UP); + } + private void updateStockAndRecord(List orderDetailList) { // 更新商品库存 for (TbOrderDetail detail : orderDetailList) { @@ -2826,7 +2892,7 @@ public class TbShopTableServiceImpl implements TbShopTableService { String shopId = orderInfo.getShopId(); // // 线上退款 - orderInfo.setRefundAmount(returnOrderInfo.getRefundAmount()); + orderInfo.setRefundAmount(orderInfo.getRefundAmount().add(returnOrderInfo.getRefundAmount())); orderInfo.setRefundRemark(returnOrderDTO.getNote()); if ("scanCode".equals(payType) || "wx_lite".equals(payType)) { payService.returnOrder(Integer.valueOf(shopId), orderInfo, returnOrderInfo); @@ -2842,6 +2908,10 @@ public class TbShopTableServiceImpl implements TbShopTableService { returnOrderDTO.getOrderId(), returnOrderDTO.getOrderDetails().stream().map(ReturnOrderDTO.OrderDetail::getId).collect(Collectors.toList())); } orderInfo.setStatus(TableConstant.OrderInfo.Status.CLOSED.getValue()); + // 订单金额全退,退优惠券以及积分 + if (orderInfo.getPayAmount().compareTo(orderInfo.getRefundAmount()) <= 0) { + returnCoupon(orderInfo); + } orderInfoMapper.updateById(orderInfo); // 打印退款小票 // producer.printMechine(newOrderInfo.getId().toString());