From 4b518e023c191b262c15a0f4cf5302512454b099 Mon Sep 17 00:00:00 2001 From: wangqx Date: Sat, 20 Sep 2025 18:18:55 +0800 Subject: [PATCH] =?UTF-8?q?[fix]=E5=BE=AE=E4=BF=A1=E5=85=85=E5=80=BC?= =?UTF-8?q?=E5=92=8C=E6=8F=90=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/app/AppPayController.java | 40 ++- .../main/resources/cert/apiclient_cert.p12 | Bin 0 -> 2775 bytes .../main/resources/cert/apiclient_cert.pem | 25 ++ .../transaction/business/IChargeBusiness.java | 9 + .../business/impl/ChargeBusinessImpl.java | 37 +++ .../soopin/transaction/domain/po/Charge.java | 2 +- .../transaction/domain/po/PayOrder.java | 2 + .../transaction/enums/ChargeStatus.java | 7 +- .../transaction/enums/PayStatusEnum.java | 29 ++ .../transaction/enums/PaymentMethodEnum.java | 22 +- .../transaction/kit/WechatPaymentSetting.java | 58 ++++ .../transaction/kit/core/kit/WxPayKit.java | 6 +- .../kit/core/utils/DateTimeZoneUtil.java | 2 +- .../soopin/transaction/kit/dto/PayParam.java | 3 +- .../kit/params/dto/CashierParam.java | 2 +- .../kit/params/impl/OrderCashier.java | 2 +- .../kit/params/impl/RechargeCashier.java | 60 ++-- .../kit/plugin/easypay/EasyPayPlugin.java | 4 +- .../kit/plugin/wallet/WalletPlugin.java | 4 +- .../kit/plugin/wechat/WechatPlugin.java | 279 ++++++++++-------- .../kit/plugin/wechat/model/Amount.java | 2 +- .../transaction/service/IChargeService.java | 2 + .../service/impl/ChargeServiceImpl.java | 31 +- .../service/impl/PayOrderServiceImpl.java | 7 + .../service/impl/WithdrawServiceImpl.java | 2 +- .../soopin/transaction/util/CurrencyUtil.java | 7 +- .../soopin/transaction/util/SnowFlake.java | 2 +- script/docker/nginx/conf/nginx.conf | 6 +- 28 files changed, 445 insertions(+), 207 deletions(-) create mode 100644 ruoyi-admin/src/main/resources/cert/apiclient_cert.p12 create mode 100644 ruoyi-admin/src/main/resources/cert/apiclient_cert.pem create mode 100644 ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/business/IChargeBusiness.java create mode 100644 ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/business/impl/ChargeBusinessImpl.java create mode 100644 ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PayStatusEnum.java create mode 100644 ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/WechatPaymentSetting.java diff --git a/ruoyi-admin/src/main/java/org/dromara/app/AppPayController.java b/ruoyi-admin/src/main/java/org/dromara/app/AppPayController.java index 4de8b9323..a3ad772b9 100644 --- a/ruoyi-admin/src/main/java/org/dromara/app/AppPayController.java +++ b/ruoyi-admin/src/main/java/org/dromara/app/AppPayController.java @@ -1,10 +1,22 @@ package org.dromara.app; +import com.wzj.soopin.transaction.business.IChargeBusiness; +import com.wzj.soopin.transaction.convert.ChargeConvert; +import com.wzj.soopin.transaction.domain.bo.ChargeBO; +import com.wzj.soopin.transaction.domain.bo.PaymentBO; +import com.wzj.soopin.transaction.domain.po.Charge; +import com.wzj.soopin.transaction.domain.po.PayOrder; import com.wzj.soopin.transaction.enums.PaymentClientEnum; import com.wzj.soopin.transaction.enums.PaymentMethodEnum; +import com.wzj.soopin.transaction.enums.TransState; +import com.wzj.soopin.transaction.enums.easypay.PayType; import com.wzj.soopin.transaction.kit.CashierSupport; import com.wzj.soopin.transaction.kit.dto.PayParam; import com.wzj.soopin.transaction.kit.params.dto.CashierParam; +import com.wzj.soopin.transaction.service.IChargeService; +import com.wzj.soopin.transaction.service.PayOrderService; +import com.wzj.soopin.transaction.util.SnowFlake; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; @@ -16,10 +28,14 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.ResultCode; import org.dromara.common.core.domain.R; +import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.satoken.utils.LoginHelper; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Date; + /** * 买家端,收银台接口 @@ -34,11 +50,11 @@ import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor public class AppPayController { - + private final IChargeBusiness chargeBusiness; private final CashierSupport cashierSupport; -// @ApiImplicitParams({ + // @ApiImplicitParams({ // @ApiImplicitParam(name = "client", value = "客户端类型", paramType = "path", allowableValues = "PC,H5,WECHAT_MP,APP") // }) @PostMapping(value = "/tradeDetail") @@ -51,19 +67,29 @@ public class AppPayController { @ApiImplicitParams({ - @ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"), - @ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP") + @ApiImplicitParam(name = "paymentMethod", value = "支付方式", paramType = "path", allowableValues = "WECHAT,ALIPAY"), + @ApiImplicitParam(name = "paymentClient", value = "调起方式", paramType = "path", allowableValues = "APP,NATIVE,JSAPI,H5,MP") }) @PostMapping(value = "/pay") @Operation(summary = "支付") public R payment( - HttpServletRequest request, - HttpServletResponse response, - @RequestBody @Validated PayParam payParam) { + HttpServletRequest request, + HttpServletResponse response, + @RequestBody @Validated PayParam payParam, @RequestBody ChargeBO chargeBO) { PaymentMethodEnum paymentMethodEnum = PaymentMethodEnum.valueOf(payParam.getPaymentMethod()); PaymentClientEnum paymentClientEnum = PaymentClientEnum.valueOf(payParam.getPaymentClient()); try { + + LoginUser user = LoginHelper.getLoginUser(); + if (user == null) { + return R.notLogin(); + } + //先生成充值订单 + chargeBO.setMemberId(user.getUserId()); + chargeBO.setMethod(paymentMethodEnum.getCode()); + chargeBusiness.charge(chargeBO); + payParam.setSn(chargeBO.getCode()); return cashierSupport.payment(paymentMethodEnum, paymentClientEnum, request, response, payParam); } catch (ServiceException se) { log.info("支付异常", se); diff --git a/ruoyi-admin/src/main/resources/cert/apiclient_cert.p12 b/ruoyi-admin/src/main/resources/cert/apiclient_cert.p12 new file mode 100644 index 0000000000000000000000000000000000000000..ad864998dc8b76fef9d70ee211a90f730eb8a165 GIT binary patch literal 2775 zcmY+^c{~(~76r@C-1Q z3{3)&p^2w)ERqa9^Un&BO9t&B$)F!hK)`9+_-6w|3PGU%{=g1|AUQ!SnYV&K&CA!H zGcmCMBFUilWrB*9KZXrCC<3>#?C4HpS;(Cb-a8h!@+N}zJvuFrn=@vbE9h}pjM)7H z-^EAFNI8;wj+k^l!DD6^l!*yDN~5tiqOZXQEFM@%{m~^_vsz!(9?$3TBm_O*h#`9T z6q3pnyLwal5Es8+K-b+@SxWbIVZHV14Mn76)8J7C zS*MDqJKd0TyS=H1xIAj%C|;`2pmVpBq;qkX*LLoByi=O+N{u>zU%d=eAZLriFE(so zloWXSy)MWlr^3%l+ScG;^!Sqs8t!NP!JhB(!?qz1$W=b`7<*REJ}&1=ucQ6pEIma# zf2~~b0hMl#Y9SGXNYFSL3inxU>2)THTn;;sU`FL zHo2eNe;xjs_s2uoIk~T^6*`Xf7y44MdUeB3#JZyM#R-2Mf|*XzD5H;Ct=5~1Mc;Ft z3#qJRd&H=))y|zjqZ}RC)W3Grs2KS0Lq_q@CJ_gXS+1Wy3*cTM1zUW>o%dvzjn7|m zv<9iU3tJf5OFC6w`QVV|w8ZH7R5$;&V}qk^Qg$;s8L$S~T{T9XcV3;7Rj(xzDl)@4>-CdC+#9+aQMqf@lp(Ycr z#MHKjTKD5u^S5s6XR-EyKU;eAZ7hH05*r_9=ImIjQo^ESI{goKYk&JDdb4vVJTf(SKZcrJcL{hp#HzuJ2)vCBQzbe|3GY{`z>9T#M; z?meJp=Fo1KOgV_BolntxEJ^LgBI@SCDnssCSk>wq%PhU1WAu1tf+i)*gC~S-+CuhqQt8O#dk;#`I0>@YpB?G2dNc2OMuy)be4<(wS@a_FPwn0c8Tln<8h6AGyByJ(zHW1ZQW<3IOsIR&$3yd|>`-PQ_sK1s z>-&6=kSkx|c8~9@rY^N6Q9k^cdi@C^6%lfdpX&dfff|%`zd(shkL)gt5K%LeYuM6SMCK)nka*&Hz|sJYwvZ@#N@4K-fR{@Kdw|Gbx6|19v>YI8|KSe` zWIA>7`zesC|ED7J-zuJQ*jR_4eKCKl2qJ?zFX5(9;%1XHbc6I+>dRiOg~$=7fTo@% zSF2;PM=9Hut$NNxf-Yug^~X%#Cn<`{>|7;mBG0JY;U&X|nC45(m@!h$8XowBNV;?Y zE%SUOv*+ak;IEz!JIa&OEO=?Rz#8(bXcxD-@)eA;iZ4!O^WA!d#RkrjYZdSj(pO)H zII0<)JLwYA(dmE@eC0S1fvnOB^Oh@=!^@OKEZnGrCe1avq2S-;#&_-`YH>Kp4OadA zY31_y25G+4I`A`l!H1!XYYJ_ppIgV+55&{lXH)`W^q8mCX>%H+vnVuidFsy!lDZ)Y zPF}O%vO!hY+{KimO)lPM*ExKcgiw}5H6_=s0V@h7Kx@VA>!wv(I-6$nIbnDC zmINpXv&~yG;aW2`$Ce1*t^Mdn(9e*hz#AaV4fihwHDjtU{GM0^u4P=uTt)gj_pz`MfAgum%9r@NIg5c-)jEbEb8AOu z&h`Np0GD;x2!piaf-N*(9MnMuD0rm@hJ84+<8Tt+e?@N_5=dN#{#5q#InB=wk{2WS zniRg(@;TotvzSg>=1_YxycIEzJ&5du^G+Evx1_mz4c*qkHup0EN%wHHpkW=nuB#xkEsq`h#%NOW`VpU#A`^H3(e zb<>+t+~I7p&YpATMWU&riukXsdRajgnob-nGV9>TgmcZCWc(5x=kL^w@k!YtX7 zcJT|eQU?Io(X?q$BGI*(Ep4nD2imEW1sXy#Vg}%%0d?~eV&Rk0Kd(qd?tl3dU~7lL`*&43>_F}_qg3P@)Fml$3}Bzy{zB@B#P%Tmhi~ zF@Wyr6aXLs2mt(Pxt*p&fICtFi9oVK!1A2TOoCtlh(~d#RaczLG8&zF5^xf R8x3ONy3(K5 { + boolean charge(ChargeBO bo); +} diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/business/impl/ChargeBusinessImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/business/impl/ChargeBusinessImpl.java new file mode 100644 index 000000000..cfd1fc324 --- /dev/null +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/business/impl/ChargeBusinessImpl.java @@ -0,0 +1,37 @@ +package com.wzj.soopin.transaction.business.impl; + +import com.wzj.soopin.transaction.business.IChargeBusiness; +import com.wzj.soopin.transaction.convert.ChargeConvert; +import com.wzj.soopin.transaction.domain.bo.ChargeBO; +import com.wzj.soopin.transaction.domain.po.Charge; +import com.wzj.soopin.transaction.domain.vo.ChargeVO; +import com.wzj.soopin.transaction.enums.ChargeStatus; +import com.wzj.soopin.transaction.service.IChargeService; +import com.wzj.soopin.transaction.util.SnowFlake; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.web.core.BusinessImpl; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +@AllArgsConstructor +public class ChargeBusinessImpl extends BusinessImpl implements IChargeBusiness { + @Override + public boolean charge(ChargeBO bo) { + + //先检查是否发起过,如果发起过则返回原订单 + Charge existCharge = service.getByCode(bo.getCode()); + if (existCharge!=null){ + return true; + } + Charge charge = converter.toPo(bo); + service.charge(charge); + bo.setCode(charge.getCode()); + return true; + } +} diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Charge.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Charge.java index 908fb08e0..e2865e9fa 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Charge.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/Charge.java @@ -68,7 +68,7 @@ public class Charge extends BaseAudit { private LocalDateTime auditTime; /** - * 提现方式 + * 充值方式 */ private Integer method; diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/PayOrder.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/PayOrder.java index 3809c289f..4799a94ed 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/PayOrder.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/po/PayOrder.java @@ -99,4 +99,6 @@ public class PayOrder extends BaseAudit { @TableLogic(value = "0", delval = "1") @TableField(value = "del_flag", fill = FieldFill.INSERT, jdbcType = JdbcType.CHAR) private String delFlag; + + private String title; } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/ChargeStatus.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/ChargeStatus.java index f90621f55..0a0a8e4d8 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/ChargeStatus.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/ChargeStatus.java @@ -4,9 +4,10 @@ import lombok.Getter; @Getter public enum ChargeStatus { - WAITING(0, "待验证"), - PENDING(1, "充值成功"), - SUCCESS(2, "充值失败"); + WAITING(0, "未支付"), + PENDING(1, "待验证"), + SUCCESS(2, "充值成功"), + FAIL(3, "充值失败"); private Integer code; private String message; diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PayStatusEnum.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PayStatusEnum.java new file mode 100644 index 000000000..62025ab86 --- /dev/null +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PayStatusEnum.java @@ -0,0 +1,29 @@ +package com.wzj.soopin.transaction.enums; + +/** + * 订单状态枚举 + * + * @author Chopper + * @since 2020/11/17 7:28 下午 + */ +public enum PayStatusEnum { + + /** + * 支付状态 + */ + UNPAID("待付款"), + PAID("已付款"), + CANCEL("已取消"), + REFUNDED("已退款"); + private final String description; + + PayStatusEnum(String description) { + this.description = description; + } + + public String description() { + return this.description; + } + + +} diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PaymentMethodEnum.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PaymentMethodEnum.java index 891c7a6be..1f77f82aa 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PaymentMethodEnum.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/enums/PaymentMethodEnum.java @@ -1,5 +1,7 @@ package com.wzj.soopin.transaction.enums; +import jakarta.persistence.criteria.CriteriaBuilder; + /** * 支付方式枚举 * @@ -11,23 +13,23 @@ public enum PaymentMethodEnum { /** * 微信 */ - WECHAT("wechatPlugin", "微信"), + WECHAT("wechatPlugin", 1), /** * 支付宝 */ - ALIPAY("aliPayPlugin", "支付宝"), + ALIPAY("aliPayPlugin", 2), /** * 余额支付 */ - WALLET("walletPlugin", "余额支付"), + WALLET("walletPlugin", 3), /** * 线下转账 */ - BANK_TRANSFER("bankTransferPlugin", "线下转账"), + BANK_TRANSFER("bankTransferPlugin", 4), /** * 易生支付 */ - EASY_PAY("easyPayPlugin", "易生支付"); + EASY_PAY("easyPayPlugin", 5); /** * 插件id 调用对象,需要实现payment接口 @@ -36,14 +38,14 @@ public enum PaymentMethodEnum { /** * 支付名称 */ - private final String paymentName; + private final Integer code; public String getPlugin() { return plugin; } - public String paymentName() { - return paymentName; + public Integer getCode() { + return code; } /** @@ -61,9 +63,9 @@ public enum PaymentMethodEnum { return null; } - PaymentMethodEnum(String plugin, String paymentName) { + PaymentMethodEnum(String plugin, Integer code) { this.plugin = plugin; - this.paymentName = paymentName; + this.code = code; } } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/WechatPaymentSetting.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/WechatPaymentSetting.java new file mode 100644 index 000000000..7e2a55de0 --- /dev/null +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/WechatPaymentSetting.java @@ -0,0 +1,58 @@ +package com.wzj.soopin.transaction.kit; + +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * 微信支付设置 + * + * @author Chopper + * @since 2020-12-02 10:08 + */ +@Accessors(chain = true) +@Data +@Configuration +@ConfigurationProperties(prefix = "wechat.pay.v3") +public class WechatPaymentSetting { + + /** + * APP应用id + */ + private String appId; + /** + * 小程序应用id + */ + private String mpAppId; + /** + * 服务号应用id + */ + private String serviceAppId; + /** + * 商户号 + */ + private String mchId; + /** + * 私钥 + */ + private String apiclient_key; + /** + * pem 证书 + */ + private String apiclient_cert_pem; + /** + * p12 证书 + */ + private String apiclient_cert_p12; + /** + * 商户证书序列号 + */ + private String mchSerialNo; + /** + * apiv3私钥 + */ + private String apiV3Key; + + private String privateKeyPath; +} diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/kit/WxPayKit.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/kit/WxPayKit.java index 57b6383b6..ad99705c7 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/kit/WxPayKit.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/kit/WxPayKit.java @@ -377,9 +377,9 @@ public class WxPayKit { if (signType == null) { signType = SignType.MD5; } -// String packageSign = createSign(packageParams, partnerKey, signType); - // 部分微信APP支付 提示签名错误 解开下方注释 替换上边的代码就好。 - String packageSign = createAppSign(packageParams, partnerKey); + String packageSign = createSign(packageParams, partnerKey, signType); +// 部分微信APP支付 提示签名错误 解开下方注释 替换上边的代码就好。 +// String packageSign = createAppSign(packageParams, partnerKey); packageParams.put("sign", packageSign); return packageParams; } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/utils/DateTimeZoneUtil.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/utils/DateTimeZoneUtil.java index 126685ac5..50108351f 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/utils/DateTimeZoneUtil.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/core/utils/DateTimeZoneUtil.java @@ -44,7 +44,7 @@ public class DateTimeZoneUtil implements Serializable { if (date == null) { throw new Exception("date is not null"); } -// ZonedDateTime zonedDateTime = DateTimeConverterUtil.toZonedDateTime(date); +// ZonedDateTime zonedDateTime = Date(date); // time = DateTimeFormatterUtil.format(zonedDateTime, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_XXX_FMT); return time; } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/dto/PayParam.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/dto/PayParam.java index 02298ce4f..93c6dfba0 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/dto/PayParam.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/dto/PayParam.java @@ -1,5 +1,6 @@ package com.wzj.soopin.transaction.kit.dto; +import com.wzj.soopin.transaction.kit.params.dto.CashierParam; import io.swagger.annotations.ApiModelProperty; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -22,7 +23,6 @@ public class PayParam { @ApiModelProperty(value = "交易类型", allowableValues = "TRADE,ORDER,RECHARGE") private String orderType; - @NotNull @ApiModelProperty(value = "订单号") private String sn; @@ -34,5 +34,4 @@ public class PayParam { private String paymentClient; - } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/dto/CashierParam.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/dto/CashierParam.java index 72d66f8df..93989a7af 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/dto/CashierParam.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/dto/CashierParam.java @@ -21,7 +21,7 @@ import java.util.List; public class CashierParam { @ApiModelProperty(value = "价格") - private BigDecimal price; + private Long price; @ApiModelProperty(value = "支付title") private String title; diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/OrderCashier.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/OrderCashier.java index cb3b5d084..83cf25f5d 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/OrderCashier.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/OrderCashier.java @@ -63,7 +63,7 @@ public class OrderCashier implements CashierExecute { if (!order.getStatus().equals(OrderStatusEnum.UNPAID.getValue())) { throw new ServiceException(ResultCode.PAY_BAN); } - cashierParam.setPrice(order.getPayAmount()); + cashierParam.setPrice(order.getPayAmount().longValue()); // // try { // BaseSetting baseSetting = JSONUtil.toBean(settingService.get(SettingEnum.BASE_SETTING.name()).getSettingValue(), BaseSetting.class); diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/RechargeCashier.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/RechargeCashier.java index c5c7eb05f..5c56537fb 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/RechargeCashier.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/params/impl/RechargeCashier.java @@ -2,17 +2,27 @@ package com.wzj.soopin.transaction.kit.params.impl; import cn.hutool.json.JSONUtil; +import com.wzj.soopin.transaction.domain.po.Charge; +import com.wzj.soopin.transaction.domain.po.PayOrder; import com.wzj.soopin.transaction.enums.CashierEnum; +import com.wzj.soopin.transaction.enums.ChargeStatus; +import com.wzj.soopin.transaction.enums.PayStatusEnum; import com.wzj.soopin.transaction.kit.dto.PayParam; import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams; import com.wzj.soopin.transaction.kit.params.CashierExecute; import com.wzj.soopin.transaction.kit.params.dto.CashierParam; +import com.wzj.soopin.transaction.mapper.ChargeMapper; +import com.wzj.soopin.transaction.mapper.PayOrderMapper; +import com.wzj.soopin.transaction.service.IChargeService; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.ResultCode; import org.dromara.common.core.exception.ServiceException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.math.BigDecimal; + /** * 充值信息获取 * @@ -21,17 +31,12 @@ import org.springframework.stereotype.Component; */ @Slf4j @Component +@AllArgsConstructor public class RechargeCashier implements CashierExecute { - /** - * 余额 - */ -// @Autowired -// private RechargeService rechargeService; -// /** -// * 设置 -// */ -// @Autowired -// private SettingService settingService; + private final IChargeService chargeService; + + + @Override @@ -55,25 +60,22 @@ public class RechargeCashier implements CashierExecute { //准备返回的数据 CashierParam cashierParam = new CashierParam(); //订单信息获取 -// Recharge recharge = rechargeService.getRecharge(payParam.getSn()); -// -// //如果订单已支付,则不能发器支付 -// if (recharge.getPayStatus().equals(PayStatusEnum.PAID.name())) { -// throw new ServiceException(ResultCode.PAY_DOUBLE_ERROR); -// } -// -// -// cashierParam.setPrice(recharge.getRechargeMoney()); -// -// try { -// BaseSetting baseSetting = JSONUtil.toBean(settingService.get(SettingEnum.BASE_SETTING.name()).getSettingValue(), BaseSetting.class); -// cashierParam.setTitle(baseSetting.getSiteName()); -// } catch (Exception e) { -// cashierParam.setTitle("多用户商城,在线充值"); -// } -// cashierParam.setDetail("余额充值"); -// cashierParam.setCreateTime(recharge.getCreateTime()); -// return cashierParam; + Charge recharge = chargeService.getByCode(payParam.getSn()); + + //如果订单已支付,则不能发器支付 + if (!recharge.getStatus().equals(ChargeStatus.WAITING.getCode())) { + throw new ServiceException(ResultCode.PAY_DOUBLE_ERROR); + } + cashierParam.setPrice( recharge.getMoney().longValue()); + + try { + cashierParam.setTitle("在线充值"); + } catch (Exception e) { + cashierParam.setTitle("多用户商城,在线充值"); + } + cashierParam.setDetail("余额充值"); + cashierParam.setCreateTime(recharge.getCreateTime()); + return cashierParam; } return null; diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/easypay/EasyPayPlugin.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/easypay/EasyPayPlugin.java index 2abb72bf9..baac75ced 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/easypay/EasyPayPlugin.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/easypay/EasyPayPlugin.java @@ -290,7 +290,7 @@ public class EasyPayPlugin implements Payment { CashierParam cashierParam = cashierSupport.cashierParam(payParam); //支付金额 - BigDecimal fen =cashierParam.getPrice(); + Long fen =cashierParam.getPrice(); //第三方付款订单 String outOrderNo = SnowFlake.getIdStr(); //过期时间 @@ -312,7 +312,7 @@ public class EasyPayPlugin implements Payment { //回传参数 .setAttach(attach) .setNotify_url(notifyUrl("apiProperties.getBuyer()", PaymentMethodEnum.WECHAT)) - .setAmount(new Amount().setTotal(fen)); + .setAmount(new Amount().setTotal(fen.intValue())); log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel)); // PaymentHttpResponse response = WechatApi.v3( diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wallet/WalletPlugin.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wallet/WalletPlugin.java index 7eb8bfb5e..4e064ad88 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wallet/WalletPlugin.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wallet/WalletPlugin.java @@ -28,6 +28,8 @@ import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; +import java.math.BigDecimal; + /** * WalletPlugin @@ -163,7 +165,7 @@ public class WalletPlugin implements Payment { } //个人账户扣减 boolean result = accountBillService.reduceMoney( - cashierParam.getPrice(), + BigDecimal.valueOf(cashierParam.getPrice() ), loginUser.getUserId(), AccountBillSourceEnum.PAYMENT, diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/WechatPlugin.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/WechatPlugin.java index f2e88c6ff..ac77a98f3 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/WechatPlugin.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/WechatPlugin.java @@ -7,16 +7,16 @@ import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.wzj.soopin.order.utils.StringUtils; import com.wzj.soopin.transaction.domain.po.RefundLog; import com.wzj.soopin.transaction.enums.PaymentMethodEnum; import com.wzj.soopin.transaction.kit.CashierSupport; import com.wzj.soopin.transaction.kit.Payment; +import com.wzj.soopin.transaction.kit.WechatPaymentSetting; import com.wzj.soopin.transaction.kit.core.PaymentHttpResponse; import com.wzj.soopin.transaction.kit.core.enums.RequestMethodEnums; import com.wzj.soopin.transaction.kit.core.enums.SignType; -import com.wzj.soopin.transaction.kit.core.kit.HttpKit; -import com.wzj.soopin.transaction.kit.core.kit.IpKit; -import com.wzj.soopin.transaction.kit.core.kit.WxPayKit; +import com.wzj.soopin.transaction.kit.core.kit.*; import com.wzj.soopin.transaction.kit.core.utils.DateTimeZoneUtil; import com.wzj.soopin.transaction.kit.dto.PayParam; import com.wzj.soopin.transaction.kit.dto.PaymentSuccessParams; @@ -27,20 +27,31 @@ import com.wzj.soopin.transaction.kit.plugin.wechat.model.*; import com.wzj.soopin.transaction.service.PaymentService; import com.wzj.soopin.transaction.service.RefundLogService; import com.wzj.soopin.transaction.util.CurrencyUtil; +import com.wzj.soopin.transaction.util.SnowFlake; +import com.wzj.soopin.transaction.wechat.WechatPayConfig; +import com.wzj.soopin.transaction.wechat.WechatPayException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.CachePrefix; import org.dromara.common.core.constant.ResultCode; import org.dromara.common.core.domain.R; import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.redis.redis.RedisCache; +import org.dromara.common.redis.utils.RedisUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Map; import java.util.Objects; +import java.util.concurrent.TimeUnit; /** * 微信支付 @@ -94,6 +105,10 @@ public class WechatPlugin implements Payment { // @Autowired // private OrderService orderService; + @Autowired + private WechatPaymentSetting setting; + @Autowired + private RedisCache redisCache; @Override public R h5pay(HttpServletRequest request, HttpServletResponse response1, PayParam payParam) { @@ -236,63 +251,68 @@ public class WechatPlugin implements Payment { CashierParam cashierParam = cashierSupport.cashierParam(payParam); //支付金额 -// Integer fen = CurrencyUtil.fen(cashierParam.getPrice()); -// //第三方付款订单 -// String outOrderNo = SnowFlake.getIdStr(); -// //过期时间 -// String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3); -// -// String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8); -// -// WechatPaymentSetting setting = wechatPaymentSetting(); -// String appid = setting.getAppId(); -// if (appid == null) { -// throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING); -// } -// UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel() -// .setAppid(appid) -// .setMchid(setting.getMchId()) -// .setDescription(cashierParam.getDetail()) -// .setOut_trade_no(outOrderNo) -// .setTime_expire(timeExpire) -// .setAttach(attach) -// .setNotify_url(notifyUrl(apiProperties.getBuyer(), PaymentMethodEnum.WECHAT)) -// .setAmount(new Amount().setTotal(fen)); -// -// -// log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel)); -// PaymentHttpResponse response = WechatApi.v3( -// RequestMethodEnums.POST, -// WechatDomain.CHINA.toString(), -// WechatApiEnum.APP_PAY.toString(), -// setting.getMchId(), -// setting.getSerialNumber(), -// null, -// setting.getApiclient_key(), -// JSONUtil.toJsonStr(unifiedOrderModel) -// ); -// //根据证书序列号查询对应的证书来验证签名结果 -// boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert()); -// log.info("verifySignature: {}", verifySignature); -// log.info("统一下单响应 {}", response); -// -// if (verifySignature) { -// JSONObject jsonObject = JSONUtil.parseObj(response.getBody()); -// String prepayId = jsonObject.getStr("prepay_id"); -// Map map = WxPayKit.appPrepayIdCreateSign(appid, -// setting.getMchId(), -// prepayId, -// setting.getApiclient_key(), SignType.HMACSHA256); -// log.info("唤起支付参数:{}", map); -// -// return R.ok(map); -// } + Integer fen = cashierParam.getPrice().intValue(); + //第三方付款订单 + String outOrderNo = SnowFlake.getIdStr(); + //过期时间 + ZonedDateTime zonedDateTime = LocalDateTime.now().plusMinutes(3).atZone(ZoneId.of("UTC")); + + // 自定义无毫秒的 RFC 3339 格式器 + DateTimeFormatter rfc3339NoMillis = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"); + String timeExpire = zonedDateTime.format(rfc3339NoMillis); + + String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam.getSn()), StandardCharsets.UTF_8); + + String appid = setting.getAppId(); + if (appid == null) { + throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING); + } + UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel() + .setAppid(appid) + .setMchid(setting.getMchId()) + .setDescription(cashierParam.getDetail()) + .setOut_trade_no(outOrderNo) + .setTime_expire(timeExpire) + .setAttach(attach) + .setNotify_url("http://cjh.wuzhongjie.com.cn/app/wechat/notify") + .setAmount(new Amount().setTotal(fen)); + + + log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel)); + PaymentHttpResponse response = WechatApi.v3( + RequestMethodEnums.POST, + WechatDomain.CHINA.toString(), + WechatApiEnum.APP_PAY.toString(), + setting.getMchId(), + setting.getMchSerialNo(), + setting.getMchSerialNo(), + setting.getPrivateKeyPath() , + JSONUtil.toJsonStr(unifiedOrderModel) + + ); + //根据证书序列号查询对应的证书来验证签名结果 + boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert()); + log.info("verifySignature: {}", verifySignature); + log.info("统一下单响应 {}", response); + + if (verifySignature) { + JSONObject jsonObject = JSONUtil.parseObj(response.getBody()); + String prepayId = jsonObject.getStr("prepay_id"); + Map map = WxPayKit.appPrepayIdCreateSign(appid, + setting.getMchId(), + prepayId, + setting.getApiclient_key(), SignType.HMACSHA256); + log.info("唤起支付参数:{}", map); + + return R.ok(map); + } log.error("微信支付参数验证错误,请及时处理"); throw new ServiceException(ResultCode.PAY_ERROR); } catch (Exception e) { log.error("支付异常", e); throw new ServiceException(ResultCode.PAY_ERROR); } + } @Override @@ -614,81 +634,80 @@ public class WechatPlugin implements Payment { // } // } -// /** -// * 获取平台公钥 -// * -// * @return 平台公钥 -// */ -// private X509Certificate getPlatformCert() { -// //获取缓存中的平台公钥,如果有则直接返回,否则去微信请求 -// String publicCert = cache.getString(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix()); -// if (!StringUtils.isEmpty(publicCert)) { -// return PayKit.getCertificate(publicCert); -// } -// //获取平台证书列表 -// try { -// -// WechatPaymentSetting setting = wechatPaymentSetting(); -// -// PaymentHttpResponse response = WechatApi.v3( -// RequestMethodEnums.GET, -// WechatDomain.CHINA.toString(), -// WechatApiEnum.GET_CERTIFICATES.toString(), -// setting.getMchId(), -// setting.getSerialNumber(), -// null, -// setting.getApiclient_key(), -// "" -// ); -// String body = response.getBody(); -// log.info("获取微信平台证书body: {}", body); -// -// if (response.getStatus() == 200) { -// JSONObject jsonObject = JSONUtil.parseObj(body); -// JSONArray dataArray = jsonObject.getJSONArray("data"); -// log.info("证书信息: {}", dataArray); -// -// //默认认为只有一个平台证书 -// JSONObject encryptObject = dataArray.getJSONObject(0); -// JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate"); -// String associatedData = encryptCertificate.getStr("associated_data"); -// String cipherText = encryptCertificate.getStr("ciphertext"); -// String nonce = encryptCertificate.getStr("nonce"); -// publicCert = getPlatformCertStr(associatedData, nonce, cipherText); -// long second = (PayKit.getCertificate(publicCert).getNotAfter().getTime() - System.currentTimeMillis()) / 1000; -// cache.put(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix(), publicCert, second); -// } else { -// log.error("证书获取失败:{}" + body); -// throw new ServiceException(ResultCode.WECHAT_CERT_ERROR); -// } -// return PayKit.getCertificate(publicCert); -// } catch (Exception e) { -// log.error("证书获取失败", e); -// } -// return null; -// } -// -// /** -// * 获取平台证书缓存的字符串 -// * 下列各个密钥参数 -// * -// * @param associatedData 密钥参数 -// * @param nonce 密钥参数 -// * @param cipherText 密钥参数 -// * @return platform key -// * @throws GeneralSecurityException 密钥获取异常 -// */ -// private String getPlatformCertStr(String associatedData, String nonce, String cipherText) throws GeneralSecurityException { -// -// -// AesUtil aesUtil = new AesUtil(wechatPaymentSetting().getApiKey3().getBytes(StandardCharsets.UTF_8)); -// //平台证书密文解密 -// //encrypt_certificate 中的 associated_data nonce ciphertext -// return aesUtil.decryptToString( -// associatedData.getBytes(StandardCharsets.UTF_8), -// nonce.getBytes(StandardCharsets.UTF_8), -// cipherText -// ); -// } + /** + * 获取平台公钥 + * + * @return 平台公钥 + */ + private X509Certificate getPlatformCert() { + //获取缓存中的平台公钥,如果有则直接返回,否则去微信请求 + String publicCert = RedisUtils.getCacheObject(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix()); + if (!StringUtils.isEmpty(publicCert)) { + return PayKit.getCertificate(publicCert); + } + //获取平台证书列表 + try { + + + PaymentHttpResponse response = WechatApi.v3( + RequestMethodEnums.GET, + WechatDomain.CHINA.toString(), + WechatApiEnum.GET_CERTIFICATES.toString(), + setting.getMchId(), + setting.getMchSerialNo(), + null, + setting.getPrivateKeyPath(), + "" + ); + String body = response.getBody(); + log.info("获取微信平台证书body: {}", body); + + if (response.getStatus() == 200) { + JSONObject jsonObject = JSONUtil.parseObj(body); + JSONArray dataArray = jsonObject.getJSONArray("data"); + log.info("证书信息: {}", dataArray); + + //默认认为只有一个平台证书 + JSONObject encryptObject = dataArray.getJSONObject(0); + JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate"); + String associatedData = encryptCertificate.getStr("associated_data"); + String cipherText = encryptCertificate.getStr("ciphertext"); + String nonce = encryptCertificate.getStr("nonce"); + publicCert = getPlatformCertStr(associatedData, nonce, cipherText); + long second = (PayKit.getCertificate(publicCert).getNotAfter().getTime() - System.currentTimeMillis()) / 1000; + redisCache.setCacheObject(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix(), publicCert, (int) second, TimeUnit.SECONDS); + } else { + log.error("证书获取失败:{}" + body); + throw new ServiceException(ResultCode.WECHAT_CERT_ERROR); + } + return PayKit.getCertificate(publicCert); + } catch (Exception e) { + log.error("证书获取失败", e); + } + return null; + } + + /** + * 获取平台证书缓存的字符串 + * 下列各个密钥参数 + * + * @param associatedData 密钥参数 + * @param nonce 密钥参数 + * @param cipherText 密钥参数 + * @return platform key + * @throws GeneralSecurityException 密钥获取异常 + */ + private String getPlatformCertStr(String associatedData, String nonce, String cipherText) throws GeneralSecurityException { + + + AesUtil aesUtil = new AesUtil(setting.getApiV3Key().getBytes(StandardCharsets.UTF_8)); + //平台证书密文解密 + //encrypt_certificate 中的 associated_data nonce ciphertext + return aesUtil.decryptToString( + associatedData.getBytes(StandardCharsets.UTF_8), + nonce.getBytes(StandardCharsets.UTF_8), + cipherText + ); + } } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/model/Amount.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/model/Amount.java index 946d0b7e1..84eab0eb3 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/model/Amount.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/kit/plugin/wechat/model/Amount.java @@ -18,7 +18,7 @@ public class Amount { /** * 总金额 */ - private BigDecimal total; + private Integer total; /** * 货币类型 diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IChargeService.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IChargeService.java index 4e772890b..34191acff 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IChargeService.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IChargeService.java @@ -9,4 +9,6 @@ public interface IChargeService extends IService { boolean charge(Charge charge); + Charge getByCode(String code); + } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/ChargeServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/ChargeServiceImpl.java index cb0acf7d2..88cc7cda8 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/ChargeServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/ChargeServiceImpl.java @@ -1,5 +1,6 @@ package com.wzj.soopin.transaction.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wzj.soopin.member.domain.po.AccountBill; import com.wzj.soopin.member.domain.po.MemberAccount; @@ -11,6 +12,7 @@ import com.wzj.soopin.transaction.domain.po.Charge; import com.wzj.soopin.transaction.enums.ChargeStatus; import com.wzj.soopin.transaction.mapper.ChargeMapper; import com.wzj.soopin.transaction.service.IChargeService; +import com.wzj.soopin.transaction.util.SnowFlake; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.exception.ServiceException; @@ -44,13 +46,13 @@ public class ChargeServiceImpl extends ServiceImpl impleme memberAccount.setWallet(memberAccount.getWallet().add(charge.getMoney())); memberAccountService.updateById(memberAccount); //生成充值记录 - AccountBill accountBill=AccountBill.builder() - .accountId(charge.getMemberId()) - .changeAmount(charge.getMoney()) - .changeType(AccountBillChangeTypeEnum.IN.getCode()) - .changeDesc("充值") - .source(AccountBillSourceEnum.RECHARGE.getCode()) - .build(); + AccountBill accountBill = AccountBill.builder() + .accountId(charge.getMemberId()) + .changeAmount(charge.getMoney()) + .changeType(AccountBillChangeTypeEnum.IN.getCode()) + .changeDesc("充值") + .source(AccountBillSourceEnum.RECHARGE.getCode()) + .build(); accountBillService.save(accountBill); return true; } @@ -62,18 +64,29 @@ public class ChargeServiceImpl extends ServiceImpl impleme @Override public boolean charge(Charge charge) { //判断充值金额不能为零 - if (charge.getMoney().compareTo(BigDecimal.ZERO) == 0) { + if (charge.getMoney()==null||charge.getMoney().compareTo(BigDecimal.ZERO) == 0) { throw new ServiceException("充值金额不能为零"); } - //状态为待审核 + //状态为待充值 charge.setStatus(ChargeStatus.WAITING.getCode()); charge.setType(1); //手续费 charge.setFee(new BigDecimal("0.01").multiply(charge.getMoney())); //实际金额 charge.setActualMoney(charge.getMoney().subtract(charge.getFee())); + + //设置充值信息 + if (charge.getMemberId() == null) { + throw new ServiceException("充值用户不能为空"); + } + charge.setCode(SnowFlake.createStr("RC")); //保存充值记录 save(charge); return false; } + + @Override + public Charge getByCode(String code) { + return baseMapper.selectOne(new LambdaQueryWrapper().eq(Charge::getCode, code)); + } } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/PayOrderServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/PayOrderServiceImpl.java index f3b00349e..f8213984b 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/PayOrderServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/PayOrderServiceImpl.java @@ -1,5 +1,6 @@ package com.wzj.soopin.transaction.service.impl; +import com.wzj.soopin.transaction.enums.TransState; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wzj.soopin.transaction.domain.po.PayOrder; @@ -8,4 +9,10 @@ import com.wzj.soopin.transaction.service.PayOrderService; @Service public class PayOrderServiceImpl extends ServiceImpl implements PayOrderService{ + @Override + public boolean save(PayOrder entity) { + // + entity.setTransState(TransState.PENDING.getCode()); + return super.save(entity); + } } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/WithdrawServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/WithdrawServiceImpl.java index 40139b60b..c50866320 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/WithdrawServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/WithdrawServiceImpl.java @@ -150,7 +150,7 @@ public class WithdrawServiceImpl extends ServiceImpl i } //检查当前用于的账户余额是否充足 BigDecimal balance = memberAccount.getWallet(); - if (balance.compareTo(withdraw.getMoney()) < 0) { + if (balance==null||balance.compareTo(withdraw.getMoney()) < 0) { throw new RuntimeException("用户余额不足"); } //生成费用 diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/CurrencyUtil.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/CurrencyUtil.java index c15f5ea1e..46d2bf7af 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/CurrencyUtil.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/CurrencyUtil.java @@ -1,5 +1,7 @@ package com.wzj.soopin.transaction.util; +import com.google.type.Decimal; + import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Arrays; @@ -120,9 +122,8 @@ public final class CurrencyUtil { * @param money 金额 * @return 转换单位为分 */ - public static Integer fen(Double money) { - double price = mul(money, 100); - return (int) price; + public static Integer fen(BigDecimal money) { + return money.multiply(BigDecimal.valueOf(100)).intValue(); } /** diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/SnowFlake.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/SnowFlake.java index 7fbaeeb1c..8db025948 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/SnowFlake.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/util/SnowFlake.java @@ -47,7 +47,7 @@ public class SnowFlake { * @return */ public static String createStr(String prefix) { - return prefix + DateUtil.toString(new Date(), "yyyyMMdd") + SnowFlake.getId(); + return prefix + DateUtil.toString(new Date(), "yyyyMMdd") + SnowFlake.getIdStr(); } public static String getIdStr() { diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf index bed85d9b7..018e80472 100644 --- a/script/docker/nginx/conf/nginx.conf +++ b/script/docker/nginx/conf/nginx.conf @@ -204,7 +204,11 @@ http { index index.html; try_files $uri $uri/ /busniess/index.html; } - + location ^~ /file/ { + proxy_pass http://43.143.227.203:9000/; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } # app分享 location ^~ /spa { alias /data/wzj/download/spa;