diff --git a/src/main/java/com/cultural/heritage/controller/good/CouponController.java b/src/main/java/com/cultural/heritage/controller/good/CouponController.java index 92db996..3e18ca6 100644 --- a/src/main/java/com/cultural/heritage/controller/good/CouponController.java +++ b/src/main/java/com/cultural/heritage/controller/good/CouponController.java @@ -1,8 +1,6 @@ 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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.ErrorCode; import com.cultural.heritage.common.ResultUtils; -import com.cultural.heritage.constant.MqConstant; import com.cultural.heritage.constant.UserConstant; import com.cultural.heritage.exception.BusinessException; 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.UserCouponService; 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.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.BeanUtils; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; @@ -65,8 +60,6 @@ public class CouponController { private UserCouponService userCouponService; - @Resource - private RabbitTemplate rabbitTemplate; /** @@ -100,18 +93,8 @@ public class CouponController { boolean result = couponService.save(coupon); ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "优惠券添加失败"); - // 延迟检查优惠券是否过期 - MultiDelayMessage 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; - }); + // 向消息队列中发送优惠券创建的消息 + couponService.sendCouponCreateMessage(coupon); return ResultUtils.success(true); } @@ -251,18 +234,8 @@ public class CouponController { boolean save = userCouponService.save(userCoupon); ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "兑换记录插入失败"); - // 延迟检查优惠券是否过期 - MultiDelayMessage 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; - }); + // 向消息队列中发送用户优惠券创建的消息 + couponService.sendUserCouponCreateMessage(userCoupon, coupon); // 更新用户积分 loginUser.setPoints(loginUser.getPoints() - requirePoints); @@ -388,8 +361,8 @@ public class CouponController { if (usableCouponQueryRequest == null) { throw new BusinessException(ErrorCode.PARAMS_ERROR); } - BigDecimal conditionAmount = usableCouponQueryRequest.getConditionAmount(); - if (conditionAmount.compareTo(BigDecimal.ZERO) <= 0) { + BigDecimal currentAmount = usableCouponQueryRequest.getCurrentAmount(); + if (currentAmount.compareTo(BigDecimal.ZERO) <= 0) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "订单金额参数错误"); } User loginUser = userService.getLoginUser(request); @@ -403,9 +376,9 @@ public class CouponController { // 获取(不)可使用的优惠券 List userCoupons = userCouponList.stream().filter(userCoupon -> { CouponVO couponVO = userCoupon.getCouponVO(); - BigDecimal couponAmount = couponVO.getConditionAmount(); + BigDecimal standardAmount = couponVO.getStandardAmount(); Boolean isAvailable = usableCouponQueryRequest.getIsAvailable(); - int result = conditionAmount.compareTo(couponAmount); + int result = currentAmount.compareTo(standardAmount); return isAvailable == (result >= 0); }).toList(); diff --git a/src/main/java/com/cultural/heritage/controller/good/GoodController.java b/src/main/java/com/cultural/heritage/controller/good/GoodController.java index 250f6e1..de6d864 100644 --- a/src/main/java/com/cultural/heritage/controller/good/GoodController.java +++ b/src/main/java/com/cultural/heritage/controller/good/GoodController.java @@ -206,7 +206,7 @@ public class GoodController { } Long id = deleteRequest.getId(); - //删除预约时间段表中与该商品关联的记录 + // 删除预约时间段表中与该商品关联的记录 QueryWrapper dateQueryWrapper = new QueryWrapper<>(); dateQueryWrapper.eq("goodId", id); List appointmentDateList = appointmentDateService.list(dateQueryWrapper); diff --git a/src/main/java/com/cultural/heritage/controller/order/OrderController.java b/src/main/java/com/cultural/heritage/controller/order/OrderController.java index f5736f7..ac84798 100644 --- a/src/main/java/com/cultural/heritage/controller/order/OrderController.java +++ b/src/main/java/com/cultural/heritage/controller/order/OrderController.java @@ -7,7 +7,6 @@ import com.cultural.heritage.annotation.AuthCheck; import com.cultural.heritage.common.BaseResponse; import com.cultural.heritage.common.ErrorCode; import com.cultural.heritage.common.ResultUtils; -import com.cultural.heritage.constant.MqConstant; import com.cultural.heritage.constant.OrderStatusConstant; import com.cultural.heritage.constant.UserConstant; 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.order.OrderQueryRequest; 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.OrderMainInfoAddRequest; import com.cultural.heritage.model.dto.snapshot.GoodSnapshot; import com.cultural.heritage.model.entity.*; import com.cultural.heritage.model.vo.order.OrderVO; 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.order.OrderItemService; import com.cultural.heritage.service.order.OrderService; 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.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; -import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.BeanUtils; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PostMapping; @@ -78,9 +77,10 @@ public class OrderController { private GoodService goodService; - @Resource - private RabbitTemplate rabbitTemplate; + private CouponService couponService; + + @@ -98,14 +98,14 @@ public class OrderController { User loginUser = userService.getLoginUser(request); Long userId = loginUser.getId(); - // 封装成订单创建请求体 - OrderMainInfoAddRequest orderMainInfoAddRequest = new OrderMainInfoAddRequest(); - BeanUtils.copyProperties(cartOrderAddRequest, orderMainInfoAddRequest); - // 校验购物车数据是否准确 List cartOrderItemAddRequestList = cartOrderAddRequest.getCartOrderItemAddRequestList(); 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列表 List cartIds = cartOrderItemAddRequestList.stream().map(CartOrderItemAddRequest::getCartRecordId).toList(); @@ -140,6 +140,11 @@ public class OrderController { Integer quantity = map.get(cartRecordId); 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); // 封装成订单明细主要信息请求体列表 @@ -157,17 +162,8 @@ public class OrderController { // 创建通用订单(常规类和服务类商品) Long orderId = orderService.createCommonOrder(orderMainInfoAddRequest, userId, true, cartIds); - // 延迟检查订单状态信息 - MultiDelayMessage 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; - }); + // 向消息队列中发送订单创建的消息 + orderService.sendCreateOrderMessage(orderId); return ResultUtils.success(orderId); } @@ -176,38 +172,36 @@ public class OrderController { /** * 小程序端用户创建常规类商品订单 - * @param orderMainInfoAddRequest 订单创建请求体 + * @param generalGoodSingleBuyAddRequest 常规类类商品单独购买创建请求体 * @return 是否创建成功 */ @PostMapping("/add") @Transactional(rollbackFor = Exception.class) @Operation(summary = "小程序端用户创建常规类商品订单", description = "参数:订单创建请求体,权限:所有人,方法名:addOrder") - public BaseResponse addOrder(@RequestBody OrderMainInfoAddRequest orderMainInfoAddRequest, HttpServletRequest request) { - if (orderMainInfoAddRequest == null) { + public BaseResponse addOrder(@RequestBody GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest, HttpServletRequest request) { + if (generalGoodSingleBuyAddRequest == null) { throw new BusinessException(ErrorCode.PARAMS_ERROR); } // 校验用户当前是否处于登录态 User loginUser = userService.getLoginUser(request); Long userId = loginUser.getId(); + // 校验单独购买的商品数据是否准确 - orderService.validSingleGoodOrder(orderMainInfoAddRequest); + orderService.validSingleGoodOrder(generalGoodSingleBuyAddRequest); + + // 封装成订单主要信息请求体 + OrderMainInfoAddRequest orderMainInfoAddRequest = new OrderMainInfoAddRequest(); + BeanUtils.copyProperties(generalGoodSingleBuyAddRequest, orderMainInfoAddRequest); + // 计算单个商品购买的总金额 BigDecimal totalAmount = orderService.calculateTotalAmount(orderMainInfoAddRequest); orderMainInfoAddRequest.setTotalAmount(totalAmount); // 创建通用订单(常规类和服务类商品) Long orderId = orderService.createCommonOrder(orderMainInfoAddRequest, userId, false, null); - // 延迟检查订单状态信息 - MultiDelayMessage 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; - }); + // 向消息队列中发送订单创建的消息 + orderService.sendCreateOrderMessage(orderId); + return ResultUtils.success(orderId); } @@ -282,11 +276,31 @@ public class OrderController { queryWrapper.eq("userId", id); queryWrapper.orderByDesc("id"); List orders = orderService.list(queryWrapper); + + QueryWrapper myOrderItemsQueryWrapper = new QueryWrapper<>(); + List orderIds = orders.stream().map(Order::getId).toList(); + myOrderItemsQueryWrapper.in("orderId", orderIds); + List myOrderItems = orderItemService.list(myOrderItemsQueryWrapper); + + // 封装map集合(键:订单id, 值:订单明细列表) + Map> map = new HashMap<>(); + for (OrderItems orderItems : myOrderItems) { + Long orderId = orderItems.getOrderId(); + + List orderItemsArrayList = map.get(orderId); + if (orderItemsArrayList == null) { + orderItemsArrayList = new ArrayList<>(); + } + orderItemsArrayList.add(orderItems); + map.put(orderId, orderItemsArrayList); + } + + List orderVOS = orders.stream().map(order -> { Long orderId = order.getId(); QueryWrapper orderItemsQueryWrapper = new QueryWrapper<>(); orderItemsQueryWrapper.eq("orderId", orderId); - List orderItemsList = orderItemService.list(orderItemsQueryWrapper); + List orderItemsList = map.get(orderId); OrderVO orderVO = new OrderVO(); BeanUtils.copyProperties(order, orderVO); orderVO.setOrderItemList(orderItemsList); diff --git a/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java b/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java index ae26dfe..48a2eb5 100644 --- a/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java +++ b/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java @@ -11,7 +11,9 @@ import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.exception.ThrowUtils; import com.cultural.heritage.model.dto.CommonRequest; 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.service.order.OrderItemService; import com.cultural.heritage.service.order.OrderService; import com.cultural.heritage.service.user.UserService; import com.cultural.heritage.service.wx.WeChatService; @@ -46,6 +48,10 @@ public class WeChatPayController { @Resource private WeChatService weChatService; + @Resource + private OrderItemService orderItemService; + + /** * JSAPI 下单 @@ -83,10 +89,14 @@ public class WeChatPayController { /** * 退款(仅管理员) + * @param commonRequest 订单id */ @PostMapping("/refund/create") @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) public BaseResponse createRefund(@RequestBody CommonRequest commonRequest) { + if (commonRequest == null || commonRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } Long orderId = commonRequest.getId(); Order order = ordersService.getById(orderId); ThrowUtils.throwIf(order == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在"); @@ -94,6 +104,26 @@ public class WeChatPayController { return ResultUtils.success(refund); } + + /** + * Web管理员退款订单明细 + * @param commonRequest 订单明细id + */ + @PostMapping("/refund/part/create") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse 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); + } + + /** * 退款回调 */ diff --git a/src/main/java/com/cultural/heritage/mapper/RefundRecordMapper.java b/src/main/java/com/cultural/heritage/mapper/RefundRecordMapper.java new file mode 100644 index 0000000..49ee451 --- /dev/null +++ b/src/main/java/com/cultural/heritage/mapper/RefundRecordMapper.java @@ -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 { +} diff --git a/src/main/java/com/cultural/heritage/model/dto/coupon/CouponAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/coupon/CouponAddRequest.java index 2055e72..dc3ef31 100644 --- a/src/main/java/com/cultural/heritage/model/dto/coupon/CouponAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/coupon/CouponAddRequest.java @@ -9,7 +9,7 @@ import java.math.BigDecimal; @Data @Schema(description = "优惠券添加请求体", requiredProperties = - {"name", "conditionAmount", "requirePoints", "content", "startTime", "endTime", "description"}) + {"name", "standardAmount", "conditionAmount", "requirePoints", "content", "startTime", "endTime", "description"}) public class CouponAddRequest implements Serializable { @@ -19,6 +19,14 @@ public class CouponAddRequest implements Serializable { @Schema(description = "优惠券名称", example = "满200减50") private String name; + + /** + * 标准金额 + */ + @Schema(description = "标准金额", example = "200") + private BigDecimal standardAmount; + + /** * 满减金额 */ diff --git a/src/main/java/com/cultural/heritage/model/dto/coupon/CouponUpdateRequest.java b/src/main/java/com/cultural/heritage/model/dto/coupon/CouponUpdateRequest.java index 401e54d..a91e2c6 100644 --- a/src/main/java/com/cultural/heritage/model/dto/coupon/CouponUpdateRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/coupon/CouponUpdateRequest.java @@ -24,6 +24,12 @@ public class CouponUpdateRequest implements Serializable { @Schema(description = "优惠券名称", example = "满200减50") private String name; + /** + * 标准金额 + */ + @Schema(description = "标准金额", example = "200") + private BigDecimal standardAmount; + /** * 满减金额 */ diff --git a/src/main/java/com/cultural/heritage/model/dto/coupon/UsableCouponQueryRequest.java b/src/main/java/com/cultural/heritage/model/dto/coupon/UsableCouponQueryRequest.java index 410d113..c558a57 100644 --- a/src/main/java/com/cultural/heritage/model/dto/coupon/UsableCouponQueryRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/coupon/UsableCouponQueryRequest.java @@ -9,7 +9,7 @@ import java.math.BigDecimal; @Data @Schema(description = "可用优惠券请求体", requiredProperties = - {"conditionAmount", "isAvailable"}) + {"standardAmount", "isAvailable"}) public class UsableCouponQueryRequest implements Serializable { @@ -17,7 +17,7 @@ public class UsableCouponQueryRequest implements Serializable { * 订单金额 */ @Schema(description = "订单金额", example = "50") - private BigDecimal conditionAmount; + private BigDecimal currentAmount; /** diff --git a/src/main/java/com/cultural/heritage/model/dto/order/capital/GeneralGoodSingleBuyAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/order/capital/GeneralGoodSingleBuyAddRequest.java new file mode 100644 index 0000000..2ed41f8 --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/order/capital/GeneralGoodSingleBuyAddRequest.java @@ -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 orderItemMainInfoAddRequestList; + + + + @Serial + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/cultural/heritage/model/dto/refund/RefundRecordAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/refund/RefundRecordAddRequest.java new file mode 100644 index 0000000..53bb51b --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/refund/RefundRecordAddRequest.java @@ -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; +} diff --git a/src/main/java/com/cultural/heritage/model/entity/Coupon.java b/src/main/java/com/cultural/heritage/model/entity/Coupon.java index 6aa0a56..00f03a6 100644 --- a/src/main/java/com/cultural/heritage/model/entity/Coupon.java +++ b/src/main/java/com/cultural/heritage/model/entity/Coupon.java @@ -46,6 +46,12 @@ public class Coupon implements Serializable { private BigDecimal conditionAmount; + /** + * 标准金额 + */ + private BigDecimal standardAmount; + + /** * 需要的积分 */ diff --git a/src/main/java/com/cultural/heritage/model/entity/RefundRecord.java b/src/main/java/com/cultural/heritage/model/entity/RefundRecord.java new file mode 100644 index 0000000..e34776d --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/entity/RefundRecord.java @@ -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; +} diff --git a/src/main/java/com/cultural/heritage/model/vo/coupon/CouponVO.java b/src/main/java/com/cultural/heritage/model/vo/coupon/CouponVO.java index 3dead69..1d8631d 100644 --- a/src/main/java/com/cultural/heritage/model/vo/coupon/CouponVO.java +++ b/src/main/java/com/cultural/heritage/model/vo/coupon/CouponVO.java @@ -28,6 +28,12 @@ public class CouponVO implements Serializable { private String content; + /** + * 标准金额 + */ + private BigDecimal standardAmount; + + /** * 满减金额 */ diff --git a/src/main/java/com/cultural/heritage/service/good/CouponService.java b/src/main/java/com/cultural/heritage/service/good/CouponService.java index 2fb0726..38af389 100644 --- a/src/main/java/com/cultural/heritage/service/good/CouponService.java +++ b/src/main/java/com/cultural/heritage/service/good/CouponService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; import com.cultural.heritage.model.dto.coupon.CouponQueryRequest; import com.cultural.heritage.model.entity.Coupon; +import com.cultural.heritage.model.entity.UserCoupon; public interface CouponService extends IService { @@ -24,4 +25,17 @@ public interface CouponService extends IService { * 校验 */ void validCoupon(Coupon coupon, boolean update); + + + /** + * 向消息队列中发送优惠券创建的消息 + */ + void sendCouponCreateMessage(Coupon coupon); + + + /** + * 向消息队列中发送用户优惠券创建的消息 + */ + void sendUserCouponCreateMessage(UserCoupon userCoupon, Coupon coupon); + } diff --git a/src/main/java/com/cultural/heritage/service/good/impl/CouponServiceImpl.java b/src/main/java/com/cultural/heritage/service/good/impl/CouponServiceImpl.java index afcbbb1..3a21dd0 100644 --- a/src/main/java/com/cultural/heritage/service/good/impl/CouponServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/good/impl/CouponServiceImpl.java @@ -1,17 +1,25 @@ 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.extension.service.impl.ServiceImpl; import com.cultural.heritage.common.ErrorCode; import com.cultural.heritage.constant.CommonConstant; +import com.cultural.heritage.constant.MqConstant; import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.mapper.CouponMapper; import com.cultural.heritage.model.dto.coupon.CouponQueryRequest; 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.utils.MultiDelayMessage; import com.cultural.heritage.utils.SqlUtils; +import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -21,6 +29,10 @@ import java.util.Date; public class CouponServiceImpl extends ServiceImpl implements CouponService { + @Resource + private RabbitTemplate rabbitTemplate; + + @Override public QueryWrapper getQueryWrapper(CouponQueryRequest couponQueryRequest) { if (couponQueryRequest == null) { @@ -57,6 +69,7 @@ public class CouponServiceImpl extends ServiceImpl impleme Long id = coupon.getId(); String name = coupon.getName(); BigDecimal conditionAmount = coupon.getConditionAmount(); + BigDecimal standardAmount = coupon.getStandardAmount(); Integer requirePoints = coupon.getRequirePoints(); String startTime = coupon.getStartTime(); String endTime = coupon.getEndTime(); @@ -69,9 +82,16 @@ public class CouponServiceImpl extends ServiceImpl impleme 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) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "满减价格错误"); } + if (conditionAmount.compareTo(standardAmount) > 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR, "满减价格不能超过标准价格"); + } + if (ObjectUtils.isEmpty(requirePoints) || requirePoints <= 0) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "积分参数错误"); } @@ -82,4 +102,46 @@ public class CouponServiceImpl extends ServiceImpl impleme throw new BusinessException(ErrorCode.PARAMS_ERROR, "有效期开始时间晚于有效期截止时间"); } } + + + + /** + * 向消息队列中发送优惠券创建的消息 + */ + @Override + public void sendCouponCreateMessage(Coupon coupon) { + // 延迟检查优惠券是否过期 + MultiDelayMessage 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 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; + }); + } } diff --git a/src/main/java/com/cultural/heritage/service/order/OrderService.java b/src/main/java/com/cultural/heritage/service/order/OrderService.java index a8091dd..e8b7681 100644 --- a/src/main/java/com/cultural/heritage/service/order/OrderService.java +++ b/src/main/java/com/cultural/heritage/service/order/OrderService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.IService; import com.cultural.heritage.model.dto.order.OrderAddRequest; 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.entity.Order; @@ -41,7 +42,7 @@ public interface OrderService extends IService { /** * 校验单独购买的商品数据是否准确 */ - void validSingleGoodOrder(OrderMainInfoAddRequest orderMainInfoAddRequest); + void validSingleGoodOrder(GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest); @@ -49,4 +50,11 @@ public interface OrderService extends IService { * 计算单个商品购买的总金额 */ BigDecimal calculateTotalAmount(OrderMainInfoAddRequest orderMainInfoAddRequest); + + + /** + * 向消息队列中发送订单创建的消息 + */ + void sendCreateOrderMessage(Long orderId); + } diff --git a/src/main/java/com/cultural/heritage/service/order/RefundRecordService.java b/src/main/java/com/cultural/heritage/service/order/RefundRecordService.java new file mode 100644 index 0000000..4f6b86d --- /dev/null +++ b/src/main/java/com/cultural/heritage/service/order/RefundRecordService.java @@ -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 { +} diff --git a/src/main/java/com/cultural/heritage/service/order/impl/OrderServiceImpl.java b/src/main/java/com/cultural/heritage/service/order/impl/OrderServiceImpl.java index d8cbffe..b062e19 100644 --- a/src/main/java/com/cultural/heritage/service/order/impl/OrderServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/order/impl/OrderServiceImpl.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cultural.heritage.common.ErrorCode; import com.cultural.heritage.constant.CommonConstant; +import com.cultural.heritage.constant.MqConstant; import com.cultural.heritage.constant.OrderStatusConstant; import com.cultural.heritage.exception.BusinessException; 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.OrderItemAddRequest; 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.OrderMainInfoAddRequest; import com.cultural.heritage.model.dto.snapshot.AddressSnapshot; import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; import com.cultural.heritage.model.dto.snapshot.CouponSnapshot; 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.Order; import com.cultural.heritage.model.entity.OrderItems; import com.cultural.heritage.model.enums.GoodTypeEnum; 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.order.OrderItemService; import com.cultural.heritage.service.order.OrderService; +import com.cultural.heritage.utils.MultiDelayMessage; import com.cultural.heritage.utils.OrderNumberUtils; import com.cultural.heritage.utils.SqlUtils; import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -72,6 +78,14 @@ public class OrderServiceImpl extends ServiceImpl implements private CartRecordService cartRecordService; + @Resource + private RabbitTemplate rabbitTemplate; + + + @Resource + private CouponService couponService; + + /** * 获取查询条件 */ @@ -255,12 +269,12 @@ public class OrderServiceImpl extends ServiceImpl implements good.setInventory(good.getInventory() - inventory); } boolean update = goodService.updateBatchById(goodList); - ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR, "商品库存更新失败"); + ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "商品库存更新失败"); // 清空购物车 if (isCartOrder) { boolean remove = cartRecordService.removeBatchByIds(cartIds); - ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR, "清空购物车失败"); + ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "清空购物车失败"); } return id; } @@ -271,8 +285,8 @@ public class OrderServiceImpl extends ServiceImpl implements * 校验单独购买的商品数据是否准确 */ @Override - public void validSingleGoodOrder(OrderMainInfoAddRequest orderMainInfoAddRequest) { - List orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList(); + public void validSingleGoodOrder(GeneralGoodSingleBuyAddRequest generalGoodSingleBuyAddRequest) { + List orderItemMainInfoAddRequestList = generalGoodSingleBuyAddRequest.getOrderItemMainInfoAddRequestList(); if (orderItemMainInfoAddRequestList.size() != 1) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "购买了多种商品或未购买商品"); } @@ -293,13 +307,39 @@ public class OrderServiceImpl extends ServiceImpl implements public BigDecimal calculateTotalAmount(OrderMainInfoAddRequest orderMainInfoAddRequest) { List orderItemMainInfoAddRequestList = orderMainInfoAddRequest.getOrderItemMainInfoAddRequestList(); 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(); Long goodId = orderItemMainInfoAddRequest.getGoodId(); 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 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获取订单(地址,联系人,优惠券,商品)信息 */ diff --git a/src/main/java/com/cultural/heritage/service/order/impl/RefundRecordServiceImpl.java b/src/main/java/com/cultural/heritage/service/order/impl/RefundRecordServiceImpl.java new file mode 100644 index 0000000..c8f8ad5 --- /dev/null +++ b/src/main/java/com/cultural/heritage/service/order/impl/RefundRecordServiceImpl.java @@ -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 implements RefundRecordService { +} diff --git a/src/main/java/com/cultural/heritage/service/wx/WeChatService.java b/src/main/java/com/cultural/heritage/service/wx/WeChatService.java index fb4a2b4..8f3a79c 100644 --- a/src/main/java/com/cultural/heritage/service/wx/WeChatService.java +++ b/src/main/java/com/cultural/heritage/service/wx/WeChatService.java @@ -35,6 +35,11 @@ public interface WeChatService { */ Refund refundPayment(String orderId, BigDecimal amount); + /** + * 退款申请 + */ + Refund refundPartPayment(String orderItemsId, BigDecimal amount); + /** * 获取退款回调信息 */ diff --git a/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java index 9fce07d..364a4fc 100644 --- a/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java @@ -12,6 +12,7 @@ import com.cultural.heritage.config.WxPayConfig; import com.cultural.heritage.constant.OrderStatusConstant; import com.cultural.heritage.exception.BusinessException; 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.entity.Good; 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.order.OrderItemService; 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.utils.RefundUtils; import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.core.notification.RequestParam; 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.math.BigDecimal; +import java.math.RoundingMode; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -67,6 +71,9 @@ public class WeChatServiceImpl implements WeChatService { @Resource private OrderItemService orderItemService; + @Resource + private RefundRecordService refundRecordService; + /** * 请求参数 @@ -144,12 +151,14 @@ public class WeChatServiceImpl implements WeChatService { // 商户订单号 createRequest.setOutTradeNo(orderNumber); // 商户退款单号 - createRequest.setOutRefundNo(orderNumber); + String outRefundNo = RefundUtils.generateRefundNo(); + createRequest.setOutRefundNo(outRefundNo); // 退款结果回调 createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/callback"); // 退款金额 AmountReq amountReq = new AmountReq(); long refundAmount = amount.movePointRight(2).intValue(); + amountReq.setRefund(refundAmount); amountReq.setTotal(refundAmount); amountReq.setCurrency("CNY"); @@ -161,12 +170,60 @@ public class WeChatServiceImpl implements WeChatService { 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 public RefundNotification getRefundInfo(HttpServletRequest request) { NotificationParser notificationParser = getNotificationParser(request); return notificationParser.parse(requestParam, RefundNotification.class); } + + @Override @Transactional(rollbackFor = Exception.class) public synchronized boolean refundCallback(RefundNotification refundNotification) { diff --git a/src/main/java/com/cultural/heritage/utils/RefundUtils.java b/src/main/java/com/cultural/heritage/utils/RefundUtils.java new file mode 100644 index 0000000..f90a9ef --- /dev/null +++ b/src/main/java/com/cultural/heritage/utils/RefundUtils.java @@ -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; + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0cfdc9d..2d55b57 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -94,8 +94,8 @@ wx: #商户APIv3密钥 apiV3Key: fbemuj4Xql7CYlQJAoTEPYxvPSNgYT2t #通知地址 -# notifyUrl: https://winning-mouse-internally.ngrok-free.app - notifyUrl: http://123.249.108.160:8888 + notifyUrl: https://winning-mouse-internally.ngrok-free.app +# notifyUrl: http://123.249.108.160:8888 #微信服务器地址 domain: https://api.mch.weixin.qq.com diff --git a/src/main/resources/mapper/RefundRecordMapper.xml b/src/main/resources/mapper/RefundRecordMapper.xml new file mode 100644 index 0000000..6057893 --- /dev/null +++ b/src/main/resources/mapper/RefundRecordMapper.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file