ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/dto/RefundDTO.java
New file @@ -0,0 +1,24 @@ package com.ruoyi.system.api.domain.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; import java.math.BigDecimal; import lombok.Data; /** * @author mitao * @date 2024/5/29 */ @Data @ApiModel("退款数据传输对象") public class RefundDTO implements Serializable { private static final long serialVersionUID = -8486815089305219482L; @ApiModelProperty("订单号") private String orderNo; @ApiModelProperty("金额") private BigDecimal amount; } ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
@@ -4,8 +4,10 @@ import com.ruoyi.system.api.domain.Order; import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO; import com.ruoyi.system.api.domain.dto.OrderDTO; import com.ruoyi.system.api.domain.dto.RefundDTO; import com.ruoyi.system.api.feignClient.OrderClient; import java.util.List; import java.util.Map; import org.springframework.cloud.openfeign.FallbackFactory; /** @@ -43,6 +45,11 @@ public R<List<Order>> getOrderByGroupPurchaseId(Long id, String source) { return R.fail("根据团购商品id获取订单列表失败:" + cause.getMessage()); } @Override public R<Map<String, Object>> refund(List<RefundDTO> refundDTOS, String source) { return R.fail("批量退款失败" + cause.getMessage()); } }; } ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
@@ -6,8 +6,10 @@ import com.ruoyi.system.api.domain.Order; import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO; import com.ruoyi.system.api.domain.dto.OrderDTO; import com.ruoyi.system.api.domain.dto.RefundDTO; import com.ruoyi.system.api.factory.OrderFallbackFactory; import java.util.List; import java.util.Map; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -56,4 +58,8 @@ @GetMapping("/order/group-purchase-id/{id}") R<List<Order>> getOrderByGroupPurchaseId(@PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); @PostMapping("/inner/pay/refund-batch") R<Map<String, Object>> refund(@RequestBody List<RefundDTO> refundDTOS, @RequestHeader(SecurityConstants.FROM_SOURCE) String source); } ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/controller/management/MemberBondController.java
File was deleted ruoyi-modules/ruoyi-auction/src/main/java/com/ruoyi/auction/service/impl/AuctionGoodsServiceImpl.java
@@ -52,9 +52,9 @@ public class AuctionGoodsServiceImpl extends ServiceImpl<AuctionGoodsMapper, AuctionGoods> implements IAuctionGoodsService { private final GoodsSkuClient goodsSkuClient; private final IAuctionBidRecordService auctionBidRecordService; private final MemberClient memberClient; private final OrderClient orderClient; private final IAuctionBidRecordService auctionBidRecordService; /** * 获取拍卖商品列表的分页数据 * @@ -227,10 +227,17 @@ orderDTO.setReceiverphone(data.getRecipientPhone()); } orderClient.saveOrderOne(orderDTO, SecurityConstants.INNER); } else { // 没有人出价,退回拍卖商品库存 goodsSkuClient.returningStock(auctionGoods.getGoodsSkuId(), auctionGoods.getAuctionStock(), SecurityConstants.INNER); } // 结束拍卖 this.lambdaUpdate().set(AuctionGoods::getStartStatus, AuctionStartStatusEnum.ENDED) .eq(AuctionGoods::getId, id).update(); // 查询已支付保证基记录 // TODO 退还保证金 } } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/PaylogController.java
@@ -1,45 +1,19 @@ package com.ruoyi.order.controller; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.response.AlipayTradeRefundResponse; import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.Paylog; import com.ruoyi.order.service.IPaylogService; import com.ruoyi.order.service.impl.PaylogServiceImpl; import com.ruoyi.order.util.DateUtil; import com.ruoyi.order.util.SinataUtil; import com.ruoyi.order.util.alipay.config.AlipayConfig; import com.ruoyi.order.util.alipay.util.PayDemoActivity; import com.ruoyi.order.util.tencent.common.Configure; import com.ruoyi.order.util.tencent.common.Signature; import com.ruoyi.order.util.tencent.common.XMLParser; import com.ruoyi.order.util.tencent.protocol.AppPayReqData; import com.ruoyi.order.util.tencent.protocol.UnifiedorderReqData; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.ruoyi.order.util.tencent.WXPay.requestRefundService; import static com.ruoyi.order.util.tencent.WXPay.requestUnifiedorderService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /** * <p> ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/inner/PayController.java
New file @@ -0,0 +1,33 @@ package com.ruoyi.order.controller.inner; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.security.annotation.InnerAuth; import com.ruoyi.order.service.IPaylogService; import com.ruoyi.order.service.impl.PaylogServiceImpl; import com.ruoyi.system.api.domain.dto.RefundDTO; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author mitao * @date 2024/5/29 */ @RestController @RequestMapping("/inner/pay") @RequiredArgsConstructor public class PayController { private final IPaylogService paylogService; private final PaylogServiceImpl paylogServiceImpl; @InnerAuth @PostMapping("/refund-batch") public R<Map<String, Object>> refund(@RequestBody List<RefundDTO> refundDTOS) { return R.ok(paylogService.refund(refundDTOS)); } } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/OrderAuctionBond.java
@@ -6,6 +6,9 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.ruoyi.common.core.enums.AuctionOrderTypeEnum; import com.ruoyi.common.core.enums.BondStatusEnum; import com.ruoyi.common.core.enums.PaymentMethodEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.io.Serializable; @@ -51,8 +54,11 @@ @ApiModelProperty(value = "保证金") private BigDecimal bond; @ApiModelProperty(value = "是否缴纳保证金") private Boolean boundStatus; @ApiModelProperty(value = "保证金状态 1=待支付 2=已支付 3=已退款") private BondStatusEnum boundStatus; @ApiModelProperty(value = "保证金类型1=普通拍品 2=拍卖会拍品") private AuctionOrderTypeEnum bondType; @ApiModelProperty(value = "创建者") @TableField(value = "create_by", fill = FieldFill.INSERT) @@ -74,7 +80,7 @@ @TableLogic private Integer delFlag; @ApiModelProperty(value = "支付方式 1=微信 2=支付宝") private Integer paymentMethod; private PaymentMethodEnum paymentMethod; @ApiModelProperty(value = "保证金订单编号") private String orderNo; ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IPaylogService.java
@@ -1,21 +1,14 @@ package com.ruoyi.order.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.core.domain.R; import com.ruoyi.order.domain.pojo.Paylog; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.order.util.tencent.common.Signature; import com.ruoyi.order.util.tencent.common.XMLParser; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.ruoyi.system.api.domain.dto.RefundDTO; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.springframework.web.bind.annotation.RequestMapping; /** * <p> @@ -48,4 +41,6 @@ * @param response */ void wxnotify(HttpServletRequest request, HttpServletResponse response); Map<String, Object> refund(List<RefundDTO> refundDTOS); } ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java
@@ -1,14 +1,18 @@ package com.ruoyi.order.service.impl; import static com.ruoyi.order.util.tencent.WXPay.requestRefundService; import static com.ruoyi.order.util.tencent.WXPay.requestUnifiedorderService; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.response.AlipayTradeRefundResponse; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.order.domain.pojo.Paylog; import com.ruoyi.order.mapper.PaylogMapper; import com.ruoyi.order.service.IPaylogService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.order.util.SinataUtil; import com.ruoyi.order.util.alipay.config.AlipayConfig; import com.ruoyi.order.util.alipay.util.PayDemoActivity; @@ -17,24 +21,27 @@ import com.ruoyi.order.util.tencent.common.XMLParser; import com.ruoyi.order.util.tencent.protocol.AppPayReqData; import com.ruoyi.order.util.tencent.protocol.UnifiedorderReqData; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.ruoyi.system.api.domain.dto.RefundDTO; import java.io.IOException; import java.io.PrintWriter; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.time.LocalDateTime; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.ruoyi.order.util.tencent.WXPay.requestRefundService; import static com.ruoyi.order.util.tencent.WXPay.requestUnifiedorderService; import org.springframework.stereotype.Service; /** * <p> @@ -431,4 +438,71 @@ return m.matches(); } @Override public Map<String, Object> refund(List<RefundDTO> refundDTOS) { Map<String, Object> map = new HashMap<>(); Set<String> orderNoList = refundDTOS.stream().map(RefundDTO::getOrderNo) .collect(Collectors.toSet()); if (StringUtils.isNotEmpty(orderNoList)) { Map<String, Paylog> paylogMap = iPaylogService.lambdaQuery() .in(Paylog::getOutTradeNo, orderNoList).eq(Paylog::getState, 1).list().stream() .collect(Collectors.toMap(Paylog::getOutTradeNo, Function.identity())); List<Paylog> updList = new ArrayList<>(); for (RefundDTO refundDTO : refundDTOS) { String orderNo = refundDTO.getOrderNo(); BigDecimal amount = refundDTO.getAmount(); Paylog paylog = paylogMap.get(orderNo); Optional.of(paylog).ifPresent(pay -> { Boolean res = handleRefund(pay, amount, orderNo); map.put(orderNo, res); if (res) { pay.setState(3); updList.add(pay); } }); } iPaylogService.updateBatchById(updList); } return map; } public static void main(String[] args) { Map<String, Object> map = new HashMap<>(); map.put("1", true); map.put("2", false); map.put("3", true); map.put("4", false); map.put("5", true); List<String> collect = map.entrySet().stream().map(entry -> { if (!(boolean) entry.getValue()) { return entry.getKey(); } return null; }).filter(Objects::nonNull).collect(Collectors.toList()); System.out.println(collect); } private Boolean handleRefund(Paylog paylog, BigDecimal amount, String orderNo) { boolean res = false; if (StringUtils.isNotNull(paylog)) { if (paylog.getPayType() == 1) { res = paylogServiceImpl.refundForAlipay(paylog.getOutTradeNo(), paylog.getTradeNo(), amount.doubleValue()); } if (paylog.getPayType() == 2) { String refundMoney = SinataUtil.doubleRetainTwo( amount.doubleValue() * 100d); Integer refundFee = Integer.parseInt( refundMoney.substring(0, refundMoney.length() - 3)); String money = SinataUtil.doubleRetainTwo(paylog.getPayMoney() * 100d); Integer totalFee = Integer.parseInt( money.substring(0, money.length() - 3)); res = paylogServiceImpl.refundForWxpay(2, paylog.getTradeNo(), paylog.getOutTradeNo(), orderNo, totalFee, refundFee, "4"); } } return res; } }