diff --git a/ruoyi-admin/src/main/java/com/ruoyi/op/BusOp.java b/ruoyi-admin/src/main/java/com/ruoyi/op/BusOp.java index 2b414992..71271bae 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/op/BusOp.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/op/BusOp.java @@ -1,20 +1,75 @@ package com.ruoyi.op; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.cai.domain.RechargeOrder; import com.ruoyi.cai.domain.User; +import com.ruoyi.cai.domain.VipOrder; +import com.ruoyi.cai.pay.PayManager; +import com.ruoyi.cai.pay.PayStatusEnum; +import com.ruoyi.cai.service.RechargeOrderService; import com.ruoyi.cai.service.UserMemberService; import com.ruoyi.cai.service.UserService; +import com.ruoyi.cai.service.VipOrderService; +import com.ruoyi.common.utils.StringUtils; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.time.LocalDateTime; import java.util.List; @Component +@Slf4j public class BusOp { @Autowired private UserService userService; @Autowired private UserMemberService userMemberService; + @Autowired + private PayManager payManager; + @Autowired + private RechargeOrderService rechargeOrderService; + @Autowired + private VipOrderService vipOrderService; + + public void checkVipOrder(LocalDateTime startTime, LocalDateTime endTime, String orderNo){ + if(StringUtils.isNotEmpty(orderNo)){ + payManager.queryAndUpdateCallbackPayStatus(orderNo,"wx228d04f4dbf691c6"); + return; + } + if(startTime != null && endTime != null){ + List list = vipOrderService.list(Wrappers.lambdaQuery(VipOrder.class) + .between(VipOrder::getCreateTime, startTime, endTime) + .eq(VipOrder::getPayStatus, PayStatusEnum.READY_PAY)); + for (VipOrder order : list) { + try { + payManager.queryAndUpdateCallbackPayStatus(order.getOrderNo(),"wx228d04f4dbf691c6"); + }catch (Exception e){ + log.error("检查订单失败!",e); + } + } + } + } + + public void checkRechargeOrder(LocalDateTime startTime, LocalDateTime endTime, String orderNo){ + if(StringUtils.isNotEmpty(orderNo)){ + payManager.queryAndUpdateCallbackPayStatus(orderNo,"wx228d04f4dbf691c6"); + return; + } + if(startTime != null && endTime != null){ + List list = rechargeOrderService.list(Wrappers.lambdaQuery(RechargeOrder.class) + .between(RechargeOrder::getCreateTime, startTime, endTime) + .eq(RechargeOrder::getPayStatus, PayStatusEnum.READY_PAY)); + for (RechargeOrder order : list) { + try { + payManager.queryAndUpdateCallbackPayStatus(order.getOrderNo(),"wx228d04f4dbf691c6"); + }catch (Exception e){ + log.error("检查订单失败!",e); + } + } + } + } public void refreshUserVipStatus(){ int current = 0; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/op/BusOpController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/op/BusOpController.java index adcd7c89..62e396ac 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/op/BusOpController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/op/BusOpController.java @@ -2,6 +2,7 @@ package com.ruoyi.web.controller.cai.admin.op; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.op.BusOp; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -11,6 +12,9 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + @Validated @RequiredArgsConstructor @RestController @@ -27,4 +31,32 @@ public class BusOpController { return R.ok(); } + @GetMapping("/checkVipOrder") + public R checkVipOrder(String orderNo,String startTimeStr,String endTimeStr){ + LocalDateTime startTime = null; + LocalDateTime endTime = null; + if(StringUtils.isNotEmpty(startTimeStr)){ + startTime = LocalDateTime.parse(startTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + if(StringUtils.isNotEmpty(endTimeStr)){ + endTime = LocalDateTime.parse(endTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + busOp.checkVipOrder(startTime,endTime,orderNo); + return R.ok(); + } + + @GetMapping("/checkRechargeOrder") + public R checkRechargeOrder(String orderNo,String startTimeStr,String endTimeStr){ + LocalDateTime startTime = null; + LocalDateTime endTime = null; + if(StringUtils.isNotEmpty(startTimeStr)){ + startTime = LocalDateTime.parse(startTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + if(StringUtils.isNotEmpty(endTimeStr)){ + endTime = LocalDateTime.parse(endTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + busOp.checkRechargeOrder(startTime,endTime,orderNo); + return R.ok(); + } + } diff --git a/ruoyi-admin/src/test/java/com/ruoyi/test/business/PayTest.java b/ruoyi-admin/src/test/java/com/ruoyi/test/business/PayTest.java new file mode 100644 index 00000000..20b4ec2c --- /dev/null +++ b/ruoyi-admin/src/test/java/com/ruoyi/test/business/PayTest.java @@ -0,0 +1,21 @@ +package com.ruoyi.test.business; + +import com.alipay.api.AlipayApiException; +import com.ruoyi.cai.pay.PayManager; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@Slf4j +public class PayTest { + @Autowired + private PayManager payManager; + + @Test + public void test() throws AlipayApiException { + String orderNo = "R1788030579317542912"; + payManager.checkOrderPayStatus(orderNo,"wx228d04f4dbf691c6"); + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayManager.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayManager.java index 20e6888c..72f5109f 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayManager.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayManager.java @@ -1,20 +1,35 @@ package com.ruoyi.cai.pay; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradeQueryModel; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ijpay.alipay.AliPayApi; +import com.ijpay.alipay.AliPayApiConfig; +import com.ijpay.alipay.AliPayApiConfigKit; +import com.ijpay.core.enums.SignType; +import com.ijpay.core.kit.WxPayKit; +import com.ijpay.wxpay.WxPayApi; +import com.ijpay.wxpay.model.OrderQueryModel; +import com.ruoyi.cai.domain.PayConfig; import com.ruoyi.cai.domain.RechargeOrder; import com.ruoyi.cai.domain.VipOrder; import com.ruoyi.cai.dto.ConsumeResp; import com.ruoyi.cai.dto.commom.consumer.RechargeConsumerResp; import com.ruoyi.cai.manager.AwardManager; import com.ruoyi.cai.manager.ConsumerManager; +import com.ruoyi.cai.pay.model.PayQueryModel; +import com.ruoyi.cai.service.PayConfigService; import com.ruoyi.cai.service.PayTotalService; import com.ruoyi.cai.service.RechargeOrderService; import com.ruoyi.cai.service.VipOrderService; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; import java.util.Map; @Component @@ -31,6 +46,121 @@ public class PayManager { private AwardManager awardManager; @Autowired private PayTotalService payTotalService; + @Autowired + private PayConfigService payConfigService; + + public PayQueryModel queryOrder(PayConfig payConfig,String orderNo,String appid) throws AlipayApiException { + if(PayTypeEnum.ALI.getCode().equals(payConfig.getPayType())){ + AliPayApiConfig aliPayApiConfig = AliPayApiConfig.builder() + .setAppId(payConfig.getAppid()) + .setAliPayPublicKey(payConfig.getPublicKey()) + .setCharset("UTF-8") + .setPrivateKey(payConfig.getPrivateKey()) + .setServiceUrl(null) + .setSignType("RSA2") + .build(); + AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig); + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + model.setOutTradeNo(orderNo); + String body = AliPayApi.tradeQueryToResponse(model).getBody(); + log.info("订单查询 body={}",body); + JSONObject jsonObject = JSON.parseObject(body); + JSONObject response = jsonObject.getJSONObject("alipay_trade_query_response"); + String code = response.getString("code"); + String tradeStatus = response.getString("trade_status"); + if(!"10000".equals(code)){ + log.error("订单查询- 异常 resultBody={}",body); + return PayQueryModel.fail(); + } + if("TRADE_SUCCESS".equals(tradeStatus)){ + log.error("订单查询- 成功-已支付 resultBody={}",body); + return PayQueryModel.ok(null,payConfig.getAppid(),PayTypeEnum.ALI); + } + }else if(PayTypeEnum.WX.getCode().equals(payConfig.getPayType())){ + Map params = OrderQueryModel.builder() + .appid(appid) + .mch_id(payConfig.getWxMcid()) + .out_trade_no(orderNo) + .nonce_str(WxPayKit.generateStr()) + .build() + .createSign(payConfig.getWxKey(), SignType.MD5); + String query = WxPayApi.orderQuery(params); + Map result = WxPayKit.xmlToMap(query); + log.info("订单查询 query={}",query); + String state = result.get("trade_state"); + String returnCode = result.get("return_code"); + String returnMsg = result.get("return_msg"); + String resultCode = result.get("result_code"); + if (!WxPayKit.codeIsOk(returnCode)) { + log.error("订单查询- 异常 returnMsg={}",returnMsg); + return PayQueryModel.fail(); + } + if (!"SUCCESS".equals(resultCode)) { + log.error("订单查询- 异常 query={}",query); + return PayQueryModel.fail(); + } + if("SUCCESS".equals(state)){ + log.error("订单查询- 成功-已支付 query={}",query); + return PayQueryModel.ok(params, appid,PayTypeEnum.WX); + } + } + return PayQueryModel.fail(); + } + + public PayQueryModel checkOrderPayStatus(String orderNo, String appid) { + List list = payConfigService.list(Wrappers.lambdaQuery(PayConfig.class).eq(PayConfig::getEnableStatus, 1)); + for (PayConfig payConfig : list) { + try { + PayQueryModel paySuccess = this.queryOrder(payConfig, orderNo, appid); + if(paySuccess.isPayStatus()){ + return paySuccess; + } + }catch (Exception e){ + log.error("订单查询 -异常",e); + } + } + return PayQueryModel.fail(); + } + + public void queryAndUpdateCallbackPayStatus(String orderNo, String appId) { + OrderTypeEnum orderTypeEnum = OrderNoUtil.getType(orderNo); + if (orderTypeEnum == null) { + log.error("订单查询 订单类型有误!orderNo={}", orderNo); + throw new ServiceException("订单类型有误,请检查订单号"); + } + switch (orderTypeEnum) { + case VIP_ORDER_SUB: + VipOrder vipOrder = vipOrderService.getByOrderNo(orderNo); + if (vipOrder == null) { + throw new ServiceException("订单不存在,请检查订单状态"); + } + if (!PayStatusEnum.READY_PAY.getCode().equals(vipOrder.getPayStatus())) { + throw new ServiceException("订单状态有误,请检查订单状态"); + } + PayQueryModel vipPayStatus = checkOrderPayStatus(orderNo, appId); + if(!vipPayStatus.isPayStatus()){ + log.info("订单查询 VIP支付成功orderNo={}",orderNo); + break; + } + this.callBack(orderNo,null,vipPayStatus.getParams(),vipPayStatus.getAppId(),vipPayStatus.getPayTypeEnum()); + case RECHARGE_ORDER_SUB: + RechargeOrder rechargeOrder = rechargeOrderService.getByOrderNo(orderNo); + if (rechargeOrder == null) { + throw new ServiceException("订单查询 订单不存在,请重新下单支付"); + } + if (!PayStatusEnum.READY_PAY.getCode().equals(rechargeOrder.getPayStatus())) { + throw new ServiceException("订单查询 订单状态有误,请重新下单支付"); + } + PayQueryModel rechargePayStatus = checkOrderPayStatus(orderNo, appId); + if(!rechargePayStatus.isPayStatus()){ + log.info("订单查询 充值支付成功orderNo={}",orderNo); + break; + } + this.callBack(orderNo,null,rechargePayStatus.getParams(),rechargePayStatus.getAppId(),rechargePayStatus.getPayTypeEnum()); + default: + break; + } + } public PayOrderInfoDTO getOrderInfo(String orderNo){ OrderTypeEnum orderTypeEnum = OrderNoUtil.getType(orderNo); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/model/PayQueryModel.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/model/PayQueryModel.java new file mode 100644 index 00000000..e06fa8b1 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/model/PayQueryModel.java @@ -0,0 +1,26 @@ +package com.ruoyi.cai.pay.model; + +import com.ruoyi.cai.pay.PayTypeEnum; +import lombok.Data; + +import java.util.Map; + +@Data +public class PayQueryModel { + private boolean payStatus = false; + private Map params; + private String appId; + private PayTypeEnum payTypeEnum; + + public static PayQueryModel fail(){ + return new PayQueryModel(); + } + public static PayQueryModel ok(Map params,String appId,PayTypeEnum payTypeEnum){ + PayQueryModel payQueryModel = new PayQueryModel(); + payQueryModel.setParams(params); + payQueryModel.setAppId(appId); + payQueryModel.setPayTypeEnum(payTypeEnum); + payQueryModel.setPayStatus(true); + return payQueryModel; + } +}