更新了优惠券模块
This commit is contained in:
parent
9082882cab
commit
f1dfd35960
|
@ -1,8 +1,6 @@
|
||||||
package com.cultural.heritage.controller.good;
|
package com.cultural.heritage.controller.good;
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.date.DateTime;
|
|
||||||
import cn.hutool.core.date.DateUnit;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
|
@ -11,7 +9,6 @@ import com.cultural.heritage.annotation.AuthCheck;
|
||||||
import com.cultural.heritage.common.BaseResponse;
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.common.ResultUtils;
|
import com.cultural.heritage.common.ResultUtils;
|
||||||
import com.cultural.heritage.constant.MqConstant;
|
|
||||||
import com.cultural.heritage.constant.UserConstant;
|
import com.cultural.heritage.constant.UserConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
|
@ -30,14 +27,12 @@ import com.cultural.heritage.model.vo.coupon.UserCouponVO;
|
||||||
import com.cultural.heritage.service.good.CouponService;
|
import com.cultural.heritage.service.good.CouponService;
|
||||||
import com.cultural.heritage.service.good.UserCouponService;
|
import com.cultural.heritage.service.good.UserCouponService;
|
||||||
import com.cultural.heritage.service.user.UserService;
|
import com.cultural.heritage.service.user.UserService;
|
||||||
import com.cultural.heritage.utils.MultiDelayMessage;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
@ -65,8 +60,6 @@ public class CouponController {
|
||||||
private UserCouponService userCouponService;
|
private UserCouponService userCouponService;
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,18 +93,8 @@ public class CouponController {
|
||||||
boolean result = couponService.save(coupon);
|
boolean result = couponService.save(coupon);
|
||||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "优惠券添加失败");
|
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "优惠券添加失败");
|
||||||
|
|
||||||
// 延迟检查优惠券是否过期
|
// 向消息队列中发送优惠券创建的消息
|
||||||
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(coupon.getId());
|
couponService.sendCouponCreateMessage(coupon);
|
||||||
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
|
||||||
MqConstant.DELAY_COUPON_ROUTING_KEY, msg, message -> {
|
|
||||||
//计算优惠券截止日期和当前的时间差
|
|
||||||
DateTime now = new DateTime();
|
|
||||||
DateTime end = DateUtil.parse(coupon.getEndTime());
|
|
||||||
long seconds = DateUtil.between(now, end, DateUnit.SECOND);
|
|
||||||
// 添加延迟消息属性
|
|
||||||
message.getMessageProperties().setDelay((int) (seconds * 1000));
|
|
||||||
return message;
|
|
||||||
});
|
|
||||||
|
|
||||||
return ResultUtils.success(true);
|
return ResultUtils.success(true);
|
||||||
}
|
}
|
||||||
|
@ -251,18 +234,8 @@ public class CouponController {
|
||||||
boolean save = userCouponService.save(userCoupon);
|
boolean save = userCouponService.save(userCoupon);
|
||||||
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "兑换记录插入失败");
|
ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "兑换记录插入失败");
|
||||||
|
|
||||||
// 延迟检查优惠券是否过期
|
// 向消息队列中发送用户优惠券创建的消息
|
||||||
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(userCoupon.getId());
|
couponService.sendUserCouponCreateMessage(userCoupon, coupon);
|
||||||
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
|
||||||
MqConstant.DELAY_USER_COUPON_ROUTING_KEY, msg, message -> {
|
|
||||||
//计算优惠券截止日期和当前的时间差
|
|
||||||
DateTime now = new DateTime();
|
|
||||||
DateTime end = DateUtil.parse(coupon.getEndTime());
|
|
||||||
long seconds = DateUtil.between(now, end, DateUnit.SECOND);
|
|
||||||
// 添加延迟消息属性
|
|
||||||
message.getMessageProperties().setDelay((int) (seconds * 1000));
|
|
||||||
return message;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 更新用户积分
|
// 更新用户积分
|
||||||
loginUser.setPoints(loginUser.getPoints() - requirePoints);
|
loginUser.setPoints(loginUser.getPoints() - requirePoints);
|
||||||
|
@ -388,8 +361,8 @@ public class CouponController {
|
||||||
if (usableCouponQueryRequest == null) {
|
if (usableCouponQueryRequest == null) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
BigDecimal conditionAmount = usableCouponQueryRequest.getConditionAmount();
|
BigDecimal currentAmount = usableCouponQueryRequest.getCurrentAmount();
|
||||||
if (conditionAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
if (currentAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单金额参数错误");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单金额参数错误");
|
||||||
}
|
}
|
||||||
User loginUser = userService.getLoginUser(request);
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
@ -403,9 +376,9 @@ public class CouponController {
|
||||||
// 获取(不)可使用的优惠券
|
// 获取(不)可使用的优惠券
|
||||||
List<UserCoupon> userCoupons = userCouponList.stream().filter(userCoupon -> {
|
List<UserCoupon> userCoupons = userCouponList.stream().filter(userCoupon -> {
|
||||||
CouponVO couponVO = userCoupon.getCouponVO();
|
CouponVO couponVO = userCoupon.getCouponVO();
|
||||||
BigDecimal couponAmount = couponVO.getConditionAmount();
|
BigDecimal standardAmount = couponVO.getStandardAmount();
|
||||||
Boolean isAvailable = usableCouponQueryRequest.getIsAvailable();
|
Boolean isAvailable = usableCouponQueryRequest.getIsAvailable();
|
||||||
int result = conditionAmount.compareTo(couponAmount);
|
int result = currentAmount.compareTo(standardAmount);
|
||||||
return isAvailable == (result >= 0);
|
return isAvailable == (result >= 0);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import com.cultural.heritage.annotation.AuthCheck;
|
||||||
import com.cultural.heritage.common.BaseResponse;
|
import com.cultural.heritage.common.BaseResponse;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.common.ResultUtils;
|
import com.cultural.heritage.common.ResultUtils;
|
||||||
import com.cultural.heritage.constant.MqConstant;
|
|
||||||
import com.cultural.heritage.constant.OrderStatusConstant;
|
import com.cultural.heritage.constant.OrderStatusConstant;
|
||||||
import com.cultural.heritage.constant.UserConstant;
|
import com.cultural.heritage.constant.UserConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
|
@ -17,23 +16,23 @@ import com.cultural.heritage.model.dto.cart.CartOrderAddRequest;
|
||||||
import com.cultural.heritage.model.dto.cart.CartOrderItemAddRequest;
|
import com.cultural.heritage.model.dto.cart.CartOrderItemAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.OrderQueryRequest;
|
import com.cultural.heritage.model.dto.order.OrderQueryRequest;
|
||||||
import com.cultural.heritage.model.dto.order.OrderUpdateRequest;
|
import com.cultural.heritage.model.dto.order.OrderUpdateRequest;
|
||||||
|
import com.cultural.heritage.model.dto.order.capital.GeneralGoodSingleBuyAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.capital.OrderItemMainInfoAddRequest;
|
import com.cultural.heritage.model.dto.order.capital.OrderItemMainInfoAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.capital.OrderMainInfoAddRequest;
|
import com.cultural.heritage.model.dto.order.capital.OrderMainInfoAddRequest;
|
||||||
import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
|
import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
|
||||||
import com.cultural.heritage.model.entity.*;
|
import com.cultural.heritage.model.entity.*;
|
||||||
import com.cultural.heritage.model.vo.order.OrderVO;
|
import com.cultural.heritage.model.vo.order.OrderVO;
|
||||||
import com.cultural.heritage.service.good.CartRecordService;
|
import com.cultural.heritage.service.good.CartRecordService;
|
||||||
|
import com.cultural.heritage.service.good.CouponService;
|
||||||
import com.cultural.heritage.service.good.GoodService;
|
import com.cultural.heritage.service.good.GoodService;
|
||||||
import com.cultural.heritage.service.order.OrderItemService;
|
import com.cultural.heritage.service.order.OrderItemService;
|
||||||
import com.cultural.heritage.service.order.OrderService;
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
import com.cultural.heritage.service.user.UserService;
|
import com.cultural.heritage.service.user.UserService;
|
||||||
import com.cultural.heritage.utils.MultiDelayMessage;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
@ -78,9 +77,10 @@ public class OrderController {
|
||||||
private GoodService goodService;
|
private GoodService goodService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RabbitTemplate rabbitTemplate;
|
private CouponService couponService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,14 +98,14 @@ public class OrderController {
|
||||||
User loginUser = userService.getLoginUser(request);
|
User loginUser = userService.getLoginUser(request);
|
||||||
Long userId = loginUser.getId();
|
Long userId = loginUser.getId();
|
||||||
|
|
||||||
// 封装成订单创建请求体
|
|
||||||
OrderMainInfoAddRequest orderMainInfoAddRequest = new OrderMainInfoAddRequest();
|
|
||||||
BeanUtils.copyProperties(cartOrderAddRequest, orderMainInfoAddRequest);
|
|
||||||
|
|
||||||
// 校验购物车数据是否准确
|
// 校验购物车数据是否准确
|
||||||
List<CartOrderItemAddRequest> cartOrderItemAddRequestList = cartOrderAddRequest.getCartOrderItemAddRequestList();
|
List<CartOrderItemAddRequest> cartOrderItemAddRequestList = cartOrderAddRequest.getCartOrderItemAddRequestList();
|
||||||
boolean isAccurate = cartRecordService.validIsConsistent(cartOrderItemAddRequestList);
|
boolean isAccurate = cartRecordService.validIsConsistent(cartOrderItemAddRequestList);
|
||||||
ThrowUtils.throwIf(!isAccurate, ErrorCode.SYSTEM_ERROR, "当前购物车中的某些商品已下架或者库存不足,无法生成订单");
|
ThrowUtils.throwIf(!isAccurate, ErrorCode.OPERATION_ERROR, "当前购物车中的某些商品已下架或者库存不足,无法生成订单");
|
||||||
|
|
||||||
|
// 封装成订单主要信息请求体
|
||||||
|
OrderMainInfoAddRequest orderMainInfoAddRequest = new OrderMainInfoAddRequest();
|
||||||
|
BeanUtils.copyProperties(cartOrderAddRequest, orderMainInfoAddRequest);
|
||||||
|
|
||||||
// 获取购物车id列表
|
// 获取购物车id列表
|
||||||
List<Long> cartIds = cartOrderItemAddRequestList.stream().map(CartOrderItemAddRequest::getCartRecordId).toList();
|
List<Long> cartIds = cartOrderItemAddRequestList.stream().map(CartOrderItemAddRequest::getCartRecordId).toList();
|
||||||
|
@ -140,6 +140,11 @@ public class OrderController {
|
||||||
Integer quantity = map.get(cartRecordId);
|
Integer quantity = map.get(cartRecordId);
|
||||||
totalAmount = totalAmount.add(good.getPrice().multiply(BigDecimal.valueOf(quantity)));
|
totalAmount = totalAmount.add(good.getPrice().multiply(BigDecimal.valueOf(quantity)));
|
||||||
}
|
}
|
||||||
|
Long couponId = orderMainInfoAddRequest.getCouponId();
|
||||||
|
Coupon coupon = couponService.getById(couponId);
|
||||||
|
ThrowUtils.throwIf(coupon == null, ErrorCode.OPERATION_ERROR, "优惠券不存在");
|
||||||
|
BigDecimal conditionAmount = coupon.getConditionAmount();
|
||||||
|
totalAmount = totalAmount.subtract(conditionAmount);
|
||||||
|
|
||||||
orderMainInfoAddRequest.setTotalAmount(totalAmount);
|
orderMainInfoAddRequest.setTotalAmount(totalAmount);
|
||||||
// 封装成订单明细主要信息请求体列表
|
// 封装成订单明细主要信息请求体列表
|
||||||
|
@ -157,17 +162,8 @@ public class OrderController {
|
||||||
// 创建通用订单(常规类和服务类商品)
|
// 创建通用订单(常规类和服务类商品)
|
||||||
Long orderId = orderService.createCommonOrder(orderMainInfoAddRequest, userId, true, cartIds);
|
Long orderId = orderService.createCommonOrder(orderMainInfoAddRequest, userId, true, cartIds);
|
||||||
|
|
||||||
// 延迟检查订单状态信息
|
// 向消息队列中发送订单创建的消息
|
||||||
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderId,
|
orderService.sendCreateOrderMessage(orderId);
|
||||||
10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L);
|
|
||||||
// 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L
|
|
||||||
int delayValue = msg.removeNextDelay().intValue();
|
|
||||||
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
|
||||||
MqConstant.DELAY_ORDER_ROUTING_KEY, msg, message -> {
|
|
||||||
// 添加延迟消息属性
|
|
||||||
message.getMessageProperties().setDelay(delayValue);
|
|
||||||
return message;
|
|
||||||
});
|
|
||||||
|
|
||||||
return ResultUtils.success(orderId);
|
return ResultUtils.success(orderId);
|
||||||
}
|
}
|
||||||
|
@ -176,38 +172,36 @@ public class OrderController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 小程序端用户创建常规类商品订单
|
* 小程序端用户创建常规类商品订单
|
||||||
* @param orderMainInfoAddRequest 订单创建请求体
|
* @param generalGoodSingleBuyAddRequest 常规类类商品单独购买创建请求体
|
||||||
* @return 是否创建成功
|
* @return 是否创建成功
|
||||||
*/
|
*/
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Operation(summary = "小程序端用户创建常规类商品订单", description = "参数:订单创建请求体,权限:所有人,方法名:addOrder")
|
@Operation(summary = "小程序端用户创建常规类商品订单", description = "参数:订单创建请求体,权限:所有人,方法名:addOrder")
|
||||||
public BaseResponse<Long> addOrder(@RequestBody OrderMainInfoAddRequest orderMainInfoAddRequest, HttpServletRequest request) {
|
public BaseResponse<Long> addOrder(@RequestBody GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest, HttpServletRequest request) {
|
||||||
if (orderMainInfoAddRequest == null) {
|
if (generalGoodSingleBuyAddRequest == null) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
}
|
}
|
||||||
// 校验用户当前是否处于登录态
|
// 校验用户当前是否处于登录态
|
||||||
User loginUser = userService.getLoginUser(request);
|
User loginUser = userService.getLoginUser(request);
|
||||||
Long userId = loginUser.getId();
|
Long userId = loginUser.getId();
|
||||||
|
|
||||||
// 校验单独购买的商品数据是否准确
|
// 校验单独购买的商品数据是否准确
|
||||||
orderService.validSingleGoodOrder(orderMainInfoAddRequest);
|
orderService.validSingleGoodOrder(generalGoodSingleBuyAddRequest);
|
||||||
|
|
||||||
|
// 封装成订单主要信息请求体
|
||||||
|
OrderMainInfoAddRequest orderMainInfoAddRequest = new OrderMainInfoAddRequest();
|
||||||
|
BeanUtils.copyProperties(generalGoodSingleBuyAddRequest, orderMainInfoAddRequest);
|
||||||
|
|
||||||
// 计算单个商品购买的总金额
|
// 计算单个商品购买的总金额
|
||||||
BigDecimal totalAmount = orderService.calculateTotalAmount(orderMainInfoAddRequest);
|
BigDecimal totalAmount = orderService.calculateTotalAmount(orderMainInfoAddRequest);
|
||||||
orderMainInfoAddRequest.setTotalAmount(totalAmount);
|
orderMainInfoAddRequest.setTotalAmount(totalAmount);
|
||||||
// 创建通用订单(常规类和服务类商品)
|
// 创建通用订单(常规类和服务类商品)
|
||||||
Long orderId = orderService.createCommonOrder(orderMainInfoAddRequest, userId, false, null);
|
Long orderId = orderService.createCommonOrder(orderMainInfoAddRequest, userId, false, null);
|
||||||
|
|
||||||
// 延迟检查订单状态信息
|
// 向消息队列中发送订单创建的消息
|
||||||
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderId,
|
orderService.sendCreateOrderMessage(orderId);
|
||||||
10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L);
|
|
||||||
// 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L
|
|
||||||
int delayValue = msg.removeNextDelay().intValue();
|
|
||||||
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
|
||||||
MqConstant.DELAY_ORDER_ROUTING_KEY, msg, message -> {
|
|
||||||
// 添加延迟消息属性
|
|
||||||
message.getMessageProperties().setDelay(delayValue);
|
|
||||||
return message;
|
|
||||||
});
|
|
||||||
return ResultUtils.success(orderId);
|
return ResultUtils.success(orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,11 +276,31 @@ public class OrderController {
|
||||||
queryWrapper.eq("userId", id);
|
queryWrapper.eq("userId", id);
|
||||||
queryWrapper.orderByDesc("id");
|
queryWrapper.orderByDesc("id");
|
||||||
List<Order> orders = orderService.list(queryWrapper);
|
List<Order> orders = orderService.list(queryWrapper);
|
||||||
|
|
||||||
|
QueryWrapper<OrderItems> myOrderItemsQueryWrapper = new QueryWrapper<>();
|
||||||
|
List<Long> orderIds = orders.stream().map(Order::getId).toList();
|
||||||
|
myOrderItemsQueryWrapper.in("orderId", orderIds);
|
||||||
|
List<OrderItems> myOrderItems = orderItemService.list(myOrderItemsQueryWrapper);
|
||||||
|
|
||||||
|
// 封装map集合(键:订单id, 值:订单明细列表)
|
||||||
|
Map<Long, List<OrderItems>> map = new HashMap<>();
|
||||||
|
for (OrderItems orderItems : myOrderItems) {
|
||||||
|
Long orderId = orderItems.getOrderId();
|
||||||
|
|
||||||
|
List<OrderItems> orderItemsArrayList = map.get(orderId);
|
||||||
|
if (orderItemsArrayList == null) {
|
||||||
|
orderItemsArrayList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
orderItemsArrayList.add(orderItems);
|
||||||
|
map.put(orderId, orderItemsArrayList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<OrderVO> orderVOS = orders.stream().map(order -> {
|
List<OrderVO> orderVOS = orders.stream().map(order -> {
|
||||||
Long orderId = order.getId();
|
Long orderId = order.getId();
|
||||||
QueryWrapper<OrderItems> orderItemsQueryWrapper = new QueryWrapper<>();
|
QueryWrapper<OrderItems> orderItemsQueryWrapper = new QueryWrapper<>();
|
||||||
orderItemsQueryWrapper.eq("orderId", orderId);
|
orderItemsQueryWrapper.eq("orderId", orderId);
|
||||||
List<OrderItems> orderItemsList = orderItemService.list(orderItemsQueryWrapper);
|
List<OrderItems> orderItemsList = map.get(orderId);
|
||||||
OrderVO orderVO = new OrderVO();
|
OrderVO orderVO = new OrderVO();
|
||||||
BeanUtils.copyProperties(order, orderVO);
|
BeanUtils.copyProperties(order, orderVO);
|
||||||
orderVO.setOrderItemList(orderItemsList);
|
orderVO.setOrderItemList(orderItemsList);
|
||||||
|
|
|
@ -11,7 +11,9 @@ import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
import com.cultural.heritage.model.dto.CommonRequest;
|
import com.cultural.heritage.model.dto.CommonRequest;
|
||||||
import com.cultural.heritage.model.entity.Order;
|
import com.cultural.heritage.model.entity.Order;
|
||||||
|
import com.cultural.heritage.model.entity.OrderItems;
|
||||||
import com.cultural.heritage.model.entity.User;
|
import com.cultural.heritage.model.entity.User;
|
||||||
|
import com.cultural.heritage.service.order.OrderItemService;
|
||||||
import com.cultural.heritage.service.order.OrderService;
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
import com.cultural.heritage.service.user.UserService;
|
import com.cultural.heritage.service.user.UserService;
|
||||||
import com.cultural.heritage.service.wx.WeChatService;
|
import com.cultural.heritage.service.wx.WeChatService;
|
||||||
|
@ -46,6 +48,10 @@ public class WeChatPayController {
|
||||||
@Resource
|
@Resource
|
||||||
private WeChatService weChatService;
|
private WeChatService weChatService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrderItemService orderItemService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSAPI 下单
|
* JSAPI 下单
|
||||||
|
@ -83,10 +89,14 @@ public class WeChatPayController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款(仅管理员)
|
* 退款(仅管理员)
|
||||||
|
* @param commonRequest 订单id
|
||||||
*/
|
*/
|
||||||
@PostMapping("/refund/create")
|
@PostMapping("/refund/create")
|
||||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
public BaseResponse<Refund> createRefund(@RequestBody CommonRequest commonRequest) {
|
public BaseResponse<Refund> createRefund(@RequestBody CommonRequest commonRequest) {
|
||||||
|
if (commonRequest == null || commonRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
Long orderId = commonRequest.getId();
|
Long orderId = commonRequest.getId();
|
||||||
Order order = ordersService.getById(orderId);
|
Order order = ordersService.getById(orderId);
|
||||||
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
|
ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在");
|
||||||
|
@ -94,6 +104,26 @@ public class WeChatPayController {
|
||||||
return ResultUtils.success(refund);
|
return ResultUtils.success(refund);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web管理员退款订单明细
|
||||||
|
* @param commonRequest 订单明细id
|
||||||
|
*/
|
||||||
|
@PostMapping("/refund/part/create")
|
||||||
|
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||||
|
public BaseResponse<Refund> createPartRefund(@RequestBody CommonRequest commonRequest) {
|
||||||
|
if (commonRequest == null || commonRequest.getId() <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||||
|
}
|
||||||
|
Long orderItemsId = commonRequest.getId();
|
||||||
|
OrderItems orderItems = orderItemService.getById(orderItemsId);
|
||||||
|
ThrowUtils.throwIf(orderItems == null, ErrorCode.OPERATION_ERROR, "订单明细不存在");
|
||||||
|
|
||||||
|
Refund refund = weChatService.refundPartPayment(String.valueOf(orderItemsId), orderItems.getItemTotalAmount());
|
||||||
|
return ResultUtils.success(refund);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款回调
|
* 退款回调
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.cultural.heritage.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.cultural.heritage.model.entity.RefundRecord;
|
||||||
|
|
||||||
|
public interface RefundRecordMapper extends BaseMapper<RefundRecord> {
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import java.math.BigDecimal;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "优惠券添加请求体", requiredProperties =
|
@Schema(description = "优惠券添加请求体", requiredProperties =
|
||||||
{"name", "conditionAmount", "requirePoints", "content", "startTime", "endTime", "description"})
|
{"name", "standardAmount", "conditionAmount", "requirePoints", "content", "startTime", "endTime", "description"})
|
||||||
public class CouponAddRequest implements Serializable {
|
public class CouponAddRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,14 @@ public class CouponAddRequest implements Serializable {
|
||||||
@Schema(description = "优惠券名称", example = "满200减50")
|
@Schema(description = "优惠券名称", example = "满200减50")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准金额
|
||||||
|
*/
|
||||||
|
@Schema(description = "标准金额", example = "200")
|
||||||
|
private BigDecimal standardAmount;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 满减金额
|
* 满减金额
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,6 +24,12 @@ public class CouponUpdateRequest implements Serializable {
|
||||||
@Schema(description = "优惠券名称", example = "满200减50")
|
@Schema(description = "优惠券名称", example = "满200减50")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准金额
|
||||||
|
*/
|
||||||
|
@Schema(description = "标准金额", example = "200")
|
||||||
|
private BigDecimal standardAmount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 满减金额
|
* 满减金额
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.math.BigDecimal;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "可用优惠券请求体", requiredProperties =
|
@Schema(description = "可用优惠券请求体", requiredProperties =
|
||||||
{"conditionAmount", "isAvailable"})
|
{"standardAmount", "isAvailable"})
|
||||||
public class UsableCouponQueryRequest implements Serializable {
|
public class UsableCouponQueryRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public class UsableCouponQueryRequest implements Serializable {
|
||||||
* 订单金额
|
* 订单金额
|
||||||
*/
|
*/
|
||||||
@Schema(description = "订单金额", example = "50")
|
@Schema(description = "订单金额", example = "50")
|
||||||
private BigDecimal conditionAmount;
|
private BigDecimal currentAmount;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.cultural.heritage.model.dto.order.capital;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "常规类商品单独购买创建请求体", requiredProperties = {"userId", "userName", "orderNumber", "addressId", "contactsId",
|
||||||
|
"couponId", "orderStatus", "note", "orderItemMainInfoAddRequestList"})
|
||||||
|
public class GeneralGoodSingleBuyAddRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单类别
|
||||||
|
*/
|
||||||
|
@Schema(description = "订单类别", example = "product")
|
||||||
|
private String orderType;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户昵称
|
||||||
|
*/
|
||||||
|
@Schema(description = "用户昵称", example = "Hello")
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址id
|
||||||
|
*/
|
||||||
|
@Schema(description = "地址id(id > 0)", example = "12")
|
||||||
|
private Long addressId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 联系人id
|
||||||
|
*/
|
||||||
|
@Schema(description = "联系人id(id > 0)", example = "3")
|
||||||
|
private Long contactsId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券id
|
||||||
|
*/
|
||||||
|
@Schema(description = "优惠券id(id > 0)", example = "2")
|
||||||
|
private Long couponId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单备注
|
||||||
|
*/
|
||||||
|
@Schema(description = "订单备注", example = "希望能完整体验非遗文化,保持产品原貌,妥善包装")
|
||||||
|
private String note;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单主要明细信息
|
||||||
|
*/
|
||||||
|
@Schema(description = "订单主要明细信息")
|
||||||
|
private List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.cultural.heritage.model.dto.refund;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "退款记录添加请求体", requiredProperties = {"outTradeNo", "outRefundNo", "refundAmount"})
|
||||||
|
public class RefundRecordAddRequest implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户单号
|
||||||
|
*/
|
||||||
|
@Schema(description = "商户单号", example = "20250206220922442039734342343")
|
||||||
|
private String outTradeNo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款单号
|
||||||
|
*/
|
||||||
|
@Schema(description = "退款单号", example = "202502062209224420397")
|
||||||
|
private String outRefundNo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
@Schema(description = "退款金额", example = "100.00")
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -46,6 +46,12 @@ public class Coupon implements Serializable {
|
||||||
private BigDecimal conditionAmount;
|
private BigDecimal conditionAmount;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准金额
|
||||||
|
*/
|
||||||
|
private BigDecimal standardAmount;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要的积分
|
* 需要的积分
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.cultural.heritage.model.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款记录表
|
||||||
|
* @TableName refund_record
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName(value = "refund_record")
|
||||||
|
@Schema(description = "退款记录", requiredProperties = {"id", "outTradeNo", "outRefundNo", "refundAmount"})
|
||||||
|
public class RefundRecord implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款记录id
|
||||||
|
*/
|
||||||
|
@TableId(type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户单号
|
||||||
|
*/
|
||||||
|
private String outTradeNo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款单号
|
||||||
|
*/
|
||||||
|
private String outRefundNo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
private Integer isDelete;
|
||||||
|
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
|
@ -28,6 +28,12 @@ public class CouponVO implements Serializable {
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准金额
|
||||||
|
*/
|
||||||
|
private BigDecimal standardAmount;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 满减金额
|
* 满减金额
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.cultural.heritage.model.dto.coupon.CouponQueryRequest;
|
import com.cultural.heritage.model.dto.coupon.CouponQueryRequest;
|
||||||
import com.cultural.heritage.model.entity.Coupon;
|
import com.cultural.heritage.model.entity.Coupon;
|
||||||
|
import com.cultural.heritage.model.entity.UserCoupon;
|
||||||
|
|
||||||
public interface CouponService extends IService<Coupon> {
|
public interface CouponService extends IService<Coupon> {
|
||||||
|
|
||||||
|
@ -24,4 +25,17 @@ public interface CouponService extends IService<Coupon> {
|
||||||
* 校验
|
* 校验
|
||||||
*/
|
*/
|
||||||
void validCoupon(Coupon coupon, boolean update);
|
void validCoupon(Coupon coupon, boolean update);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向消息队列中发送优惠券创建的消息
|
||||||
|
*/
|
||||||
|
void sendCouponCreateMessage(Coupon coupon);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向消息队列中发送用户优惠券创建的消息
|
||||||
|
*/
|
||||||
|
void sendUserCouponCreateMessage(UserCoupon userCoupon, Coupon coupon);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
package com.cultural.heritage.service.good.impl;
|
package com.cultural.heritage.service.good.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUnit;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.constant.CommonConstant;
|
import com.cultural.heritage.constant.CommonConstant;
|
||||||
|
import com.cultural.heritage.constant.MqConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.mapper.CouponMapper;
|
import com.cultural.heritage.mapper.CouponMapper;
|
||||||
import com.cultural.heritage.model.dto.coupon.CouponQueryRequest;
|
import com.cultural.heritage.model.dto.coupon.CouponQueryRequest;
|
||||||
import com.cultural.heritage.model.entity.Coupon;
|
import com.cultural.heritage.model.entity.Coupon;
|
||||||
|
import com.cultural.heritage.model.entity.UserCoupon;
|
||||||
import com.cultural.heritage.service.good.CouponService;
|
import com.cultural.heritage.service.good.CouponService;
|
||||||
|
import com.cultural.heritage.utils.MultiDelayMessage;
|
||||||
import com.cultural.heritage.utils.SqlUtils;
|
import com.cultural.heritage.utils.SqlUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -21,6 +29,10 @@ import java.util.Date;
|
||||||
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {
|
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryWrapper<Coupon> getQueryWrapper(CouponQueryRequest couponQueryRequest) {
|
public QueryWrapper<Coupon> getQueryWrapper(CouponQueryRequest couponQueryRequest) {
|
||||||
if (couponQueryRequest == null) {
|
if (couponQueryRequest == null) {
|
||||||
|
@ -57,6 +69,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
|
||||||
Long id = coupon.getId();
|
Long id = coupon.getId();
|
||||||
String name = coupon.getName();
|
String name = coupon.getName();
|
||||||
BigDecimal conditionAmount = coupon.getConditionAmount();
|
BigDecimal conditionAmount = coupon.getConditionAmount();
|
||||||
|
BigDecimal standardAmount = coupon.getStandardAmount();
|
||||||
Integer requirePoints = coupon.getRequirePoints();
|
Integer requirePoints = coupon.getRequirePoints();
|
||||||
String startTime = coupon.getStartTime();
|
String startTime = coupon.getStartTime();
|
||||||
String endTime = coupon.getEndTime();
|
String endTime = coupon.getEndTime();
|
||||||
|
@ -69,9 +82,16 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数id错误");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数id错误");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ObjectUtils.isEmpty(standardAmount) || standardAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "标准价格错误");
|
||||||
|
}
|
||||||
if (ObjectUtils.isEmpty(conditionAmount) || conditionAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
if (ObjectUtils.isEmpty(conditionAmount) || conditionAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "满减价格错误");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "满减价格错误");
|
||||||
}
|
}
|
||||||
|
if (conditionAmount.compareTo(standardAmount) > 0) {
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "满减价格不能超过标准价格");
|
||||||
|
}
|
||||||
|
|
||||||
if (ObjectUtils.isEmpty(requirePoints) || requirePoints <= 0) {
|
if (ObjectUtils.isEmpty(requirePoints) || requirePoints <= 0) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "积分参数错误");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "积分参数错误");
|
||||||
}
|
}
|
||||||
|
@ -82,4 +102,46 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "有效期开始时间晚于有效期截止时间");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "有效期开始时间晚于有效期截止时间");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向消息队列中发送优惠券创建的消息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendCouponCreateMessage(Coupon coupon) {
|
||||||
|
// 延迟检查优惠券是否过期
|
||||||
|
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(coupon.getId());
|
||||||
|
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
||||||
|
MqConstant.DELAY_COUPON_ROUTING_KEY, msg, message -> {
|
||||||
|
//计算优惠券截止日期和当前的时间差
|
||||||
|
DateTime now = new DateTime();
|
||||||
|
DateTime end = DateUtil.parse(coupon.getEndTime());
|
||||||
|
long seconds = DateUtil.between(now, end, DateUnit.SECOND);
|
||||||
|
// 添加延迟消息属性
|
||||||
|
message.getMessageProperties().setDelay((int) (seconds * 1000));
|
||||||
|
return message;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向消息队列中发送用户优惠券创建的消息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendUserCouponCreateMessage(UserCoupon userCoupon, Coupon coupon) {
|
||||||
|
// 延迟检查优惠券是否过期
|
||||||
|
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(userCoupon.getId());
|
||||||
|
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
||||||
|
MqConstant.DELAY_USER_COUPON_ROUTING_KEY, msg, message -> {
|
||||||
|
//计算优惠券截止日期和当前的时间差
|
||||||
|
DateTime now = new DateTime();
|
||||||
|
DateTime end = DateUtil.parse(coupon.getEndTime());
|
||||||
|
long seconds = DateUtil.between(now, end, DateUnit.SECOND);
|
||||||
|
// 添加延迟消息属性
|
||||||
|
message.getMessageProperties().setDelay((int) (seconds * 1000));
|
||||||
|
return message;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.cultural.heritage.model.dto.order.OrderAddRequest;
|
import com.cultural.heritage.model.dto.order.OrderAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.OrderQueryRequest;
|
import com.cultural.heritage.model.dto.order.OrderQueryRequest;
|
||||||
|
import com.cultural.heritage.model.dto.order.capital.GeneralGoodSingleBuyAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.capital.OrderMainInfoAddRequest;
|
import com.cultural.heritage.model.dto.order.capital.OrderMainInfoAddRequest;
|
||||||
import com.cultural.heritage.model.entity.Order;
|
import com.cultural.heritage.model.entity.Order;
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ public interface OrderService extends IService<Order> {
|
||||||
/**
|
/**
|
||||||
* 校验单独购买的商品数据是否准确
|
* 校验单独购买的商品数据是否准确
|
||||||
*/
|
*/
|
||||||
void validSingleGoodOrder(OrderMainInfoAddRequest orderMainInfoAddRequest);
|
void validSingleGoodOrder(GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,4 +50,11 @@ public interface OrderService extends IService<Order> {
|
||||||
* 计算单个商品购买的总金额
|
* 计算单个商品购买的总金额
|
||||||
*/
|
*/
|
||||||
BigDecimal calculateTotalAmount(OrderMainInfoAddRequest orderMainInfoAddRequest);
|
BigDecimal calculateTotalAmount(OrderMainInfoAddRequest orderMainInfoAddRequest);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向消息队列中发送订单创建的消息
|
||||||
|
*/
|
||||||
|
void sendCreateOrderMessage(Long orderId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.cultural.heritage.service.order;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.cultural.heritage.model.entity.RefundRecord;
|
||||||
|
|
||||||
|
public interface RefundRecordService extends IService<RefundRecord> {
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.cultural.heritage.common.ErrorCode;
|
import com.cultural.heritage.common.ErrorCode;
|
||||||
import com.cultural.heritage.constant.CommonConstant;
|
import com.cultural.heritage.constant.CommonConstant;
|
||||||
|
import com.cultural.heritage.constant.MqConstant;
|
||||||
import com.cultural.heritage.constant.OrderStatusConstant;
|
import com.cultural.heritage.constant.OrderStatusConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
|
@ -12,25 +13,30 @@ import com.cultural.heritage.mapper.*;
|
||||||
import com.cultural.heritage.model.dto.order.OrderAddRequest;
|
import com.cultural.heritage.model.dto.order.OrderAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.OrderItemAddRequest;
|
import com.cultural.heritage.model.dto.order.OrderItemAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.OrderQueryRequest;
|
import com.cultural.heritage.model.dto.order.OrderQueryRequest;
|
||||||
|
import com.cultural.heritage.model.dto.order.capital.GeneralGoodSingleBuyAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.capital.OrderItemMainInfoAddRequest;
|
import com.cultural.heritage.model.dto.order.capital.OrderItemMainInfoAddRequest;
|
||||||
import com.cultural.heritage.model.dto.order.capital.OrderMainInfoAddRequest;
|
import com.cultural.heritage.model.dto.order.capital.OrderMainInfoAddRequest;
|
||||||
import com.cultural.heritage.model.dto.snapshot.AddressSnapshot;
|
import com.cultural.heritage.model.dto.snapshot.AddressSnapshot;
|
||||||
import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot;
|
import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot;
|
||||||
import com.cultural.heritage.model.dto.snapshot.CouponSnapshot;
|
import com.cultural.heritage.model.dto.snapshot.CouponSnapshot;
|
||||||
import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
|
import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
|
||||||
|
import com.cultural.heritage.model.entity.Coupon;
|
||||||
import com.cultural.heritage.model.entity.Good;
|
import com.cultural.heritage.model.entity.Good;
|
||||||
import com.cultural.heritage.model.entity.Order;
|
import com.cultural.heritage.model.entity.Order;
|
||||||
import com.cultural.heritage.model.entity.OrderItems;
|
import com.cultural.heritage.model.entity.OrderItems;
|
||||||
import com.cultural.heritage.model.enums.GoodTypeEnum;
|
import com.cultural.heritage.model.enums.GoodTypeEnum;
|
||||||
import com.cultural.heritage.service.good.CartRecordService;
|
import com.cultural.heritage.service.good.CartRecordService;
|
||||||
|
import com.cultural.heritage.service.good.CouponService;
|
||||||
import com.cultural.heritage.service.good.GoodService;
|
import com.cultural.heritage.service.good.GoodService;
|
||||||
import com.cultural.heritage.service.order.OrderItemService;
|
import com.cultural.heritage.service.order.OrderItemService;
|
||||||
import com.cultural.heritage.service.order.OrderService;
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
|
import com.cultural.heritage.utils.MultiDelayMessage;
|
||||||
import com.cultural.heritage.utils.OrderNumberUtils;
|
import com.cultural.heritage.utils.OrderNumberUtils;
|
||||||
import com.cultural.heritage.utils.SqlUtils;
|
import com.cultural.heritage.utils.SqlUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@ -72,6 +78,14 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||||
private CartRecordService cartRecordService;
|
private CartRecordService cartRecordService;
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CouponService couponService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取查询条件
|
* 获取查询条件
|
||||||
*/
|
*/
|
||||||
|
@ -255,12 +269,12 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||||
good.setInventory(good.getInventory() - inventory);
|
good.setInventory(good.getInventory() - inventory);
|
||||||
}
|
}
|
||||||
boolean update = goodService.updateBatchById(goodList);
|
boolean update = goodService.updateBatchById(goodList);
|
||||||
ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR, "商品库存更新失败");
|
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "商品库存更新失败");
|
||||||
|
|
||||||
// 清空购物车
|
// 清空购物车
|
||||||
if (isCartOrder) {
|
if (isCartOrder) {
|
||||||
boolean remove = cartRecordService.removeBatchByIds(cartIds);
|
boolean remove = cartRecordService.removeBatchByIds(cartIds);
|
||||||
ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR, "清空购物车失败");
|
ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "清空购物车失败");
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -271,8 +285,8 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||||
* 校验单独购买的商品数据是否准确
|
* 校验单独购买的商品数据是否准确
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void validSingleGoodOrder(OrderMainInfoAddRequest orderMainInfoAddRequest) {
|
public void validSingleGoodOrder(GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest) {
|
||||||
List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList();
|
List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList = generalGoodSingleBuyAddRequest.getOrderItemMainInfoAddRequestList();
|
||||||
if (orderItemMainInfoAddRequestList.size() != 1) {
|
if (orderItemMainInfoAddRequestList.size() != 1) {
|
||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "购买了多种商品或未购买商品");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "购买了多种商品或未购买商品");
|
||||||
}
|
}
|
||||||
|
@ -293,13 +307,39 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
|
||||||
public BigDecimal calculateTotalAmount(OrderMainInfoAddRequest orderMainInfoAddRequest) {
|
public BigDecimal calculateTotalAmount(OrderMainInfoAddRequest orderMainInfoAddRequest) {
|
||||||
List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList();
|
List<OrderItemMainInfoAddRequest> orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList();
|
||||||
OrderItemMainInfoAddRequest orderItemMainInfoAddRequest = orderItemMainInfoAddRequestList.get(0);
|
OrderItemMainInfoAddRequest orderItemMainInfoAddRequest = orderItemMainInfoAddRequestList.get(0);
|
||||||
|
Long couponId = orderMainInfoAddRequest.getCouponId();
|
||||||
|
Coupon coupon = couponService.getById(couponId);
|
||||||
|
ThrowUtils.throwIf(coupon == null, ErrorCode.OPERATION_ERROR, "优惠券不存在");
|
||||||
|
BigDecimal conditionAmount = coupon.getConditionAmount();
|
||||||
Integer quantity = orderItemMainInfoAddRequest.getQuantity();
|
Integer quantity = orderItemMainInfoAddRequest.getQuantity();
|
||||||
Long goodId = orderItemMainInfoAddRequest.getGoodId();
|
Long goodId = orderItemMainInfoAddRequest.getGoodId();
|
||||||
Good good = goodService.getById(goodId);
|
Good good = goodService.getById(goodId);
|
||||||
return good.getPrice().multiply(BigDecimal.valueOf(quantity));
|
return good.getPrice().multiply(BigDecimal.valueOf(quantity)).subtract(conditionAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向消息队列中发送订单创建的消息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void sendCreateOrderMessage(Long orderId) {
|
||||||
|
// 延迟检查订单状态信息
|
||||||
|
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderId,
|
||||||
|
10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L);
|
||||||
|
// 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L
|
||||||
|
int delayValue = msg.removeNextDelay().intValue();
|
||||||
|
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
|
||||||
|
MqConstant.DELAY_ORDER_ROUTING_KEY, msg, message -> {
|
||||||
|
// 添加延迟消息属性
|
||||||
|
message.getMessageProperties().setDelay(delayValue);
|
||||||
|
return message;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据id获取订单(地址,联系人,优惠券,商品)信息
|
* 根据id获取订单(地址,联系人,优惠券,商品)信息
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.cultural.heritage.service.order.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.cultural.heritage.mapper.RefundRecordMapper;
|
||||||
|
import com.cultural.heritage.model.entity.RefundRecord;
|
||||||
|
import com.cultural.heritage.service.order.RefundRecordService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RefundRecordServiceImpl extends ServiceImpl<RefundRecordMapper, RefundRecord> implements RefundRecordService {
|
||||||
|
}
|
|
@ -35,6 +35,11 @@ public interface WeChatService {
|
||||||
*/
|
*/
|
||||||
Refund refundPayment(String orderId, BigDecimal amount);
|
Refund refundPayment(String orderId, BigDecimal amount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款申请
|
||||||
|
*/
|
||||||
|
Refund refundPartPayment(String orderItemsId, BigDecimal amount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取退款回调信息
|
* 获取退款回调信息
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.cultural.heritage.config.WxPayConfig;
|
||||||
import com.cultural.heritage.constant.OrderStatusConstant;
|
import com.cultural.heritage.constant.OrderStatusConstant;
|
||||||
import com.cultural.heritage.exception.BusinessException;
|
import com.cultural.heritage.exception.BusinessException;
|
||||||
import com.cultural.heritage.exception.ThrowUtils;
|
import com.cultural.heritage.exception.ThrowUtils;
|
||||||
|
import com.cultural.heritage.model.dto.snapshot.CouponSnapshot;
|
||||||
import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
|
import com.cultural.heritage.model.dto.snapshot.GoodSnapshot;
|
||||||
import com.cultural.heritage.model.entity.Good;
|
import com.cultural.heritage.model.entity.Good;
|
||||||
import com.cultural.heritage.model.entity.Order;
|
import com.cultural.heritage.model.entity.Order;
|
||||||
|
@ -19,7 +20,9 @@ import com.cultural.heritage.model.entity.OrderItems;
|
||||||
import com.cultural.heritage.service.good.GoodService;
|
import com.cultural.heritage.service.good.GoodService;
|
||||||
import com.cultural.heritage.service.order.OrderItemService;
|
import com.cultural.heritage.service.order.OrderItemService;
|
||||||
import com.cultural.heritage.service.order.OrderService;
|
import com.cultural.heritage.service.order.OrderService;
|
||||||
|
import com.cultural.heritage.service.order.RefundRecordService;
|
||||||
import com.cultural.heritage.service.wx.WeChatService;
|
import com.cultural.heritage.service.wx.WeChatService;
|
||||||
|
import com.cultural.heritage.utils.RefundUtils;
|
||||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||||
import com.wechat.pay.java.core.notification.RequestParam;
|
import com.wechat.pay.java.core.notification.RequestParam;
|
||||||
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
|
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
|
||||||
|
@ -40,6 +43,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -67,6 +71,9 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
@Resource
|
@Resource
|
||||||
private OrderItemService orderItemService;
|
private OrderItemService orderItemService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RefundRecordService refundRecordService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求参数
|
* 请求参数
|
||||||
|
@ -144,12 +151,14 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
// 商户订单号
|
// 商户订单号
|
||||||
createRequest.setOutTradeNo(orderNumber);
|
createRequest.setOutTradeNo(orderNumber);
|
||||||
// 商户退款单号
|
// 商户退款单号
|
||||||
createRequest.setOutRefundNo(orderNumber);
|
String outRefundNo = RefundUtils.generateRefundNo();
|
||||||
|
createRequest.setOutRefundNo(outRefundNo);
|
||||||
// 退款结果回调
|
// 退款结果回调
|
||||||
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback");
|
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback");
|
||||||
// 退款金额
|
// 退款金额
|
||||||
AmountReq amountReq = new AmountReq();
|
AmountReq amountReq = new AmountReq();
|
||||||
long refundAmount = amount.movePointRight(2).intValue();
|
long refundAmount = amount.movePointRight(2).intValue();
|
||||||
|
|
||||||
amountReq.setRefund(refundAmount);
|
amountReq.setRefund(refundAmount);
|
||||||
amountReq.setTotal(refundAmount);
|
amountReq.setTotal(refundAmount);
|
||||||
amountReq.setCurrency("CNY");
|
amountReq.setCurrency("CNY");
|
||||||
|
@ -161,12 +170,60 @@ public class WeChatServiceImpl implements WeChatService {
|
||||||
return refund;
|
return refund;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Refund refundPartPayment(String orderItemsId, BigDecimal amount) {
|
||||||
|
// 获取订单明细
|
||||||
|
OrderItems orderItems = orderItemService.getById(orderItemsId);
|
||||||
|
ThrowUtils.throwIf(orderItemsId == null, ErrorCode.OPERATION_ERROR, "订单明细不存在");
|
||||||
|
// 获取订单明细所属的订单
|
||||||
|
Order order = orderService.getById(orderItems.getOrderId());
|
||||||
|
ThrowUtils.throwIf(order == null, ErrorCode.OPERATION_ERROR, "订单不存在");
|
||||||
|
String orderNumber = order.getOrderNumber();
|
||||||
|
// 退款请求
|
||||||
|
CreateRequest createRequest = new CreateRequest();
|
||||||
|
// 商户订单号
|
||||||
|
createRequest.setOutTradeNo(orderNumber);
|
||||||
|
// 商户退款单号
|
||||||
|
String outRefundNo = RefundUtils.generateRefundNo();
|
||||||
|
createRequest.setOutRefundNo(outRefundNo);
|
||||||
|
// 退款结果回调
|
||||||
|
createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback");
|
||||||
|
// 退款金额
|
||||||
|
AmountReq amountReq = new AmountReq();
|
||||||
|
|
||||||
|
BigDecimal refundAmount;
|
||||||
|
CouponSnapshot couponSnapshot = order.getCouponSnapshot();
|
||||||
|
if (couponSnapshot == null) {
|
||||||
|
refundAmount = amount;
|
||||||
|
} else {
|
||||||
|
BigDecimal couponAmount = couponSnapshot.getConditionAmount();
|
||||||
|
BigDecimal totalAmount = order.getTotalAmount().add(couponAmount);
|
||||||
|
BigDecimal itemShare = amount.divide(totalAmount, 10, RoundingMode.HALF_UP);
|
||||||
|
BigDecimal itemCouponRefund = itemShare.multiply(couponAmount);
|
||||||
|
refundAmount = amount.subtract(itemCouponRefund);
|
||||||
|
}
|
||||||
|
refundAmount = refundAmount.movePointRight(2).setScale(0, RoundingMode.HALF_UP);
|
||||||
|
amountReq.setRefund(refundAmount.longValue());
|
||||||
|
amountReq.setTotal(order.getTotalAmount().movePointRight(2).longValue());
|
||||||
|
amountReq.setCurrency("CNY");
|
||||||
|
createRequest.setAmount(amountReq);
|
||||||
|
// 申请退款
|
||||||
|
System.out.println("退款请求:" + createRequest);
|
||||||
|
Refund refund = wxPayConfig.getRefundService().create(createRequest);
|
||||||
|
System.out.println("退款申请结果:" + refund);
|
||||||
|
return refund;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RefundNotification getRefundInfo(HttpServletRequest request) {
|
public RefundNotification getRefundInfo(HttpServletRequest request) {
|
||||||
NotificationParser notificationParser = getNotificationParser(request);
|
NotificationParser notificationParser = getNotificationParser(request);
|
||||||
return notificationParser.parse(requestParam, RefundNotification.class);
|
return notificationParser.parse(requestParam, RefundNotification.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public synchronized boolean refundCallback(RefundNotification refundNotification) {
|
public synchronized boolean refundCallback(RefundNotification refundNotification) {
|
||||||
|
|
21
src/main/java/com/cultural/heritage/utils/RefundUtils.java
Normal file
21
src/main/java/com/cultural/heritage/utils/RefundUtils.java
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package com.cultural.heritage.utils;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RefundUtils {
|
||||||
|
|
||||||
|
// 生成唯一的退款单号,格式为 yyyyMMddHHmmssSSS + 随机数
|
||||||
|
public static String generateRefundNo() {
|
||||||
|
// 获取当前时间的时间戳
|
||||||
|
String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
|
||||||
|
|
||||||
|
// 生成一个 4 位随机数,保证每次退款单号不同
|
||||||
|
int randomNum = new Random().nextInt(9000) + 1000; // 生成1000到9999之间的随机数
|
||||||
|
|
||||||
|
// 拼接退款单号
|
||||||
|
return timestamp + randomNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -94,8 +94,8 @@ wx:
|
||||||
#商户APIv3密钥
|
#商户APIv3密钥
|
||||||
apiV3Key: fbemuj4Xql7CYlQJAoTEPYxvPSNgYT2t
|
apiV3Key: fbemuj4Xql7CYlQJAoTEPYxvPSNgYT2t
|
||||||
#通知地址
|
#通知地址
|
||||||
# notifyUrl: https://winning-mouse-internally.ngrok-free.app
|
notifyUrl: https://winning-mouse-internally.ngrok-free.app
|
||||||
notifyUrl: http://123.249.108.160:8888
|
# notifyUrl: http://123.249.108.160:8888
|
||||||
#微信服务器地址
|
#微信服务器地址
|
||||||
domain: https://api.mch.weixin.qq.com
|
domain: https://api.mch.weixin.qq.com
|
||||||
|
|
||||||
|
|
7
src/main/resources/mapper/RefundRecordMapper.xml
Normal file
7
src/main/resources/mapper/RefundRecordMapper.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.cultural.heritage.model.dto.refund.RefundRecordAddRequest">
|
||||||
|
|
||||||
|
</mapper>
|
Loading…
Reference in New Issue
Block a user