From 8b795f834346960d9bb4cf20804d117667ed55fb Mon Sep 17 00:00:00 2001 From: Paidax Date: Mon, 10 Mar 2025 11:27:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v/nutz/base/annontation/RepeatSubmit.java | 23 ++++ .../v/nutz/base/constant/RedisConstant.java | 4 + .../v/nutz/base/exception/BaseException.java | 16 +++ .../RepeatSubmitAopConfiguration.java | 19 +++ .../RepeatSubmitAopInterceptor.java | 51 ++++++++ .../controller/AlipayClientController.java | 4 +- .../alipay/service/AlipayClientConfig.java | 2 +- .../payment/alipay/service/AlipayService.java | 2 +- .../service/impl/AlipayNewServiceImpl.java | 6 +- .../payment/enums/RefundStateEnum.java | 4 +- .../payment/enums/TradingChannelEnum.java | 4 +- .../payment/enums/TradingStateEnum.java | 4 +- .../payment/enums/TradingTypeEnum.java | 4 +- .../base/payment/enums/WxPayResultCode.java | 30 +++++ .../payment/model/PaymentTransaction.java | 8 +- .../payment/model/RefundRecord.java | 6 +- .../payment/wxpay/bean/WxPayV3Bean.java | 2 +- .../payment/wxpay/pem/apiclient_cert.pem | 0 .../payment/wxpay/pem/apiclient_key.pem | 0 .../payment/wxpay/pem/wechatpay.pem | 0 .../wxpay/service/WxPayCommonService.java | 13 +- .../service/impl/WxPayCommonServiceImpl.java | 117 +++++++++++++----- .../payment/wxpay/vo/WxPayNeedParamVo.java | 2 +- .../java/io/v/nutz/base/utils/WebUtil.java | 33 +++++ .../web/commons/proc/WkFailProcessor.java | 15 ++- .../MemberPaymentMineController.java | 19 ++- 26 files changed, 334 insertions(+), 54 deletions(-) create mode 100644 src/main/java/io/v/nutz/base/annontation/RepeatSubmit.java create mode 100644 src/main/java/io/v/nutz/base/exception/BaseException.java create mode 100644 src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopConfiguration.java create mode 100644 src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopInterceptor.java rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/alipay/controller/AlipayClientController.java (93%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/alipay/service/AlipayClientConfig.java (98%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/alipay/service/AlipayService.java (85%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/alipay/service/impl/AlipayNewServiceImpl.java (96%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/enums/RefundStateEnum.java (80%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/enums/TradingChannelEnum.java (79%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/enums/TradingStateEnum.java (79%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/enums/TradingTypeEnum.java (75%) create mode 100644 src/main/java/io/v/nutz/base/payment/enums/WxPayResultCode.java rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/model/PaymentTransaction.java (91%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/model/RefundRecord.java (87%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/bean/WxPayV3Bean.java (95%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/pem/apiclient_cert.pem (100%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/pem/apiclient_key.pem (100%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/pem/wechatpay.pem (100%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/service/WxPayCommonService.java (84%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/service/impl/WxPayCommonServiceImpl.java (81%) rename src/main/java/io/v/nutz/{zhgh/memberCost => base}/payment/wxpay/vo/WxPayNeedParamVo.java (94%) create mode 100644 src/main/java/io/v/nutz/base/utils/WebUtil.java diff --git a/src/main/java/io/v/nutz/base/annontation/RepeatSubmit.java b/src/main/java/io/v/nutz/base/annontation/RepeatSubmit.java new file mode 100644 index 0000000..1c2e698 --- /dev/null +++ b/src/main/java/io/v/nutz/base/annontation/RepeatSubmit.java @@ -0,0 +1,23 @@ +package io.v.nutz.base.annontation; + +import java.lang.annotation.*; + +/** + * 自定义注解防止表单重复提交 + * + * @author ruoyi + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RepeatSubmit { + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + + /** + * 提示消息 + */ + public String message() default "请求过于频繁,请稍后再试"; +} \ No newline at end of file diff --git a/src/main/java/io/v/nutz/base/constant/RedisConstant.java b/src/main/java/io/v/nutz/base/constant/RedisConstant.java index 8978298..6d464bf 100644 --- a/src/main/java/io/v/nutz/base/constant/RedisConstant.java +++ b/src/main/java/io/v/nutz/base/constant/RedisConstant.java @@ -22,4 +22,8 @@ public class RedisConstant { //健步走小程序TOKEN public final static String REDIS_KEY_WE_APP_ACCESS_TOKEN = "weapp:token:"; + /** + * 接口重复提交前缀 + */ + public static final String REPEAT_SUBMIT_PREFIX = PLATFORM_REDIS_PREFIX + "repeat_submit:"; } diff --git a/src/main/java/io/v/nutz/base/exception/BaseException.java b/src/main/java/io/v/nutz/base/exception/BaseException.java new file mode 100644 index 0000000..e982c60 --- /dev/null +++ b/src/main/java/io/v/nutz/base/exception/BaseException.java @@ -0,0 +1,16 @@ +package io.v.nutz.base.exception; + +import cn.hutool.core.util.StrUtil; + +public class BaseException extends RuntimeException{ + + private static final long serialVersionUID = 7192152812384031563L; + + public BaseException(String message) { + super(message); + } + + public BaseException(String message, Object... arguments) { + super(StrUtil.format(message, arguments)); + } +} diff --git a/src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopConfiguration.java b/src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopConfiguration.java new file mode 100644 index 0000000..2aad748 --- /dev/null +++ b/src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopConfiguration.java @@ -0,0 +1,19 @@ +package io.v.nutz.base.interceptor.repeatSubmit; + +import io.v.nutz.base.annontation.RepeatSubmit; +import org.nutz.aop.MethodInterceptor; +import org.nutz.ioc.Ioc; +import org.nutz.ioc.aop.SimpleAopMaker; +import org.nutz.ioc.loader.annotation.IocBean; + +import java.lang.reflect.Method; +import java.util.List; + +@IocBean(name = "$aop_repeatSubmit") +public class RepeatSubmitAopConfiguration extends SimpleAopMaker { + + @Override + public List makeIt(RepeatSubmit repeatSubmit, Method method, Ioc ioc) { + return List.of(new RepeatSubmitAopInterceptor(ioc, repeatSubmit, method)); + } +} diff --git a/src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopInterceptor.java b/src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopInterceptor.java new file mode 100644 index 0000000..d1800f3 --- /dev/null +++ b/src/main/java/io/v/nutz/base/interceptor/repeatSubmit/RepeatSubmitAopInterceptor.java @@ -0,0 +1,51 @@ +package io.v.nutz.base.interceptor.repeatSubmit; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import io.v.nutz.base.annontation.RepeatSubmit; +import io.v.nutz.base.constant.RedisConstant; +import io.v.nutz.base.exception.BaseException; +import io.v.nutz.web.commons.utils.ShiroUtil; +import org.nutz.aop.InterceptorChain; +import org.nutz.aop.MethodInterceptor; +import org.nutz.integration.jedis.RedisService; +import org.nutz.ioc.Ioc; +import org.nutz.mvc.Mvcs; + +import java.lang.reflect.Method; + +public class RepeatSubmitAopInterceptor implements MethodInterceptor { + + protected Ioc ioc; + + public RepeatSubmitAopInterceptor(Ioc ioc, RepeatSubmit repeatSubmit, Method method) { + RedisService redisService = ioc.get(RedisService.class); + } + + @Override + public void filter(InterceptorChain chain) throws Throwable { + Method method = chain.getCallingMethod(); + RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); + int interval = annotation.interval(); + RedisService redisService = Mvcs.getIoc().get(RedisService.class); + String source = method.getDeclaringClass().getName() + "#" + method.getName(); + Object[] args = chain.getArgs(); + String parameterJson = ""; + if (ObjectUtil.isNotEmpty(args)) { + parameterJson = JSONUtil.toJsonStr(args); // 序列化实际参数 + } + String key = RedisConstant.REPEAT_SUBMIT_PREFIX + ShiroUtil.getUserId() + ":" + source; + + Boolean exists = redisService.exists(key); + if (exists) { + // 判断 + String oldParameterJson = redisService.get(key); + if (oldParameterJson != null && oldParameterJson.equalsIgnoreCase(parameterJson)) { + throw new BaseException(annotation.message()); + } + } else { + redisService.setex(key, interval / 1000, parameterJson); + } + chain.doChain(); + } +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/controller/AlipayClientController.java b/src/main/java/io/v/nutz/base/payment/alipay/controller/AlipayClientController.java similarity index 93% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/controller/AlipayClientController.java rename to src/main/java/io/v/nutz/base/payment/alipay/controller/AlipayClientController.java index abc1f68..3a20c7c 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/controller/AlipayClientController.java +++ b/src/main/java/io/v/nutz/base/payment/alipay/controller/AlipayClientController.java @@ -1,6 +1,6 @@ -package io.v.nutz.zhgh.memberCost.payment.alipay.controller; +package io.v.nutz.base.payment.alipay.controller; -import io.v.nutz.zhgh.memberCost.payment.alipay.service.AlipayService; +import io.v.nutz.base.payment.alipay.service.AlipayService; import lombok.extern.slf4j.Slf4j; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/AlipayClientConfig.java b/src/main/java/io/v/nutz/base/payment/alipay/service/AlipayClientConfig.java similarity index 98% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/AlipayClientConfig.java rename to src/main/java/io/v/nutz/base/payment/alipay/service/AlipayClientConfig.java index 0594c7c..243fa05 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/AlipayClientConfig.java +++ b/src/main/java/io/v/nutz/base/payment/alipay/service/AlipayClientConfig.java @@ -1,4 +1,4 @@ -package io.v.nutz.zhgh.memberCost.payment.alipay.service; +package io.v.nutz.base.payment.alipay.service; /** * @ClassName AlipayClientConfig diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/AlipayService.java b/src/main/java/io/v/nutz/base/payment/alipay/service/AlipayService.java similarity index 85% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/AlipayService.java rename to src/main/java/io/v/nutz/base/payment/alipay/service/AlipayService.java index f0fe4d8..255d7db 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/AlipayService.java +++ b/src/main/java/io/v/nutz/base/payment/alipay/service/AlipayService.java @@ -1,4 +1,4 @@ -package io.v.nutz.zhgh.memberCost.payment.alipay.service; +package io.v.nutz.base.payment.alipay.service; import io.v.nutz.base.service.ViService; diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/impl/AlipayNewServiceImpl.java b/src/main/java/io/v/nutz/base/payment/alipay/service/impl/AlipayNewServiceImpl.java similarity index 96% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/impl/AlipayNewServiceImpl.java rename to src/main/java/io/v/nutz/base/payment/alipay/service/impl/AlipayNewServiceImpl.java index b78cd14..2c99caa 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/alipay/service/impl/AlipayNewServiceImpl.java +++ b/src/main/java/io/v/nutz/base/payment/alipay/service/impl/AlipayNewServiceImpl.java @@ -1,4 +1,4 @@ -package io.v.nutz.zhgh.memberCost.payment.alipay.service.impl; +package io.v.nutz.base.payment.alipay.service.impl; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayConstants; @@ -7,11 +7,11 @@ import com.alipay.api.domain.AlipayTradeWapPayModel; import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.request.AlipayTradeWapPayRequest; import com.alipay.api.response.AlipayTradeWapPayResponse; +import io.v.nutz.base.payment.alipay.service.AlipayClientConfig; +import io.v.nutz.base.payment.alipay.service.AlipayService; import io.v.nutz.base.service.impl.ViServiceImpl; import io.v.nutz.web.commons.utils.ShiroUtil; -import io.v.nutz.zhgh.memberCost.payment.alipay.service.AlipayClientConfig; import io.v.nutz.zhgh.memberCost.model.MemberPaymentInfo; -import io.v.nutz.zhgh.memberCost.payment.alipay.service.AlipayService; import lombok.extern.slf4j.Slf4j; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/RefundStateEnum.java b/src/main/java/io/v/nutz/base/payment/enums/RefundStateEnum.java similarity index 80% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/RefundStateEnum.java rename to src/main/java/io/v/nutz/base/payment/enums/RefundStateEnum.java index 3e54d0a..33b6b38 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/RefundStateEnum.java +++ b/src/main/java/io/v/nutz/base/payment/enums/RefundStateEnum.java @@ -1,6 +1,8 @@ -package io.v.nutz.zhgh.memberCost.payment.enums; +package io.v.nutz.base.payment.enums; import io.v.nutz.base.annontation.SelectEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * 退款状态枚举 diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingChannelEnum.java b/src/main/java/io/v/nutz/base/payment/enums/TradingChannelEnum.java similarity index 79% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingChannelEnum.java rename to src/main/java/io/v/nutz/base/payment/enums/TradingChannelEnum.java index 2f1ea6c..9939c3b 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingChannelEnum.java +++ b/src/main/java/io/v/nutz/base/payment/enums/TradingChannelEnum.java @@ -1,6 +1,8 @@ -package io.v.nutz.zhgh.memberCost.payment.enums; +package io.v.nutz.base.payment.enums; import io.v.nutz.base.annontation.SelectEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * 交易渠道枚举 diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingStateEnum.java b/src/main/java/io/v/nutz/base/payment/enums/TradingStateEnum.java similarity index 79% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingStateEnum.java rename to src/main/java/io/v/nutz/base/payment/enums/TradingStateEnum.java index 17c7c9f..95703dc 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingStateEnum.java +++ b/src/main/java/io/v/nutz/base/payment/enums/TradingStateEnum.java @@ -1,6 +1,8 @@ -package io.v.nutz.zhgh.memberCost.payment.enums; +package io.v.nutz.base.payment.enums; import io.v.nutz.base.annontation.SelectEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; /** diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingTypeEnum.java b/src/main/java/io/v/nutz/base/payment/enums/TradingTypeEnum.java similarity index 75% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingTypeEnum.java rename to src/main/java/io/v/nutz/base/payment/enums/TradingTypeEnum.java index 31865e4..174dd6a 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/enums/TradingTypeEnum.java +++ b/src/main/java/io/v/nutz/base/payment/enums/TradingTypeEnum.java @@ -1,6 +1,8 @@ -package io.v.nutz.zhgh.memberCost.payment.enums; +package io.v.nutz.base.payment.enums; import io.v.nutz.base.annontation.SelectEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; /** * 交易类型枚举 diff --git a/src/main/java/io/v/nutz/base/payment/enums/WxPayResultCode.java b/src/main/java/io/v/nutz/base/payment/enums/WxPayResultCode.java new file mode 100644 index 0000000..2a9e741 --- /dev/null +++ b/src/main/java/io/v/nutz/base/payment/enums/WxPayResultCode.java @@ -0,0 +1,30 @@ +package io.v.nutz.base.payment.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @version 1.0 + * @Author zzr + * @name:WxPayResultCode + * @Date 2025/3/10 10:27 + * @注释 微信支付返回码 + */ +@Getter +@AllArgsConstructor +public enum WxPayResultCode { + + SUCCESS(200, "操作成功"), + APPID_MCHID_NOT_MATCH(400, "商户ID和服务号或企业微信号不匹配"), + INVALID_REQUEST(400, "无效请求"), + MCH_NOT_EXISTS(400, "商户号不存在"), + PARAM_ERROR(400, "参数错误"), + SIGN_ERROR(401, "签名错误"), + NO_AUTH(403, "商户无权限"), + OUT_TRADE_NO_USED(403, "商户订单号重复"), + FREQUENCY_LIMITED(429, "频率超限"), + SYSTEM_ERROR(500, "系统错误"); + + final int code; + final String msg; +} diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/model/PaymentTransaction.java b/src/main/java/io/v/nutz/base/payment/model/PaymentTransaction.java similarity index 91% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/model/PaymentTransaction.java rename to src/main/java/io/v/nutz/base/payment/model/PaymentTransaction.java index 1a9c092..12ec042 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/model/PaymentTransaction.java +++ b/src/main/java/io/v/nutz/base/payment/model/PaymentTransaction.java @@ -1,6 +1,10 @@ -package io.v.nutz.zhgh.memberCost.payment.model; +package io.v.nutz.base.payment.model; import io.v.nutz.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; import java.math.BigDecimal; @@ -83,7 +87,7 @@ public class PaymentTransaction extends BaseModel { @Column @Comment("退款金额") @ColDefine(customType = "decimal") - private String refundAmount; + private BigDecimal refundAmount; @Column @Comment("订单描述") diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/model/RefundRecord.java b/src/main/java/io/v/nutz/base/payment/model/RefundRecord.java similarity index 87% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/model/RefundRecord.java rename to src/main/java/io/v/nutz/base/payment/model/RefundRecord.java index d65049f..a8757ca 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/model/RefundRecord.java +++ b/src/main/java/io/v/nutz/base/payment/model/RefundRecord.java @@ -1,6 +1,10 @@ -package io.v.nutz.zhgh.memberCost.payment.model; +package io.v.nutz.base.payment.model; import io.v.nutz.base.model.BaseModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.nutz.dao.entity.annotation.*; +import org.nutz.dao.interceptor.annotation.PrevInsert; import java.math.BigDecimal; diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/bean/WxPayV3Bean.java b/src/main/java/io/v/nutz/base/payment/wxpay/bean/WxPayV3Bean.java similarity index 95% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/bean/WxPayV3Bean.java rename to src/main/java/io/v/nutz/base/payment/wxpay/bean/WxPayV3Bean.java index 4999027..ea01f2f 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/bean/WxPayV3Bean.java +++ b/src/main/java/io/v/nutz/base/payment/wxpay/bean/WxPayV3Bean.java @@ -1,4 +1,4 @@ -package io.v.nutz.zhgh.memberCost.payment.wxpay.bean; +package io.v.nutz.base.payment.wxpay.bean; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/pem/apiclient_cert.pem b/src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_cert.pem similarity index 100% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/pem/apiclient_cert.pem rename to src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_cert.pem diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/pem/apiclient_key.pem b/src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_key.pem similarity index 100% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/pem/apiclient_key.pem rename to src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_key.pem diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/pem/wechatpay.pem b/src/main/java/io/v/nutz/base/payment/wxpay/pem/wechatpay.pem similarity index 100% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/pem/wechatpay.pem rename to src/main/java/io/v/nutz/base/payment/wxpay/pem/wechatpay.pem diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/service/WxPayCommonService.java b/src/main/java/io/v/nutz/base/payment/wxpay/service/WxPayCommonService.java similarity index 84% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/service/WxPayCommonService.java rename to src/main/java/io/v/nutz/base/payment/wxpay/service/WxPayCommonService.java index 60d8689..25215d9 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/service/WxPayCommonService.java +++ b/src/main/java/io/v/nutz/base/payment/wxpay/service/WxPayCommonService.java @@ -1,6 +1,7 @@ -package io.v.nutz.zhgh.memberCost.payment.wxpay.service; +package io.v.nutz.base.payment.wxpay.service; -import io.v.nutz.zhgh.memberCost.payment.wxpay.vo.WxPayNeedParamVo; +import io.v.nutz.base.payment.wxpay.vo.WxPayNeedParamVo; +import io.v.nutz.base.result.Result; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -21,7 +22,7 @@ public interface WxPayCommonService { * 注意Amount的总价total是int类型,会自动乘以0.01,例如传递100元,会自动转换为1元 * @return */ - String nativePay(WxPayNeedParamVo paramVo); + Result nativePay(WxPayNeedParamVo paramVo); /** @@ -31,7 +32,7 @@ public interface WxPayCommonService { * JsAPI支付,需要传递openId,请自行获取 * @return */ - String jsApiPay(WxPayNeedParamVo paramVo); + Result jsApiPay(WxPayNeedParamVo paramVo); /** * WAP支付,返回支付参数 @@ -39,7 +40,7 @@ public interface WxPayCommonService { * 注意Amount的总价total是int类型,会自动乘以0.01,例如传递100元,会自动转换为1元 * @return */ - String wapPay(WxPayNeedParamVo paramVo); + Result wapPay(WxPayNeedParamVo paramVo); /** @@ -56,7 +57,7 @@ public interface WxPayCommonService { * @param outTradeNo 商户订单号 * @return */ - String refund(String transactionId, String outTradeNo); + Result refund(String transactionId, String outTradeNo); /** diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/service/impl/WxPayCommonServiceImpl.java b/src/main/java/io/v/nutz/base/payment/wxpay/service/impl/WxPayCommonServiceImpl.java similarity index 81% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/service/impl/WxPayCommonServiceImpl.java rename to src/main/java/io/v/nutz/base/payment/wxpay/service/impl/WxPayCommonServiceImpl.java index 8d2a0a0..66c294a 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/service/impl/WxPayCommonServiceImpl.java +++ b/src/main/java/io/v/nutz/base/payment/wxpay/service/impl/WxPayCommonServiceImpl.java @@ -1,4 +1,4 @@ -package io.v.nutz.zhgh.memberCost.payment.wxpay.service.impl; +package io.v.nutz.base.payment.wxpay.service.impl; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateTime; @@ -19,16 +19,29 @@ import com.ijpay.wxpay.WxPayApi; import com.ijpay.wxpay.enums.WxDomainEnum; import com.ijpay.wxpay.enums.v3.BasePayApiEnum; import com.ijpay.wxpay.model.v3.*; -import io.v.nutz.zhgh.memberCost.payment.wxpay.bean.WxPayV3Bean; -import io.v.nutz.zhgh.memberCost.payment.wxpay.service.WxPayCommonService; -import io.v.nutz.zhgh.memberCost.payment.wxpay.vo.WxPayNeedParamVo; +import io.v.nutz.base.payment.enums.TradingChannelEnum; +import io.v.nutz.base.payment.enums.TradingTypeEnum; +import io.v.nutz.base.payment.enums.WxPayResultCode; +import io.v.nutz.base.payment.model.PaymentTransaction; +import io.v.nutz.base.payment.wxpay.bean.WxPayV3Bean; +import io.v.nutz.base.payment.wxpay.service.WxPayCommonService; +import io.v.nutz.base.payment.wxpay.vo.WxPayNeedParamVo; +import io.v.nutz.base.result.Result; +import io.v.nutz.sys.models.User; +import io.v.nutz.sys.services.SysUserService; +import io.v.nutz.web.commons.utils.ShiroUtil; import lombok.extern.slf4j.Slf4j; +import org.nutz.dao.Cnd; +import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.random.R; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.FileWriter; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.security.cert.X509Certificate; import java.util.ArrayList; @@ -50,14 +63,15 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { // 判断下单接口成功返回码 private final static int OK = 200; + // 1666930980 商户号 // 微信V3必要的支付参数,后期优化 private final static WxPayV3Bean WX_PAY_V3_BEAN = new WxPayV3Bean( "ww3eda050a1b5ad96e", - "src/main/java/io/v/nutz/zhgh/memberCost/wxpay/pem/apiclient_key.pem", - "src/main/java/io/v/nutz/zhgh/memberCost/wxpay/pem/apiclient_key.pem", - "src/main/java/io/v/nutz/zhgh/memberCost/wxpay/pem/apiclient_cert.pem", - "src/main/java/io/v/nutz/zhgh/memberCost/wxpay/pem/apiclient_cert.pem", - "src/main/java/io/v/nutz/zhgh/memberCost/wxpay/pem/wechatpay.pem", + "src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_key.pem", + "src/main/java/io/v/nutz/base/payment/wxpay/wxpay/pem/apiclient_key.pem", + "src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_cert.pem", + "src/main/java/io/v/nutz/base/payment/wxpay/pem/apiclient_cert.pem", + "src/main/java/io/v/nutz/base/payment/wxpay/pem/wechatpay.pem", "1666930980", "", "4ebd020883285d698c44ec50939c0967", @@ -65,9 +79,12 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { ""); // 自定义参数,内容是统一的,但会被多次调用,直接声明 - String serialNo; - String platSerialNo; - String payNotifyUrl = WX_PAY_V3_BEAN.getDomain().concat("/wxPay/notifyMessage"); + private String serialNo; + private String platSerialNo; + private final String payNotifyUrl = WX_PAY_V3_BEAN.getDomain().concat("/wxPay/notifyMessage"); + + @Inject + private SysUserService sysUserService; /** * 微信扫描二维码支付 @@ -76,7 +93,7 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { * @return */ @Override - public String nativePay(WxPayNeedParamVo paramVo) { + public Result nativePay(WxPayNeedParamVo paramVo) { try { // 商户订单号,存储当前用户的订单 String outTradeNo = PayKit.generateStr(); @@ -113,20 +130,25 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { // 下单返回数据 String result = response.getBody(); - if (result != null) { - // 向数据库插入订单记录 - } + JSONObject jsonObject = JSONUtil.parseObj(result); - return result; + if (response.getStatus() == OK) { + // 统一下单成功,向数据库插入订单记录 + insertTradingOrder(paramVo, outTradeNo, result); + return Result.success("请在三分钟内完成支付,超时将自动取消订单").addData(result); + } else { + WxPayResultCode code = WxPayResultCode.valueOf(WxPayResultCode.class, jsonObject.getStr("code")); + return Result.error(code.getMsg()); + } } catch (Exception e) { log.error("系统异常", e); - return e.getMessage(); + return Result.error(e.getMessage()); } } @Override - public String jsApiPay(WxPayNeedParamVo paramVo) { + public Result jsApiPay(WxPayNeedParamVo paramVo) { try { // 商户订单号,存储当前用户的订单 String outTradeNo = PayKit.generateStr(); @@ -166,18 +188,19 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { log.info("唤起支付参数:{}", map); // 唤起支付成功,向数据库插入订单参数 - return JSONUtil.toJsonStr(map); + return Result.success(JSONUtil.toJsonStr(map)); } - return JSONUtil.toJsonStr(response); +// return JSONUtil.toJsonStr(response); + return null; } catch (Exception e) { log.error("系统异常", e); - return e.getMessage(); + return Result.error(e.getMessage()); } } @Override - public String wapPay(WxPayNeedParamVo paramVo) { + public Result wapPay(WxPayNeedParamVo paramVo) { try { // 商户订单号,存储当前用户的订单 String outTradeNo = PayKit.generateStr(); @@ -215,12 +238,13 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { log.info("verifySignature: {}", verifySignature); if (response.getStatus() == OK && verifySignature) { String body = response.getBody(); - return JSONUtil.toJsonStr(body); + return Result.success(JSONUtil.toJsonStr(body)); } - return JSONUtil.toJsonStr(response); +// return JSONUtil.toJsonStr(response); + return null; } catch (Exception e) { log.error("系统异常", e); - return e.getMessage(); + return Result.error(e.getMessage()); } } @@ -278,7 +302,7 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { * @return */ @Override - public String refund(String transactionId, String outTradeNo) { + public Result refund(String transactionId, String outTradeNo) { try { String outRefundNo = PayKit.generateStr(); log.info("商户退款单号: {}", outRefundNo); @@ -324,11 +348,11 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { log.info("退款响应 {}", response); if (verifySignature) { - return response.getBody(); + return Result.success(response.getBody()); } } catch (Exception e) { log.error("系统异常", e); - return e.getMessage(); + return Result.error(e.getMessage()); } return null; } @@ -476,4 +500,39 @@ public class WxPayCommonServiceImpl implements WxPayCommonService { DateTime dateTime = DateUtil.date(currentTimeMillis); return DateUtil.format(dateTime, "yyyy-MM-dd'T'HH:mm:ssXXX"); } + + + /** + * 公共方法,插入交易订单 + * @param paramVo 交易必填参数Vo + * @param outTradeNo 商户交易号 + * @param result 下单返回结构 + */ + private void insertTradingOrder(WxPayNeedParamVo paramVo, String outTradeNo, String result){ + User user = sysUserService.dao().fetch(User.class, Cnd.where("id", "=", ShiroUtil.getUserId())); + PaymentTransaction transaction = new PaymentTransaction(); + transaction.setId(R.UU32()); + transaction.setMchId(WX_PAY_V3_BEAN.getMchId()); + transaction.setOutTradeNo(outTradeNo); + transaction.setTradingOrderNo(null); + transaction.setTradingChannel(TradingChannelEnum.WX_PAY.name()); + transaction.setTradingType(TradingTypeEnum.PAYMENT.name()); + transaction.setUserId(user.getId()); + transaction.setLoginName(user.getLoginname()); + transaction.setUserName(user.getUsername()); + transaction.setUnitName(user.getUnitname()); + transaction.setUnionName(user.getUnionname()); + // 获取订单金额 + int total = paramVo.getAmount().getTotal(); + BigDecimal bigDecimalValue = new BigDecimal(String.valueOf(total)); + BigDecimal resultTotal = bigDecimalValue.divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP); + transaction.setTradingAmount(resultTotal); + transaction.setIsRefund(false); + transaction.setRefundAmount(null); + transaction.setDescription(paramVo.getDescription()); + transaction.setAttach(paramVo.getAttach()); + transaction.setOpenId(null); + transaction.setResultJson(result); + sysUserService.dao().insert(transaction); + } } diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/vo/WxPayNeedParamVo.java b/src/main/java/io/v/nutz/base/payment/wxpay/vo/WxPayNeedParamVo.java similarity index 94% rename from src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/vo/WxPayNeedParamVo.java rename to src/main/java/io/v/nutz/base/payment/wxpay/vo/WxPayNeedParamVo.java index 58977a1..8b374a0 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/payment/wxpay/vo/WxPayNeedParamVo.java +++ b/src/main/java/io/v/nutz/base/payment/wxpay/vo/WxPayNeedParamVo.java @@ -1,4 +1,4 @@ -package io.v.nutz.zhgh.memberCost.payment.wxpay.vo; +package io.v.nutz.base.payment.wxpay.vo; import com.ijpay.wxpay.model.v3.Amount; import com.ijpay.wxpay.model.v3.Payer; diff --git a/src/main/java/io/v/nutz/base/utils/WebUtil.java b/src/main/java/io/v/nutz/base/utils/WebUtil.java new file mode 100644 index 0000000..7bd68e7 --- /dev/null +++ b/src/main/java/io/v/nutz/base/utils/WebUtil.java @@ -0,0 +1,33 @@ +package io.v.nutz.base.utils; + +import org.nutz.json.JsonFormat; +import org.nutz.lang.Encoding; +import org.nutz.mvc.view.UTF8JsonView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author wizzer@qq.com + */ +public class WebUtil { + + public static String AjaxEncode = Encoding.UTF8; + + public static boolean isAjax(HttpServletRequest req) { + String value = req.getHeader("X-Requested-With"); + return value != null && "XMLHttpRequest".equalsIgnoreCase(value.trim()); + } + + public static void rendAjaxResp(HttpServletRequest req, HttpServletResponse resp, Object re) { + try { + if (AjaxEncode != null) { + resp.setCharacterEncoding(AjaxEncode); + } + (new UTF8JsonView(JsonFormat.compact())).render(req, resp, re); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/io/v/nutz/web/commons/proc/WkFailProcessor.java b/src/main/java/io/v/nutz/web/commons/proc/WkFailProcessor.java index 34e5cd9..5707521 100644 --- a/src/main/java/io/v/nutz/web/commons/proc/WkFailProcessor.java +++ b/src/main/java/io/v/nutz/web/commons/proc/WkFailProcessor.java @@ -1,6 +1,8 @@ package io.v.nutz.web.commons.proc; +import io.v.nutz.base.exception.BaseException; import io.v.nutz.base.result.Result; +import io.v.nutz.base.utils.WebUtil; import org.nutz.integration.shiro.NutShiro; import org.nutz.ioc.IocException; import org.nutz.log.Log; @@ -27,13 +29,24 @@ public class WkFailProcessor extends ViewProcessor { String uri = Mvcs.getRequestPath(ac.getRequest()); log.warn(String.format("Error@%s :", uri), ac.getError()); } - if (ac.getError() instanceof IocException) { + Throwable e = ac.getError(); + if (e instanceof IocException) { if (NutShiro.isAjax(ac.getRequest())) { NutShiro.rendAjaxResp(ac.getRequest(), ac.getResponse(), Result.error(Mvcs.getMessage(ac.getRequest(), "system.exception"))); } else { ac.getRequest().setAttribute("original_request_uri",ac.getRequest().getRequestURI()); new ForwardView(errorUri).render(ac.getRequest(), ac.getResponse(), Mvcs.getMessage(ac.getRequest(), "system.exception")); } + } else if (e instanceof BaseException) { + if (WebUtil.isAjax(ac.getRequest())) { +// WebUtil.rendAjaxResp(ac.getRequest(), ac.getResponse(), Result.error(ResultCode.FAILURE.getCode(), !log.isDebugEnabled() ? ResultCode.FAILURE.getMsg() : e.getMessage())); + WebUtil.rendAjaxResp(ac.getRequest(), ac.getResponse(), Result.error(400, e.getMessage())); + } else { + ac.getRequest().setAttribute("original_request_uri", ac.getRequest().getRequestURI()); + ac.getRequest().setAttribute("error_message", Mvcs.getMessage(ac.getRequest(), "业务异常")); +// new ForwardView(errorUri).render(ac.getRequest(), ac.getResponse(), null); + } + return; } super.process(ac); } diff --git a/src/main/java/io/v/nutz/zhgh/memberCost/controller/MemberPaymentMineController.java b/src/main/java/io/v/nutz/zhgh/memberCost/controller/MemberPaymentMineController.java index 84b8f67..eccff62 100644 --- a/src/main/java/io/v/nutz/zhgh/memberCost/controller/MemberPaymentMineController.java +++ b/src/main/java/io/v/nutz/zhgh/memberCost/controller/MemberPaymentMineController.java @@ -1,6 +1,9 @@ package io.v.nutz.zhgh.memberCost.controller; -import io.v.nutz.zhgh.memberCost.payment.wxpay.service.WxPayCommonService; +import com.ijpay.wxpay.model.v3.Amount; +import io.v.nutz.base.annontation.RepeatSubmit; +import io.v.nutz.base.payment.wxpay.service.WxPayCommonService; +import io.v.nutz.base.payment.wxpay.vo.WxPayNeedParamVo; import io.v.nutz.zhgh.memberCost.service.MemberPaymentService; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authz.annotation.RequiresPermissions; @@ -29,12 +32,24 @@ public class MemberPaymentMineController { @At("") @Ok("beetl:/platform/membercost/mine/index.html") - @RequiresPermissions("member.payment.project") + @RequiresPermissions("member.payment.mine") public void index() { } + @At public Object pageData(){ return null; } + + + @At + @RepeatSubmit + public Object pcOrderPay(){ + WxPayNeedParamVo paramVo = new WxPayNeedParamVo(); + paramVo.setDescription("会费缴纳支付"); + paramVo.setAttach(""); + paramVo.setAmount(new Amount().setTotal(1)); + return wxPayCommonService.nativePay(paramVo); + } }