Compare commits
12 Commits
main
...
feature/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f46f3044b | ||
|
|
1a65c76613 | ||
|
|
34e996019e | ||
|
|
4ed514a806 | ||
|
|
42fb1c3d7a | ||
|
|
16dc1360ef | ||
|
|
f586059272 | ||
|
|
3d7c2cb156 | ||
|
|
4c059f6a27 | ||
|
|
9087a0cf93 | ||
|
|
675171c15f | ||
|
|
287c4a3b0f |
@@ -0,0 +1,31 @@
|
|||||||
|
package org.wfc.user.api;
|
||||||
|
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestHeader;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.wfc.common.core.constant.SecurityConstants;
|
||||||
|
import org.wfc.common.core.constant.ServiceNameConstants;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.user.api.factory.RemoteUPaymentFallbackFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 支付服务
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-27
|
||||||
|
*/
|
||||||
|
@FeignClient(contextId = "remoteUPaymentService", value = ServiceNameConstants.PAYMENT_SERVICE, fallbackFactory = RemoteUPaymentFallbackFactory.class)
|
||||||
|
public interface RemoteUPaymentService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款
|
||||||
|
*
|
||||||
|
* @param orderId 订单id
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/aliPay/tradeRefund")
|
||||||
|
R<Boolean> aliPayRefund(@RequestParam(value = "orderId") Long orderId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
@PostMapping(value = "/refund")
|
||||||
|
R<String> wxPayRefund(@RequestParam(value = "orderId") Long orderId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
}
|
||||||
@@ -86,8 +86,12 @@ public interface RemoteUUserService
|
|||||||
@PostMapping("/client/recordClientUser")
|
@PostMapping("/client/recordClientUser")
|
||||||
public R<Boolean> recordClientUser(@RequestBody UClientBo clientBo);
|
public R<Boolean> recordClientUser(@RequestBody UClientBo clientBo);
|
||||||
|
|
||||||
@PostMapping("/order/paySuccess/{id}")
|
@PostMapping("/order/paySuccess/{paymentType}/{id}")
|
||||||
public R<Boolean> paySuccess(@PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
public R<Boolean> paySuccess(@PathVariable("paymentType")Integer paymentType, @PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
@PostMapping("/order/refundSuccess/{paymentType}/{id}")
|
||||||
|
public R<Boolean> refundSuccess(@PathVariable("paymentType")Integer paymentType, @PathVariable("id") Long id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
|
||||||
|
|
||||||
|
|
||||||
@GetMapping(value = "/order/{id}")
|
@GetMapping(value = "/order/{id}")
|
||||||
public R<UOrderVo> getOrderById(@PathVariable("id") Long id);
|
public R<UOrderVo> getOrderById(@PathVariable("id") Long id);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.wfc.user.api.factory;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.user.api.RemoteUPaymentService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 支付服务降级处理
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-27
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class RemoteUPaymentFallbackFactory implements FallbackFactory<RemoteUPaymentService> {
|
||||||
|
@Override
|
||||||
|
public RemoteUPaymentService create(Throwable throwable) {
|
||||||
|
log.error("Payment service call failed:{}", throwable.getMessage());
|
||||||
|
return new RemoteUPaymentService() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> aliPayRefund(Long orderId, String source) {
|
||||||
|
return R.fail("Failed to alipay refund:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<String> wxPayRefund(Long orderId, String source) {
|
||||||
|
return R.fail("Failed to wxpay refund:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,10 +74,15 @@ public class RemoteUUserFallbackFactory implements FallbackFactory<RemoteUUserSe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<Boolean> paySuccess(Long id, String source) {
|
public R<Boolean> paySuccess(Integer type, Long id, String source) {
|
||||||
return R.fail("pay callback error:" + throwable.getMessage());
|
return R.fail("pay callback error:" + throwable.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<Boolean> refundSuccess(Integer paymentType, Long id, String source) {
|
||||||
|
return R.fail("refund callback error:" + throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<UOrderVo> getOrderById(Long id) {
|
public R<UOrderVo> getOrderById(Long id) {
|
||||||
return R.fail("get order error:" + throwable.getMessage());
|
return R.fail("get order error:" + throwable.getMessage());
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
org.wfc.user.api.factory.RemoteUUserFallbackFactory
|
org.wfc.user.api.factory.RemoteUUserFallbackFactory
|
||||||
org.wfc.user.api.factory.RemoteULogFallbackFactory
|
org.wfc.user.api.factory.RemoteULogFallbackFactory
|
||||||
org.wfc.user.api.factory.RemoteUFileFallbackFactory
|
org.wfc.user.api.factory.RemoteUFileFallbackFactory
|
||||||
|
org.wfc.user.api.factory.RemoteUPaymentFallbackFactory
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ public class ServiceNameConstants
|
|||||||
*/
|
*/
|
||||||
public static final String FILE_SERVICE = "wfc-file";
|
public static final String FILE_SERVICE = "wfc-file";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付服务的serviceid
|
||||||
|
*/
|
||||||
|
public static final String PAYMENT_SERVICE = "wfc-payment";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户平台模块的 service_id
|
* 用户平台模块的 service_id
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.wfc.user.domain.constant;
|
package org.wfc.common.core.enums;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -14,8 +14,10 @@ public enum OrderStatusEnum {
|
|||||||
|
|
||||||
UNPAID(0, "未支付"),
|
UNPAID(0, "未支付"),
|
||||||
PAID(1, "已支付"),
|
PAID(1, "已支付"),
|
||||||
CANCELLED(2, "已取消");
|
CANCELLED(2, "已取消"),
|
||||||
|
REFUNDING(3, "退款中"),
|
||||||
|
REFUNDED(4, "已退款"),
|
||||||
|
;
|
||||||
private final Integer code;
|
private final Integer code;
|
||||||
private final String desc;
|
private final String desc;
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.wfc.common.core.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 支付方式枚举
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-27
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum PaymentTypeEnum {
|
||||||
|
|
||||||
|
BALANCE(0, "余额"),
|
||||||
|
ALIPAY(1, "支付宝"),
|
||||||
|
WX_PAY(2, "微信");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
public static PaymentTypeEnum getByCode(Integer code) {
|
||||||
|
if (code == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (PaymentTypeEnum typeEnum : PaymentTypeEnum.values()) {
|
||||||
|
if (typeEnum.getCode().equals(code)) {
|
||||||
|
return typeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.wfc.common.core.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 退款状态枚举
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-26
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum RefundStatusEnum {
|
||||||
|
|
||||||
|
PENDING(0, "待审批"),
|
||||||
|
PASSED(1, "已通过"),
|
||||||
|
REJECTED(2, "已驳回"),
|
||||||
|
EXPIRED(3, "已过期");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String desc;
|
||||||
|
}
|
||||||
@@ -179,6 +179,9 @@ common.request.parameter.type.not.match=Request parameter''{0}'' requires type:
|
|||||||
common.demo.mode=Demo mode, no operation is allowed
|
common.demo.mode=Demo mode, no operation is allowed
|
||||||
common.system.error=Internal error, please contact the administrator
|
common.system.error=Internal error, please contact the administrator
|
||||||
|
|
||||||
|
## wfc-payment
|
||||||
|
payment.pay.error=pay error
|
||||||
|
|
||||||
## system portal menu
|
## system portal menu
|
||||||
menu.system.management=System Management
|
menu.system.management=System Management
|
||||||
menu.system.config=System Config
|
menu.system.config=System Config
|
||||||
|
|||||||
@@ -181,6 +181,9 @@ common.request.parameter.type.not.match=请求参数类型不匹配,参数''{0
|
|||||||
common.demo.mode=演示模式,不允许操作
|
common.demo.mode=演示模式,不允许操作
|
||||||
common.system.error=内部错误,请联系管理员
|
common.system.error=内部错误,请联系管理员
|
||||||
|
|
||||||
|
## wfc-payment
|
||||||
|
payment.pay.error=支付错误
|
||||||
|
|
||||||
## system portal menu
|
## system portal menu
|
||||||
menu.system.management=系统管理
|
menu.system.management=系统管理
|
||||||
menu.system.config=系统配置
|
menu.system.config=系统配置
|
||||||
|
|||||||
@@ -19,12 +19,9 @@ import com.alipay.api.domain.AlipayTradeCancelModel;
|
|||||||
import com.alipay.api.domain.AlipayTradeCloseModel;
|
import com.alipay.api.domain.AlipayTradeCloseModel;
|
||||||
import com.alipay.api.domain.AlipayTradeCreateModel;
|
import com.alipay.api.domain.AlipayTradeCreateModel;
|
||||||
import com.alipay.api.domain.AlipayTradeOrderSettleModel;
|
import com.alipay.api.domain.AlipayTradeOrderSettleModel;
|
||||||
import com.alipay.api.domain.AlipayTradePagePayModel;
|
|
||||||
import com.alipay.api.domain.AlipayTradePayModel;
|
import com.alipay.api.domain.AlipayTradePayModel;
|
||||||
import com.alipay.api.domain.AlipayTradePrecreateModel;
|
import com.alipay.api.domain.AlipayTradePrecreateModel;
|
||||||
import com.alipay.api.domain.AlipayTradeQueryModel;
|
import com.alipay.api.domain.AlipayTradeQueryModel;
|
||||||
import com.alipay.api.domain.AlipayTradeRefundModel;
|
|
||||||
import com.alipay.api.domain.AlipayTradeWapPayModel;
|
|
||||||
import com.alipay.api.domain.Participant;
|
import com.alipay.api.domain.Participant;
|
||||||
import com.alipay.api.internal.util.AlipaySignature;
|
import com.alipay.api.internal.util.AlipaySignature;
|
||||||
import com.alipay.api.response.AlipayFundAuthOrderFreezeResponse;
|
import com.alipay.api.response.AlipayFundAuthOrderFreezeResponse;
|
||||||
@@ -35,31 +32,31 @@ import com.ijpay.alipay.AliPayApiConfig;
|
|||||||
import com.ijpay.alipay.AliPayApiConfigKit;
|
import com.ijpay.alipay.AliPayApiConfigKit;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.wfc.common.core.domain.R;
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.security.annotation.InnerAuth;
|
||||||
import org.wfc.payment.domain.AliPayBean;
|
import org.wfc.payment.domain.AliPayBean;
|
||||||
import org.wfc.payment.utils.StringUtils;
|
|
||||||
import org.wfc.payment.domain.vo.AjaxResult;
|
import org.wfc.payment.domain.vo.AjaxResult;
|
||||||
import org.wfc.user.api.RemoteUUserService;
|
import org.wfc.payment.pay.alipay.service.IAliPayService;
|
||||||
import org.wfc.user.api.domain.vo.UOrderVo;
|
import org.wfc.payment.utils.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* <p>支付宝支付 Demo</p>
|
* <p>支付宝支付</p>
|
||||||
*
|
*
|
||||||
* @author cyc
|
* @author cyc
|
||||||
*/
|
*/
|
||||||
@Controller
|
@RestController
|
||||||
@RequestMapping("/aliPay")
|
@RequestMapping("/aliPay")
|
||||||
public class AliPayController extends AbstractAliPayApiController {
|
public class AliPayController extends AbstractAliPayApiController {
|
||||||
private static final Logger log = LoggerFactory.getLogger(AliPayController.class);
|
private static final Logger log = LoggerFactory.getLogger(AliPayController.class);
|
||||||
@@ -68,7 +65,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
private AliPayBean aliPayBean;
|
private AliPayBean aliPayBean;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RemoteUUserService remoteUUserService;
|
private IAliPayService aliPayService;
|
||||||
|
|
||||||
private final AjaxResult result = new AjaxResult();
|
private final AjaxResult result = new AjaxResult();
|
||||||
// 普通公钥模式
|
// 普通公钥模式
|
||||||
@@ -110,8 +107,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return aliPayApiConfig;
|
return aliPayApiConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/test")
|
@GetMapping("/test")
|
||||||
@ResponseBody
|
|
||||||
public AliPayApiConfig test() {
|
public AliPayApiConfig test() {
|
||||||
AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig();
|
AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig();
|
||||||
String charset = aliPayApiConfig.getCharset();
|
String charset = aliPayApiConfig.getCharset();
|
||||||
@@ -123,8 +119,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* app支付
|
* app支付
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/appPay")
|
@PostMapping(value = "/appPay")
|
||||||
@ResponseBody
|
|
||||||
public AjaxResult appPay() {
|
public AjaxResult appPay() {
|
||||||
try {
|
try {
|
||||||
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
|
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
|
||||||
@@ -144,97 +139,36 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/wapPay")
|
@PostMapping(value = "/wapPay")
|
||||||
@ResponseBody
|
|
||||||
public void wapPay(HttpServletResponse response, @RequestParam Long orderId) {
|
public void wapPay(HttpServletResponse response, @RequestParam Long orderId) {
|
||||||
R<UOrderVo> orderRes = remoteUUserService.getOrderById(orderId);
|
|
||||||
UOrderVo orderVo = orderRes.getData();
|
|
||||||
if (orderVo == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String totalAmount = orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString();
|
|
||||||
|
|
||||||
String body = "WANFI WAP PAY";
|
|
||||||
String subject = "WANFI PAY";
|
|
||||||
// String totalAmount = "1";
|
|
||||||
String passBackParams = "1";
|
|
||||||
String returnUrl = aliPayBean.getDomain() + RETURN_URL;
|
String returnUrl = aliPayBean.getDomain() + RETURN_URL;
|
||||||
// String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;
|
|
||||||
String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
||||||
if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) {
|
if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) {
|
||||||
notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
||||||
}
|
}
|
||||||
|
aliPayService.wapPay(response, orderId, returnUrl, notifyUrl);
|
||||||
|
|
||||||
|
|
||||||
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
|
|
||||||
model.setBody(body);
|
|
||||||
model.setSubject(subject);
|
|
||||||
model.setTotalAmount(totalAmount);
|
|
||||||
model.setPassbackParams(passBackParams);
|
|
||||||
System.out.println("wap outTradeNo>" + orderId);
|
|
||||||
model.setOutTradeNo(orderId.toString());
|
|
||||||
model.setProductCode("QUICK_WAP_PAY");
|
|
||||||
|
|
||||||
log.info("wap notifyUrl>" + notifyUrl);
|
|
||||||
try {
|
|
||||||
AliPayApi.wapPay(response, model, returnUrl, notifyUrl);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PC支付
|
* PC支付
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/pcPay")
|
@PostMapping(value = "/pcPay")
|
||||||
@ResponseBody
|
|
||||||
public void pcPay(HttpServletResponse response, @RequestParam Long orderId) {
|
public void pcPay(HttpServletResponse response, @RequestParam Long orderId) {
|
||||||
try {
|
|
||||||
R<UOrderVo> orderRes = remoteUUserService.getOrderById(orderId);
|
|
||||||
UOrderVo orderVo = orderRes.getData();
|
|
||||||
if (orderVo == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String totalAmount = orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString();
|
|
||||||
// String outTradeNo = StringUtils.getOutTradeNo();
|
|
||||||
log.info("pc outTradeNo>" + orderId);
|
|
||||||
|
|
||||||
String returnUrl = aliPayBean.getDomain() + RETURN_URL;
|
String returnUrl = aliPayBean.getDomain() + RETURN_URL;
|
||||||
String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
||||||
if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) {
|
if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) {
|
||||||
notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL;
|
||||||
}
|
|
||||||
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
|
|
||||||
|
|
||||||
model.setOutTradeNo(orderId.toString());
|
|
||||||
model.setProductCode("FAST_INSTANT_TRADE_PAY");
|
|
||||||
model.setTotalAmount(totalAmount);
|
|
||||||
model.setSubject("WANFI PAY");
|
|
||||||
// model.setBody("Javen IJPay PC支付测试");
|
|
||||||
model.setPassbackParams("passback_params");
|
|
||||||
/**
|
|
||||||
* 花呗分期相关的设置,测试环境不支持花呗分期的测试
|
|
||||||
* hb_fq_num代表花呗分期数,仅支持传入3、6、12,其他期数暂不支持,传入会报错;
|
|
||||||
* hb_fq_seller_percent代表卖家承担收费比例,商家承担手续费传入100,用户承担手续费传入0,仅支持传入100、0两种,其他比例暂不支持,传入会报错。
|
|
||||||
*/
|
|
||||||
// ExtendParams extendParams = new ExtendParams();
|
|
||||||
// extendParams.setHbFqNum("3");
|
|
||||||
// extendParams.setHbFqSellerPercent("0");
|
|
||||||
// model.setExtendParams(extendParams);
|
|
||||||
log.info("pc notifyUrl>" + notifyUrl);
|
|
||||||
AliPayApi.tradePage(response, model, notifyUrl, returnUrl);
|
|
||||||
// https://opensupport.alipay.com/support/helpcenter/192/201602488772?ant_source=antsupport
|
|
||||||
// Alipay Easy SDK(新版)目前只支持输出form表单,不支持打印出url链接。
|
|
||||||
// AliPayApi.tradePage(response, "GET", model, notifyUrl, returnUrl);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aliPayService.pcPay(response, orderId, returnUrl, notifyUrl);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/tradePay")
|
@PostMapping(value = "/tradePay")
|
||||||
@ResponseBody
|
|
||||||
public String tradePay(@RequestParam("authCode") String authCode, @RequestParam("scene") String scene) {
|
public String tradePay(@RequestParam("authCode") String authCode, @RequestParam("scene") String scene) {
|
||||||
String subject = null;
|
String subject = null;
|
||||||
String waveCode = "wave_code";
|
String waveCode = "wave_code";
|
||||||
@@ -265,8 +199,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 扫码支付
|
* 扫码支付
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradePreCreatePay")
|
@PostMapping(value = "/tradePreCreatePay")
|
||||||
@ResponseBody
|
|
||||||
public String tradePreCreatePay() {
|
public String tradePreCreatePay() {
|
||||||
String subject = "Javen 支付宝扫码支付测试";
|
String subject = "Javen 支付宝扫码支付测试";
|
||||||
String totalAmount = "86";
|
String totalAmount = "86";
|
||||||
@@ -294,8 +227,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
* 单笔转账到支付宝账户
|
* 单笔转账到支付宝账户
|
||||||
* https://docs.open.alipay.com/309/106235/
|
* https://docs.open.alipay.com/309/106235/
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/transfer")
|
@PostMapping(value = "/transfer")
|
||||||
@ResponseBody
|
|
||||||
public String transfer() {
|
public String transfer() {
|
||||||
String totalAmount = "66";
|
String totalAmount = "66";
|
||||||
AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
|
AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
|
||||||
@@ -315,8 +247,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/transferQuery")
|
@GetMapping(value = "/transferQuery")
|
||||||
@ResponseBody
|
|
||||||
public String transferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo,
|
public String transferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo,
|
||||||
@RequestParam(required = false, name = "orderId") String orderId) {
|
@RequestParam(required = false, name = "orderId") String orderId) {
|
||||||
AlipayFundTransOrderQueryModel model = new AlipayFundTransOrderQueryModel();
|
AlipayFundTransOrderQueryModel model = new AlipayFundTransOrderQueryModel();
|
||||||
@@ -335,8 +266,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/uniTransfer")
|
@PostMapping(value = "/uniTransfer")
|
||||||
@ResponseBody
|
|
||||||
public String uniTransfer() {
|
public String uniTransfer() {
|
||||||
String totalAmount = "1";
|
String totalAmount = "1";
|
||||||
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
|
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
|
||||||
@@ -361,8 +291,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/uniTransferQuery")
|
@GetMapping(value = "/uniTransferQuery")
|
||||||
@ResponseBody
|
|
||||||
public String uniTransferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo,
|
public String uniTransferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo,
|
||||||
@RequestParam(required = false, name = "orderId") String orderId) {
|
@RequestParam(required = false, name = "orderId") String orderId) {
|
||||||
AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
|
AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
|
||||||
@@ -381,8 +310,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/accountQuery")
|
@GetMapping(value = "/accountQuery")
|
||||||
@ResponseBody
|
|
||||||
public String accountQuery(@RequestParam(required = true, name = "aliPayUserId") String aliPayUserId) {
|
public String accountQuery(@RequestParam(required = true, name = "aliPayUserId") String aliPayUserId) {
|
||||||
AlipayFundAccountQueryModel model = new AlipayFundAccountQueryModel();
|
AlipayFundAccountQueryModel model = new AlipayFundAccountQueryModel();
|
||||||
model.setAlipayUserId(aliPayUserId);
|
model.setAlipayUserId(aliPayUserId);
|
||||||
@@ -398,8 +326,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 资金授权冻结接口
|
* 资金授权冻结接口
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/authOrderFreeze")
|
@PostMapping(value = "/authOrderFreeze")
|
||||||
@ResponseBody
|
|
||||||
public AlipayFundAuthOrderFreezeResponse authOrderFreeze(@RequestParam("auth_code") String authCode) {
|
public AlipayFundAuthOrderFreezeResponse authOrderFreeze(@RequestParam("auth_code") String authCode) {
|
||||||
try {
|
try {
|
||||||
AlipayFundAuthOrderFreezeModel model = new AlipayFundAuthOrderFreezeModel();
|
AlipayFundAuthOrderFreezeModel model = new AlipayFundAuthOrderFreezeModel();
|
||||||
@@ -423,8 +350,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
* 红包协议支付接口
|
* 红包协议支付接口
|
||||||
* https://docs.open.alipay.com/301/106168/
|
* https://docs.open.alipay.com/301/106168/
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/agreementPay")
|
@PostMapping(value = "/agreementPay")
|
||||||
@ResponseBody
|
|
||||||
public AlipayFundCouponOrderAgreementPayResponse agreementPay() {
|
public AlipayFundCouponOrderAgreementPayResponse agreementPay() {
|
||||||
try {
|
try {
|
||||||
AlipayFundCouponOrderAgreementPayModel model = new AlipayFundCouponOrderAgreementPayModel();
|
AlipayFundCouponOrderAgreementPayModel model = new AlipayFundCouponOrderAgreementPayModel();
|
||||||
@@ -444,8 +370,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 下载对账单
|
* 下载对账单
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/dataDataServiceBill")
|
@PostMapping(value = "/dataDataServiceBill")
|
||||||
@ResponseBody
|
|
||||||
public String dataDataServiceBill(@RequestParam("billDate") String billDate) {
|
public String dataDataServiceBill(@RequestParam("billDate") String billDate) {
|
||||||
try {
|
try {
|
||||||
AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
|
AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
|
||||||
@@ -461,32 +386,17 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 退款
|
* 退款
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradeRefund")
|
@InnerAuth
|
||||||
@ResponseBody
|
@PostMapping(value = "/tradeRefund")
|
||||||
public String tradeRefund(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
public R<Boolean> tradeRefund(@RequestParam Long orderId) {
|
||||||
|
|
||||||
try {
|
return R.ok(aliPayService.tradeRefund(orderId));
|
||||||
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
|
||||||
if (StringUtils.isNotEmpty(outTradeNo)) {
|
|
||||||
model.setOutTradeNo(outTradeNo);
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotEmpty(tradeNo)) {
|
|
||||||
model.setTradeNo(tradeNo);
|
|
||||||
}
|
|
||||||
model.setRefundAmount("86.00");
|
|
||||||
model.setRefundReason("正常退款");
|
|
||||||
return AliPayApi.tradeRefundToResponse(model).getBody();
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 交易查询
|
* 交易查询
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradeQuery")
|
@GetMapping(value = "/tradeQuery")
|
||||||
@ResponseBody
|
|
||||||
public String tradeQuery(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
public String tradeQuery(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
||||||
try {
|
try {
|
||||||
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
|
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
|
||||||
@@ -503,8 +413,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/tradeQueryByStr")
|
@GetMapping(value = "/tradeQueryByStr")
|
||||||
@ResponseBody
|
|
||||||
public String tradeQueryByStr(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
public String tradeQueryByStr(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
||||||
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
|
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
|
||||||
if (StringUtils.isNotEmpty(outTradeNo)) {
|
if (StringUtils.isNotEmpty(outTradeNo)) {
|
||||||
@@ -527,8 +436,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
* 创建订单
|
* 创建订单
|
||||||
* {"alipay_trade_create_response":{"code":"10000","msg":"Success","out_trade_no":"081014283315033","trade_no":"2017081021001004200200274066"},"sign":"ZagfFZntf0loojZzdrBNnHhenhyRrsXwHLBNt1Z/dBbx7cF1o7SZQrzNjRHHmVypHKuCmYifikZIqbNNrFJauSuhT4MQkBJE+YGPDtHqDf4Ajdsv3JEyAM3TR/Xm5gUOpzCY7w+RZzkHevsTd4cjKeGM54GBh0hQH/gSyhs4pEN3lRWopqcKkrkOGZPcmunkbrUAF7+AhKGUpK+AqDw4xmKFuVChDKaRdnhM6/yVsezJFXzlQeVgFjbfiWqULxBXq1gqicntyUxvRygKA+5zDTqE5Jj3XRDjVFIDBeOBAnM+u03fUP489wV5V5apyI449RWeybLg08Wo+jUmeOuXOA=="}
|
* {"alipay_trade_create_response":{"code":"10000","msg":"Success","out_trade_no":"081014283315033","trade_no":"2017081021001004200200274066"},"sign":"ZagfFZntf0loojZzdrBNnHhenhyRrsXwHLBNt1Z/dBbx7cF1o7SZQrzNjRHHmVypHKuCmYifikZIqbNNrFJauSuhT4MQkBJE+YGPDtHqDf4Ajdsv3JEyAM3TR/Xm5gUOpzCY7w+RZzkHevsTd4cjKeGM54GBh0hQH/gSyhs4pEN3lRWopqcKkrkOGZPcmunkbrUAF7+AhKGUpK+AqDw4xmKFuVChDKaRdnhM6/yVsezJFXzlQeVgFjbfiWqULxBXq1gqicntyUxvRygKA+5zDTqE5Jj3XRDjVFIDBeOBAnM+u03fUP489wV5V5apyI449RWeybLg08Wo+jUmeOuXOA=="}
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradeCreate")
|
@PostMapping(value = "/tradeCreate")
|
||||||
@ResponseBody
|
|
||||||
public String tradeCreate(@RequestParam("outTradeNo") String outTradeNo) {
|
public String tradeCreate(@RequestParam("outTradeNo") String outTradeNo) {
|
||||||
|
|
||||||
String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;
|
String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;
|
||||||
@@ -552,8 +460,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 撤销订单
|
* 撤销订单
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradeCancel")
|
@PostMapping(value = "/tradeCancel")
|
||||||
@ResponseBody
|
|
||||||
public String tradeCancel(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
public String tradeCancel(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
|
||||||
try {
|
try {
|
||||||
AlipayTradeCancelModel model = new AlipayTradeCancelModel();
|
AlipayTradeCancelModel model = new AlipayTradeCancelModel();
|
||||||
@@ -574,8 +481,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 关闭订单
|
* 关闭订单
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradeClose")
|
@PostMapping(value = "/tradeClose")
|
||||||
@ResponseBody
|
|
||||||
public String tradeClose(@RequestParam("outTradeNo") String outTradeNo, @RequestParam("tradeNo") String tradeNo) {
|
public String tradeClose(@RequestParam("outTradeNo") String outTradeNo, @RequestParam("tradeNo") String tradeNo) {
|
||||||
try {
|
try {
|
||||||
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
|
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
|
||||||
@@ -596,8 +502,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 结算
|
* 结算
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/tradeOrderSettle")
|
@PostMapping(value = "/tradeOrderSettle")
|
||||||
@ResponseBody
|
|
||||||
public String tradeOrderSettle(@RequestParam("tradeNo") String tradeNo) {
|
public String tradeOrderSettle(@RequestParam("tradeNo") String tradeNo) {
|
||||||
try {
|
try {
|
||||||
AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
|
AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
|
||||||
@@ -614,8 +519,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 获取应用授权URL并授权
|
* 获取应用授权URL并授权
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/toOauth")
|
@PostMapping(value = "/toOauth")
|
||||||
@ResponseBody
|
|
||||||
public void toOauth(HttpServletResponse response) {
|
public void toOauth(HttpServletResponse response) {
|
||||||
try {
|
try {
|
||||||
String redirectUri = aliPayBean.getDomain() + "/aliPay/redirect_uri";
|
String redirectUri = aliPayBean.getDomain() + "/aliPay/redirect_uri";
|
||||||
@@ -629,8 +533,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 应用授权回调
|
* 应用授权回调
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/redirect_uri")
|
@PostMapping(value = "/redirect_uri")
|
||||||
@ResponseBody
|
|
||||||
public String redirectUri(@RequestParam("app_id") String appId, @RequestParam("app_auth_code") String appAuthCode) {
|
public String redirectUri(@RequestParam("app_id") String appId, @RequestParam("app_auth_code") String appAuthCode) {
|
||||||
try {
|
try {
|
||||||
System.out.println("app_id:" + appId);
|
System.out.println("app_id:" + appId);
|
||||||
@@ -649,8 +552,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 查询授权信息
|
* 查询授权信息
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/openAuthTokenAppQuery")
|
@GetMapping(value = "/openAuthTokenAppQuery")
|
||||||
@ResponseBody
|
|
||||||
public String openAuthTokenAppQuery(@RequestParam("appAuthToken") String appAuthToken) {
|
public String openAuthTokenAppQuery(@RequestParam("appAuthToken") String appAuthToken) {
|
||||||
try {
|
try {
|
||||||
AlipayOpenAuthTokenAppQueryModel model = new AlipayOpenAuthTokenAppQueryModel();
|
AlipayOpenAuthTokenAppQueryModel model = new AlipayOpenAuthTokenAppQueryModel();
|
||||||
@@ -665,8 +567,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 批量付款到支付宝账户有密接口
|
* 批量付款到支付宝账户有密接口
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/batchTrans")
|
@PostMapping(value = "/batchTrans")
|
||||||
@ResponseBody
|
|
||||||
public void batchTrans(HttpServletResponse response) {
|
public void batchTrans(HttpServletResponse response) {
|
||||||
try {
|
try {
|
||||||
String signType = "MD5";
|
String signType = "MD5";
|
||||||
@@ -692,8 +593,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 地铁购票核销码发码
|
* 地铁购票核销码发码
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/voucherGenerate")
|
@PostMapping(value = "/voucherGenerate")
|
||||||
@ResponseBody
|
|
||||||
public String voucherGenerate(@RequestParam("tradeNo") String tradeNo) {
|
public String voucherGenerate(@RequestParam("tradeNo") String tradeNo) {
|
||||||
try {
|
try {
|
||||||
//需要支付成功的订单号
|
//需要支付成功的订单号
|
||||||
@@ -715,8 +615,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/return_url")
|
@PostMapping(value = "/return_url")
|
||||||
@ResponseBody
|
|
||||||
public String returnUrl(HttpServletRequest request) {
|
public String returnUrl(HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
// 获取支付宝GET过来反馈信息
|
// 获取支付宝GET过来反馈信息
|
||||||
@@ -729,13 +628,13 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
"RSA2");
|
"RSA2");
|
||||||
|
|
||||||
if (verifyResult) {
|
if (verifyResult) {
|
||||||
// TODO 请在这里加上商户的业务逻辑程序代码
|
// 请在这里加上商户的业务逻辑程序代码
|
||||||
System.out.println("return_url 验证成功");
|
System.out.println("return_url 验证成功");
|
||||||
|
|
||||||
return "success";
|
return "success";
|
||||||
} else {
|
} else {
|
||||||
System.out.println("return_url 验证失败");
|
System.out.println("return_url 验证失败");
|
||||||
// TODO
|
//
|
||||||
return "failure";
|
return "failure";
|
||||||
}
|
}
|
||||||
} catch (AlipayApiException e) {
|
} catch (AlipayApiException e) {
|
||||||
@@ -744,8 +643,7 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/cert_return_url")
|
@PostMapping(value = "/cert_return_url")
|
||||||
@ResponseBody
|
|
||||||
public String certReturnUrl(HttpServletRequest request) {
|
public String certReturnUrl(HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
// 获取支付宝GET过来反馈信息
|
// 获取支付宝GET过来反馈信息
|
||||||
@@ -758,13 +656,13 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
"RSA2");
|
"RSA2");
|
||||||
|
|
||||||
if (verifyResult) {
|
if (verifyResult) {
|
||||||
// TODO 请在这里加上商户的业务逻辑程序代码
|
// 请在这里加上商户的业务逻辑程序代码
|
||||||
System.out.println("certReturnUrl 验证成功");
|
System.out.println("certReturnUrl 验证成功");
|
||||||
|
|
||||||
return "success";
|
return "success";
|
||||||
} else {
|
} else {
|
||||||
System.out.println("certReturnUrl 验证失败");
|
System.out.println("certReturnUrl 验证失败");
|
||||||
// TODO
|
//
|
||||||
return "failure";
|
return "failure";
|
||||||
}
|
}
|
||||||
} catch (AlipayApiException e) {
|
} catch (AlipayApiException e) {
|
||||||
@@ -774,38 +672,13 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping(value = "/callback")
|
@PostMapping(value = "/callback")
|
||||||
@ResponseBody
|
|
||||||
public String notifyUrl(HttpServletRequest request) {
|
public String notifyUrl(HttpServletRequest request) {
|
||||||
try {
|
|
||||||
// 获取支付宝POST过来反馈信息
|
|
||||||
Map<String, String> params = AliPayApi.toMap(request);
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
return aliPayService.notifyUrl(request, aliPayBean.getPublicKey());
|
||||||
System.out.println(entry.getKey() + " = " + entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean verifyResult = AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8", "RSA2");
|
|
||||||
|
|
||||||
if (verifyResult) {
|
|
||||||
// TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
|
|
||||||
System.out.println("notify_url 验证成功succcess");
|
|
||||||
String outTradeNo = params.get("out_trade_no");
|
|
||||||
remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner");
|
|
||||||
return "success";
|
|
||||||
} else {
|
|
||||||
System.out.println("notify_url 验证失败");
|
|
||||||
// TODO
|
|
||||||
return "failure";
|
|
||||||
}
|
|
||||||
} catch (AlipayApiException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return "failure";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/cert_notify_url")
|
@PostMapping(value = "/cert_notify_url")
|
||||||
@ResponseBody
|
|
||||||
public String certNotifyUrl(HttpServletRequest request) {
|
public String certNotifyUrl(HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
// 获取支付宝POST过来反馈信息
|
// 获取支付宝POST过来反馈信息
|
||||||
@@ -818,12 +691,12 @@ public class AliPayController extends AbstractAliPayApiController {
|
|||||||
boolean verifyResult = AlipaySignature.rsaCertCheckV1(params, aliPayBean.getAliPayCertPath(), "UTF-8", "RSA2");
|
boolean verifyResult = AlipaySignature.rsaCertCheckV1(params, aliPayBean.getAliPayCertPath(), "UTF-8", "RSA2");
|
||||||
|
|
||||||
if (verifyResult) {
|
if (verifyResult) {
|
||||||
// TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
|
// 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
|
||||||
System.out.println("certNotifyUrl 验证成功succcess");
|
System.out.println("certNotifyUrl 验证成功succcess");
|
||||||
return "success";
|
return "success";
|
||||||
} else {
|
} else {
|
||||||
System.out.println("certNotifyUrl 验证失败");
|
System.out.println("certNotifyUrl 验证失败");
|
||||||
// TODO
|
//
|
||||||
return "failure";
|
return "failure";
|
||||||
}
|
}
|
||||||
} catch (AlipayApiException e) {
|
} catch (AlipayApiException e) {
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.wfc.payment.pay.alipay.service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 支付宝支付Service
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-21
|
||||||
|
*/
|
||||||
|
public interface IAliPayService {
|
||||||
|
|
||||||
|
void pcPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl);
|
||||||
|
|
||||||
|
void wapPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl);
|
||||||
|
|
||||||
|
String notifyUrl(HttpServletRequest request, String publicKey);
|
||||||
|
|
||||||
|
Boolean tradeRefund(Long orderId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
package org.wfc.payment.pay.alipay.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.alipay.api.AlipayApiException;
|
||||||
|
import com.alipay.api.domain.AlipayTradePagePayModel;
|
||||||
|
import com.alipay.api.domain.AlipayTradeRefundModel;
|
||||||
|
import com.alipay.api.domain.AlipayTradeWapPayModel;
|
||||||
|
import com.alipay.api.internal.util.AlipaySignature;
|
||||||
|
import com.alipay.api.response.AlipayTradeRefundResponse;
|
||||||
|
import com.ijpay.alipay.AliPayApi;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.core.enums.PaymentTypeEnum;
|
||||||
|
import org.wfc.payment.pay.alipay.service.IAliPayService;
|
||||||
|
import org.wfc.user.api.RemoteUUserService;
|
||||||
|
import org.wfc.user.api.domain.vo.UOrderVo;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 支付宝支付ServiceImpl
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-21
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class AliPayServiceImpl implements IAliPayService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RemoteUUserService remoteUUserService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pcPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl) {
|
||||||
|
try {
|
||||||
|
String totalAmount = getAmountByOrder(orderId);
|
||||||
|
if (StrUtil.isBlank(totalAmount)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info("pc outTradeNo>" + orderId);
|
||||||
|
|
||||||
|
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
|
||||||
|
|
||||||
|
model.setOutTradeNo(orderId.toString());
|
||||||
|
model.setProductCode("FAST_INSTANT_TRADE_PAY");
|
||||||
|
model.setTotalAmount(totalAmount);
|
||||||
|
model.setSubject("WANFI PAY");
|
||||||
|
model.setPassbackParams("passback_params");
|
||||||
|
|
||||||
|
log.info("pc notifyUrl>" + notifyUrl);
|
||||||
|
AliPayApi.tradePage(response, model, notifyUrl, returnUrl);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("alipay pc pay error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAmountByOrder(Long orderId) {
|
||||||
|
R<UOrderVo> orderRes = remoteUUserService.getOrderById(orderId);
|
||||||
|
UOrderVo orderVo = orderRes.getData();
|
||||||
|
if (orderVo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void wapPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl) {
|
||||||
|
String totalAmount = getAmountByOrder(orderId);
|
||||||
|
if (StrUtil.isBlank(totalAmount)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String body = "WANFI WAP PAY";
|
||||||
|
String subject = "WANFI PAY";
|
||||||
|
String passBackParams = "1";
|
||||||
|
|
||||||
|
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
|
||||||
|
model.setBody(body);
|
||||||
|
model.setSubject(subject);
|
||||||
|
model.setTotalAmount(totalAmount);
|
||||||
|
model.setPassbackParams(passBackParams);
|
||||||
|
System.out.println("wap outTradeNo>" + orderId);
|
||||||
|
model.setOutTradeNo(orderId.toString());
|
||||||
|
model.setProductCode("QUICK_WAP_PAY");
|
||||||
|
|
||||||
|
log.info("wap notifyUrl>" + notifyUrl);
|
||||||
|
try {
|
||||||
|
AliPayApi.wapPay(response, model, returnUrl, notifyUrl);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("alipay wap pay error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String notifyUrl(HttpServletRequest request, String publicKey) {
|
||||||
|
try {
|
||||||
|
// 获取支付宝POST过来反馈信息
|
||||||
|
Map<String, String> params = AliPayApi.toMap(request);
|
||||||
|
|
||||||
|
boolean verifyResult = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", "RSA2");
|
||||||
|
|
||||||
|
if (verifyResult) {
|
||||||
|
// 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
|
||||||
|
String outTradeNo = params.get("out_trade_no");
|
||||||
|
remoteUUserService.paySuccess(PaymentTypeEnum.ALIPAY.getCode(), Long.valueOf(outTradeNo), "inner");
|
||||||
|
return "success";
|
||||||
|
} else {
|
||||||
|
log.error("notify_url 验证失败");
|
||||||
|
return "failure";
|
||||||
|
}
|
||||||
|
} catch (AlipayApiException e) {
|
||||||
|
log.error("alipay notifyUrl error", e);
|
||||||
|
return "failure";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean tradeRefund(Long orderId) {
|
||||||
|
try {
|
||||||
|
String totalAmount = getAmountByOrder(orderId);
|
||||||
|
if (StrUtil.isBlank(totalAmount)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
|
||||||
|
if (ObjectUtil.isNotNull(orderId)) {
|
||||||
|
model.setOutTradeNo(orderId.toString());
|
||||||
|
}
|
||||||
|
model.setRefundAmount(totalAmount);
|
||||||
|
model.setRefundReason("normal refund");
|
||||||
|
AlipayTradeRefundResponse alipayTradeRefundResponse = AliPayApi.tradeRefundToResponse(model);
|
||||||
|
if ("Y".equals(alipayTradeRefundResponse.getFundChange())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (AlipayApiException e) {
|
||||||
|
log.error("alipay refund error", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.wfc.payment.pay.wxpay.controller;
|
package org.wfc.payment.pay.wxpay.controller;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
@@ -20,7 +19,6 @@ import com.ijpay.wxpay.model.MicroPayModel;
|
|||||||
import com.ijpay.wxpay.model.OrderQueryModel;
|
import com.ijpay.wxpay.model.OrderQueryModel;
|
||||||
import com.ijpay.wxpay.model.ProfitSharingModel;
|
import com.ijpay.wxpay.model.ProfitSharingModel;
|
||||||
import com.ijpay.wxpay.model.ReceiverModel;
|
import com.ijpay.wxpay.model.ReceiverModel;
|
||||||
import com.ijpay.wxpay.model.RefundModel;
|
|
||||||
import com.ijpay.wxpay.model.RefundQueryModel;
|
import com.ijpay.wxpay.model.RefundQueryModel;
|
||||||
import com.ijpay.wxpay.model.SendRedPackModel;
|
import com.ijpay.wxpay.model.SendRedPackModel;
|
||||||
import com.ijpay.wxpay.model.TransferModel;
|
import com.ijpay.wxpay.model.TransferModel;
|
||||||
@@ -28,41 +26,36 @@ import com.ijpay.wxpay.model.UnifiedOrderModel;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.wfc.common.core.domain.R;
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.security.annotation.InnerAuth;
|
||||||
import org.wfc.payment.domain.H5SceneInfo;
|
import org.wfc.payment.domain.H5SceneInfo;
|
||||||
import org.wfc.payment.domain.WxPayBean;
|
import org.wfc.payment.domain.WxPayBean;
|
||||||
import org.wfc.payment.domain.vo.AjaxResult;
|
import org.wfc.payment.domain.vo.AjaxResult;
|
||||||
import org.wfc.payment.utils.MultipartFileUtil;
|
import org.wfc.payment.pay.wxpay.service.IWxPayService;
|
||||||
import org.wfc.system.api.RemoteFileService;
|
|
||||||
import org.wfc.system.api.domain.SysFile;
|
|
||||||
import org.wfc.user.api.RemoteUUserService;
|
|
||||||
import org.wfc.user.api.domain.vo.UOrderVo;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
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;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>微信支付 Demo</p>
|
* <p>微信支付</p>
|
||||||
*
|
*
|
||||||
* @author cyc
|
* @author cyc
|
||||||
*/
|
*/
|
||||||
@Controller
|
@RestController
|
||||||
@RequestMapping("/wxPay")
|
@RequestMapping("/wxPay")
|
||||||
public class WxPayController extends AbstractWxPayApiController {
|
public class WxPayController extends AbstractWxPayApiController {
|
||||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||||
@@ -71,10 +64,7 @@ public class WxPayController extends AbstractWxPayApiController {
|
|||||||
private WxPayBean wxPayBean;
|
private WxPayBean wxPayBean;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RemoteUUserService remoteUUserService;
|
private IWxPayService wxPayService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RemoteFileService remoteFileService;
|
|
||||||
|
|
||||||
private String notifyUrl;
|
private String notifyUrl;
|
||||||
private String refundNotifyUrl;
|
private String refundNotifyUrl;
|
||||||
@@ -373,76 +363,8 @@ public class WxPayController extends AbstractWxPayApiController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult scanCode2(HttpServletRequest request, HttpServletResponse response,
|
public AjaxResult scanCode2(HttpServletRequest request, HttpServletResponse response,
|
||||||
@RequestParam("orderId") Long orderId) {
|
@RequestParam("orderId") Long orderId) {
|
||||||
R<UOrderVo> orderRes = remoteUUserService.getOrderById(orderId);
|
String url = wxPayService.scanCode2(request, orderId, notifyUrl);
|
||||||
UOrderVo orderVo = orderRes.getData();
|
return new AjaxResult().success(url);
|
||||||
if (orderVo == null) {
|
|
||||||
return new AjaxResult().addError("订单不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
String totalFee = orderVo.getOrderAmount().multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).toString();
|
|
||||||
// String totalFee = "0.01";
|
|
||||||
if (StrUtil.isBlank(totalFee)) {
|
|
||||||
return new AjaxResult().addError("支付金额不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
String ip = IpKit.getRealIp(request);
|
|
||||||
if (StrUtil.isBlank(ip)) {
|
|
||||||
ip = "127.0.0.1";
|
|
||||||
}
|
|
||||||
WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
|
|
||||||
|
|
||||||
Map<String, String> params = UnifiedOrderModel
|
|
||||||
.builder()
|
|
||||||
.appid(wxPayApiConfig.getAppId())
|
|
||||||
.mch_id(wxPayApiConfig.getMchId())
|
|
||||||
.nonce_str(WxPayKit.generateStr())
|
|
||||||
.body("WANFI PAY")
|
|
||||||
.out_trade_no(WxPayKit.generateStr())
|
|
||||||
.total_fee(totalFee)
|
|
||||||
.spbill_create_ip(ip)
|
|
||||||
.notify_url(notifyUrl)
|
|
||||||
.trade_type(TradeType.NATIVE.getTradeType())
|
|
||||||
.build()
|
|
||||||
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
|
|
||||||
|
|
||||||
String xmlResult = WxPayApi.pushOrder(false, params);
|
|
||||||
log.info("统一下单:" + xmlResult);
|
|
||||||
|
|
||||||
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
|
||||||
|
|
||||||
String returnCode = result.get("return_code");
|
|
||||||
String returnMsg = result.get("return_msg");
|
|
||||||
System.out.println(returnMsg);
|
|
||||||
if (!WxPayKit.codeIsOk(returnCode)) {
|
|
||||||
return new AjaxResult().addError("error:" + returnMsg);
|
|
||||||
}
|
|
||||||
String resultCode = result.get("result_code");
|
|
||||||
if (!WxPayKit.codeIsOk(resultCode)) {
|
|
||||||
return new AjaxResult().addError("error:" + returnMsg);
|
|
||||||
}
|
|
||||||
//生成预付订单success
|
|
||||||
|
|
||||||
String qrCodeUrl = result.get("code_url");
|
|
||||||
String name = "payQRCode2.png";
|
|
||||||
|
|
||||||
String basePath = System.getProperty("user.dir") + File.separator + name;
|
|
||||||
// String url = fileBean.getDomain() + fileBean.getPrefix() + File.separator + orderId + File.separator + name;
|
|
||||||
FileUtil.mkdir(basePath);
|
|
||||||
|
|
||||||
boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
|
|
||||||
basePath);
|
|
||||||
File uploadFile = new File(basePath);
|
|
||||||
MultipartFile multipartFile = MultipartFileUtil.getMultipartFile(uploadFile);
|
|
||||||
R<SysFile> fileResult = remoteFileService.upload(multipartFile);
|
|
||||||
String url = fileResult.getData().getUrl();
|
|
||||||
log.info("qr code file: {}", basePath);
|
|
||||||
FileUtil.del(uploadFile);
|
|
||||||
|
|
||||||
if (encode) {
|
|
||||||
//在页面上显示
|
|
||||||
return new AjaxResult().success(url);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -846,37 +768,11 @@ public class WxPayController extends AbstractWxPayApiController {
|
|||||||
/**
|
/**
|
||||||
* 微信退款
|
* 微信退款
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/refund", method = {RequestMethod.POST, RequestMethod.GET})
|
@InnerAuth
|
||||||
|
@PostMapping(value = "/refund")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String refund(@RequestParam(value = "transactionId", required = false) String transactionId,
|
public R<String> refund(@RequestParam(value = "orderId") Long orderId) {
|
||||||
@RequestParam(value = "outTradeNo", required = false) String outTradeNo) {
|
return R.ok(wxPayService.refund(orderId, refundNotifyUrl));
|
||||||
try {
|
|
||||||
log.info("transactionId: {} outTradeNo:{}", transactionId, outTradeNo);
|
|
||||||
|
|
||||||
if (StrUtil.isBlank(outTradeNo) && StrUtil.isBlank(transactionId)) {
|
|
||||||
return "transactionId、out_trade_no二选一";
|
|
||||||
}
|
|
||||||
WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
|
|
||||||
|
|
||||||
Map<String, String> params = RefundModel.builder()
|
|
||||||
.appid(wxPayApiConfig.getAppId())
|
|
||||||
.mch_id(wxPayApiConfig.getMchId())
|
|
||||||
.nonce_str(WxPayKit.generateStr())
|
|
||||||
.transaction_id(transactionId)
|
|
||||||
.out_trade_no(outTradeNo)
|
|
||||||
.out_refund_no(WxPayKit.generateStr())
|
|
||||||
.total_fee("1")
|
|
||||||
.refund_fee("1")
|
|
||||||
.notify_url(refundNotifyUrl)
|
|
||||||
.build()
|
|
||||||
.createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
|
|
||||||
String refundStr = WxPayApi.orderRefund(false, params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
|
|
||||||
log.info("refundStr: {}", refundStr);
|
|
||||||
return refundStr;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -911,24 +807,7 @@ public class WxPayController extends AbstractWxPayApiController {
|
|||||||
@RequestMapping(value = "/refundNotify", method = {RequestMethod.POST, RequestMethod.GET})
|
@RequestMapping(value = "/refundNotify", method = {RequestMethod.POST, RequestMethod.GET})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String refundNotify(HttpServletRequest request) {
|
public String refundNotify(HttpServletRequest request) {
|
||||||
String xmlMsg = HttpKit.readData(request);
|
return wxPayService.refundNotify(request);
|
||||||
log.info("退款通知=" + xmlMsg);
|
|
||||||
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
|
|
||||||
|
|
||||||
String returnCode = params.get("return_code");
|
|
||||||
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
|
|
||||||
if (WxPayKit.codeIsOk(returnCode)) {
|
|
||||||
String reqInfo = params.get("req_info");
|
|
||||||
String decryptData = WxPayKit.decryptData(reqInfo, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey());
|
|
||||||
log.info("退款通知解密后的数据=" + decryptData);
|
|
||||||
// 更新订单信息
|
|
||||||
// 发送通知等
|
|
||||||
Map<String, String> xml = new HashMap<String, String>(2);
|
|
||||||
xml.put("return_code", "SUCCESS");
|
|
||||||
xml.put("return_msg", "OK");
|
|
||||||
return WxPayKit.toXml(xml);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/sendRedPack", method = {RequestMethod.POST, RequestMethod.GET})
|
@RequestMapping(value = "/sendRedPack", method = {RequestMethod.POST, RequestMethod.GET})
|
||||||
@@ -973,26 +852,6 @@ public class WxPayController extends AbstractWxPayApiController {
|
|||||||
@RequestMapping(value = "/callback", method = {RequestMethod.POST, RequestMethod.GET})
|
@RequestMapping(value = "/callback", method = {RequestMethod.POST, RequestMethod.GET})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String payNotify(HttpServletRequest request) {
|
public String payNotify(HttpServletRequest request) {
|
||||||
String xmlMsg = HttpKit.readData(request);
|
return wxPayService.payNotify(request);
|
||||||
log.info("支付通知=" + xmlMsg);
|
|
||||||
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
|
|
||||||
|
|
||||||
String returnCode = params.get("return_code");
|
|
||||||
|
|
||||||
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
|
|
||||||
// 注意此处签名方式需与统一下单的签名类型一致
|
|
||||||
if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
|
|
||||||
if (WxPayKit.codeIsOk(returnCode)) {
|
|
||||||
// 更新订单信息
|
|
||||||
// 发送通知等
|
|
||||||
Map<String, String> xml = new HashMap<String, String>(2);
|
|
||||||
String outTradeNo = params.get("out_trade_no");
|
|
||||||
remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner");
|
|
||||||
xml.put("return_code", "SUCCESS");
|
|
||||||
xml.put("return_msg", "OK");
|
|
||||||
return WxPayKit.toXml(xml);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.wfc.payment.pay.wxpay.service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 微信支付Service
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-21
|
||||||
|
*/
|
||||||
|
public interface IWxPayService {
|
||||||
|
|
||||||
|
String scanCode2(HttpServletRequest request, Long orderId, String notifyUrl);
|
||||||
|
|
||||||
|
String payNotify(HttpServletRequest request);
|
||||||
|
|
||||||
|
String refund(Long orderId, String notifyUrl);
|
||||||
|
|
||||||
|
String refundNotify(HttpServletRequest request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
package org.wfc.payment.pay.wxpay.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||||
|
import com.ijpay.core.enums.SignType;
|
||||||
|
import com.ijpay.core.enums.TradeType;
|
||||||
|
import com.ijpay.core.kit.HttpKit;
|
||||||
|
import com.ijpay.core.kit.IpKit;
|
||||||
|
import com.ijpay.core.kit.QrCodeKit;
|
||||||
|
import com.ijpay.core.kit.WxPayKit;
|
||||||
|
import com.ijpay.wxpay.WxPayApi;
|
||||||
|
import com.ijpay.wxpay.WxPayApiConfig;
|
||||||
|
import com.ijpay.wxpay.WxPayApiConfigKit;
|
||||||
|
import com.ijpay.wxpay.model.RefundModel;
|
||||||
|
import com.ijpay.wxpay.model.UnifiedOrderModel;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.core.enums.PaymentTypeEnum;
|
||||||
|
import org.wfc.common.core.exception.ServiceException;
|
||||||
|
import org.wfc.payment.pay.wxpay.service.IWxPayService;
|
||||||
|
import org.wfc.payment.utils.MultipartFileUtil;
|
||||||
|
import org.wfc.system.api.RemoteFileService;
|
||||||
|
import org.wfc.system.api.domain.SysFile;
|
||||||
|
import org.wfc.user.api.RemoteUUserService;
|
||||||
|
import org.wfc.user.api.domain.vo.UOrderVo;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.File;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 微信支付ServiceImpl
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-21
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class WxPayServiceImpl implements IWxPayService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RemoteUUserService remoteUUserService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RemoteFileService remoteFileService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String scanCode2(HttpServletRequest request, Long orderId, String notifyUrl) {
|
||||||
|
String totalFee = getAmountByOrder(orderId);
|
||||||
|
|
||||||
|
String ip = IpKit.getRealIp(request);
|
||||||
|
if (StrUtil.isBlank(ip)) {
|
||||||
|
ip = "127.0.0.1";
|
||||||
|
}
|
||||||
|
WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
|
||||||
|
|
||||||
|
Map<String, String> params = UnifiedOrderModel
|
||||||
|
.builder()
|
||||||
|
.appid(wxPayApiConfig.getAppId())
|
||||||
|
.mch_id(wxPayApiConfig.getMchId())
|
||||||
|
.nonce_str(WxPayKit.generateStr())
|
||||||
|
.body("WANFI PAY")
|
||||||
|
.out_trade_no(WxPayKit.generateStr())
|
||||||
|
.total_fee(totalFee)
|
||||||
|
.spbill_create_ip(ip)
|
||||||
|
.notify_url(notifyUrl)
|
||||||
|
.trade_type(TradeType.NATIVE.getTradeType())
|
||||||
|
.build()
|
||||||
|
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
|
||||||
|
|
||||||
|
String xmlResult = WxPayApi.pushOrder(false, params);
|
||||||
|
log.info("统一下单:" + xmlResult);
|
||||||
|
|
||||||
|
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
||||||
|
|
||||||
|
String returnCode = result.get("return_code");
|
||||||
|
String returnMsg = result.get("return_msg");
|
||||||
|
System.out.println(returnMsg);
|
||||||
|
if (!WxPayKit.codeIsOk(returnCode)) {
|
||||||
|
log.error("error:{}", returnMsg);
|
||||||
|
throw new ServiceException("payment.pay.error");
|
||||||
|
}
|
||||||
|
String resultCode = result.get("result_code");
|
||||||
|
if (!WxPayKit.codeIsOk(resultCode)) {
|
||||||
|
log.error("error:{}", returnMsg);
|
||||||
|
throw new ServiceException("payment.pay.error");
|
||||||
|
}
|
||||||
|
//生成预付订单success
|
||||||
|
|
||||||
|
String qrCodeUrl = result.get("code_url");
|
||||||
|
String name = "payQRCode2.png";
|
||||||
|
|
||||||
|
String basePath = System.getProperty("user.dir") + File.separator + name;
|
||||||
|
// String url = fileBean.getDomain() + fileBean.getPrefix() + File.separator + orderId + File.separator + name;
|
||||||
|
FileUtil.mkdir(basePath);
|
||||||
|
|
||||||
|
boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
|
||||||
|
basePath);
|
||||||
|
File uploadFile = new File(basePath);
|
||||||
|
MultipartFile multipartFile = MultipartFileUtil.getMultipartFile(uploadFile);
|
||||||
|
R<SysFile> fileResult = remoteFileService.upload(multipartFile);
|
||||||
|
String url = fileResult.getData().getUrl();
|
||||||
|
log.info("qr code file: {}", basePath);
|
||||||
|
FileUtil.del(uploadFile);
|
||||||
|
|
||||||
|
if (encode) {
|
||||||
|
//在页面上显示
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
throw new ServiceException("payment.pay.error");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String payNotify(HttpServletRequest request) {
|
||||||
|
String xmlMsg = HttpKit.readData(request);
|
||||||
|
log.info("支付通知=" + xmlMsg);
|
||||||
|
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
|
||||||
|
|
||||||
|
String returnCode = params.get("return_code");
|
||||||
|
|
||||||
|
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
|
||||||
|
// 注意此处签名方式需与统一下单的签名类型一致
|
||||||
|
if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
|
||||||
|
if (WxPayKit.codeIsOk(returnCode)) {
|
||||||
|
// 更新订单信息
|
||||||
|
// 发送通知等
|
||||||
|
Map<String, String> xml = new HashMap<String, String>(2);
|
||||||
|
String outTradeNo = params.get("out_trade_no");
|
||||||
|
remoteUUserService.paySuccess(PaymentTypeEnum.WX_PAY.getCode(), Long.valueOf(outTradeNo), "inner");
|
||||||
|
xml.put("return_code", "SUCCESS");
|
||||||
|
xml.put("return_msg", "OK");
|
||||||
|
return WxPayKit.toXml(xml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refund(Long orderId, String notifyUrl) {
|
||||||
|
try {
|
||||||
|
String totalFee = getAmountByOrder(orderId);
|
||||||
|
log.info("outTradeNo:{}", orderId);
|
||||||
|
|
||||||
|
WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
|
||||||
|
|
||||||
|
Map<String, String> params = RefundModel.builder()
|
||||||
|
.appid(wxPayApiConfig.getAppId())
|
||||||
|
.mch_id(wxPayApiConfig.getMchId())
|
||||||
|
.nonce_str(WxPayKit.generateStr())
|
||||||
|
.out_trade_no(orderId.toString())
|
||||||
|
.out_refund_no(WxPayKit.generateStr())
|
||||||
|
.total_fee(totalFee)
|
||||||
|
.refund_fee(totalFee)
|
||||||
|
.notify_url(notifyUrl)
|
||||||
|
.build()
|
||||||
|
.createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
|
||||||
|
String refundStr = WxPayApi.orderRefund(false, params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
|
||||||
|
|
||||||
|
log.info("refundStr: {}", refundStr);
|
||||||
|
return refundStr;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("refund error", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refundNotify(HttpServletRequest request) {
|
||||||
|
String xmlMsg = HttpKit.readData(request);
|
||||||
|
log.info("退款通知=" + xmlMsg);
|
||||||
|
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
|
||||||
|
|
||||||
|
String returnCode = params.get("return_code");
|
||||||
|
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
|
||||||
|
if (WxPayKit.codeIsOk(returnCode)) {
|
||||||
|
String reqInfo = params.get("req_info");
|
||||||
|
String decryptData = WxPayKit.decryptData(reqInfo, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey());
|
||||||
|
log.info("退款通知解密后的数据=" + decryptData);
|
||||||
|
JSONObject dataJson = JSONUtil.parseObj(decryptData);
|
||||||
|
String refundStatus = dataJson.get("refund_status").toString();
|
||||||
|
if ("SUCCESS".equals(refundStatus)) {
|
||||||
|
String outTradeNo = dataJson.get("out_trade_no").toString();
|
||||||
|
remoteUUserService.refundSuccess(PaymentTypeEnum.WX_PAY.getCode(), Long.valueOf(outTradeNo), "inner");
|
||||||
|
|
||||||
|
// 更新订单信息
|
||||||
|
// 发送通知等
|
||||||
|
Map<String, String> xml = new HashMap<String, String>(2);
|
||||||
|
xml.put("return_code", "SUCCESS");
|
||||||
|
xml.put("return_msg", "OK");
|
||||||
|
return WxPayKit.toXml(xml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull String getAmountByOrder(Long orderId) {
|
||||||
|
R<UOrderVo> orderRes = remoteUUserService.getOrderById(orderId);
|
||||||
|
UOrderVo orderVo = orderRes.getData();
|
||||||
|
if (orderVo == null) {
|
||||||
|
throw new ServiceException("payment.pay.error");
|
||||||
|
}
|
||||||
|
|
||||||
|
String totalFee = orderVo.getOrderAmount().multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).toString();
|
||||||
|
if (StrUtil.isBlank(totalFee)) {
|
||||||
|
throw new ServiceException("payment.pay.error");
|
||||||
|
}
|
||||||
|
return totalFee;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package org.wfc.system.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.core.web.controller.BaseController;
|
||||||
|
import org.wfc.common.core.web.domain.AjaxResult;
|
||||||
|
import org.wfc.common.core.web.page.TableDataInfo;
|
||||||
|
import org.wfc.system.domain.URefund;
|
||||||
|
import org.wfc.system.domain.bo.URefundApproveBo;
|
||||||
|
import org.wfc.system.service.IURefundService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 前端控制器
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-27
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/refund")
|
||||||
|
public class URefundController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IURefundService uRefundService;
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
public TableDataInfo page(URefund uRefund) {
|
||||||
|
startPage();
|
||||||
|
List<URefund> list = uRefundService.queryList(uRefund);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/list")
|
||||||
|
public AjaxResult list(URefund uRefund) {
|
||||||
|
List<URefund> list = uRefundService.queryList(uRefund);
|
||||||
|
return success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/{id}")
|
||||||
|
public AjaxResult getById(@PathVariable("id") Long id) {
|
||||||
|
return success(uRefundService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@RequestBody URefund uRefund) {
|
||||||
|
return toAjax(uRefundService.save(uRefund));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@RequestBody URefund uRefund) {
|
||||||
|
return toAjax(uRefundService.updateById(uRefund));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||||
|
return toAjax(uRefundService.removeByIds(CollUtil.newArrayList(ids)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("pass")
|
||||||
|
public R<Boolean> pass(@RequestBody URefundApproveBo refundApproveBo) {
|
||||||
|
uRefundService.pass(refundApproveBo);
|
||||||
|
return R.ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("reject")
|
||||||
|
public R<Boolean> reject(@RequestBody URefundApproveBo refundApproveBo) {
|
||||||
|
uRefundService.reject(refundApproveBo);
|
||||||
|
return R.ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package org.wfc.system.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import org.wfc.common.mybatis.domain.BaseData;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-27
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@TableName("u_refund")
|
||||||
|
@Schema(name = "URefund", description = "用户平台-退款表")
|
||||||
|
public class URefund extends BaseData {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "订单ID")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
@Schema(description = "申请时间")
|
||||||
|
private Date applyTime;
|
||||||
|
|
||||||
|
@Schema(description = "申请原因")
|
||||||
|
private String applyReason;
|
||||||
|
|
||||||
|
@Schema(description = "退款金额")
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
@Schema(description = "退款方式")
|
||||||
|
private Integer refundMethod;
|
||||||
|
|
||||||
|
@Schema(description = "审批状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.wfc.system.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 退款审批Bo
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-27
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class URefundApproveBo {
|
||||||
|
private Long id;
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.wfc.system.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
|
import org.wfc.system.domain.URefund;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-27
|
||||||
|
*/
|
||||||
|
@DS("user")
|
||||||
|
public interface URefundMapper extends BaseMapper<URefund> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.wfc.system.service;
|
||||||
|
|
||||||
|
import org.wfc.system.domain.URefund;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.wfc.system.domain.bo.URefundApproveBo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 服务类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-27
|
||||||
|
*/
|
||||||
|
public interface IURefundService extends IService<URefund> {
|
||||||
|
|
||||||
|
List<URefund> queryList(URefund uRefund);
|
||||||
|
|
||||||
|
void pass(URefundApproveBo refundApproveBo);
|
||||||
|
|
||||||
|
void reject(URefundApproveBo refundApproveBo);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package org.wfc.system.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.core.enums.OrderStatusEnum;
|
||||||
|
import org.wfc.common.core.enums.PaymentTypeEnum;
|
||||||
|
import org.wfc.common.core.enums.RefundStatusEnum;
|
||||||
|
import org.wfc.system.domain.UOrder;
|
||||||
|
import org.wfc.system.domain.URefund;
|
||||||
|
import org.wfc.system.domain.bo.URefundApproveBo;
|
||||||
|
import org.wfc.system.mapper.UOrderMapper;
|
||||||
|
import org.wfc.system.mapper.URefundMapper;
|
||||||
|
import org.wfc.system.service.IURefundService;
|
||||||
|
import org.wfc.user.api.RemoteUPaymentService;
|
||||||
|
import org.wfc.user.api.RemoteUUserService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 服务实现类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-27
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class URefundServiceImpl extends ServiceImpl<URefundMapper, URefund> implements IURefundService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UOrderMapper orderMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RemoteUUserService remoteUUserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RemoteUPaymentService remoteUPaymentService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URefund> queryList(URefund uRefund) {
|
||||||
|
return this.list(buildQueryWrapper(uRefund));
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<URefund> buildQueryWrapper(URefund bo) {
|
||||||
|
LambdaQueryWrapper<URefund> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(bo.getOrderId() != null, URefund::getOrderId, bo.getOrderId());
|
||||||
|
lqw.eq(bo.getApplyTime() != null, URefund::getApplyTime, bo.getApplyTime());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getApplyReason()), URefund::getApplyReason, bo.getApplyReason());
|
||||||
|
lqw.eq(bo.getRefundAmount() != null, URefund::getRefundAmount, bo.getRefundAmount());
|
||||||
|
lqw.eq(bo.getRefundMethod() != null, URefund::getRefundMethod, bo.getRefundMethod());
|
||||||
|
lqw.eq(bo.getStatus() != null, URefund::getStatus, bo.getStatus());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getRemark()), URefund::getRemark, bo.getRemark());
|
||||||
|
return lqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void pass(URefundApproveBo refundApproveBo) {
|
||||||
|
// 只有待审批状态的才能审批
|
||||||
|
URefund refund = this.getById(refundApproveBo.getId());
|
||||||
|
if (!RefundStatusEnum.PENDING.getCode().equals(refund.getStatus())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 更新审批原因
|
||||||
|
refund.setRemark(refundApproveBo.getRemark());
|
||||||
|
this.updateById(refund);
|
||||||
|
UOrder order = orderMapper.selectById(refund.getOrderId());
|
||||||
|
switch (PaymentTypeEnum.getByCode(order.getPaymentId().intValue())) {
|
||||||
|
case ALIPAY:
|
||||||
|
// 支付宝
|
||||||
|
// 调用退款接口
|
||||||
|
R<Boolean> result = remoteUPaymentService.aliPayRefund(refund.getOrderId(), "inner");
|
||||||
|
if (result.getData()) {
|
||||||
|
remoteUUserService.refundSuccess(PaymentTypeEnum.ALIPAY.getCode(), refund.getId(), "inner");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WX_PAY:
|
||||||
|
// 微信
|
||||||
|
remoteUPaymentService.wxPayRefund(refund.getOrderId(), "inner");
|
||||||
|
break;
|
||||||
|
case BALANCE:
|
||||||
|
// 余额
|
||||||
|
remoteUUserService.refundSuccess(PaymentTypeEnum.BALANCE.getCode(), refund.getId(), "inner");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void reject(URefundApproveBo refundApproveBo) {
|
||||||
|
// 只有待审批状态的才能审批
|
||||||
|
URefund refund = this.getById(refundApproveBo.getId());
|
||||||
|
if (!RefundStatusEnum.PENDING.getCode().equals(refund.getStatus())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 修改审批状态
|
||||||
|
refund.setRemark(refundApproveBo.getRemark());
|
||||||
|
refund.setStatus(RefundStatusEnum.REJECTED.getCode());
|
||||||
|
this.save(refund);
|
||||||
|
// 修改订单状态
|
||||||
|
UOrder order = new UOrder();
|
||||||
|
order.setId(refund.getOrderId());
|
||||||
|
order.setStatus(OrderStatusEnum.PAID.getCode());
|
||||||
|
orderMapper.updateById(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="org.wfc.system.mapper.URefundMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -24,10 +24,10 @@ import java.util.List;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author sys
|
* @author sys
|
||||||
* @since 2025-02-10
|
* @since 2025-03-13
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/user/uAccountPackage")
|
@RequestMapping("/accountPackage")
|
||||||
public class UAccountPackageController extends BaseController {
|
public class UAccountPackageController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -36,13 +36,13 @@ public class UAccountPackageController extends BaseController {
|
|||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public TableDataInfo page(UAccountPackage uAccountPackage) {
|
public TableDataInfo page(UAccountPackage uAccountPackage) {
|
||||||
startPage();
|
startPage();
|
||||||
List<UAccountPackage> list = uAccountPackageService.list();
|
List<UAccountPackage> list = uAccountPackageService.queryList(uAccountPackage);
|
||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public AjaxResult list(UAccountPackage uAccountPackage) {
|
public AjaxResult list(UAccountPackage uAccountPackage) {
|
||||||
List<UAccountPackage> list = uAccountPackageService.list();
|
List<UAccountPackage> list = uAccountPackageService.queryList(uAccountPackage);
|
||||||
return success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.wfc.common.security.annotation.InnerAuth;
|
|||||||
import org.wfc.common.security.utils.SecurityUtils;
|
import org.wfc.common.security.utils.SecurityUtils;
|
||||||
import org.wfc.user.domain.UOrder;
|
import org.wfc.user.domain.UOrder;
|
||||||
import org.wfc.user.domain.UPackage;
|
import org.wfc.user.domain.UPackage;
|
||||||
|
import org.wfc.user.domain.vo.UOrderPackageVo;
|
||||||
import org.wfc.user.service.IUOrderService;
|
import org.wfc.user.service.IUOrderService;
|
||||||
import org.wfc.user.service.IUPackageService;
|
import org.wfc.user.service.IUPackageService;
|
||||||
import org.wfc.user.service.IURateLimitService;
|
import org.wfc.user.service.IURateLimitService;
|
||||||
@@ -77,10 +78,8 @@ public class UOrderController extends BaseController {
|
|||||||
@GetMapping("/packagePage")
|
@GetMapping("/packagePage")
|
||||||
public TableDataInfo packagePage() {
|
public TableDataInfo packagePage() {
|
||||||
startPage();
|
startPage();
|
||||||
List<UOrder> list = uOrderService.list(Wrappers.<UOrder>lambdaQuery()
|
List<UOrderPackageVo> list = uOrderService.getOrderPackage(SecurityUtils.getUserId());
|
||||||
.eq(UOrder::getUserId, SecurityUtils.getUserId()).eq(UOrder::getType, 0)
|
for (UOrderPackageVo uOrder : list) {
|
||||||
.orderByDesc(UOrder::getCreateTime));
|
|
||||||
for (UOrder uOrder : list) {
|
|
||||||
if (ObjectUtil.isNull(uOrder.getPackageId())) {
|
if (ObjectUtil.isNull(uOrder.getPackageId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -117,9 +116,15 @@ public class UOrderController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@InnerAuth
|
@InnerAuth
|
||||||
@PostMapping("paySuccess/{id}")
|
@PostMapping("paySuccess/{paymentType}/{id}")
|
||||||
public AjaxResult paySuccess(@PathVariable("id") Long id) {
|
public AjaxResult paySuccess(@PathVariable("paymentType")Integer paymentType, @PathVariable("id") Long id) {
|
||||||
return toAjax(uOrderService.paySuccess(id));
|
return toAjax(uOrderService.paySuccess(id, paymentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@InnerAuth
|
||||||
|
@PostMapping("refundSuccess/{paymentType}/{id}")
|
||||||
|
public AjaxResult refundSuccess(@PathVariable("paymentType")Integer paymentType, @PathVariable("id") Long id) {
|
||||||
|
return toAjax(uOrderService.refundSuccess(id, paymentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("payBalance/{id}")
|
@PostMapping("payBalance/{id}")
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package org.wfc.user.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.wfc.common.core.domain.R;
|
||||||
|
import org.wfc.common.core.web.controller.BaseController;
|
||||||
|
import org.wfc.common.core.web.domain.AjaxResult;
|
||||||
|
import org.wfc.common.core.web.page.TableDataInfo;
|
||||||
|
import org.wfc.user.domain.URefund;
|
||||||
|
import org.wfc.user.domain.bo.URefundApplyBo;
|
||||||
|
import org.wfc.user.service.IURefundService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 前端控制器
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-26
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/refund")
|
||||||
|
public class URefundController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IURefundService uRefundService;
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
public TableDataInfo page(URefund uRefund) {
|
||||||
|
startPage();
|
||||||
|
List<URefund> list = uRefundService.queryList(uRefund);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/list")
|
||||||
|
public AjaxResult list(URefund uRefund) {
|
||||||
|
List<URefund> list = uRefundService.queryList(uRefund);
|
||||||
|
return success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/{id}")
|
||||||
|
public AjaxResult getById(@PathVariable("id") Long id) {
|
||||||
|
return success(uRefundService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@RequestBody URefund uRefund) {
|
||||||
|
return toAjax(uRefundService.save(uRefund));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@RequestBody URefund uRefund) {
|
||||||
|
return toAjax(uRefundService.updateById(uRefund));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||||
|
return toAjax(uRefundService.removeByIds(CollUtil.newArrayList(ids)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("apply")
|
||||||
|
public R<Boolean> apply(URefundApplyBo refundApplyBo) {
|
||||||
|
uRefundService.apply(refundApplyBo);
|
||||||
|
return R.ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.wfc.user.domain;
|
package org.wfc.user.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -84,4 +85,8 @@ public class UAccountPackage extends BaseData {
|
|||||||
|
|
||||||
@Schema(description = "上行限速启用")
|
@Schema(description = "上行限速启用")
|
||||||
private Boolean upLimitEnable;
|
private Boolean upLimitEnable;
|
||||||
|
|
||||||
|
@Schema(description = "上行限速启用")
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Integer status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package org.wfc.user.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import org.wfc.common.mybatis.domain.BaseData;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-26
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@TableName("u_refund")
|
||||||
|
@Schema(name = "URefund", description = "用户平台-退款表")
|
||||||
|
public class URefund extends BaseData {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "订单ID")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
@Schema(description = "申请时间")
|
||||||
|
private Date applyTime;
|
||||||
|
|
||||||
|
@Schema(description = "申请原因")
|
||||||
|
private String applyReason;
|
||||||
|
|
||||||
|
@Schema(description = "退款金额")
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
@Schema(description = "退款方式")
|
||||||
|
private Integer refundMethod;
|
||||||
|
|
||||||
|
@Schema(description = "审批状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.wfc.user.domain.bo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 退款申请Bo
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-26
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class URefundApplyBo {
|
||||||
|
|
||||||
|
private String orderId;
|
||||||
|
|
||||||
|
private String applyReason;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.wfc.user.domain.constant;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 套餐状态
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-14
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum PackageStatusEnum {
|
||||||
|
|
||||||
|
INVALID(0, "未生效"),
|
||||||
|
VALID(1, "生效");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String desc;
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package org.wfc.user.domain.convert;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
import org.wfc.user.domain.UAccount;
|
||||||
|
import org.wfc.user.domain.UAccountPackage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: AccountPackageConvert
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-14
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface AccountPackageConvert {
|
||||||
|
AccountPackageConvert INSTANCE = Mappers.getMapper(AccountPackageConvert.class);
|
||||||
|
|
||||||
|
UAccountPackage toAccountPackage(UAccount account);
|
||||||
|
}
|
||||||
@@ -67,4 +67,6 @@ public class UAccountDashboardVo {
|
|||||||
private Long activity;
|
private Long activity;
|
||||||
|
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
private Integer packageNum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package org.wfc.user.domain.vo;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.wfc.user.domain.UPackage;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 套餐订单Vo
|
||||||
|
* @author: cyc
|
||||||
|
* @since: 2025-03-26
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(name = "UOrderPackageVo", description = "套餐订单Vo")
|
||||||
|
public class UOrderPackageVo {
|
||||||
|
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "套餐ID")
|
||||||
|
private Long packageId;
|
||||||
|
|
||||||
|
@Schema(description = "支付ID")
|
||||||
|
private Long paymentId;
|
||||||
|
|
||||||
|
@Schema(description = "订单编号")
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
@Schema(description = "订单类型(0套餐 1充值)")
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
@Schema(description = "订单金额")
|
||||||
|
private BigDecimal orderAmount;
|
||||||
|
|
||||||
|
@Schema(description = "订单状态(0待支付 1已支付 2已取消)")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private UPackage uPackage;
|
||||||
|
|
||||||
|
@Schema(description = "套餐名称")
|
||||||
|
private String packageName;
|
||||||
|
|
||||||
|
@Schema(description = "套餐状态(0待生效 1已生效)")
|
||||||
|
private Integer packageStatus;
|
||||||
|
|
||||||
|
@Schema(description = "订单时间")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
package org.wfc.user.mapper;
|
package org.wfc.user.mapper;
|
||||||
|
|
||||||
import org.wfc.user.domain.UOrder;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.wfc.user.domain.UOrder;
|
||||||
|
import org.wfc.user.domain.vo.UOrderPackageVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -13,4 +17,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||||||
*/
|
*/
|
||||||
public interface UOrderMapper extends BaseMapper<UOrder> {
|
public interface UOrderMapper extends BaseMapper<UOrder> {
|
||||||
|
|
||||||
|
List<UOrderPackageVo> getOrderPackage(@Param("userId") Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.wfc.user.mapper;
|
||||||
|
|
||||||
|
import org.wfc.user.domain.URefund;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-26
|
||||||
|
*/
|
||||||
|
public interface URefundMapper extends BaseMapper<URefund> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,14 +3,17 @@ package org.wfc.user.service;
|
|||||||
import org.wfc.user.domain.UAccountPackage;
|
import org.wfc.user.domain.UAccountPackage;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户平台-账户套餐表 服务类
|
* 用户平台-账户套餐表 服务类
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author sys
|
* @author sys
|
||||||
* @since 2025-02-10
|
* @since 2025-03-13
|
||||||
*/
|
*/
|
||||||
public interface IUAccountPackageService extends IService<UAccountPackage> {
|
public interface IUAccountPackageService extends IService<UAccountPackage> {
|
||||||
|
|
||||||
|
List<UAccountPackage> queryList(UAccountPackage uAccountPackage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package org.wfc.user.service;
|
|||||||
|
|
||||||
import org.wfc.user.domain.UOrder;
|
import org.wfc.user.domain.UOrder;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.wfc.user.domain.vo.UOrderPackageVo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -15,7 +18,11 @@ public interface IUOrderService extends IService<UOrder> {
|
|||||||
|
|
||||||
Long saveOrder(UOrder order);
|
Long saveOrder(UOrder order);
|
||||||
|
|
||||||
boolean paySuccess(Long orderId);
|
boolean paySuccess(Long orderId, Integer paymentType);
|
||||||
|
|
||||||
|
boolean refundSuccess(Long refundId, Integer paymentType);
|
||||||
|
|
||||||
boolean payByBalance(Long orderId);
|
boolean payByBalance(Long orderId);
|
||||||
|
|
||||||
|
List<UOrderPackageVo> getOrderPackage(Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.wfc.user.service;
|
||||||
|
|
||||||
|
import org.wfc.user.domain.URefund;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.wfc.user.domain.bo.URefundApplyBo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 服务类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-26
|
||||||
|
*/
|
||||||
|
public interface IURefundService extends IService<URefund> {
|
||||||
|
|
||||||
|
List<URefund> queryList(URefund uRefund);
|
||||||
|
|
||||||
|
void apply(URefundApplyBo refundApplyBo);
|
||||||
|
}
|
||||||
@@ -1,10 +1,28 @@
|
|||||||
package org.wfc.user.service.impl;
|
package org.wfc.user.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.wfc.common.mybatis.domain.BaseData;
|
||||||
|
import org.wfc.common.security.utils.SecurityUtils;
|
||||||
|
import org.wfc.user.domain.UAccount;
|
||||||
import org.wfc.user.domain.UAccountPackage;
|
import org.wfc.user.domain.UAccountPackage;
|
||||||
|
import org.wfc.user.domain.constant.PackageStatusEnum;
|
||||||
|
import org.wfc.user.domain.convert.AccountPackageConvert;
|
||||||
|
import org.wfc.user.mapper.UAccountMapper;
|
||||||
import org.wfc.user.mapper.UAccountPackageMapper;
|
import org.wfc.user.mapper.UAccountPackageMapper;
|
||||||
import org.wfc.user.service.IUAccountPackageService;
|
import org.wfc.user.service.IUAccountPackageService;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import org.wfc.user.util.AccountUtil;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -12,9 +30,58 @@ import org.springframework.stereotype.Service;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author sys
|
* @author sys
|
||||||
* @since 2025-02-10
|
* @since 2025-03-13
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class UAccountPackageServiceImpl extends ServiceImpl<UAccountPackageMapper, UAccountPackage> implements IUAccountPackageService {
|
public class UAccountPackageServiceImpl extends ServiceImpl<UAccountPackageMapper, UAccountPackage> implements IUAccountPackageService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UAccountMapper accountMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UAccountPackage> queryList(UAccountPackage uAccountPackage) {
|
||||||
|
UAccount account = accountMapper.selectOne(Wrappers.<UAccount>lambdaQuery().eq(UAccount::getUserId, SecurityUtils.getLoginUser().getUserid()), false);
|
||||||
|
if (ObjectUtil.isNull(account) || !AccountUtil.isPackageValid(account, new Date())) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<UAccountPackage> packages = new ArrayList<>();
|
||||||
|
// 添加当前生效的
|
||||||
|
UAccountPackage accountPackage = AccountPackageConvert.INSTANCE.toAccountPackage(account);
|
||||||
|
accountPackage.setAccountId(account.getId());
|
||||||
|
accountPackage.setStatus(PackageStatusEnum.VALID.getCode());
|
||||||
|
packages.add(accountPackage);
|
||||||
|
|
||||||
|
uAccountPackage.setAccountId(account.getId());
|
||||||
|
List<UAccountPackage> invalidPackages = this.list(buildQueryWrapper(uAccountPackage));
|
||||||
|
invalidPackages = invalidPackages.stream().peek(p -> p.setStatus(PackageStatusEnum.INVALID.getCode()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
packages.addAll(invalidPackages);
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<UAccountPackage> buildQueryWrapper(UAccountPackage bo) {
|
||||||
|
LambdaQueryWrapper<UAccountPackage> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(bo.getAccountId() != null, UAccountPackage::getAccountId, bo.getAccountId());
|
||||||
|
lqw.eq(bo.getPackageId() != null, UAccountPackage::getPackageId, bo.getPackageId());
|
||||||
|
lqw.eq(bo.getTraffic() != null, UAccountPackage::getTraffic, bo.getTraffic());
|
||||||
|
lqw.eq(bo.getDuration() != null, UAccountPackage::getDuration, bo.getDuration());
|
||||||
|
lqw.eq(bo.getClientNum() != null, UAccountPackage::getClientNum, bo.getClientNum());
|
||||||
|
lqw.eq(bo.getExpiredTime() != null, UAccountPackage::getExpiredTime, bo.getExpiredTime());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getPackageName()), UAccountPackage::getPackageName, bo.getPackageName());
|
||||||
|
lqw.eq(bo.getPeriodNum() != null, UAccountPackage::getPeriodNum, bo.getPeriodNum());
|
||||||
|
lqw.eq(bo.getPeriodType() != null, UAccountPackage::getPeriodType, bo.getPeriodType());
|
||||||
|
lqw.eq(bo.getPrice() != null, UAccountPackage::getPrice, bo.getPrice());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getRemark()), UAccountPackage::getRemark, bo.getRemark());
|
||||||
|
lqw.eq(bo.getRateLimitEnable() != null, UAccountPackage::getRateLimitEnable, bo.getRateLimitEnable());
|
||||||
|
lqw.eq(bo.getTrafficEnable() != null, UAccountPackage::getTrafficEnable, bo.getTrafficEnable());
|
||||||
|
lqw.eq(bo.getDurationEnable() != null, UAccountPackage::getDurationEnable, bo.getDurationEnable());
|
||||||
|
lqw.eq(bo.getClientNumEnable() != null, UAccountPackage::getClientNumEnable, bo.getClientNumEnable());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getRateLimitName()), UAccountPackage::getRateLimitName, bo.getRateLimitName());
|
||||||
|
lqw.eq(bo.getDownLimit() != null, UAccountPackage::getDownLimit, bo.getDownLimit());
|
||||||
|
lqw.eq(bo.getDownLimitEnable() != null, UAccountPackage::getDownLimitEnable, bo.getDownLimitEnable());
|
||||||
|
lqw.eq(bo.getUpLimit() != null, UAccountPackage::getUpLimit, bo.getUpLimit());
|
||||||
|
lqw.eq(bo.getUpLimitEnable() != null, UAccountPackage::getUpLimitEnable, bo.getUpLimitEnable());
|
||||||
|
lqw.orderByAsc(BaseData::getCreateTime);
|
||||||
|
return lqw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.wfc.user.service.impl;
|
package org.wfc.user.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
@@ -26,10 +27,11 @@ import org.wfc.user.api.domain.bo.UClientBo;
|
|||||||
import org.wfc.user.api.omada.domain.convert.OmadaConvert;
|
import org.wfc.user.api.omada.domain.convert.OmadaConvert;
|
||||||
import org.wfc.user.api.omada.domain.dto.ClientRateLimitSettingDto;
|
import org.wfc.user.api.omada.domain.dto.ClientRateLimitSettingDto;
|
||||||
import org.wfc.user.domain.UAccount;
|
import org.wfc.user.domain.UAccount;
|
||||||
|
import org.wfc.user.domain.UAccountPackage;
|
||||||
import org.wfc.user.domain.UBill;
|
import org.wfc.user.domain.UBill;
|
||||||
import org.wfc.user.domain.UBillRule;
|
import org.wfc.user.domain.UBillRule;
|
||||||
import org.wfc.user.domain.UClient;
|
import org.wfc.user.domain.UClient;
|
||||||
import org.wfc.user.domain.constant.OrderStatusEnum;
|
import org.wfc.common.core.enums.OrderStatusEnum;
|
||||||
import org.wfc.user.domain.constant.OrderTypeEnum;
|
import org.wfc.user.domain.constant.OrderTypeEnum;
|
||||||
import org.wfc.user.domain.vo.UAccountDashboardVo;
|
import org.wfc.user.domain.vo.UAccountDashboardVo;
|
||||||
import org.wfc.user.domain.vo.UCdrUserVo;
|
import org.wfc.user.domain.vo.UCdrUserVo;
|
||||||
@@ -39,6 +41,7 @@ import org.wfc.user.mapper.UBillMapper;
|
|||||||
import org.wfc.user.mapper.UBillRuleMapper;
|
import org.wfc.user.mapper.UBillRuleMapper;
|
||||||
import org.wfc.user.mapper.UCdrMapper;
|
import org.wfc.user.mapper.UCdrMapper;
|
||||||
import org.wfc.user.mapper.UClientMapper;
|
import org.wfc.user.mapper.UClientMapper;
|
||||||
|
import org.wfc.user.service.IUAccountPackageService;
|
||||||
import org.wfc.user.service.IUAccountService;
|
import org.wfc.user.service.IUAccountService;
|
||||||
import org.wfc.user.service.IUClientService;
|
import org.wfc.user.service.IUClientService;
|
||||||
import org.wfc.user.util.AccountUtil;
|
import org.wfc.user.util.AccountUtil;
|
||||||
@@ -88,6 +91,9 @@ public class UAccountServiceImpl extends ServiceImpl<UAccountMapper, UAccount> i
|
|||||||
@Lazy
|
@Lazy
|
||||||
private IUClientService uClientService;
|
private IUClientService uClientService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IUAccountPackageService accountPackageService;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void statAndCancelAuthUser() {
|
public void statAndCancelAuthUser() {
|
||||||
// 定时任务查询所有未过期或刚过期(失效时间+定时任务间隔时间)的账户套餐,套餐过期/流量用完/时长用完则取消授权
|
// 定时任务查询所有未过期或刚过期(失效时间+定时任务间隔时间)的账户套餐,套餐过期/流量用完/时长用完则取消授权
|
||||||
@@ -163,6 +169,30 @@ public class UAccountServiceImpl extends ServiceImpl<UAccountMapper, UAccount> i
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
UAccount account = this.getOne(Wrappers.<UAccount>lambdaQuery().eq(UAccount::getUserId, loginClient.getUserId()), false);
|
UAccount account = this.getOne(Wrappers.<UAccount>lambdaQuery().eq(UAccount::getUserId, loginClient.getUserId()), false);
|
||||||
|
// 套餐失效,但是还有其他可用套餐
|
||||||
|
if (!AccountUtil.isPackageValid(account, current)) {
|
||||||
|
List<UAccountPackage> accountPackages = accountPackageService.list(Wrappers.<UAccountPackage>lambdaQuery()
|
||||||
|
.eq(UAccountPackage::getAccountId, account.getId()).orderByAsc(UAccountPackage::getCreateTime));
|
||||||
|
Optional<UAccountPackage> accountPackageOptional = accountPackages.stream().findFirst();
|
||||||
|
if (accountPackageOptional.isPresent()) {
|
||||||
|
wifiApi.reconnectClient(site.getSiteId(), client.getMac());
|
||||||
|
UAccountPackage accountPackage = accountPackageOptional.get();
|
||||||
|
Long accountId = account.getId();
|
||||||
|
BeanUtils.copyProperties(accountPackage, account);
|
||||||
|
account.setId(accountId);
|
||||||
|
account.setTrafficUsed(0L);
|
||||||
|
account.setDurationUsed(0L);
|
||||||
|
account.setClientNumUsed(0);
|
||||||
|
Date startTime = new Date();
|
||||||
|
DateTime endTime = AccountUtil.getEndTime(accountPackage.getPeriodType(), accountPackage.getPeriodNum(), startTime);
|
||||||
|
account.setStartTime(current);
|
||||||
|
account.setEndTime(endTime);
|
||||||
|
// 更新账号套餐和删除使用套餐
|
||||||
|
this.updateById(account);
|
||||||
|
accountPackageService.removeById(accountPackage.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 套餐失效,但是有余额且没有已使用余额,reconnect
|
// 套餐失效,但是有余额且没有已使用余额,reconnect
|
||||||
if (AccountUtil.isPackageUnValidBalanceValid(account, current)) {
|
if (AccountUtil.isPackageUnValidBalanceValid(account, current)) {
|
||||||
wifiApi.reconnectClient(site.getSiteId(), client.getMac());
|
wifiApi.reconnectClient(site.getSiteId(), client.getMac());
|
||||||
@@ -254,8 +284,10 @@ public class UAccountServiceImpl extends ServiceImpl<UAccountMapper, UAccount> i
|
|||||||
} else {
|
} else {
|
||||||
dashboardVo.setStatus(0);
|
dashboardVo.setStatus(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<UAccountPackage> accountPackages = accountPackageService.queryList(new UAccountPackage());
|
||||||
|
dashboardVo.setPackageNum(accountPackages.size());
|
||||||
return dashboardVo;
|
return dashboardVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,9 @@ public class UCdrServiceImpl extends ServiceImpl<UCdrMapper, UCdr> implements IU
|
|||||||
|
|
||||||
// 新增cdr历史
|
// 新增cdr历史
|
||||||
for (UClient client : allClients) {
|
for (UClient client : allClients) {
|
||||||
|
if (!Objects.equals(client.getSiteId(), site.getSiteId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
UCdr uCdr = this.getOne(Wrappers.<UCdr>lambdaQuery().eq(UCdr::getUserId, client.getUserId())
|
UCdr uCdr = this.getOne(Wrappers.<UCdr>lambdaQuery().eq(UCdr::getUserId, client.getUserId())
|
||||||
.eq(UCdr::getClientId, client.getId()), false);
|
.eq(UCdr::getClientId, client.getId()), false);
|
||||||
if (ObjectUtil.isNotNull(uCdr)) {
|
if (ObjectUtil.isNotNull(uCdr)) {
|
||||||
@@ -286,6 +289,7 @@ public class UCdrServiceImpl extends ServiceImpl<UCdrMapper, UCdr> implements IU
|
|||||||
userId = hasClient.getUserId();
|
userId = hasClient.getUserId();
|
||||||
}
|
}
|
||||||
UClient uClient = UClient.builder().clientMac(client.getMac())
|
UClient uClient = UClient.builder().clientMac(client.getMac())
|
||||||
|
.siteId(siteId)
|
||||||
.userId(userId)
|
.userId(userId)
|
||||||
.clientName(client.getName())
|
.clientName(client.getName())
|
||||||
.clientDeviceType(client.getDeviceType())
|
.clientDeviceType(client.getDeviceType())
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.wfc.user.service.impl;
|
package org.wfc.user.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateField;
|
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
@@ -11,6 +9,8 @@ import org.springframework.beans.BeanUtils;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.wfc.common.core.enums.PaymentTypeEnum;
|
||||||
|
import org.wfc.common.core.enums.RefundStatusEnum;
|
||||||
import org.wfc.common.core.exception.ServiceException;
|
import org.wfc.common.core.exception.ServiceException;
|
||||||
import org.wfc.common.security.utils.SecurityUtils;
|
import org.wfc.common.security.utils.SecurityUtils;
|
||||||
import org.wfc.user.api.IWifiApi;
|
import org.wfc.user.api.IWifiApi;
|
||||||
@@ -24,13 +24,15 @@ import org.wfc.user.domain.UClient;
|
|||||||
import org.wfc.user.domain.UOrder;
|
import org.wfc.user.domain.UOrder;
|
||||||
import org.wfc.user.domain.UPackage;
|
import org.wfc.user.domain.UPackage;
|
||||||
import org.wfc.user.domain.URateLimit;
|
import org.wfc.user.domain.URateLimit;
|
||||||
import org.wfc.user.domain.constant.OrderStatusEnum;
|
import org.wfc.common.core.enums.OrderStatusEnum;
|
||||||
|
import org.wfc.user.domain.URefund;
|
||||||
import org.wfc.user.domain.constant.OrderTypeEnum;
|
import org.wfc.user.domain.constant.OrderTypeEnum;
|
||||||
import org.wfc.user.domain.constant.PeriodTypeEnum;
|
import org.wfc.user.domain.vo.UOrderPackageVo;
|
||||||
import org.wfc.user.mapper.UAccountPackageMapper;
|
import org.wfc.user.mapper.UAccountPackageMapper;
|
||||||
import org.wfc.user.mapper.UBillMapper;
|
import org.wfc.user.mapper.UBillMapper;
|
||||||
import org.wfc.user.mapper.UBillRuleMapper;
|
import org.wfc.user.mapper.UBillRuleMapper;
|
||||||
import org.wfc.user.mapper.UOrderMapper;
|
import org.wfc.user.mapper.UOrderMapper;
|
||||||
|
import org.wfc.user.mapper.URefundMapper;
|
||||||
import org.wfc.user.service.IUAccountService;
|
import org.wfc.user.service.IUAccountService;
|
||||||
import org.wfc.user.service.IUClientService;
|
import org.wfc.user.service.IUClientService;
|
||||||
import org.wfc.user.service.IUOrderService;
|
import org.wfc.user.service.IUOrderService;
|
||||||
@@ -75,18 +77,22 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UAccountPackageMapper accountPackageMapper;
|
private UAccountPackageMapper accountPackageMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private URefundMapper refundMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IWifiApi wifiApi;
|
private IWifiApi wifiApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean paySuccess(Long orderId) {
|
public boolean paySuccess(Long orderId, Integer paymentType) {
|
||||||
// 支付成功回调
|
// 支付成功回调
|
||||||
// 更新当前订单状态为已支付
|
// 更新当前订单状态为已支付
|
||||||
UOrder order = this.getById(orderId);
|
UOrder order = this.getById(orderId);
|
||||||
if (OrderStatusEnum.PAID.getCode().equals(order.getStatus())) {
|
if (OrderStatusEnum.PAID.getCode().equals(order.getStatus())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
order.setPaymentId(paymentType.longValue());
|
||||||
order.setStatus(OrderStatusEnum.PAID.getCode());
|
order.setStatus(OrderStatusEnum.PAID.getCode());
|
||||||
this.updateById(order);
|
this.updateById(order);
|
||||||
|
|
||||||
@@ -111,11 +117,11 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
} else {
|
} else {
|
||||||
accountId = account.getId();
|
accountId = account.getId();
|
||||||
oldBalance = account.getBalance();
|
oldBalance = account.getBalance();
|
||||||
isValid = AccountUtil.isValid(account, new Date());
|
isValid = AccountUtil.isPackageValid(account, new Date());
|
||||||
}
|
}
|
||||||
if (OrderTypeEnum.PACKAGE.getCode().equals(order.getType())) {
|
if (OrderTypeEnum.PACKAGE.getCode().equals(order.getType())) {
|
||||||
// 套餐
|
// 套餐
|
||||||
callbackPackage(order, account, false);
|
callbackPackage(order, account, isValid);
|
||||||
} else if (OrderTypeEnum.RECHARGE.getCode().equals(order.getType())) {
|
} else if (OrderTypeEnum.RECHARGE.getCode().equals(order.getType())) {
|
||||||
// 充值
|
// 充值
|
||||||
// 更新账户余额
|
// 更新账户余额
|
||||||
@@ -138,7 +144,7 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
wifiApi.authClient(client.getSiteId(), client.getClientMac());
|
wifiApi.authClient(client.getSiteId(), client.getClientMac());
|
||||||
// 套餐生效已授权时,调reconnect重连接口,以便截取时间
|
// 套餐生效已授权时,调reconnect重连接口,以便截取时间
|
||||||
if (isValid && !(OrderTypeEnum.RECHARGE.getCode().equals(order.getType()) && oldBalance.compareTo(BigDecimal.ZERO) > 0)) {
|
if (isValid && !(OrderTypeEnum.RECHARGE.getCode().equals(order.getType()) && oldBalance.compareTo(BigDecimal.ZERO) > 0)) {
|
||||||
wifiApi.reconnectClient(client.getSiteId(), client.getClientMac());
|
// wifiApi.reconnectClient(client.getSiteId(), client.getClientMac());
|
||||||
}
|
}
|
||||||
// 带宽限速
|
// 带宽限速
|
||||||
ClientRateLimitSettingDto clientRateLimitSetting = OmadaConvert.INSTANCE.toClientRateLimitSettingDto(account);
|
ClientRateLimitSettingDto clientRateLimitSetting = OmadaConvert.INSTANCE.toClientRateLimitSettingDto(account);
|
||||||
@@ -148,6 +154,31 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean refundSuccess(Long refundId, Integer paymentType) {
|
||||||
|
URefund refund = refundMapper.selectById(refundId);
|
||||||
|
if (!RefundStatusEnum.PENDING.getCode().equals(refund.getStatus())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 修改审批状态
|
||||||
|
refund.setStatus(RefundStatusEnum.PASSED.getCode());
|
||||||
|
refundMapper.updateById(refund);
|
||||||
|
// 修改订单状态
|
||||||
|
UOrder order = this.getById(refund.getOrderId());
|
||||||
|
order.setStatus(OrderStatusEnum.REFUNDING.getCode());
|
||||||
|
this.updateById(order);
|
||||||
|
if (PaymentTypeEnum.BALANCE.getCode().equals(paymentType)) {
|
||||||
|
// 余额退款成功时恢复余额
|
||||||
|
UAccount account = accountService.getOne(Wrappers.<UAccount>lambdaQuery().eq(UAccount::getUserId, order.getUserId()), false);
|
||||||
|
if (account != null) {
|
||||||
|
account.setBalance(account.getBalance().add(order.getOrderAmount()));
|
||||||
|
accountService.updateById(account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除待生效套餐
|
||||||
|
accountPackageMapper.delete(Wrappers.<UAccountPackage>lambdaQuery().eq(UAccountPackage::getPackageId, refund.getOrderId()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean payByBalance(Long orderId) {
|
public boolean payByBalance(Long orderId) {
|
||||||
@@ -167,7 +198,7 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
if (order.getOrderAmount().compareTo(balance) > 0) {
|
if (order.getOrderAmount().compareTo(balance) > 0) {
|
||||||
throw new ServiceException("user.order.pay.amount.error");
|
throw new ServiceException("user.order.pay.amount.error");
|
||||||
}
|
}
|
||||||
if (paySuccess(orderId)) {
|
if (paySuccess(orderId, PaymentTypeEnum.BALANCE.getCode())) {
|
||||||
UAccount updateAccount = new UAccount();
|
UAccount updateAccount = new UAccount();
|
||||||
updateAccount.setId(account.getId());
|
updateAccount.setId(account.getId());
|
||||||
updateAccount.setBalance(account.getBalance().subtract(order.getOrderAmount()));
|
updateAccount.setBalance(account.getBalance().subtract(order.getOrderAmount()));
|
||||||
@@ -177,6 +208,11 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UOrderPackageVo> getOrderPackage(Long userId) {
|
||||||
|
return this.baseMapper.getOrderPackage(userId);
|
||||||
|
}
|
||||||
|
|
||||||
private void callbackPackage(UOrder order, UAccount account, boolean isValid) {
|
private void callbackPackage(UOrder order, UAccount account, boolean isValid) {
|
||||||
if (ObjectUtil.isNull(order.getPackageId())) {
|
if (ObjectUtil.isNull(order.getPackageId())) {
|
||||||
return;
|
return;
|
||||||
@@ -197,42 +233,24 @@ public class UOrderServiceImpl extends ServiceImpl<UOrderMapper, UOrder> impleme
|
|||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
BeanUtils.copyProperties(uPackage, accountPackage);
|
BeanUtils.copyProperties(uPackage, accountPackage);
|
||||||
accountPackage.setPackageId(order.getPackageId());
|
accountPackage.setId(null);
|
||||||
|
accountPackage.setCreateTime(null);
|
||||||
|
accountPackage.setAccountId(account.getId());
|
||||||
|
accountPackage.setPackageId(order.getId());
|
||||||
accountPackageMapper.insert(accountPackage);
|
accountPackageMapper.insert(accountPackage);
|
||||||
} else {
|
} else {
|
||||||
BeanUtils.copyProperties(uPackage, account);
|
BeanUtils.copyProperties(uPackage, account);
|
||||||
account.setPackageId(order.getPackageId());
|
account.setPackageId(order.getId());
|
||||||
account.setTrafficUsed(0L);
|
account.setTrafficUsed(0L);
|
||||||
account.setDurationUsed(0L);
|
account.setDurationUsed(0L);
|
||||||
account.setClientNumUsed(0);
|
account.setClientNumUsed(0);
|
||||||
Date current = new Date();
|
Date current = new Date();
|
||||||
DateTime endTime = getEndTime(uPackage, current);
|
DateTime endTime = AccountUtil.getEndTime(uPackage.getPeriodType(), uPackage.getPeriodNum(), current);
|
||||||
account.setStartTime(current);
|
account.setStartTime(current);
|
||||||
account.setEndTime(endTime);
|
account.setEndTime(endTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateTime getEndTime(UPackage uPackage, Date current) {
|
|
||||||
DateTime endTime = null;
|
|
||||||
// 计算有效时间
|
|
||||||
switch (PeriodTypeEnum.getByCode(uPackage.getPeriodType())) {
|
|
||||||
case HOUR:
|
|
||||||
endTime = DateUtil.offset(current, DateField.HOUR, uPackage.getPeriodNum());
|
|
||||||
break;
|
|
||||||
case DAY:
|
|
||||||
endTime = DateUtil.offset(current, DateField.DAY_OF_YEAR, uPackage.getPeriodNum());
|
|
||||||
break;
|
|
||||||
case MONTH:
|
|
||||||
endTime = DateUtil.offset(current, DateField.MONTH, uPackage.getPeriodNum());
|
|
||||||
break;
|
|
||||||
case YEAR:
|
|
||||||
endTime = DateUtil.offset(current, DateField.YEAR, uPackage.getPeriodNum());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
return endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long saveOrder(UOrder order) {
|
public Long saveOrder(UOrder order) {
|
||||||
order.setUserId(SecurityUtils.getUserId());
|
order.setUserId(SecurityUtils.getUserId());
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package org.wfc.user.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.wfc.user.domain.UOrder;
|
||||||
|
import org.wfc.user.domain.URefund;
|
||||||
|
import org.wfc.user.domain.bo.URefundApplyBo;
|
||||||
|
import org.wfc.common.core.enums.OrderStatusEnum;
|
||||||
|
import org.wfc.common.core.enums.RefundStatusEnum;
|
||||||
|
import org.wfc.user.mapper.UOrderMapper;
|
||||||
|
import org.wfc.user.mapper.URefundMapper;
|
||||||
|
import org.wfc.user.service.IURefundService;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 用户平台-退款表 服务实现类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author sys
|
||||||
|
* @since 2025-03-26
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class URefundServiceImpl extends ServiceImpl<URefundMapper, URefund> implements IURefundService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UOrderMapper orderMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<URefund> queryList(URefund uRefund) {
|
||||||
|
return this.list(buildQueryWrapper(uRefund));
|
||||||
|
}
|
||||||
|
|
||||||
|
private LambdaQueryWrapper<URefund> buildQueryWrapper(URefund bo) {
|
||||||
|
LambdaQueryWrapper<URefund> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(bo.getOrderId() != null, URefund::getOrderId, bo.getOrderId());
|
||||||
|
lqw.eq(bo.getApplyTime() != null, URefund::getApplyTime, bo.getApplyTime());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getApplyReason()), URefund::getApplyReason, bo.getApplyReason());
|
||||||
|
lqw.eq(bo.getRefundAmount() != null, URefund::getRefundAmount, bo.getRefundAmount());
|
||||||
|
lqw.eq(bo.getRefundMethod() != null, URefund::getRefundMethod, bo.getRefundMethod());
|
||||||
|
lqw.eq(bo.getStatus() != null, URefund::getStatus, bo.getStatus());
|
||||||
|
lqw.like(StrUtil.isNotBlank(bo.getRemark()), URefund::getRemark, bo.getRemark());
|
||||||
|
return lqw;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void apply(URefundApplyBo refundApplyBo) {
|
||||||
|
UOrder order = orderMapper.selectById(refundApplyBo.getOrderId());
|
||||||
|
// 发起退款申请
|
||||||
|
URefund refund = new URefund();
|
||||||
|
refund.setOrderId(order.getId());
|
||||||
|
refund.setApplyReason(refundApplyBo.getApplyReason());
|
||||||
|
refund.setApplyTime(new Date());
|
||||||
|
refund.setRefundAmount(order.getOrderAmount());
|
||||||
|
refund.setStatus(RefundStatusEnum.PENDING.getCode());
|
||||||
|
this.save(refund);
|
||||||
|
// 修改订单状态
|
||||||
|
order.setStatus(OrderStatusEnum.REFUNDING.getCode());
|
||||||
|
orderMapper.updateById(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package org.wfc.user.util;
|
package org.wfc.user.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateField;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import org.wfc.user.domain.UAccount;
|
import org.wfc.user.domain.UAccount;
|
||||||
|
import org.wfc.user.domain.constant.PeriodTypeEnum;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -69,4 +72,25 @@ public class AccountUtil {
|
|||||||
&& (!account.getDurationEnable() || account.getDurationUsed() <= account.getDuration()))
|
&& (!account.getDurationEnable() || account.getDurationUsed() <= account.getDuration()))
|
||||||
&& (ObjectUtil.isNull(account.getBalanceUsed()) || account.getBalanceUsed().compareTo(BigDecimal.ZERO) == 0);
|
&& (ObjectUtil.isNull(account.getBalanceUsed()) || account.getBalanceUsed().compareTo(BigDecimal.ZERO) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DateTime getEndTime(Integer periodType, Integer periodNum, Date current) {
|
||||||
|
DateTime endTime = null;
|
||||||
|
// 计算有效时间
|
||||||
|
switch (PeriodTypeEnum.getByCode(periodType)) {
|
||||||
|
case HOUR:
|
||||||
|
endTime = DateUtil.offset(current, DateField.HOUR, periodNum);
|
||||||
|
break;
|
||||||
|
case DAY:
|
||||||
|
endTime = DateUtil.offset(current, DateField.DAY_OF_YEAR, periodNum);
|
||||||
|
break;
|
||||||
|
case MONTH:
|
||||||
|
endTime = DateUtil.offset(current, DateField.MONTH, periodNum);
|
||||||
|
break;
|
||||||
|
case YEAR:
|
||||||
|
endTime = DateUtil.offset(current, DateField.YEAR, periodNum);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return endTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.wfc.user.mapper.UOrderMapper">
|
<mapper namespace="org.wfc.user.mapper.UOrderMapper">
|
||||||
|
|
||||||
|
<select id="getOrderPackage" resultType="org.wfc.user.domain.vo.UOrderPackageVo">
|
||||||
|
SELECT
|
||||||
|
o.*, p.package_name, if(o.`status` = 1, if(ap.id is null, 1, 0),null) package_status
|
||||||
|
FROM
|
||||||
|
`u_order` o
|
||||||
|
LEFT JOIN u_package p ON o.package_id = p.id
|
||||||
|
AND p.del_flag = 0
|
||||||
|
LEFT JOIN u_account_package ap ON o.id = ap.package_id
|
||||||
|
AND ap.del_flag = 0
|
||||||
|
AND o.type = 1
|
||||||
|
WHERE
|
||||||
|
o.del_flag = 0
|
||||||
|
AND o.user_id = #{userId}
|
||||||
|
ORDER BY o.create_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="org.wfc.user.mapper.URefundMapper">
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user