From 7b293cde78002625214ed22c1d94503bc08938d8 Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 10:24:57 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E4=B8=8B=E5=8D=95=E8=B0=83=E6=95=B4=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bnyer/pay/design/factory/PayFactory.java | 4 ++-- .../com/bnyer/pay/design/strategy/WxPayStrategy.java | 10 ++++++++-- .../bnyer/pay/service/impl/UnifiedPayServiceImpl.java | 4 ++-- pom.xml | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/factory/PayFactory.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/factory/PayFactory.java index c9afe6c..7bd34cd 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/factory/PayFactory.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/factory/PayFactory.java @@ -27,11 +27,11 @@ public class PayFactory { } public static class SingletonHolder{ - public static PayFactory payStrategy = new PayFactory(); + public static PayFactory payFactory = new PayFactory(); } public static PayFactory getInstance(){ - return SingletonHolder.payStrategy; + return SingletonHolder.payFactory; } public IPayStrategy getConcreteStrategy(String payType){ diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/strategy/WxPayStrategy.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/strategy/WxPayStrategy.java index f3a936c..71d0557 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/strategy/WxPayStrategy.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/design/strategy/WxPayStrategy.java @@ -102,14 +102,18 @@ public class WxPayStrategy extends AbstractPayStrategy { amount.setTotal(BaseWxPayRequest.yuanToFen(bo.getPayAmount())); orderRequest.setAmount(amount); //调用微信支付接口 - WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPayService.createOrderV3(TradeTypeEnum.JSAPI, orderRequest); + WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPayService.unifiedOrderV3(TradeTypeEnum.JSAPI, orderRequest); WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = wxPayUnifiedOrderV3Result.getPayInfo(TradeTypeEnum.JSAPI, wxPayConfig.getAppid(), wxPayConfig.getMchid(), wxPayService.getConfig().getPrivateKey()); - thirdUnifiedOrderVo.setAppId(wxPayConfig.getAppid()); ThirdUnifiedOrderVo.WxThirdInOrderVo wxThirdInOrderVo = new ThirdUnifiedOrderVo.WxThirdInOrderVo(); + //微信返回信息封装 + wxThirdInOrderVo.setAppId(jsapiResult.getAppId()); wxThirdInOrderVo.setPackageValue(jsapiResult.getPackageValue()); wxThirdInOrderVo.setTimeStamp(jsapiResult.getTimeStamp()); wxThirdInOrderVo.setNonceStr(jsapiResult.getNonceStr()); wxThirdInOrderVo.setPaySign(jsapiResult.getPaySign()); + wxThirdInOrderVo.setSignType(jsapiResult.getSignType()); + + thirdUnifiedOrderVo.setAppId(wxPayConfig.getAppid()); thirdUnifiedOrderVo.setOutOrderNo(bo.getPayId()); thirdUnifiedOrderVo.setAppId(jsapiResult.getAppId()); @@ -117,6 +121,8 @@ public class WxPayStrategy extends AbstractPayStrategy { thirdUnifiedOrderVo.setThirdCode("0"); thirdUnifiedOrderVo.setThirdMsg("ok"); thirdUnifiedOrderVo.setThirdNo(wxPayUnifiedOrderV3Result.getPrepayId()); + + thirdUnifiedOrderVo.setWxThirdInOrderVo(wxThirdInOrderVo); return thirdUnifiedOrderVo; } catch (WxPayException e) { log.error("微信支付:统一下单接口调用失败,payId:{},error{}", bo.getPayId(), e.getMessage()); diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java index 9ca0618..de68f55 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java @@ -121,8 +121,8 @@ public class UnifiedPayServiceImpl implements UnifiedPayService { * @param dto */ private void checkData(UnifiedOrderDto dto) { - PayInfo payInfo = payInfoMapper.selectOne(new LambdaQueryWrapper().eq(PayInfo::getOrderNo,dto.getOrderNo())); - if (Objects.nonNull(payInfo) && EnumPayStatus.SUCCESS.getStatus() == payInfo.getPayStatus()){ + PayInfo payInfo = payInfoMapper.selectOne(new LambdaQueryWrapper().eq(PayInfo::getOrderNo,dto.getOrderNo()).eq(PayInfo::getPayStatus,EnumPayStatus.SUCCESS.getStatus())); + if (Objects.nonNull(payInfo)){ throw new ServiceException(ResponseEnum.ORDER_REPEAT_PAY); } } diff --git a/pom.xml b/pom.xml index 7b9dce0..0a3953b 100644 --- a/pom.xml +++ b/pom.xml @@ -44,7 +44,7 @@ 5.8.0.M3 3.16.2 4.23.21.ALL - 4.4.0 + 4.5.0 7.2.18 2.2.2 From 88caf1747a95abe45c75143d4c616bc4d4f910cf Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 11:28:08 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=94=AF=E4=BB=98=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E9=80=80=E6=AC=BE=E6=B7=BB=E5=8A=A0=E9=80=80?= =?UTF-8?q?=E6=AC=BE=E5=89=8D=E7=AD=BE=E5=90=8D=E6=A0=A1=E9=AA=8C=EF=BC=8C?= =?UTF-8?q?=E4=BF=9D=E8=AF=81=E8=B5=84=E9=87=91=E5=AE=89=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bnyer/common/core/enums/ResponseEnum.java | 18 +-- .../com/bnyer/common/core/utils/MD5Util.java | 140 ++++++++++++++++++ .../com/bnyer/pay/bean/dto/RefundDto.java | 16 ++ .../com/bnyer/pay/bean/vo/UnifiedOrderVo.java | 3 - .../pay/controller/UnifiedPayController.java | 15 ++ .../bnyer/pay/enums/EnumVerificationKey.java | 20 +++ .../bnyer/pay/service/UnifiedPayService.java | 4 + .../service/impl/UnifiedPayServiceImpl.java | 6 + .../bnyer/pay/utils/PaymentRefundUtil.java | 39 +++++ 9 files changed, 248 insertions(+), 13 deletions(-) create mode 100644 bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/MD5Util.java create mode 100644 bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/enums/EnumVerificationKey.java create mode 100644 bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/utils/PaymentRefundUtil.java diff --git a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java index e018622..71d7c0f 100644 --- a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java +++ b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java @@ -11,26 +11,24 @@ public enum ResponseEnum { SERVER_ERROR(500, "系统繁忙,请稍候重试!"), NOT_AUTH(500, "未登录!"), PARAM_ERROR(400, "参数异常!"), - NOT_EXIST(110001, "查询为空"), - PAY_CONFIG_ERROR(110002, "支付配置未启用或未配置!"), - //======================订单异常======================== - + //======================业务异常======================== + NOT_EXIST(110001, "查询为空"), + PAY_CONFIG_ERROR(110002, "支付配置未启用或未配置!"), /** * 订单已过期,当前端看到该状态码的时候,提示订单信息已过期,请重新确认后提交,此时用户点击确定,前端刷新页面。 */ - ORDER_EXPIRED(210001, "订单已过期"), - + ORDER_EXPIRED(110003, "订单已过期"), /** * 请勿重复提交订单, * 1.当前端遇到该异常时,说明前端防多次点击没做好 * 2.提示用户 订单已发生改变,请勿重复下单 */ - REPEAT_ORDER(210002,"请勿重复提交订单"), - - ORDER_CANCEL(210003, "该订单已取消,请重新下单!"), - ORDER_REPEAT_PAY(210004, "该订单已支付,请勿重复支付!"), + REPEAT_ORDER(110004,"请勿重复提交订单"), + ORDER_CANCEL(110005, "该订单已取消,请重新下单!"), + ORDER_REPEAT_PAY(110006, "该订单已支付,请勿重复支付!"), + REFUND_SING_ERROR(110007, "签名错误!"), diff --git a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/MD5Util.java b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/MD5Util.java new file mode 100644 index 0000000..461bf1f --- /dev/null +++ b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/utils/MD5Util.java @@ -0,0 +1,140 @@ +package com.bnyer.common.core.utils; + +import org.apache.commons.codec.digest.DigestUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description : + */ +public class MD5Util { + + /** + * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合 + */ + protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + protected static MessageDigest messagedigest = null; + static { + try { + messagedigest = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException nsaex) { + System.err.println(MD5Util.class.getName() + + "初始化失败,MessageDigest不支持MD5Util。"); + nsaex.printStackTrace(); + } + } + + /** + * 生成字符串的md5校验值 + * + * @param s + * @return + */ + public static String getMD5String(String s) { + return getMD5String(s.getBytes()); + } + public static String getStaffMD5String(String staffId,String s) { + + return getMD5String((staffId+s).getBytes()); + } + public static String getUserMD5String(String userId,String s) { + return getMD5String(s.getBytes()); + } + + /** + * 判断字符串的md5校验码是否与一个已知的md5码相匹配 + * + * @param password 要校验的字符串 + * @param md5PwdStr 已知的md5校验码 + * @return + */ + public static boolean checkPassword(String password, String md5PwdStr) { + String s = getMD5String(password); + return s.equals(md5PwdStr); + } + + /** + * 生成文件的md5校验值 + * + * @param file + * @return + * @throws IOException + */ + public static String getFileMD5String(File file) throws IOException { + InputStream fis; + fis = new FileInputStream(file); + byte[] buffer = new byte[1024]; + int numRead = 0; + while ((numRead = fis.read(buffer)) > 0) { + messagedigest.update(buffer, 0, numRead); + } + fis.close(); + return bufferToHex(messagedigest.digest()); + } + public static String getFileMD5String(InputStream fis) throws IOException { + byte[] buffer = new byte[1024]; + int numRead = 0; + while ((numRead = fis.read(buffer)) > 0) { + messagedigest.update(buffer, 0, numRead); + } + fis.close(); + return bufferToHex(messagedigest.digest()); + } + + public static String getMD5String(byte[] bytes) { + messagedigest.update(bytes); + return bufferToHex(messagedigest.digest()); + } + + private static String bufferToHex(byte bytes[]) { + return bufferToHex(bytes, 0, bytes.length); + } + + private static String bufferToHex(byte bytes[], int m, int n) { + StringBuffer stringbuffer = new StringBuffer(2 * n); + int k = m + n; + for (int l = m; l < k; l++) { + appendHexPair(bytes[l], stringbuffer); + } + return stringbuffer.toString(); + } + + private static void appendHexPair(byte bt, StringBuffer stringbuffer) { + char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换, >>> 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同 + char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换 + stringbuffer.append(c0); + stringbuffer.append(c1); + } + + + /** + * MD5方法 + * + * @param text 明文 + * @param key 密钥 + * @return 密文 + * @throws Exception + */ + public static String md5(String text, String key) throws Exception { + //加密后的字符串 + System.out.println("text + key "+text + key); + String encodeStr= DigestUtils.md5Hex(text + key); + System.out.println("MD5加密后的字符串为:encodeStr="+encodeStr); + return encodeStr; + } + + public static void main(String[] args) throws IOException { + System.out.println(MD5Util.getMD5String("RVWU202305121022211042vip")); + + } + +} diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/dto/RefundDto.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/dto/RefundDto.java index a48386d..ff096ee 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/dto/RefundDto.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/dto/RefundDto.java @@ -1,9 +1,13 @@ package com.bnyer.pay.bean.dto; +import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import javax.validation.constraints.NotBlank; +import java.math.BigDecimal; + /** * @author :WXC * @Date :2023/05/08 @@ -14,4 +18,16 @@ import lombok.Setter; @NoArgsConstructor public class RefundDto { + @NotBlank(message = "支付订单号不能为空") + @ApiModelProperty(value = "支付订单号") + private String payId; + + @ApiModelProperty(value = " 退款金额(元) ,如果不传则全额退款", example = "0.01") + private BigDecimal refundAmount; + + @NotBlank(message = "签名不能为空") + @ApiModelProperty(value = "签名") + private String sign; + + } diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/vo/UnifiedOrderVo.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/vo/UnifiedOrderVo.java index 4772706..dac9b91 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/vo/UnifiedOrderVo.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/bean/vo/UnifiedOrderVo.java @@ -13,9 +13,6 @@ import lombok.NoArgsConstructor; @NoArgsConstructor public class UnifiedOrderVo { - @ApiModelProperty(value = "应用id") - private String appId; - @ApiModelProperty(value = "内部系统支付单号/开发者测单号") private String outOrderNo; diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java index c0da0a4..0f8a9a2 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java @@ -1,11 +1,16 @@ package com.bnyer.pay.controller; import com.bnyer.common.core.domain.R; +import com.bnyer.common.core.enums.ResponseEnum; +import com.bnyer.common.core.exception.ServiceException; +import com.bnyer.pay.bean.dto.RefundDto; import com.bnyer.pay.bean.dto.UnifiedOrderDto; import com.bnyer.pay.bean.dto.QueryOrderDto; +import com.bnyer.pay.bean.vo.ThirdRefundVo; import com.bnyer.pay.service.UnifiedPayService; import com.bnyer.pay.bean.vo.UnifiedOrderVo; import com.bnyer.pay.bean.vo.QueryOrderVo; +import com.bnyer.pay.utils.PaymentRefundUtil; import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; @@ -46,4 +51,14 @@ public class UnifiedPayController { return R.ok(queryOrderVo); } + @PostMapping("/refund") + @Operation(summary = "统一退款" , description = "统一退款") + public R refund(@Valid @RequestBody RefundDto dto){ + if (!PaymentRefundUtil.checkSign(dto)){ + throw new ServiceException(ResponseEnum.REFUND_SING_ERROR); + } + ThirdRefundVo unifiedOrderVo = unifiedPayService.refund(dto); + return R.ok(unifiedOrderVo); + } + } diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/enums/EnumVerificationKey.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/enums/EnumVerificationKey.java new file mode 100644 index 0000000..279434e --- /dev/null +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/enums/EnumVerificationKey.java @@ -0,0 +1,20 @@ +package com.bnyer.pay.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description : + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum EnumVerificationKey { + VIP("vip", "VipInOrder20230512Key"), + ; + private String key; + private String value; +} diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java index 75f8af8..2ec7e84 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java @@ -1,7 +1,9 @@ package com.bnyer.pay.service; +import com.bnyer.pay.bean.dto.RefundDto; import com.bnyer.pay.bean.dto.UnifiedOrderDto; import com.bnyer.pay.bean.dto.QueryOrderDto; +import com.bnyer.pay.bean.vo.ThirdRefundVo; import com.bnyer.pay.bean.vo.UnifiedOrderVo; import com.bnyer.pay.bean.vo.QueryOrderVo; @@ -28,4 +30,6 @@ public interface UnifiedPayService { * @return */ QueryOrderVo queryOrder(QueryOrderDto dto); + + ThirdRefundVo refund(RefundDto dto); } diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java index de68f55..90ab6d2 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java @@ -18,6 +18,7 @@ import com.bnyer.pay.bean.bo.QueryOrderBo; import com.bnyer.pay.bean.bo.UnifiedOrderBo; import com.bnyer.pay.bean.dto.AddPayInfoDto; import com.bnyer.pay.bean.dto.QueryOrderDto; +import com.bnyer.pay.bean.dto.RefundDto; import com.bnyer.pay.bean.dto.UnifiedOrderDto; import com.bnyer.pay.bean.vo.*; import com.bnyer.pay.constant.KSPayConstants; @@ -222,6 +223,11 @@ public class UnifiedPayServiceImpl implements UnifiedPayService { return queryOrderVo; } + @Override + public ThirdRefundVo refund(RefundDto dto) { + return null; + } + /** * 通过第三方系统支付状态构建业务系统对应支付状态 * @param payType diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/utils/PaymentRefundUtil.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/utils/PaymentRefundUtil.java new file mode 100644 index 0000000..cadee6e --- /dev/null +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/utils/PaymentRefundUtil.java @@ -0,0 +1,39 @@ +package com.bnyer.pay.utils; + +import com.bnyer.common.core.utils.MD5Util; +import com.bnyer.pay.bean.dto.RefundDto; +import com.bnyer.pay.enums.EnumVerificationKey; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description : 退款工具类 + */ +public class PaymentRefundUtil { + + /** + * 获取签名 + * @param dto + * @return + */ + public static String getSign(RefundDto dto) { + return MD5Util.getMD5String(dto.getPayId() + EnumVerificationKey.VIP.getValue()); + } + + /** + * 校验签名 + * @param dto + * @return + */ + public static boolean checkSign(RefundDto dto) { + + return MD5Util.getMD5String(dto.getPayId() + EnumVerificationKey.VIP.getValue()).equals(dto.getSign()); + } + + public static void main(String[] args) { + String sign = MD5Util.getMD5String("RVWU202305121022211042" + EnumVerificationKey.VIP.getValue()); + System.out.println(sign); + System.out.println(MD5Util.getMD5String("RVWU202305121022211042" + EnumVerificationKey.VIP.getValue()).equals(sign)); + } + +} From 59690f7c8cd982b789f39bd7379742b238e27c27 Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 16:09:13 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=98=B2=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=8F=90=E4=BA=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/bnyer/common/core/domain/R.java | 9 ++ .../bnyer/common/core/enums/ResponseEnum.java | 13 +- .../order/annotation/LimitRepeatRequest.java | 63 ++++++++ .../order/aop/LimitRepeatRequestAspect.java | 150 ++++++++++++++++++ .../order/controller/VipOrderController.java | 2 + .../pay/annotation/LimitRepeatRequest.java | 63 ++++++++ .../pay/aop/LimitRepeatRequestAspect.java | 150 ++++++++++++++++++ .../pay/controller/UnifiedPayController.java | 9 +- .../bnyer/pay/service/UnifiedPayService.java | 6 +- .../service/impl/UnifiedPayServiceImpl.java | 10 +- 10 files changed, 457 insertions(+), 18 deletions(-) create mode 100644 bnyer-services/bnyer-order/src/main/java/com/bnyer/order/annotation/LimitRepeatRequest.java create mode 100644 bnyer-services/bnyer-order/src/main/java/com/bnyer/order/aop/LimitRepeatRequestAspect.java create mode 100644 bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/annotation/LimitRepeatRequest.java create mode 100644 bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/aop/LimitRepeatRequestAspect.java diff --git a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/domain/R.java b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/domain/R.java index 825ea22..035eb42 100644 --- a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/domain/R.java +++ b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/domain/R.java @@ -77,6 +77,15 @@ public class R implements Serializable return restResult(null,responseEnum.getCode(), responseEnum.getMsg()); } + /** + * 构建重复提交错误消息 + * @param time + * @return + */ + public R buildRepeatRequest(int time){ + return restResult(null,ResponseEnum.REPEAT_REQUEST_ERROR.getCode(),time+"分钟内"+ResponseEnum.REPEAT_REQUEST_ERROR.getMsg()); + } + private static R restResult(T data, int code, String msg) { R apiResult = new R<>(); diff --git a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java index 71d7c0f..e84e13a 100644 --- a/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java +++ b/bnyer-common/bnyer-common-core/src/main/java/com/bnyer/common/core/enums/ResponseEnum.java @@ -10,6 +10,7 @@ public enum ResponseEnum { //======================系统异常========================, SERVER_ERROR(500, "系统繁忙,请稍候重试!"), NOT_AUTH(500, "未登录!"), + REPEAT_REQUEST_ERROR(500, "请勿重复请求"), PARAM_ERROR(400, "参数异常!"), @@ -20,15 +21,9 @@ public enum ResponseEnum { * 订单已过期,当前端看到该状态码的时候,提示订单信息已过期,请重新确认后提交,此时用户点击确定,前端刷新页面。 */ ORDER_EXPIRED(110003, "订单已过期"), - /** - * 请勿重复提交订单, - * 1.当前端遇到该异常时,说明前端防多次点击没做好 - * 2.提示用户 订单已发生改变,请勿重复下单 - */ - REPEAT_ORDER(110004,"请勿重复提交订单"), - ORDER_CANCEL(110005, "该订单已取消,请重新下单!"), - ORDER_REPEAT_PAY(110006, "该订单已支付,请勿重复支付!"), - REFUND_SING_ERROR(110007, "签名错误!"), + ORDER_CANCEL(110004, "该订单已取消,请重新下单!"), + ORDER_REPEAT_PAY(110005, "该订单已支付,请勿重复支付!"), + REFUND_SING_ERROR(110006, "签名错误!"), diff --git a/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/annotation/LimitRepeatRequest.java b/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/annotation/LimitRepeatRequest.java new file mode 100644 index 0000000..c27d369 --- /dev/null +++ b/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/annotation/LimitRepeatRequest.java @@ -0,0 +1,63 @@ +package com.bnyer.order.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description : 防重复提交 + */ +@Target({ METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface LimitRepeatRequest { + + /** + * 限制当前用户同一个api 不能重复提交 + */ + String SELF="self"; + + /** + * 限制所有用户同一个参数不能重复提交,如我新增了用户 张三, 那么其他人不能再并发情况下重复添加张三 + */ + String ALL_USER="all"; + + /** + * 当前时间内 api 只能请求一次,单位秒 + * @return + */ + int time() default 5; + + /** + * 对部分参数做重复请求限制 + * @return + */ + String[] bodyParam() default {}; + + /** + * 是否对全部参数做重复请求限制 + * @return + */ + boolean bodyAllParam() default false; + + /** + * 重复请求限制的用户范围 + * LimitRepeatRequest.SELF:针对当前登录用户 + * LimitRepeatRequest.ALL_USER:针对所有用户 + * + * @return + */ + String userRange() default SELF; + + /** + * 错误提示信息 + * @return + */ + String message() default ""; + +} diff --git a/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/aop/LimitRepeatRequestAspect.java b/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/aop/LimitRepeatRequestAspect.java new file mode 100644 index 0000000..b13f80b --- /dev/null +++ b/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/aop/LimitRepeatRequestAspect.java @@ -0,0 +1,150 @@ +package com.bnyer.order.aop; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bnyer.common.core.domain.R; +import com.bnyer.common.core.utils.MD5Util; +import com.bnyer.common.core.utils.StringUtils; +import com.bnyer.common.core.vo.UserInfoVo; +import com.bnyer.common.redis.service.RedisService; +import com.bnyer.common.security.utils.SecurityUtils; +import com.bnyer.order.annotation.LimitRepeatRequest; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description :重复提交限制aop + */ +@Slf4j +@Aspect +@Component +public class LimitRepeatRequestAspect { + + @Autowired + private RedisService redisService; + + @Around("@annotation(limitRepeatRequest)") + public Object around(ProceedingJoinPoint joinPoint, LimitRepeatRequest limitRepeatRequest) throws Throwable{ + String key = getKey(joinPoint,limitRepeatRequest); + Object cacheObject = redisService.getCacheObject(key); + Object message; + if (Objects.nonNull(cacheObject)){ + if (StringUtils.isNotBlank(limitRepeatRequest.message())){ + message = limitRepeatRequest.message(); + }else { + message = new R().buildRepeatRequest(limitRepeatRequest.time()); + } + }else { + redisService.setCacheObject(key,"1",(long)limitRepeatRequest.time(), TimeUnit.SECONDS); + message = joinPoint.proceed(); + } + return message; + } + + /** + * 获取rediskey + * + * @param joinPoint + * @param limitRepeatRequest + * @return + */ + private String getKey(ProceedingJoinPoint joinPoint, LimitRepeatRequest limitRepeatRequest) { + UserInfoVo userInfo = SecurityUtils.getUserInfo(); + Method currentMethod = getCurrentMethod(joinPoint); + //最后拼接好的key + StringBuilder key = new StringBuilder("LimitRepeatRequestAspect#" + currentMethod.getName()); + //限制范围 + String userRange = limitRepeatRequest.userRange(); + if (LimitRepeatRequest.SELF.equals(userRange)){ + key.append("#"); + key.append(userInfo.getUserClientType()); + key.append("#"); + key.append(userInfo.getId()); + } + //获取请求参数 + JSONObject requestParams = getRequestParams(joinPoint); + //部分参数做重复请求限制 + if (Objects.nonNull(requestParams)){ + String[] bodyParam = limitRepeatRequest.bodyParam(); + if (bodyParam != null){ + for (String param : bodyParam) { + key.append("#"); + Object obj = requestParams.get(param); + if (obj instanceof JSONArray){ + JSONArray jsonArray = requestParams.getJSONArray(param); + if (CollUtil.isNotEmpty(jsonArray)){ + for (Object o : jsonArray) { + if (o instanceof String){ + key.append(o); + } + } + } + }else if(obj instanceof String){ + String value = requestParams.containsKey(param)?requestParams.getString(param):""; + key.append(value); + }else if(obj instanceof Integer){ + String value = requestParams.containsKey(param)?requestParams.getString(param):""; + key.append(value); + } + } + } + } + //全部参数做重复请求限制 + if (limitRepeatRequest.bodyAllParam()){ + String jsonStr = JSON.toJSONString(requestParams); + key.append("#"); + key.append(jsonStr); + } + return MD5Util.getMD5String(key.toString()); + } + + /** + * 获取请求参数 + * @param joinPoint + * @return + */ + private JSONObject getRequestParams(ProceedingJoinPoint joinPoint) { + Object[] args = joinPoint.getArgs(); + if (args != null && args.length != 0){ + String jsonString = JSON.toJSONString(args); + JSONArray parseArray = JSON.parseArray(jsonString); + return parseArray.getJSONObject(0); + } + return null; + } + + /** + * 获取当前方法 + * @param joinPoint + * @return + */ + private Method getCurrentMethod(ProceedingJoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + if (!(signature instanceof MethodSignature)){ + throw new IllegalArgumentException("该注解只能作用于方法上面"); + } + MethodSignature methodSignature = (MethodSignature)signature; + Object target = joinPoint.getTarget(); + try { + Method method = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes()); + return method; + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/controller/VipOrderController.java b/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/controller/VipOrderController.java index 2208272..39611fa 100644 --- a/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/controller/VipOrderController.java +++ b/bnyer-services/bnyer-order/src/main/java/com/bnyer/order/controller/VipOrderController.java @@ -2,6 +2,7 @@ package com.bnyer.order.controller; import com.bnyer.common.core.domain.R; import com.bnyer.common.core.web.controller.BaseController; +import com.bnyer.order.annotation.LimitRepeatRequest; import com.bnyer.order.bean.dto.AddVipOrderDto; import com.bnyer.order.bean.query.VipOrderExtQuery; import com.bnyer.order.bean.query.VipOrderQuery; @@ -38,6 +39,7 @@ public class VipOrderController extends BaseController { /** * 提交订单 */ + @LimitRepeatRequest(bodyAllParam = true, message = "您的订单已提交,请勿频繁操作") @PostMapping("/addVipOrder") @Operation(summary = "生成会员订单,返回订单号" , description = "生成会员订单,返回订单号,通过订单号调用支付接口") public R addVipOrder(@Valid @RequestBody AddVipOrderDto addVipOrderDto) { diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/annotation/LimitRepeatRequest.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/annotation/LimitRepeatRequest.java new file mode 100644 index 0000000..605b466 --- /dev/null +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/annotation/LimitRepeatRequest.java @@ -0,0 +1,63 @@ +package com.bnyer.pay.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description : 防重复提交 + */ +@Target({ METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface LimitRepeatRequest { + + /** + * 限制当前用户同一个api 不能重复提交 + */ + String SELF="self"; + + /** + * 限制所有用户同一个参数不能重复提交,如我新增了用户 张三, 那么其他人不能再并发情况下重复添加张三 + */ + String ALL_USER="all"; + + /** + * 当前时间内 api 只能请求一次,单位秒 + * @return + */ + int time() default 5; + + /** + * 对部分参数做重复请求限制 + * @return + */ + String[] bodyParam() default {}; + + /** + * 是否对全部参数做重复请求限制 + * @return + */ + boolean bodyAllParam() default false; + + /** + * 重复请求限制的用户范围 + * LimitRepeatRequest.SELF:针对当前登录用户 + * LimitRepeatRequest.ALL_USER:针对所有用户 + * + * @return + */ + String userRange() default SELF; + + /** + * 错误提示信息 + * @return + */ + String message() default ""; + +} diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/aop/LimitRepeatRequestAspect.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/aop/LimitRepeatRequestAspect.java new file mode 100644 index 0000000..e3116f0 --- /dev/null +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/aop/LimitRepeatRequestAspect.java @@ -0,0 +1,150 @@ +package com.bnyer.pay.aop; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bnyer.common.core.domain.R; +import com.bnyer.common.core.utils.MD5Util; +import com.bnyer.common.core.utils.StringUtils; +import com.bnyer.common.core.vo.UserInfoVo; +import com.bnyer.common.redis.service.RedisService; +import com.bnyer.common.security.utils.SecurityUtils; +import com.bnyer.pay.annotation.LimitRepeatRequest; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * @author :WXC + * @Date :2023/05/12 + * @description :重复提交限制aop + */ +@Slf4j +@Aspect +@Component +public class LimitRepeatRequestAspect { + + @Autowired + private RedisService redisService; + + @Around("@annotation(limitRepeatRequest)") + public Object around(ProceedingJoinPoint joinPoint, LimitRepeatRequest limitRepeatRequest) throws Throwable{ + String key = getKey(joinPoint,limitRepeatRequest); + Object cacheObject = redisService.getCacheObject(key); + Object message; + if (Objects.nonNull(cacheObject)){ + if (StringUtils.isNotBlank(limitRepeatRequest.message())){ + message = limitRepeatRequest.message(); + }else { + message = new R().buildRepeatRequest(limitRepeatRequest.time()); + } + }else { + redisService.setCacheObject(key,"1",(long)limitRepeatRequest.time(), TimeUnit.SECONDS); + message = joinPoint.proceed(); + } + return message; + } + + /** + * 获取rediskey + * + * @param joinPoint + * @param limitRepeatRequest + * @return + */ + private String getKey(ProceedingJoinPoint joinPoint, LimitRepeatRequest limitRepeatRequest) { + UserInfoVo userInfo = SecurityUtils.getUserInfo(); + Method currentMethod = getCurrentMethod(joinPoint); + //最后拼接好的key + StringBuilder key = new StringBuilder("LimitRepeatRequestAspect#" + currentMethod.getName()); + //限制范围 + String userRange = limitRepeatRequest.userRange(); + if (LimitRepeatRequest.SELF.equals(userRange)){ + key.append("#"); + key.append(userInfo.getUserClientType()); + key.append("#"); + key.append(userInfo.getId()); + } + //获取请求参数 + JSONObject requestParams = getRequestParams(joinPoint); + //部分参数做重复请求限制 + if (Objects.nonNull(requestParams)){ + String[] bodyParam = limitRepeatRequest.bodyParam(); + if (bodyParam != null){ + for (String param : bodyParam) { + key.append("#"); + Object obj = requestParams.get(param); + if (obj instanceof JSONArray){ + JSONArray jsonArray = requestParams.getJSONArray(param); + if (CollUtil.isNotEmpty(jsonArray)){ + for (Object o : jsonArray) { + if (o instanceof String){ + key.append(o); + } + } + } + }else if(obj instanceof String){ + String value = requestParams.containsKey(param)?requestParams.getString(param):""; + key.append(value); + }else if(obj instanceof Integer){ + String value = requestParams.containsKey(param)?requestParams.getString(param):""; + key.append(value); + } + } + } + } + //全部参数做重复请求限制 + if (limitRepeatRequest.bodyAllParam()){ + String jsonStr = JSON.toJSONString(requestParams); + key.append("#"); + key.append(jsonStr); + } + return MD5Util.getMD5String(key.toString()); + } + + /** + * 获取请求参数 + * @param joinPoint + * @return + */ + private JSONObject getRequestParams(ProceedingJoinPoint joinPoint) { + Object[] args = joinPoint.getArgs(); + if (args != null && args.length != 0){ + String jsonString = JSON.toJSONString(args); + JSONArray parseArray = JSON.parseArray(jsonString); + return parseArray.getJSONObject(0); + } + return null; + } + + /** + * 获取当前方法 + * @param joinPoint + * @return + */ + private Method getCurrentMethod(ProceedingJoinPoint joinPoint) { + Signature signature = joinPoint.getSignature(); + if (!(signature instanceof MethodSignature)){ + throw new IllegalArgumentException("该注解只能作用于方法上面"); + } + MethodSignature methodSignature = (MethodSignature)signature; + Object target = joinPoint.getTarget(); + try { + Method method = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes()); + return method; + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java index 0f8a9a2..1296451 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/controller/UnifiedPayController.java @@ -3,6 +3,7 @@ package com.bnyer.pay.controller; import com.bnyer.common.core.domain.R; import com.bnyer.common.core.enums.ResponseEnum; import com.bnyer.common.core.exception.ServiceException; +import com.bnyer.pay.annotation.LimitRepeatRequest; import com.bnyer.pay.bean.dto.RefundDto; import com.bnyer.pay.bean.dto.UnifiedOrderDto; import com.bnyer.pay.bean.dto.QueryOrderDto; @@ -37,6 +38,7 @@ public class UnifiedPayController { @Autowired private UnifiedPayService unifiedPayService; + @LimitRepeatRequest(bodyAllParam = true, message = "您的订单已提交,请勿频繁操作") @PostMapping("/unifiedOrder") @Operation(summary = "统一下单,并生成支付订单" , description = "生成支付订单,返回前端支付所需参数") public R unifiedOrder(@Valid @RequestBody UnifiedOrderDto dto, HttpServletRequest request){ @@ -51,14 +53,15 @@ public class UnifiedPayController { return R.ok(queryOrderVo); } + @LimitRepeatRequest(time = 10, message = "请勿频繁操作") @PostMapping("/refund") @Operation(summary = "统一退款" , description = "统一退款") - public R refund(@Valid @RequestBody RefundDto dto){ + public R refund(@Valid @RequestBody RefundDto dto){ if (!PaymentRefundUtil.checkSign(dto)){ throw new ServiceException(ResponseEnum.REFUND_SING_ERROR); } - ThirdRefundVo unifiedOrderVo = unifiedPayService.refund(dto); - return R.ok(unifiedOrderVo); + unifiedPayService.refund(dto); + return R.ok(); } } diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java index 2ec7e84..59ed825 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/UnifiedPayService.java @@ -31,5 +31,9 @@ public interface UnifiedPayService { */ QueryOrderVo queryOrder(QueryOrderDto dto); - ThirdRefundVo refund(RefundDto dto); + /** + * 统一退款 + * @param dto + */ + void refund(RefundDto dto); } diff --git a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java index 90ab6d2..ec9fe52 100644 --- a/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java +++ b/bnyer-services/bnyer-pay/src/main/java/com/bnyer/pay/service/impl/UnifiedPayServiceImpl.java @@ -223,11 +223,6 @@ public class UnifiedPayServiceImpl implements UnifiedPayService { return queryOrderVo; } - @Override - public ThirdRefundVo refund(RefundDto dto) { - return null; - } - /** * 通过第三方系统支付状态构建业务系统对应支付状态 * @param payType @@ -254,4 +249,9 @@ public class UnifiedPayServiceImpl implements UnifiedPayService { } } + @Override + public void refund(RefundDto dto) { + + } + } From 6081e560422d7773f1aeb9540dde52d50179cc73 Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 17:05:43 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/UserVipRecordController.java | 39 +++++++++++++ .../bnyer/img/mapper/UserVipRecordMapper.java | 3 + .../bnyer/img/query/UserVipRecordQuery.java | 26 +++++++++ .../img/service/UserVipRecordService.java | 9 +++ .../impl/UserVipServiceRecordImpl.java | 31 ++++++++++ .../com/bnyer/img/vo/UserVipRecordVo.java | 56 +++++++++++++++++++ .../bnyer/img/mapper/UserVipRecordMapper.xml | 29 +++++++++- 7 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/UserVipRecordController.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/query/UserVipRecordQuery.java create mode 100644 bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/UserVipRecordController.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/UserVipRecordController.java new file mode 100644 index 0000000..82d0413 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/controller/UserVipRecordController.java @@ -0,0 +1,39 @@ +package com.bnyer.img.controller; + +import com.bnyer.common.core.domain.R; +import com.bnyer.img.query.UserVipQuery; +import com.bnyer.img.query.UserVipRecordQuery; +import com.bnyer.img.service.UserVipRecordService; +import com.bnyer.img.service.UserVipService; +import com.bnyer.img.vo.UserVipRecordVo; +import com.bnyer.img.vo.UserVipVo; +import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.Operation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @author :WXC + * @Date :2023/05/10 + * @description : + */ +@Api(value = "用户会员记录相关接口",tags = "用户会员记录相关接口") +@RestController +@RequestMapping("/img/mini/vipRecord") +@Slf4j +public class UserVipRecordController { + + @Resource + private UserVipRecordService userVipRecordService; + + @Operation(summary="获取用户会员记录",description = "获取用户会员记录") + @GetMapping(value = "/queryUserVipRecord") + public R queryUserVipRecord(UserVipRecordQuery query){ + return R.ok(userVipRecordService.queryUserVipRecord(query)); + } + + +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/mapper/UserVipRecordMapper.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/mapper/UserVipRecordMapper.java index 113a89d..db8dd32 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/mapper/UserVipRecordMapper.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/mapper/UserVipRecordMapper.java @@ -2,8 +2,11 @@ package com.bnyer.img.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.bnyer.common.core.domain.UserVipRecord; +import com.bnyer.img.query.UserVipRecordQuery; +import com.bnyer.img.vo.UserVipRecordVo; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserVipRecordMapper extends BaseMapper { + UserVipRecordVo queryUserVipRecord(UserVipRecordQuery query); } \ No newline at end of file diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/query/UserVipRecordQuery.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/query/UserVipRecordQuery.java new file mode 100644 index 0000000..3f2c6a6 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/query/UserVipRecordQuery.java @@ -0,0 +1,26 @@ +package com.bnyer.img.query; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +/** + * @author :WXC + * @Date :2023/03/31 + * @description : + */ +@Getter +@Setter +@ApiModel("用户会员记录查询请求对象") +public class UserVipRecordQuery { + @ApiModelProperty(value = "id") + private Long id; + + @ApiModelProperty(value = "用户id") + private Long userId; + /** + * 用户客户端类型 + */ + private Integer userClientType; +} diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/UserVipRecordService.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/UserVipRecordService.java index d6d4c08..7520259 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/UserVipRecordService.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/UserVipRecordService.java @@ -2,6 +2,9 @@ package com.bnyer.img.service; import com.bnyer.common.core.dto.AddUserVipRecordDto; import com.bnyer.common.core.dto.PayUserVipDto; +import com.bnyer.img.query.UserVipRecordQuery; +import com.bnyer.img.vo.UserVipRecordVo; +import com.bnyer.img.vo.UserVipVo; public interface UserVipRecordService { @@ -20,4 +23,10 @@ public interface UserVipRecordService { */ void addUserVipRecord(AddUserVipRecordDto dto); + /** + * 查询用户会员记录 + * @param query + * @return + */ + UserVipRecordVo queryUserVipRecord(UserVipRecordQuery query); } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java index 2646c0e..ca45af0 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java @@ -6,13 +6,20 @@ import com.bnyer.common.core.domain.UserVipRecord; import com.bnyer.common.core.domain.VipOrder; import com.bnyer.common.core.dto.AddUserVipRecordDto; import com.bnyer.common.core.dto.PayUserVipDto; +import com.bnyer.common.core.enums.ResponseEnum; import com.bnyer.common.core.exception.ServiceException; +import com.bnyer.common.core.utils.StringUtils; import com.bnyer.common.core.utils.bean.EntityConvertUtil; +import com.bnyer.common.core.vo.UserInfoVo; import com.bnyer.common.redis.service.RedissonService; +import com.bnyer.common.security.utils.SecurityUtils; import com.bnyer.img.constants.UserVipOrderStatusConstant; import com.bnyer.img.enums.EnumUserVipRecordStatus; import com.bnyer.img.mapper.UserVipRecordMapper; +import com.bnyer.img.query.UserVipRecordQuery; import com.bnyer.img.service.UserVipRecordService; +import com.bnyer.img.vo.UserVipRecordVo; +import com.bnyer.img.vo.UserVipVo; import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.springframework.beans.factory.annotation.Autowired; @@ -20,6 +27,7 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.util.Date; +import java.util.Objects; import java.util.concurrent.TimeUnit; @Service @@ -91,4 +99,27 @@ public class UserVipServiceRecordImpl implements UserVipRecordService { userVipRecord.setStatus(EnumUserVipRecordStatus.VALID.getStatus()); userVipRecordMapper.insert(userVipRecord); } + + /** + * 获取用户会员记录 + * @param query + * @return + */ + @Override + public UserVipRecordVo queryUserVipRecord(UserVipRecordQuery query) { + UserInfoVo userInfo = SecurityUtils.getUserInfo(); + if (Objects.isNull(query.getId())){ + query.setUserId(userInfo.getId()); + query.setUserClientType(userInfo.getUserClientType()); + } + UserVipRecordVo userVipRecordVo = userVipRecordMapper.queryUserVipRecord(query); + if (Objects.isNull(userVipRecordVo)){ + userVipRecordVo = new UserVipRecordVo(); + userVipRecordVo.setIsVip("0"); + }else { + // TODO: 2023/05/12 同步会员到期状态 + userVipRecordVo.setIsVip("1"); + } + return userVipRecordVo; + } } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java new file mode 100644 index 0000000..6c03a22 --- /dev/null +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java @@ -0,0 +1,56 @@ +package com.bnyer.img.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.Date; + +@Getter +@Setter +@NoArgsConstructor +@ApiModel(value = "用户会员记录查询响应对象") +public class UserVipRecordVo { + + @ApiModelProperty(value="id") + private Long id; + + @ApiModelProperty(value="订单号") + private String orderNo; + + @ApiModelProperty(value="用户id") + private Long userId; + + @ApiModelProperty(value="用户手机号") + private String phone; + + @ApiModelProperty(value="vip表id") + private Long vipId; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value="开始时间") + private Date startTime; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value="到期时间") + private Date endTime; + + @ApiModelProperty(value="状态(0->已到期;1->已生效;)") + private Integer status; + + @ApiModelProperty(value="vip名称") + private String vipName; + + @ApiModelProperty(value = "vip类型名称") + private String vipTypeName; + + @ApiModelProperty(value = "用户客户端类型:10用户-抖音 20用户-快手 30用户-微信 40艺术家-微信") + private Integer userClientType; + + @ApiModelProperty(value = "是否开通会员:0 未开通 1已开通") + private String isVip; + +} diff --git a/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml b/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml index a037825..b502f4b 100644 --- a/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml +++ b/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml @@ -22,7 +22,32 @@ - id,order_no,user_id , phone,vip_name,vip_type_name,user_client_type,status, vip_id, start_time, end_time, is_show, create_time, update_time, - sort + a.id, + a.order_no, + a.user_id , + a.phone,vip_name, + a.vip_type_name, + a.user_client_type, + a.`status`, vip_id, + a.start_time, end_time, + a.is_show, + a.create_time, + a.update_time, + a.sort + From c1a7cc27d19f428cbb57bb78c380881392a6e754 Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 17:15:25 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/com/bnyer/img/mapper/UserVipRecordMapper.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml b/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml index b502f4b..9b35c02 100644 --- a/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml +++ b/bnyer-services/bnyer-img/src/main/resources/com/bnyer/img/mapper/UserVipRecordMapper.xml @@ -40,14 +40,15 @@ FROM img_user_vip_record a WHERE + a.status = 1 - a.id = #{id} + and a.id = #{id} - a.user_id = #{userId} + and a.user_id = #{userId} - a.user_client_type = #{userClientType} + and a.user_client_type = #{userClientType} From 8e094cf2ea4cb8ccd3757d985969a0afe4e2f639 Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 17:24:36 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bnyer/img/service/impl/UserVipServiceRecordImpl.java | 3 +-- .../src/main/java/com/bnyer/img/vo/UserVipRecordVo.java | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java index ca45af0..8ca0ecf 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java @@ -115,10 +115,9 @@ public class UserVipServiceRecordImpl implements UserVipRecordService { UserVipRecordVo userVipRecordVo = userVipRecordMapper.queryUserVipRecord(query); if (Objects.isNull(userVipRecordVo)){ userVipRecordVo = new UserVipRecordVo(); - userVipRecordVo.setIsVip("0"); + userVipRecordVo.setStatus(0); }else { // TODO: 2023/05/12 同步会员到期状态 - userVipRecordVo.setIsVip("1"); } return userVipRecordVo; } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java index 6c03a22..426d225 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java @@ -50,7 +50,4 @@ public class UserVipRecordVo { @ApiModelProperty(value = "用户客户端类型:10用户-抖音 20用户-快手 30用户-微信 40艺术家-微信") private Integer userClientType; - @ApiModelProperty(value = "是否开通会员:0 未开通 1已开通") - private String isVip; - } From 0f2ce5f74481c2fd57569f9c4fb484af5cfb2965 Mon Sep 17 00:00:00 2001 From: wuxicheng <1441859745@qq.com> Date: Fri, 12 May 2023 17:37:34 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/bnyer/img/service/impl/UserVipServiceRecordImpl.java | 3 ++- .../src/main/java/com/bnyer/img/vo/UserVipRecordVo.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java index 8ca0ecf..ca45af0 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/service/impl/UserVipServiceRecordImpl.java @@ -115,9 +115,10 @@ public class UserVipServiceRecordImpl implements UserVipRecordService { UserVipRecordVo userVipRecordVo = userVipRecordMapper.queryUserVipRecord(query); if (Objects.isNull(userVipRecordVo)){ userVipRecordVo = new UserVipRecordVo(); - userVipRecordVo.setStatus(0); + userVipRecordVo.setIsVip("0"); }else { // TODO: 2023/05/12 同步会员到期状态 + userVipRecordVo.setIsVip("1"); } return userVipRecordVo; } diff --git a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java index 426d225..6c03a22 100644 --- a/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java +++ b/bnyer-services/bnyer-img/src/main/java/com/bnyer/img/vo/UserVipRecordVo.java @@ -50,4 +50,7 @@ public class UserVipRecordVo { @ApiModelProperty(value = "用户客户端类型:10用户-抖音 20用户-快手 30用户-微信 40艺术家-微信") private Integer userClientType; + @ApiModelProperty(value = "是否开通会员:0 未开通 1已开通") + private String isVip; + }