ソースを参照

Merge branch 'hjb' of SH-Arbitrate/Arbitrate-Backend into dev

hejinbo 2 年 前
コミット
695aff6bce
共有75 個のファイルを変更した3522 個の追加23 個の削除を含む
  1. 59
    0
      pay/pom.xml
  2. 32
    0
      pay/src/main/java/com/ruoyi/CallBackService.java
  3. 66
    0
      pay/src/main/java/com/ruoyi/ElegentPay.java
  4. 40
    0
      pay/src/main/java/com/ruoyi/ali/AlipayConfig.java
  5. 30
    0
      pay/src/main/java/com/ruoyi/ali/AlipayConstant.java
  6. 461
    0
      pay/src/main/java/com/ruoyi/ali/AlipayElegentTrade.java
  7. 124
    0
      pay/src/main/java/com/ruoyi/ali/AlipayElegentValid.java
  8. 20
    0
      pay/src/main/java/com/ruoyi/annotation/TradePlatform.java
  9. 23
    0
      pay/src/main/java/com/ruoyi/config/CallbackConfig.java
  10. 11
    0
      pay/src/main/java/com/ruoyi/constant/PayConstant.java
  11. 16
    0
      pay/src/main/java/com/ruoyi/constant/Platform.java
  12. 33
    0
      pay/src/main/java/com/ruoyi/constant/TradeType.java
  13. 35
    0
      pay/src/main/java/com/ruoyi/core/CallBackServiceImpl.java
  14. 90
    0
      pay/src/main/java/com/ruoyi/core/CallbackController.java
  15. 73
    0
      pay/src/main/java/com/ruoyi/core/CallbackWatch.java
  16. 27
    0
      pay/src/main/java/com/ruoyi/core/ElegentConfig.java
  17. 82
    0
      pay/src/main/java/com/ruoyi/core/ElegentLoader.java
  18. 136
    0
      pay/src/main/java/com/ruoyi/core/ElegentPayImpl.java
  19. 54
    0
      pay/src/main/java/com/ruoyi/core/ElegentTrade.java
  20. 48
    0
      pay/src/main/java/com/ruoyi/core/ElegentValid.java
  21. 20
    0
      pay/src/main/java/com/ruoyi/core/WatchList.java
  22. 20
    0
      pay/src/main/java/com/ruoyi/dto/PayRequest.java
  23. 29
    0
      pay/src/main/java/com/ruoyi/dto/PayResponse.java
  24. 24
    0
      pay/src/main/java/com/ruoyi/dto/QueryRefundResponse.java
  25. 25
    0
      pay/src/main/java/com/ruoyi/dto/QueryResponse.java
  26. 16
    0
      pay/src/main/java/com/ruoyi/dto/RefundRequest.java
  27. 15
    0
      pay/src/main/java/com/ruoyi/dto/ValidResponse.java
  28. 12
    0
      pay/src/main/java/com/ruoyi/dto/WatchDTO.java
  29. 24
    0
      pay/src/main/java/com/ruoyi/exceptions/TradeException.java
  30. 16
    0
      pay/src/main/java/com/ruoyi/key/KeyManager.java
  31. 19
    0
      pay/src/main/java/com/ruoyi/key/impl/DefaultKeyManager.java
  32. 37
    0
      pay/src/main/java/com/ruoyi/util/FileUtil.java
  33. 459
    0
      pay/src/main/java/com/ruoyi/wx/WxPayElegentTrade.java
  34. 153
    0
      pay/src/main/java/com/ruoyi/wx/WxPayElegentValid.java
  35. 20
    0
      pay/src/main/java/com/ruoyi/wx/WxpayConfig.java
  36. 48
    0
      pay/src/main/java/com/ruoyi/wx/WxpayConstant.java
  37. 14
    0
      pay/src/main/resources/META-INF/spring.factories
  38. 1
    0
      pom.xml
  39. 5
    1
      ruoyi-admin/pom.xml
  40. 0
    1
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/ArbitratorController.java
  41. 0
    2
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CaseApplicationController.java
  42. 41
    0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CaseArbitrateController.java
  43. 81
    0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CaseEvidenceController.java
  44. 41
    0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CasePaymentController.java
  45. 1
    0
      ruoyi-admin/src/main/resources/alipay_private.key
  46. 1
    0
      ruoyi-admin/src/main/resources/alipay_public.key
  47. 3
    3
      ruoyi-admin/src/main/resources/application-druid.yml
  48. 22
    4
      ruoyi-admin/src/main/resources/application.yml
  49. 1
    0
      ruoyi-admin/src/main/resources/wxpay_private.key
  50. 13
    0
      ruoyi-common/pom.xml
  51. 85
    0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/SmsUtils.java
  52. 5
    1
      ruoyi-system/pom.xml
  53. 3
    4
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CaseApplication.java
  54. 46
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CaseAttach.java
  55. 3
    3
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CaseLogRecord.java
  56. 41
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CasePaymentRecord.java
  57. 26
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/dto/CasePayDTO.java
  58. 67
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/CaseDetailVO.java
  59. 28
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/CaseEvidenceVO.java
  60. 11
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/CaseAttachMapper.java
  61. 15
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/CaseEvidenceMapper.java
  62. 11
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/CasePaymentRecordMapper.java
  63. 10
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/ICaseArbitrateService.java
  64. 21
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/ICaseEvidenceService.java
  65. 15
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/ICasePaymentService.java
  66. 35
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CallBackHandleServiceImpl.java
  67. 102
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CaseArbitrateServiceImpl.java
  68. 145
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CaseEvidenceServiceImpl.java
  69. 0
    1
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CaseLogRecordServiceImpl.java
  70. 135
    0
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CasePaymentServiceImpl.java
  71. 4
    3
      ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/IdentityAuthenticationServiceImpl.java
  72. 1
    0
      ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CaseApplicationMapper.xml
  73. 25
    0
      ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CaseAttachMapper.xml
  74. 28
    0
      ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CaseEvidenceMapper.xml
  75. 39
    0
      ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CasePaymentRecordMapper.xml

+ 59
- 0
pay/pom.xml ファイルの表示

@@ -0,0 +1,59 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project xmlns="http://maven.apache.org/POM/4.0.0"
3
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
+    <parent>
6
+        <artifactId>ruoyi</artifactId>
7
+        <groupId>com.ruoyi</groupId>
8
+        <version>3.8.6</version>
9
+    </parent>
10
+    <modelVersion>4.0.0</modelVersion>
11
+    <artifactId>pay</artifactId>
12
+    <version>1.0.0-SNAPSHOT</version>
13
+
14
+    <properties>
15
+        <maven.compiler.source>8</maven.compiler.source>
16
+        <maven.compiler.target>8</maven.compiler.target>
17
+    </properties>
18
+
19
+    <dependencies>
20
+        <dependency>
21
+            <groupId>org.springframework.boot</groupId>
22
+            <artifactId>spring-boot-starter-web</artifactId>
23
+        </dependency>
24
+        <dependency>
25
+            <groupId>org.springframework.boot</groupId>
26
+            <artifactId>spring-boot-autoconfigure</artifactId>
27
+            <version>2.7.10</version>
28
+            <optional>true</optional>
29
+        </dependency>
30
+
31
+        <dependency>
32
+            <groupId>org.projectlombok</groupId>
33
+            <artifactId>lombok</artifactId>
34
+            <version>1.18.22</version>
35
+        </dependency>
36
+        <dependency>
37
+            <groupId>com.alibaba</groupId>
38
+            <artifactId>fastjson</artifactId>
39
+            <version>1.2.72</version>
40
+        </dependency>
41
+        <dependency>
42
+            <groupId>cn.hutool</groupId>
43
+            <artifactId>hutool-all</artifactId>
44
+            <version>5.7.12</version>
45
+        </dependency>
46
+        <dependency>
47
+            <groupId>com.github.wechatpay-apiv3</groupId>
48
+            <artifactId>wechatpay-apache-httpclient</artifactId>
49
+            <version>0.4.7</version>
50
+        </dependency>
51
+        <dependency>
52
+            <groupId>com.alipay.sdk</groupId>
53
+            <artifactId>alipay-sdk-java</artifactId>
54
+            <version>4.34.8.ALL</version>
55
+        </dependency>
56
+    </dependencies>
57
+
58
+
59
+</project>

+ 32
- 0
pay/src/main/java/com/ruoyi/CallBackService.java ファイルの表示

@@ -0,0 +1,32 @@
1
+package com.ruoyi;
2
+
3
+/**
4
+ * 业务回调处理接口
5
+ */
6
+public interface CallBackService {
7
+
8
+    /**
9
+     * 成功支付--处理业务逻辑
10
+     * @param orderSn 订单号
11
+     */
12
+    void successPay(String orderSn);
13
+
14
+    /**
15
+     * 失败支付-处理业务逻辑
16
+     * @param orderSn 订单号
17
+     */
18
+    void failPay(String orderSn);
19
+
20
+    /**
21
+     * 退款成功-处理业务逻辑
22
+     * @param orderSn 订单号
23
+     */
24
+    void successRefund(String orderSn);
25
+
26
+    /**
27
+     * 退款失败-处理业务逻辑
28
+     * @param orderSn 订单号
29
+     */
30
+    void failRefund(String orderSn);
31
+
32
+}

+ 66
- 0
pay/src/main/java/com/ruoyi/ElegentPay.java ファイルの表示

@@ -0,0 +1,66 @@
1
+package com.ruoyi;
2
+
3
+
4
+import com.ruoyi.dto.*;
5
+import com.ruoyi.exceptions.TradeException;
6
+
7
+public interface ElegentPay {
8
+
9
+
10
+    /**
11
+     * 统一下单接口
12
+     * @param payRequest 支付请求
13
+     * @param tradeType 交易类型
14
+     * @param platform 平台
15
+     * @return 支付响应
16
+     * @throws TradeException
17
+     */
18
+    PayResponse requestPay(PayRequest payRequest, String tradeType, String platform) throws TradeException;
19
+
20
+
21
+    /**
22
+     * 关闭订单
23
+     * @param orderSn 订单号
24
+     * @param platform 平台
25
+     * @return 是否成功关闭订单
26
+     * @throws TradeException
27
+     */
28
+    Boolean closePay(String orderSn, String platform) throws TradeException;
29
+
30
+    /**
31
+     * 退款
32
+     * @param refundRequest 退款请求封装对象
33
+     * @param platform 平台
34
+     * @return 是否成功退款
35
+     * @throws TradeException
36
+     */
37
+    Boolean refund(RefundRequest refundRequest, String platform) throws TradeException;
38
+
39
+    /**
40
+     * 根据订单号查询订单
41
+     * @param orderSn 订单号
42
+     * @param platform 平台
43
+     * @return 查询响应对象
44
+     * @throws TradeException
45
+     */
46
+    QueryResponse queryTradingOrderNo(String orderSn , String platform) throws TradeException;
47
+
48
+
49
+    /**
50
+     * 查询单笔退款API
51
+     * @param orderSn 订单号
52
+     * @param platform 平台
53
+     * @return 查询退款响应对象
54
+     * @throws TradeException
55
+     */
56
+    QueryRefundResponse queryRefundTrading(String orderSn , String platform) throws TradeException;
57
+
58
+
59
+    /**
60
+     * 获得openID
61
+     * @param code
62
+     * @return
63
+     */
64
+    public String getOpenid(String code, String platform);
65
+
66
+}

+ 40
- 0
pay/src/main/java/com/ruoyi/ali/AlipayConfig.java ファイルの表示

@@ -0,0 +1,40 @@
1
+package com.ruoyi.ali;
2
+
3
+import com.ruoyi.key.KeyManager;
4
+import lombok.Data;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.beans.factory.annotation.Value;
7
+import org.springframework.boot.context.properties.ConfigurationProperties;
8
+import org.springframework.stereotype.Component;
9
+
10
+/**
11
+ * 支付宝权限对接类
12
+ */
13
+@Component
14
+@ConfigurationProperties("elegent.pay.alipay")
15
+@Data
16
+public class AlipayConfig {
17
+    /**
18
+     * 应用识别码
19
+     */
20
+    private String appId;
21
+
22
+    /**
23
+     * 密钥加密方式 RSA2
24
+     */
25
+    @Value("${elegent.pay.alipay.charset:RSA2}")
26
+    private String signType;
27
+
28
+    @Autowired
29
+    private KeyManager keyManager;
30
+
31
+    public String getPrivateKey(){
32
+        return keyManager.getKey("alipay_private.key");
33
+    }
34
+
35
+    public String getPublicKey(){
36
+        return keyManager.getKey("alipay_public.key");
37
+    }
38
+
39
+
40
+}

+ 30
- 0
pay/src/main/java/com/ruoyi/ali/AlipayConstant.java ファイルの表示

@@ -0,0 +1,30 @@
1
+package com.ruoyi.ali;
2
+
3
+import java.util.HashMap;
4
+import java.util.Map;
5
+
6
+/**
7
+ * ZFBConstant
8
+ * @description 支付宝相关的常量
9
+*/
10
+public class AlipayConstant {
11
+
12
+    public static final String SUCCESS = "SUCCESS";
13
+
14
+    public static final String  FAIL  = "FAIL";
15
+
16
+    /**
17
+     * 交易状态(用于转换)
18
+     */
19
+    public static final Map<String,String> TRADE_STATE = new HashMap<String,String>(){
20
+        {
21
+            put("TRADE_SUCCESS", "SUCCESS");
22
+            put("WAIT_BUYER_PAY", "NOTPAY");
23
+            put("TRADE_CLOSED", "CLOSED");
24
+            put("TRADE_FINISHED", "FINISHED");
25
+        }
26
+    };
27
+
28
+    public static final String domain="https://openapi.alipay.com/gateway.do";
29
+
30
+}

+ 461
- 0
pay/src/main/java/com/ruoyi/ali/AlipayElegentTrade.java ファイルの表示

@@ -0,0 +1,461 @@
1
+package com.ruoyi.ali;
2
+
3
+import com.alibaba.fastjson.JSON;
4
+import com.alibaba.fastjson.JSONObject;
5
+import com.alipay.api.AlipayApiException;
6
+import com.alipay.api.AlipayClient;
7
+import com.alipay.api.DefaultAlipayClient;
8
+import com.alipay.api.request.*;
9
+import com.alipay.api.response.*;
10
+import com.ruoyi.CallBackService;
11
+import com.ruoyi.annotation.TradePlatform;
12
+import com.ruoyi.config.CallbackConfig;
13
+import com.ruoyi.constant.PayConstant;
14
+import com.ruoyi.constant.Platform;
15
+import com.ruoyi.constant.TradeType;
16
+import com.ruoyi.core.ElegentTrade;
17
+import com.ruoyi.dto.*;
18
+import com.ruoyi.exceptions.TradeException;
19
+import lombok.extern.slf4j.Slf4j;
20
+import org.springframework.beans.factory.annotation.Autowired;
21
+import org.springframework.stereotype.Service;
22
+
23
+import java.math.BigDecimal;
24
+import java.util.Map;
25
+
26
+/**
27
+ * 支付宝支付的策略类
28
+ * @author wgl
29
+ */
30
+@Service
31
+@TradePlatform(Platform.ALI)
32
+@Slf4j
33
+public class AlipayElegentTrade implements ElegentTrade {
34
+
35
+    @Autowired
36
+    private AlipayConfig alipayConfig;
37
+
38
+    @Autowired
39
+    private CallbackConfig callbackConfig;
40
+
41
+    @Autowired
42
+    private CallBackService callBackService;
43
+
44
+
45
+    /**
46
+     * 获取回调地址
47
+     * @return
48
+     */
49
+    private String getPayNotifyUrl(){
50
+        return callbackConfig.getDomain()+ PayConstant.CALLBACK_PATH+ PayConstant.NOTIFY +"/"+ Platform.ALI;
51
+    }
52
+
53
+    /**
54
+     * 获取退款回调
55
+     * @return
56
+     */
57
+    private String getRefundNotifyUrl(){
58
+        return callbackConfig.getDomain()+ PayConstant.CALLBACK_PATH+ PayConstant.REFUND_NOTIFY +"/"+ Platform.ALI;
59
+    }
60
+
61
+
62
+
63
+    /**
64
+     * 创建支付订单
65
+      * @param payRequest
66
+     * @return
67
+     * @throws TradeException
68
+     */
69
+    @Override
70
+    public PayResponse requestPay(PayRequest payRequest, String tradeType) throws TradeException {
71
+        if(TradeType.NATIVE.equals( tradeType )){
72
+            return createNativeOrder(payRequest);
73
+        }
74
+        if(TradeType.JSAPI.equals( tradeType )){
75
+            return createJsApiOrder(payRequest);
76
+        }
77
+        if(TradeType.H5.equals( tradeType )){
78
+            return createH5Order(payRequest);
79
+        }
80
+        if(TradeType.APP.equals( tradeType )){
81
+            return createAPPOrder(payRequest);
82
+        }
83
+        return createNativeOrder(payRequest);
84
+    }
85
+
86
+
87
+    /**
88
+     * 本地支付(扫码)
89
+     * https://opendocs.alipay.com/open/194/106078?ref=api#预下单
90
+     * @param payRequest
91
+     * @return
92
+     * @throws TradeException
93
+     */
94
+    private PayResponse createNativeOrder(PayRequest payRequest) throws TradeException {
95
+        try {
96
+            AlipayClient alipayClient = getAliHttpClient();
97
+            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
98
+
99
+            request.setNotifyUrl(getPayNotifyUrl());
100
+
101
+            JSONObject bizContent = new JSONObject();
102
+            bizContent.put("out_trade_no", payRequest.getOrderSn());
103
+            //转换
104
+            //String totalFee= BigDecimal.valueOf(payRequest.getTotalFee()).divide(new BigDecimal(100)  ).toString();
105
+            bizContent.put("total_amount", fenToYuan(payRequest.getTotalFee()));
106
+            bizContent.put("subject", payRequest.getBody());
107
+            request.setBizContent(bizContent.toString());
108
+            AlipayTradePrecreateResponse response = alipayClient.execute(request);
109
+
110
+            if (response.isSuccess()) {
111
+                PayResponse payResponse =new PayResponse();
112
+                payResponse.setSuccess(true);
113
+                payResponse.setCode_url(response.getQrCode()); //本地支付二维码
114
+                payResponse.setOrder_sn(payRequest.getOrderSn());
115
+                return payResponse;
116
+            } else {
117
+                log.error("调用失败");
118
+                return null;
119
+            }
120
+        }catch (Exception e){
121
+            e.printStackTrace();
122
+            throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
123
+        }
124
+    }
125
+
126
+
127
+    /**
128
+     * 小程序
129
+     * https://opendocs.alipay.com/mini/03l5wn
130
+     * @param payRequest
131
+     * @return
132
+     * @throws TradeException
133
+     */
134
+    private PayResponse createJsApiOrder(PayRequest payRequest) throws TradeException {
135
+        AlipayClient alipayClient = getAliHttpClient();
136
+        try {
137
+            AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
138
+            request.setNotifyUrl(getPayNotifyUrl());
139
+            JSONObject bizContent = new JSONObject();
140
+            bizContent.put("out_trade_no", payRequest.getOrderSn());
141
+            bizContent.put("total_amount", fenToYuan( payRequest.getTotalFee() ));
142
+            bizContent.put("subject", payRequest.getBody());
143
+            bizContent.put("buyer_id", payRequest.getOpenid());
144
+            bizContent.put("timeout_express", "10m");
145
+            request.setBizContent(bizContent.toString());
146
+            AlipayTradeCreateResponse response = alipayClient.sdkExecute(request);
147
+            if (response.isSuccess()) {
148
+                PayResponse payResponse =new PayResponse();
149
+                payResponse.setSuccess(true);
150
+                payResponse.setPrepay_id(response.getTradeNo());
151
+                payResponse.setOrder_sn(response.getOutTradeNo());
152
+                return payResponse;
153
+            } else {
154
+                log.error("调用失败");
155
+                return null;
156
+            }
157
+        }catch (Exception e){
158
+            throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
159
+        }
160
+    }
161
+
162
+
163
+    /**
164
+     * H5
165
+     * https://opendocs.alipay.com/mini/03l5wn
166
+     * @param payRequest
167
+     * @return
168
+     * @throws TradeException
169
+     */
170
+    private PayResponse createH5Order(PayRequest payRequest) throws TradeException {
171
+        AlipayClient alipayClient = getAliHttpClient();
172
+        try {
173
+            AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
174
+            request.setNotifyUrl(getPayNotifyUrl());
175
+            request.setReturnUrl("");
176
+            JSONObject bizContent = new JSONObject();
177
+            bizContent.put("out_trade_no", payRequest.getOrderSn());
178
+            bizContent.put("total_amount", fenToYuan( payRequest.getTotalFee() ));
179
+            bizContent.put("subject", payRequest.getBody());
180
+            bizContent.put("product_code", "QUICK_WAP_WAY");
181
+
182
+            request.setBizContent(bizContent.toString());
183
+            AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
184
+            if (response.isSuccess()) {
185
+                PayResponse payResponse =new PayResponse();
186
+                payResponse.setSuccess(true);
187
+                payResponse.setPrepay_id(response.getTradeNo());
188
+                payResponse.setOrder_sn(response.getOutTradeNo());
189
+                return payResponse;
190
+            } else {
191
+                log.error("调用失败");
192
+                return null;
193
+            }
194
+        }catch (Exception e){
195
+            throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
196
+        }
197
+    }
198
+
199
+
200
+    /**
201
+     * APP
202
+     * https://opendocs.alipay.com/open/02e7gq?ref=api&scene=20
203
+     * @param payRequest
204
+     * @return
205
+     * @throws TradeException
206
+     */
207
+    private PayResponse createAPPOrder(PayRequest payRequest) throws TradeException {
208
+        AlipayClient alipayClient = getAliHttpClient();
209
+        try {
210
+            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
211
+            request.setNotifyUrl(getPayNotifyUrl());
212
+            JSONObject bizContent = new JSONObject();
213
+            bizContent.put("out_trade_no", payRequest.getOrderSn());
214
+            bizContent.put("total_amount", fenToYuan( payRequest.getTotalFee() ));
215
+            bizContent.put("subject", payRequest.getBody());
216
+            bizContent.put("product_code", "QUICK_MSECURITY_PAY");
217
+
218
+            request.setBizContent(bizContent.toString());
219
+            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
220
+            if (response.isSuccess()) {
221
+                PayResponse payResponse =new PayResponse();
222
+                payResponse.setSuccess(true);
223
+                payResponse.setPrepay_id(response.getTradeNo());
224
+                payResponse.setOrder_sn(response.getOutTradeNo());
225
+                return payResponse;
226
+            } else {
227
+                log.error("调用失败");
228
+                return null;
229
+            }
230
+        }catch (Exception e){
231
+            throw new TradeException("订单创建失败,订单号:"+ payRequest.getOrderSn());
232
+        }
233
+    }
234
+
235
+
236
+
237
+    /**
238
+     * 关闭订单
239
+     * @param orderSn
240
+     * @return
241
+     * @throws TradeException
242
+     */
243
+    @Override
244
+    public Boolean closePay(String orderSn) throws TradeException {
245
+        try {
246
+            AlipayClient alipayClient = getAliHttpClient();
247
+            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
248
+            JSONObject bizContent = new JSONObject();
249
+            bizContent.put("trade_no", orderSn);
250
+            request.setBizContent(bizContent.toString());
251
+            AlipayTradeCloseResponse response = alipayClient.execute(request);
252
+            if (response.isSuccess()) {
253
+                log.info("调用成功");
254
+                return true;
255
+            } else {
256
+                log.error("调用失败");
257
+                return false;
258
+            }
259
+        }catch (Exception e){
260
+            throw new TradeException("订单关闭失败,订单号:"+orderSn);
261
+        }
262
+    }
263
+
264
+    /**
265
+     * 退款接口
266
+     * alipay.trade.refund(统一收单交易退款接口)
267
+     * https://opendocs.alipay.com/open/02ekfk
268
+     * @param refundRequest
269
+     * @return
270
+     * @throws TradeException
271
+     */
272
+    @Override
273
+    public Boolean refund(RefundRequest refundRequest) throws TradeException {
274
+        try {
275
+            AlipayClient alipayClient = getAliHttpClient();
276
+            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
277
+            request.setNotifyUrl(getRefundNotifyUrl()); //退款回调
278
+            JSONObject bizContent = new JSONObject();
279
+            bizContent.put("refund_amount", fenToYuan(refundRequest.getRefundAmount() ));
280
+            bizContent.put("out_trade_no", refundRequest.getOrderSn());
281
+            //退款请求号,做幂等性校验
282
+            if(refundRequest.getRequestNo()!=null){
283
+                bizContent.put("out_request_no", refundRequest.getRequestNo());
284
+            }else{
285
+                bizContent.put("out_request_no", refundRequest.getOrderSn());
286
+            }
287
+            request.setBizContent(bizContent.toString());
288
+            AlipayTradeRefundResponse response = alipayClient.execute(request);
289
+            if (response.isSuccess()) {
290
+                if("Y".equals(response.getFundChange())) {
291
+                    log.info("退款成功{}",refundRequest.getOrderSn());
292
+                    callBackService.successRefund(refundRequest.getOrderSn());
293
+                    return true;
294
+                }else{
295
+                    //退款失败
296
+                    log.error("退款失败{}",refundRequest.getOrderSn());
297
+                    callBackService.failRefund(refundRequest.getOrderSn());
298
+                    return false;
299
+                }
300
+            } else {
301
+                log.error("退款调用失败{}",refundRequest.getOrderSn());
302
+                return false;
303
+            }
304
+        }catch (Exception e){
305
+            e.printStackTrace();
306
+            throw new TradeException("订单退款失败,订单号:"+ refundRequest.getOrderSn());
307
+        }
308
+    }
309
+
310
+    /**
311
+     * 查询单笔交易订单
312
+     * 参考官网: https://opendocs.alipay.com/open/02e7gm?ref=api#请求示例
313
+     *
314
+     * @param orderSn
315
+     * @return
316
+     * @throws TradeException
317
+     */
318
+    @Override
319
+    public QueryResponse queryTradingOrderNo(String orderSn) throws TradeException {
320
+        AlipayClient alipayClient = getAliHttpClient();
321
+        try {
322
+            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
323
+            JSONObject bizContent = new JSONObject();
324
+            bizContent.put("out_trade_no", orderSn);
325
+            request.setBizContent(bizContent.toString());
326
+            AlipayTradeQueryResponse response = alipayClient.execute(request);
327
+            QueryResponse queryResponse=new QueryResponse();
328
+            queryResponse.setOrder_sn(orderSn );
329
+            if (response.isSuccess()) {
330
+                queryResponse.setTransaction_id( response.getTradeNo() );
331
+                queryResponse.setTrade_state(AlipayConstant.TRADE_STATE.get(  response.getTradeStatus()) );//交易状态
332
+
333
+                //int total = BigDecimal.valueOf(Double.valueOf(response.getTotalAmount())).multiply(new BigDecimal(100)).intValue();
334
+                queryResponse.setTotal(  yuanToFen(response.getTotalAmount())   ); //总金额
335
+
336
+                //int buyer_pay_amount = BigDecimal.valueOf(Double.valueOf(response.getBuyerPayAmount())).multiply(new BigDecimal(100)).intValue();
337
+                //queryResponse.setPayer_total( yuanToFen(response.getBuyerPayAmount()) );//支付金额
338
+
339
+                queryResponse.setOpenid( response.getBuyerUserId());
340
+                Map map = JSON.parseObject(response.getBody(), Map.class  ) ;
341
+                queryResponse.setExpand(map);//全部数据
342
+                return queryResponse;
343
+            } else {
344
+                queryResponse.setTrade_state("NOTPAY");
345
+                return queryResponse;
346
+            }
347
+        }catch (Exception e){
348
+            e.printStackTrace();
349
+            //throw new TradeException("订单查询失败,订单号:"+orderSn);
350
+            return null;
351
+        }
352
+    }
353
+
354
+    /**
355
+     * 查询退款订单
356
+     * @param orderSn
357
+     * @return
358
+     * @throws TradeException
359
+     */
360
+    @Override
361
+    public QueryRefundResponse queryRefundTrading(String orderSn) throws TradeException {
362
+        try {
363
+            AlipayClient alipayClient = getAliHttpClient();
364
+            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
365
+            JSONObject bizContent = new JSONObject();
366
+            bizContent.put("out_request_no", orderSn);
367
+            request.setBizContent(bizContent.toString());
368
+            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
369
+            if (response.isSuccess()) {
370
+                log.info("调用成功");
371
+                Map map = JSON.parseObject(response.getBody(), Map.class   );
372
+
373
+                QueryRefundResponse queryRefundResponse=new QueryRefundResponse();
374
+
375
+                queryRefundResponse.setOrder_sn( (String) map.get("out_trade_no") );
376
+                queryRefundResponse.setTransaction_id(   (String) map.get("trade_no") );
377
+                queryRefundResponse.setTotal( (Integer) map.get("total_amount")  ); //总金额
378
+                //queryRefundResponse.setPayer_total( (Integer) map.get("total_amount")  );//支付金额
379
+                queryRefundResponse.setRefund((Integer) map.get("refund_amount")   ); //退款金额
380
+                queryRefundResponse.setRefund_id((String) map.get("trade_no")  );  //退款单号
381
+                queryRefundResponse.setOut_refund_no( (String) map.get("out_request_no")    );//退款订单号
382
+                //queryRefundResponse.setChannel(  (String) map.get("channel")  );  //通道
383
+                //queryRefundResponse.setUser_received_account(  (String) map.get("user_received_account") ); //账号
384
+                queryRefundResponse.setStatus(   (String) map.get("refund_status")  ); //状态
385
+                queryRefundResponse.setSuccess_time(  (String) map.get("gmt_refund_pay")  );
386
+                //queryRefundResponse.setCreate_time(  (String) map.get("gmt_refund_pay") );
387
+
388
+                queryRefundResponse.setExpand(map);
389
+                return queryRefundResponse;
390
+
391
+            } else {
392
+                log.error("调用失败");
393
+                return null;
394
+            }
395
+        }catch (Exception e){
396
+            e.printStackTrace();
397
+            //throw new TradeException("退款订单查询失败,订单号:"+ orderSn);
398
+            return null;
399
+        }
400
+    }
401
+
402
+    @Override
403
+    public String getOpenid(String code) {
404
+        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
405
+                alipayConfig.getAppId(), alipayConfig.getPrivateKey(), "json", "utf-8", alipayConfig.getPublicKey(), alipayConfig.getSignType());
406
+        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
407
+        request.setCode(code);
408
+        request.setGrantType("authorization_code");
409
+        try {
410
+            AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
411
+            return  oauthTokenResponse.getUserId();
412
+        } catch (AlipayApiException e) {
413
+            //处理异常
414
+            e.printStackTrace();
415
+            return "";
416
+        }
417
+    }
418
+
419
+
420
+    /**
421
+     * 获取支付宝连接
422
+     * 参考官网:https://opendocs.alipay.com/open/01csp3?ref=api#公钥模式加签
423
+     * 公钥模式加签
424
+     * @return
425
+     */
426
+    private AlipayClient getAliHttpClient(){
427
+        try {
428
+            com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig();
429
+            alipayConfig.setServerUrl(AlipayConstant.domain);
430
+            alipayConfig.setAppId(this.alipayConfig.getAppId());
431
+            alipayConfig.setPrivateKey(this.alipayConfig.getPrivateKey());
432
+            alipayConfig.setFormat("json");
433
+            alipayConfig.setCharset("utf-8");
434
+            alipayConfig.setAlipayPublicKey(this.alipayConfig.getPublicKey());
435
+            alipayConfig.setSignType(this.alipayConfig.getSignType());
436
+            //构造client
437
+            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
438
+            return alipayClient;
439
+        }catch (Exception e){
440
+            e.printStackTrace();
441
+            throw new TradeException("支付宝支付--初始化,校验系统参数失败");
442
+        }
443
+
444
+    }
445
+
446
+    /**
447
+     * 分转换为元
448
+     * @param fen
449
+     * @return
450
+     */
451
+    private String fenToYuan(int fen){
452
+        //转换为元
453
+        return BigDecimal.valueOf(fen).divide(new BigDecimal(100)  ).toString();
454
+    }
455
+
456
+    private int yuanToFen(String yuan){
457
+        return BigDecimal.valueOf(Double.valueOf(yuan)).multiply(new BigDecimal(100)).intValue();
458
+    }
459
+
460
+
461
+}

+ 124
- 0
pay/src/main/java/com/ruoyi/ali/AlipayElegentValid.java ファイルの表示

@@ -0,0 +1,124 @@
1
+package com.ruoyi.ali;
2
+
3
+
4
+import com.alipay.api.internal.util.AlipaySignature;
5
+import com.ruoyi.annotation.TradePlatform;
6
+import com.ruoyi.constant.Platform;
7
+import com.ruoyi.core.ElegentValid;
8
+import com.ruoyi.dto.ValidResponse;
9
+import com.ruoyi.exceptions.TradeException;
10
+import lombok.extern.slf4j.Slf4j;
11
+import org.springframework.beans.factory.annotation.Autowired;
12
+import org.springframework.http.HttpEntity;
13
+import org.springframework.stereotype.Service;
14
+
15
+import javax.servlet.http.HttpServletRequest;
16
+import java.util.HashMap;
17
+import java.util.Iterator;
18
+import java.util.Map;
19
+
20
+@Service
21
+@TradePlatform(Platform.ALI)
22
+@Slf4j
23
+public class AlipayElegentValid implements ElegentValid {
24
+
25
+
26
+    @Autowired
27
+    private AlipayConfig alipayConfig;
28
+
29
+
30
+    /**
31
+     * 订单回调结果通知验签
32
+     * 参考代码: https://opendocs.alipay.com/open/194/103296?ref=api  异步返回结果的验签
33
+     * @param httpEntity
34
+     * @param httpRequest
35
+     * @return
36
+     */
37
+    @Override
38
+    public ValidResponse validPay(HttpEntity<String> httpEntity, HttpServletRequest httpRequest) throws TradeException {
39
+        ValidResponse validResponse=new ValidResponse();
40
+        try {
41
+            Map<String, String> params = getParams(httpRequest);
42
+            //获取支付宝POST过来反馈信息,将异步通知中收到的待验证所有参数都存放到map中
43
+            //String body = httpEntity.getBody();
44
+            //调用SDK验证签名
45
+            //公钥验签示例代码
46
+            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getPublicKey(), "utf-8", alipayConfig.getSignType());
47
+            if (signVerified) {
48
+                validResponse.setValid(true);
49
+                validResponse.setOrderSn((String) params.get("out_trade_no"));
50
+                return validResponse;
51
+            } else {
52
+                validResponse.setValid(false);
53
+                validResponse.setOrderSn( (String) params.get("out_trade_no") );
54
+                return validResponse;
55
+            }
56
+        }catch (Exception e){
57
+            e.printStackTrace();
58
+            throw new TradeException("验签异常");
59
+        }
60
+    }
61
+
62
+    /**
63
+     * 退款结果通知验签
64
+     * 参考官网 https://opendocs.alipay.com/support/01ravh
65
+     * @param httpEntity
66
+     * @param httpRequest
67
+     * @return
68
+     * @throws TradeException
69
+     */
70
+    @Override
71
+    public ValidResponse validRefund(HttpEntity<String> httpEntity, HttpServletRequest httpRequest) throws TradeException {
72
+        ValidResponse validResponse=new ValidResponse();
73
+
74
+        try {
75
+            //获取支付宝POST过来反馈信息,将异步通知中收到的待验证所有参数都存放到map中
76
+            Map<String, String> params = getParams(httpRequest);
77
+            //调用SDK验证签名
78
+            //公钥验签示例代码
79
+            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getPublicKey(), "utf-8", alipayConfig.getSignType());
80
+            if (signVerified) {
81
+                validResponse.setValid(true);
82
+                validResponse.setOrderSn( (String) params.get("out_trade_no") );
83
+                return validResponse;
84
+            } else {
85
+                validResponse.setValid(false);
86
+                validResponse.setOrderSn( (String) params.get("out_trade_no") );
87
+                return validResponse;
88
+            }
89
+        }catch (Exception e){
90
+            e.printStackTrace();
91
+            validResponse.setValid(false);
92
+            return validResponse;
93
+        }
94
+    }
95
+
96
+    private Map<String,String> getParams(HttpServletRequest httpServletRequest){
97
+        Map<String,String> params = new HashMap< String , String >();
98
+        Map requestParams = httpServletRequest.getParameterMap();
99
+
100
+        for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();){
101
+            String name = (String)iter.next();
102
+            String[] values = (String [])requestParams.get(name);
103
+            String valueStr = "";
104
+            for(int i = 0;i < values.length;i ++ ){
105
+                valueStr =  (i==values.length-1)?valueStr + values [i]:valueStr + values[i] + ",";
106
+            }
107
+            //乱码解决,这段代码在出现乱码时使用。
108
+            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
109
+            params.put (name,valueStr);
110
+        }
111
+        log.info("params:{}",params);
112
+        return params;
113
+    }
114
+
115
+    @Override
116
+    public String successResult() {
117
+        return AlipayConstant.SUCCESS;
118
+    }
119
+
120
+    @Override
121
+    public String failResult() {
122
+        return AlipayConstant.FAIL;
123
+    }
124
+}

+ 20
- 0
pay/src/main/java/com/ruoyi/annotation/TradePlatform.java ファイルの表示

@@ -0,0 +1,20 @@
1
+package com.ruoyi.annotation;
2
+
3
+import java.lang.annotation.*;
4
+
5
+/**
6
+ * create by: wgl
7
+ * desc: 自定义支付平台注解,支付平台 微信:wx 支付宝:zfb
8
+ */
9
+@Documented
10
+@Retention(RetentionPolicy.RUNTIME)
11
+@Target({ElementType.TYPE})
12
+public @interface TradePlatform {
13
+
14
+    /**
15
+     * 平台的id
16
+     * Platform.WX
17
+     * @return
18
+     */
19
+    String value();
20
+}

+ 23
- 0
pay/src/main/java/com/ruoyi/config/CallbackConfig.java ファイルの表示

@@ -0,0 +1,23 @@
1
+package com.ruoyi.config;
2
+import lombok.Data;
3
+import org.springframework.beans.factory.annotation.Value;
4
+import org.springframework.boot.context.properties.ConfigurationProperties;
5
+import org.springframework.stereotype.Component;
6
+
7
+/**
8
+ * 微信权限对接类
9
+ */
10
+@Component
11
+@ConfigurationProperties("elegent.pay.callback")
12
+@Data
13
+public class CallbackConfig {
14
+
15
+    private String domain; //回调域名
16
+
17
+    @Value("${elegent.pay.callback.watch:false}")
18
+    private boolean watch; //是否开启监听
19
+
20
+    @Value("${elegent.pay.callback.cycle:10}")
21
+    private int cycle;//检查周期
22
+
23
+}

+ 11
- 0
pay/src/main/java/com/ruoyi/constant/PayConstant.java ファイルの表示

@@ -0,0 +1,11 @@
1
+package com.ruoyi.constant;
2
+
3
+public class PayConstant {
4
+
5
+    public final static String CALLBACK_PATH = "/payCallBack";
6
+
7
+    public final static String NOTIFY = "/notify";
8
+
9
+    public final static String  REFUND_NOTIFY = "/refund_notify";
10
+
11
+}

+ 16
- 0
pay/src/main/java/com/ruoyi/constant/Platform.java ファイルの表示

@@ -0,0 +1,16 @@
1
+package com.ruoyi.constant;
2
+
3
+/**
4
+ * Platform
5
+ * 支付方式
6
+*/
7
+public class Platform {
8
+    /**
9
+     * 微信
10
+     */
11
+    public final static String WX = "wxpay";
12
+    /**
13
+     * 支付宝
14
+     */
15
+    public final static String ALI = "alipay";
16
+}

+ 33
- 0
pay/src/main/java/com/ruoyi/constant/TradeType.java ファイルの表示

@@ -0,0 +1,33 @@
1
+package com.ruoyi.constant;
2
+
3
+import lombok.Data;
4
+
5
+/**
6
+ * 交易类型
7
+ */
8
+@Data
9
+public class TradeType {
10
+
11
+    /**
12
+     * native(扫码)
13
+     */
14
+    public final static String NATIVE = "native";
15
+
16
+    /**
17
+     * jsapi(小程序)
18
+     */
19
+    public final static String JSAPI = "jsapi";
20
+
21
+
22
+    /**
23
+     * app
24
+     */
25
+    public final static String APP = "app";
26
+
27
+
28
+    /**
29
+     * h5
30
+     */
31
+    public final static String H5 = "h5";
32
+
33
+}

+ 35
- 0
pay/src/main/java/com/ruoyi/core/CallBackServiceImpl.java ファイルの表示

@@ -0,0 +1,35 @@
1
+package com.ruoyi.core;
2
+
3
+import com.ruoyi.CallBackService;
4
+import lombok.extern.slf4j.Slf4j;
5
+
6
+/**
7
+ * 回调类
8
+ */
9
+@Slf4j
10
+public class CallBackServiceImpl implements CallBackService {
11
+
12
+
13
+    @Override
14
+    public void successPay(String orderSn) {
15
+        log.info("支付成功回调!"+orderSn);
16
+    }
17
+
18
+    @Override
19
+    public void failPay(String orderSn) {
20
+        log.info("支付失败回调!"+orderSn);
21
+    }
22
+
23
+
24
+    @Override
25
+    public void successRefund(String orderSn) {
26
+        log.info("退款成功回调!"+orderSn);
27
+    }
28
+
29
+    @Override
30
+    public void failRefund(String orderSn) {
31
+        log.info("退款失败回调!"+orderSn);
32
+    }
33
+
34
+
35
+}

+ 90
- 0
pay/src/main/java/com/ruoyi/core/CallbackController.java ファイルの表示

@@ -0,0 +1,90 @@
1
+package com.ruoyi.core;
2
+
3
+import com.ruoyi.CallBackService;
4
+import com.ruoyi.constant.PayConstant;
5
+import com.ruoyi.dto.ValidResponse;
6
+import lombok.extern.slf4j.Slf4j;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.http.HttpEntity;
9
+import org.springframework.web.bind.annotation.PathVariable;
10
+import org.springframework.web.bind.annotation.RequestMapping;
11
+import org.springframework.web.bind.annotation.RestController;
12
+
13
+import javax.servlet.http.HttpServletRequest;
14
+import javax.servlet.http.HttpServletResponse;
15
+
16
+/**
17
+ * CallbackController
18
+ * @description 系统默认提供的微信回调的Controller
19
+*/
20
+@RestController
21
+@Slf4j
22
+@RequestMapping(PayConstant.CALLBACK_PATH)
23
+public class CallbackController {
24
+
25
+    @Autowired
26
+    private CallBackService callBackService;
27
+
28
+    /**
29
+     * 系统提供的默认的微信回调的接口(支付回调)
30
+     * @param httpEntity
31
+     * @param response
32
+     * @return
33
+     */
34
+    @RequestMapping( PayConstant.NOTIFY + "/{platform}")
35
+    public String notify(HttpEntity<String> httpEntity, HttpServletRequest request, HttpServletResponse response, @PathVariable("platform") String platform){
36
+
37
+        ElegentValid elegentValid = ElegentLoader.getElegentValid(platform);  //获取验证器
38
+        try {
39
+            ValidResponse validResponse = elegentValid.validPay(httpEntity, request);//验证支付通知
40
+            String orderSn =validResponse.getOrderSn(); //订单号
41
+            if(validResponse.isValid()){  //返回码成功
42
+                callBackService.successPay(orderSn);
43
+                //返回成功消费
44
+                return elegentValid.successResult();
45
+            }else{
46
+                callBackService.failPay(orderSn);
47
+                return elegentValid.failResult();
48
+            }
49
+        }catch (Exception e){
50
+            log.error("支付回调处理失败",e);
51
+            //微信返回的状态非正常
52
+            return elegentValid.failResult();
53
+        }
54
+    }
55
+
56
+
57
+    /**
58
+     * 系统提供的默认的微信回调的接口(退款通知)
59
+     *
60
+     * @param httpEntity
61
+     * @param response
62
+     * @return
63
+     */
64
+    @RequestMapping( PayConstant.REFUND_NOTIFY + "/{platform}")
65
+    public String refundNotify(HttpEntity<String> httpEntity, HttpServletRequest request, HttpServletResponse response,@PathVariable("platform") String platform) {
66
+
67
+        ElegentValid elegentValid = ElegentLoader.getElegentValid(platform);  //获取验证器
68
+
69
+        try {
70
+            ValidResponse validResponse = elegentValid.validRefund(httpEntity, request);
71
+            String orderSn = validResponse.getOrderSn();
72
+            //订单号
73
+            if (validResponse.isValid()) {  //返回码成功
74
+                callBackService.successRefund(orderSn);
75
+                //返回成功消费
76
+                return elegentValid.successResult();
77
+            } else {
78
+                callBackService.failRefund(orderSn);
79
+                return elegentValid.failResult();
80
+            }
81
+        } catch (Exception e) {
82
+            log.error("退款回调处理失败", e);
83
+            //微信返回的状态非正常
84
+            return elegentValid.failResult();
85
+        }
86
+
87
+    }
88
+
89
+
90
+}

+ 73
- 0
pay/src/main/java/com/ruoyi/core/CallbackWatch.java ファイルの表示

@@ -0,0 +1,73 @@
1
+package com.ruoyi.core;
2
+
3
+
4
+
5
+import com.ruoyi.CallBackService;
6
+import com.ruoyi.ElegentPay;
7
+import com.ruoyi.config.CallbackConfig;
8
+import com.ruoyi.dto.QueryRefundResponse;
9
+import com.ruoyi.dto.QueryResponse;
10
+import com.ruoyi.dto.WatchDTO;
11
+import lombok.extern.slf4j.Slf4j;
12
+import org.springframework.beans.factory.annotation.Autowired;
13
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
14
+import org.springframework.stereotype.Component;
15
+import javax.annotation.PostConstruct;
16
+import java.util.Timer;
17
+import java.util.TimerTask;
18
+
19
+@Component
20
+@ConditionalOnProperty(prefix = "elegent.pay.callback",name = "watch",havingValue = "true")
21
+@Slf4j
22
+public class CallbackWatch {
23
+
24
+    @Autowired
25
+    private CallBackService callBackService;
26
+
27
+    @Autowired
28
+    private CallbackConfig callbackConfig;
29
+
30
+    @Autowired
31
+    private ElegentPay elegentPay;
32
+
33
+    @PostConstruct
34
+    public void queryWatch(){
35
+        if(callbackConfig.getCycle()<=0){
36
+            return;
37
+        }
38
+        //log.info("开启支付结果定期巡检");
39
+        Timer timer = new Timer();
40
+        // 2、创建 TimerTask 任务线程
41
+        TimerTask task=new TimerTask() {
42
+            @Override
43
+            public void run() {
44
+                try{
45
+                    //查询支付状态
46
+                    //log.info("支付状态定期巡检,{}",WatchList.payList);
47
+                    for( WatchDTO watchDTO: WatchList.payList ){
48
+                        //查询订单是否支付成功
49
+                        QueryResponse queryResponse = elegentPay.queryTradingOrderNo(watchDTO.getOrderSn(),watchDTO.getPlatform());
50
+                        if("SUCCESS".equals(queryResponse.getTrade_state())){
51
+                            callBackService.successPay(queryResponse.getOrder_sn());
52
+                            WatchList.payList.remove(watchDTO );
53
+                        }
54
+                    }
55
+                    //log.info("退款状态定期巡检,{}",WatchList.refundList);
56
+                    //查询退款状态
57
+                    for( WatchDTO watchDTO: WatchList.refundList ){
58
+                        //查询退款中订单
59
+                        QueryRefundResponse queryResponse = elegentPay.queryRefundTrading( watchDTO.getOrderSn(),watchDTO.getPlatform());
60
+                        if("SUCCESS".equals(queryResponse.getStatus())){
61
+                            callBackService.successRefund(queryResponse.getOrder_sn());
62
+                            WatchList.refundList.remove(watchDTO);
63
+                        }
64
+                    }
65
+                }catch (Exception ex){
66
+                }
67
+            }
68
+        };
69
+        // 4、启动定时任务
70
+        timer.schedule(task, callbackConfig.getCycle()*1000, callbackConfig.getCycle()*1000);
71
+    }
72
+
73
+}

+ 27
- 0
pay/src/main/java/com/ruoyi/core/ElegentConfig.java ファイルの表示

@@ -0,0 +1,27 @@
1
+package com.ruoyi.core;
2
+
3
+
4
+import com.ruoyi.CallBackService;
5
+import com.ruoyi.key.KeyManager;
6
+import com.ruoyi.key.impl.DefaultKeyManager;
7
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
8
+import org.springframework.context.annotation.Bean;
9
+import org.springframework.context.annotation.Configuration;
10
+
11
+@Configuration
12
+public class ElegentConfig {
13
+
14
+    @Bean
15
+    @ConditionalOnMissingBean
16
+    public CallBackService callBackService(){
17
+        return new CallBackServiceImpl();
18
+    }
19
+
20
+
21
+    @Bean
22
+    @ConditionalOnMissingBean
23
+    public KeyManager keyManager(){
24
+        return new DefaultKeyManager();
25
+    }
26
+
27
+}

+ 82
- 0
pay/src/main/java/com/ruoyi/core/ElegentLoader.java ファイルの表示

@@ -0,0 +1,82 @@
1
+package com.ruoyi.core;
2
+
3
+import com.ruoyi.annotation.TradePlatform;
4
+import com.ruoyi.exceptions.TradeException;
5
+import lombok.extern.slf4j.Slf4j;
6
+import org.springframework.beans.BeansException;
7
+import org.springframework.context.ApplicationContext;
8
+import org.springframework.context.ApplicationContextAware;
9
+import org.springframework.stereotype.Component;
10
+
11
+import java.util.Collection;
12
+import java.util.HashMap;
13
+import java.util.Map;
14
+
15
+/**
16
+ * PlatformLoader
17
+ * @description 第三方支付平台类加载器
18
+ * 服务启动的时候自动加载第三方支付组件
19
+*/
20
+@Component
21
+@Slf4j
22
+public class ElegentLoader implements ApplicationContextAware {
23
+
24
+    private static Map<String, ElegentTrade> elegentTradeMap = new HashMap<>();
25
+
26
+    private static Map<String, ElegentValid> elegentValidMap = new HashMap<>();
27
+
28
+    @Override
29
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
30
+
31
+        //加载所有的交易实现类
32
+        Collection<ElegentTrade> elegentTrades = applicationContext.getBeansOfType(ElegentTrade.class).values();
33
+        elegentTrades.stream().forEach(e->{
34
+            //通过反射拿到类上的平台注解
35
+            TradePlatform annotation = e.getClass().getAnnotation(TradePlatform.class);
36
+            if (annotation != null) {
37
+                elegentTradeMap.put(annotation.value(), e);
38
+            }
39
+        });
40
+
41
+        //加载所有的验证实现类
42
+        Collection<ElegentValid> elegentValids = applicationContext.getBeansOfType(ElegentValid.class).values();
43
+        elegentValids.stream().forEach(e->{
44
+            //通过反射拿到类上的平台注解
45
+            TradePlatform annotation = e.getClass().getAnnotation(TradePlatform.class);
46
+            if (annotation != null) {
47
+                elegentValidMap.put(annotation.value(), e);
48
+            }
49
+        });
50
+
51
+    }
52
+
53
+    /**
54
+     * 根据平台id获取具体的第三方平台
55
+     * @param platform 平台id
56
+     * @return
57
+     */
58
+    public static ElegentTrade getElegentTrade(String platform){
59
+        ElegentTrade elegentPayTemplate = elegentTradeMap.get(platform);
60
+        if(elegentPayTemplate!=null){
61
+            return elegentPayTemplate;
62
+        }else{
63
+            throw new TradeException("未找到适配的交易类型,交易平台id:"+platform);
64
+        }
65
+    }
66
+
67
+
68
+    /**
69
+     * 根据平台id获取具体的验证类
70
+     * @param platform 平台id
71
+     * @return
72
+     */
73
+    public static ElegentValid getElegentValid(String platform){
74
+        ElegentValid elegentValidTemplate = elegentValidMap.get(platform);
75
+        if(elegentValidTemplate!=null){
76
+            return elegentValidTemplate;
77
+        }else{
78
+            throw new TradeException("未找到适配的交易类型,交易平台id:"+platform);
79
+        }
80
+    }
81
+
82
+}

+ 136
- 0
pay/src/main/java/com/ruoyi/core/ElegentPayImpl.java ファイルの表示

@@ -0,0 +1,136 @@
1
+package com.ruoyi.core;
2
+import com.ruoyi.ElegentPay;
3
+import com.ruoyi.config.CallbackConfig;
4
+import com.ruoyi.dto.*;
5
+import com.ruoyi.exceptions.TradeException;
6
+import org.springframework.beans.factory.annotation.Autowired;
7
+import org.springframework.stereotype.Component;
8
+
9
+/**
10
+ * ElegentPayTemplate
11
+ * @description 统一模板 在模板层进行第三方平台的选择
12
+*/
13
+@Component
14
+public class ElegentPayImpl implements ElegentPay {
15
+
16
+    @Autowired
17
+    private CallbackConfig callbackConfig;
18
+
19
+    /**
20
+     * 统一下单接口
21
+     * @param payRequest
22
+     * @return
23
+     */
24
+    @Override
25
+    public PayResponse requestPay(PayRequest payRequest, String tradeType, String platform) throws TradeException {
26
+        //获取交易策略
27
+        PayResponse payResponse = getPlatFormService(platform).requestPay(payRequest, tradeType);
28
+
29
+        //加入监听列表
30
+        if(callbackConfig.isWatch()){
31
+            WatchDTO watchDTO=new WatchDTO();
32
+            watchDTO.setOrderSn(payRequest.getOrderSn());
33
+            watchDTO.setPlatform(platform);
34
+            WatchList.payList.add( watchDTO );
35
+        }
36
+        return payResponse;
37
+    }
38
+
39
+
40
+    /**
41
+     * 关闭订单
42
+     * @param orderSn
43
+     * @param platform
44
+     * @return
45
+     * @throws Exception
46
+     */
47
+    @Override
48
+    public Boolean closePay(String orderSn, String platform) throws TradeException {
49
+        //调用对应第三方的创建订单接口
50
+        Boolean aBoolean = getPlatFormService(platform).closePay(orderSn);
51
+        //加入监听列表
52
+        if(callbackConfig.isWatch()){
53
+            WatchDTO watchDTO=new WatchDTO();
54
+            watchDTO.setOrderSn(orderSn);
55
+            watchDTO.setPlatform(platform);
56
+            WatchList.payList.remove( watchDTO );
57
+        }
58
+
59
+        return aBoolean;
60
+    }
61
+
62
+    /**
63
+     * 退款方法
64
+     * @param refundRequest
65
+     * @return
66
+     * @throws Exception
67
+     */
68
+    @Override
69
+    public Boolean refund(RefundRequest refundRequest, String platform) throws TradeException {
70
+        Boolean refund = getPlatFormService(platform).refund(refundRequest);
71
+        //加入监听列表
72
+        if(callbackConfig.isWatch()  && refund){
73
+            WatchDTO watchDTO=new WatchDTO();
74
+            watchDTO.setOrderSn(refundRequest.getRequestNo());
75
+            watchDTO.setPlatform(platform);
76
+            WatchList.refundList.add( watchDTO );
77
+        }
78
+        return refund;
79
+    }
80
+
81
+
82
+    /**
83
+     * 手动查询订单的方法
84
+     * 商户订单号查询 根据订单号查询订单
85
+     * 该接口基于生成的订单号来进行订单的查询
86
+     * 可以基于查询的结果判断用户订单是否支付成功
87
+     * @param orderSn
88
+     * @param Platform
89
+     * @return
90
+     * @throws Exception
91
+     */
92
+    @Override
93
+    public QueryResponse queryTradingOrderNo(String  orderSn , String Platform) throws TradeException {
94
+        //调用具体第三方的退款接口
95
+        return getPlatFormService(Platform).queryTradingOrderNo(orderSn);
96
+    }
97
+
98
+
99
+    /**
100
+     * 查询退款单号
101
+     *
102
+     * @return
103
+     * @throws Exception
104
+     */
105
+    @Override
106
+    public QueryRefundResponse queryRefundTrading(String orderSn , String platform) throws TradeException {
107
+        //获取请求参数
108
+        return getPlatFormService(platform).queryRefundTrading(orderSn);
109
+    }
110
+
111
+    /**
112
+     * 获得openId
113
+     * @param code
114
+     * @param platform
115
+     * @return
116
+     */
117
+    @Override
118
+    public String getOpenid(String code, String platform) {
119
+        return getPlatFormService(platform).getOpenid(code);
120
+    }
121
+
122
+/**
123
+ * ====================================提供的模板类需要使用的方法=====================================
124
+ */
125
+
126
+
127
+    /**
128
+     * 跟进具体内容获取实现类的方法
129
+     * @param platForm
130
+     * @return
131
+     */
132
+    private ElegentTrade getPlatFormService(String platForm) {
133
+        return ElegentLoader.getElegentTrade(platForm);
134
+    }
135
+
136
+}

+ 54
- 0
pay/src/main/java/com/ruoyi/core/ElegentTrade.java ファイルの表示

@@ -0,0 +1,54 @@
1
+package com.ruoyi.core;
2
+
3
+
4
+import com.ruoyi.dto.*;
5
+import com.ruoyi.exceptions.TradeException;
6
+
7
+public interface ElegentTrade {
8
+
9
+
10
+    /**
11
+     * 单独的创建本地支付订单接口
12
+     * 该接口基于设计模式实现,对接了微信V3版支付代码和支付宝支付sdk
13
+     * 业务编写人员仅仅只需要准备好请求参数调用该方法即可完成下单请求
14
+     * @return 交易数据对象 包含有native支付的二维码+jsApi支付的支付组件
15
+     */
16
+    PayResponse requestPay(PayRequest payRequest, String tradeType) throws TradeException;
17
+
18
+    /**
19
+     * 关闭订单
20
+     * 该结构基于设计模式实现,对接了微信V3版支付代码和支付宝支付sdk
21
+     * 业务编写人员在处理超时订单的时候需要 通知微信 由于是超时订单需要进行远程关闭
22
+     */
23
+    Boolean closePay(String orderSn) throws TradeException;
24
+
25
+    /**
26
+     * 退款s申请
27
+     * 该接口基于设计模式实现,对接了微信V3版支付代码和支付宝支付sdk
28
+     * 业务编写人员在处理业务执行失败时需要进行退款
29
+     */
30
+    Boolean refund(RefundRequest refundRequest) throws TradeException;
31
+
32
+    /**
33
+     * 商户订单号查询 根据订单号查询订单
34
+     * 该接口基于生成的订单号来进行订单的查询
35
+     * 可以基于查询的结果判断用户订单是否支付成功
36
+     */
37
+    QueryResponse queryTradingOrderNo(String orderSn) throws TradeException;
38
+
39
+
40
+    /**
41
+     * 查询单笔退款API
42
+     *
43
+     */
44
+    QueryRefundResponse queryRefundTrading(String orderSn) throws TradeException;
45
+
46
+
47
+    /**
48
+     * 获得openId
49
+     * @param code
50
+     * @return
51
+     */
52
+    String getOpenid(String code);
53
+
54
+}

+ 48
- 0
pay/src/main/java/com/ruoyi/core/ElegentValid.java ファイルの表示

@@ -0,0 +1,48 @@
1
+package com.ruoyi.core;
2
+
3
+
4
+import com.ruoyi.dto.ValidResponse;
5
+import com.ruoyi.exceptions.TradeException;
6
+import org.springframework.http.HttpEntity;
7
+
8
+import javax.servlet.http.HttpServletRequest;
9
+
10
+/**
11
+ * 验证器接口
12
+ *
13
+ */
14
+public interface ElegentValid {
15
+
16
+
17
+    /**
18
+     * 支付结果通知校验
19
+     * 该接口基于设计模式实现,对接了微信V3版支付代码和支付宝支付sdk
20
+     * 业务编写人员在接收到微信或支付宝回调的时候可以使用该方法验证回调是否成功,是否是伪回调
21
+     * @return 交易数据对象
22
+     */
23
+    ValidResponse validPay(HttpEntity<String> httpEntity, HttpServletRequest request) throws TradeException;
24
+
25
+
26
+
27
+    /**
28
+     * 退款结果通知校验
29
+     * 该接口基于设计模式实现,对接了微信V3版支付代码和支付宝支付sdk
30
+     * 业务编写人员在接收到微信或支付宝回调的时候可以使用该方法验证回调是否成功,是否是伪回调
31
+     */
32
+    ValidResponse validRefund(HttpEntity<String> httpEntity, HttpServletRequest request) throws TradeException;
33
+
34
+
35
+    /**
36
+     * 成功返回结构
37
+     * @return
38
+     */
39
+    String successResult();
40
+
41
+
42
+    /**
43
+     * 失败返回内容
44
+     * @return
45
+     */
46
+    String failResult();
47
+
48
+}

+ 20
- 0
pay/src/main/java/com/ruoyi/core/WatchList.java ファイルの表示

@@ -0,0 +1,20 @@
1
+package com.ruoyi.core;
2
+
3
+
4
+
5
+import com.ruoyi.dto.WatchDTO;
6
+
7
+import java.util.concurrent.CopyOnWriteArraySet;
8
+
9
+/**
10
+ * 监听列表
11
+ */
12
+public class WatchList {
13
+
14
+
15
+
16
+    public static CopyOnWriteArraySet<WatchDTO> payList=new CopyOnWriteArraySet<>(); //支付中列表
17
+
18
+    public static CopyOnWriteArraySet<WatchDTO> refundList=new CopyOnWriteArraySet<>();  //退款中列表
19
+
20
+}

+ 20
- 0
pay/src/main/java/com/ruoyi/dto/PayRequest.java ファイルの表示

@@ -0,0 +1,20 @@
1
+package com.ruoyi.dto;
2
+
3
+
4
+import lombok.Data;
5
+
6
+/**
7
+ * PayRequest
8
+ * 支付请求外观类
9
+*/
10
+@Data
11
+public class PayRequest {
12
+
13
+    private String body;//商品描述
14
+
15
+    private String orderSn; //订单号
16
+
17
+    private int totalFee; //订单金额
18
+
19
+    private String openid;//openId
20
+}

+ 29
- 0
pay/src/main/java/com/ruoyi/dto/PayResponse.java ファイルの表示

@@ -0,0 +1,29 @@
1
+package com.ruoyi.dto;
2
+
3
+import lombok.Data;
4
+
5
+import java.util.Map;
6
+
7
+/**
8
+ * 结果统一封装类
9
+ */
10
+@Data
11
+public class PayResponse {
12
+
13
+    private boolean success;  //是否成功
14
+
15
+    private String message;//信息
16
+
17
+    private String order_sn;//订单编号
18
+
19
+    private Map<String,String>  expand;//扩展属性
20
+
21
+    private String code_url;//二维码连接(native返回)
22
+
23
+    private String prepay_id;//预支付Id(小程序返回)
24
+
25
+    private String h5_url;//支付跳转链接
26
+
27
+    private Map<String,String>  jsapiData;//小程序返回
28
+
29
+}

+ 24
- 0
pay/src/main/java/com/ruoyi/dto/QueryRefundResponse.java ファイルの表示

@@ -0,0 +1,24 @@
1
+package com.ruoyi.dto;
2
+
3
+import lombok.Data;
4
+
5
+@Data
6
+public class QueryRefundResponse extends QueryResponse{
7
+
8
+
9
+    private String refund_id;  //微信支付退款单号
10
+
11
+    private String out_refund_no;//商户退款单号
12
+
13
+    private String channel;//退款渠道
14
+
15
+    private String user_received_account;//退款账号
16
+
17
+    private String success_time;//退款成功时间
18
+
19
+    private String status;//退款状态
20
+
21
+    private int refund;//退款金额
22
+
23
+
24
+}

+ 25
- 0
pay/src/main/java/com/ruoyi/dto/QueryResponse.java ファイルの表示

@@ -0,0 +1,25 @@
1
+package com.ruoyi.dto;
2
+
3
+import lombok.Data;
4
+
5
+import java.util.Map;
6
+
7
+/**
8
+ * 查询响应对象
9
+ */
10
+@Data
11
+public class QueryResponse {
12
+
13
+    private String openid;//用户id
14
+
15
+    private String trade_state;//交易状态
16
+
17
+    private String order_sn;//订单号
18
+
19
+    private String transaction_id;//交易单号
20
+
21
+    private int total;//金额
22
+
23
+    private Map expand;//扩展(全部的返回数据)
24
+
25
+}

+ 16
- 0
pay/src/main/java/com/ruoyi/dto/RefundRequest.java ファイルの表示

@@ -0,0 +1,16 @@
1
+package com.ruoyi.dto;
2
+
3
+import lombok.Data;
4
+
5
+@Data
6
+public class RefundRequest {
7
+
8
+    private int totalFee; //订单金额
9
+
10
+    private int refundAmount; //退款金额
11
+
12
+    private String orderSn; //订单号
13
+
14
+    private String requestNo; //退款请求号,做退款幂等性校验,当部分退款时必须给出
15
+
16
+}

+ 15
- 0
pay/src/main/java/com/ruoyi/dto/ValidResponse.java ファイルの表示

@@ -0,0 +1,15 @@
1
+package com.ruoyi.dto;
2
+
3
+import lombok.Data;
4
+
5
+/**
6
+ * 验证签名
7
+ */
8
+@Data
9
+public class ValidResponse {
10
+
11
+    private boolean isValid;// 是否通过验签
12
+
13
+    private String orderSn;// 订单号
14
+
15
+}

+ 12
- 0
pay/src/main/java/com/ruoyi/dto/WatchDTO.java ファイルの表示

@@ -0,0 +1,12 @@
1
+package com.ruoyi.dto;
2
+
3
+import lombok.Data;
4
+
5
+@Data
6
+public class WatchDTO {
7
+
8
+    private String orderSn; //订单号
9
+
10
+    private String platform;//平台
11
+
12
+}

+ 24
- 0
pay/src/main/java/com/ruoyi/exceptions/TradeException.java ファイルの表示

@@ -0,0 +1,24 @@
1
+package com.ruoyi.exceptions;
2
+
3
+import lombok.Getter;
4
+import lombok.Setter;
5
+
6
+/**
7
+ * 交易SDK提供的总的异常
8
+ */
9
+@Getter
10
+@Setter
11
+public class TradeException extends RuntimeException{
12
+    private String code;
13
+    private String msg;
14
+
15
+    public TradeException(String code, String msg) {
16
+        super(msg);
17
+        this.code = code;
18
+        this.msg = msg;
19
+    }
20
+
21
+    public TradeException(String msg) {
22
+        super(msg);
23
+    }
24
+}

+ 16
- 0
pay/src/main/java/com/ruoyi/key/KeyManager.java ファイルの表示

@@ -0,0 +1,16 @@
1
+package com.ruoyi.key;
2
+
3
+/**
4
+ * 密钥管理器接口
5
+ */
6
+public interface KeyManager {
7
+
8
+
9
+    /**
10
+     * 根据名字获取key字符串
11
+     * @param name
12
+     * @return
13
+     */
14
+    String getKey(String name);
15
+
16
+}

+ 19
- 0
pay/src/main/java/com/ruoyi/key/impl/DefaultKeyManager.java ファイルの表示

@@ -0,0 +1,19 @@
1
+package com.ruoyi.key.impl;
2
+
3
+
4
+import com.ruoyi.key.KeyManager;
5
+import com.ruoyi.util.FileUtil;
6
+
7
+/**
8
+ * 默认的key管理器-文件管理器
9
+ */
10
+public class DefaultKeyManager implements KeyManager {
11
+
12
+
13
+    @Override
14
+    public String getKey(String name) {
15
+        return FileUtil.readToStr(name);
16
+    }
17
+
18
+
19
+}

+ 37
- 0
pay/src/main/java/com/ruoyi/util/FileUtil.java ファイルの表示

@@ -0,0 +1,37 @@
1
+package com.ruoyi.util;
2
+
3
+import java.io.ByteArrayOutputStream;
4
+import java.io.IOException;
5
+import java.io.InputStream;
6
+
7
+/**
8
+ * 文件读取类
9
+ */
10
+public class FileUtil {
11
+
12
+
13
+    /**
14
+     * 获取文件内容
15
+     * @param fileName
16
+     * @return
17
+     */
18
+    public static String readToStr(String fileName){
19
+        InputStream is = FileUtil.class.getClassLoader().getResourceAsStream(fileName);
20
+        ByteArrayOutputStream os = new ByteArrayOutputStream(2048);
21
+        byte[] buffer = new byte[1024];
22
+
23
+        String str;
24
+        try {
25
+            int length;
26
+            while((length = is.read(buffer)) != -1) {
27
+                os.write(buffer, 0, length);
28
+            }
29
+
30
+            str = os.toString("UTF-8");
31
+        } catch (IOException var5) {
32
+            throw new IllegalArgumentException("无效的密钥", var5);
33
+        }
34
+        return str;
35
+    }
36
+
37
+}

+ 459
- 0
pay/src/main/java/com/ruoyi/wx/WxPayElegentTrade.java ファイルの表示

@@ -0,0 +1,459 @@
1
+package com.ruoyi.wx;
2
+
3
+
4
+import cn.hutool.core.util.CharsetUtil;
5
+import cn.hutool.core.util.IdUtil;
6
+import cn.hutool.core.util.StrUtil;
7
+import com.alibaba.fastjson.JSON;
8
+import com.ruoyi.annotation.TradePlatform;
9
+import com.ruoyi.config.CallbackConfig;
10
+import com.ruoyi.constant.PayConstant;
11
+import com.ruoyi.constant.Platform;
12
+import com.ruoyi.core.ElegentTrade;
13
+import com.ruoyi.dto.*;
14
+import com.ruoyi.exceptions.TradeException;
15
+import com.ruoyi.util.FileUtil;
16
+import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
17
+import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
18
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
19
+import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
20
+import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
21
+import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
22
+import lombok.extern.slf4j.Slf4j;
23
+import org.apache.http.client.methods.CloseableHttpResponse;
24
+import org.apache.http.client.methods.HttpGet;
25
+import org.apache.http.client.methods.HttpPost;
26
+import org.apache.http.client.utils.URIBuilder;
27
+import org.apache.http.entity.StringEntity;
28
+import org.apache.http.impl.client.CloseableHttpClient;
29
+import org.apache.http.util.EntityUtils;
30
+import org.springframework.beans.factory.annotation.Autowired;
31
+import org.springframework.stereotype.Component;
32
+import org.springframework.web.client.RestTemplate;
33
+
34
+import java.io.ByteArrayInputStream;
35
+import java.io.IOException;
36
+import java.net.URISyntaxException;
37
+import java.security.PrivateKey;
38
+import java.security.Signature;
39
+import java.util.Base64;
40
+import java.util.HashMap;
41
+import java.util.Map;
42
+
43
+@Component
44
+@Slf4j
45
+@TradePlatform(Platform.WX)
46
+public class WxPayElegentTrade implements ElegentTrade {
47
+
48
+    @Autowired
49
+    private WxpayConfig wxpayConfig;
50
+
51
+    @Autowired
52
+    private CallbackConfig callbackConfig;
53
+
54
+    /**
55
+     * 创建微信支付订单方法
56
+     * 这里参考官网代码:
57
+     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml   Native下单
58
+     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml   JSAPI 下单
59
+     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_1.shtml   H5下单
60
+     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml   APP下单
61
+     * @param payRequest 支付请求
62
+     * @return 支付响应
63
+     * @throws IOException
64
+     */
65
+    @Override
66
+    public PayResponse requestPay(PayRequest payRequest, String tradeType)throws TradeException {
67
+        PayResponse payResponse = new PayResponse(); //返回结果
68
+        try {
69
+            // 请求body参数构建
70
+            Map<String, Object> params = new HashMap<String, Object>() {
71
+                {
72
+                    put("mchid", wxpayConfig.getMchId());
73
+                    put("appid", wxpayConfig.getAppId());
74
+                    put("notify_url", callbackConfig.getDomain()+ PayConstant.CALLBACK_PATH + PayConstant.NOTIFY +"/"+ Platform.WX );
75
+                    put("out_trade_no", payRequest.getOrderSn());
76
+                    put("amount", new HashMap<String, Object>() {
77
+                        {
78
+                            put("total", payRequest.getTotalFee());//金额,单位:分
79
+                            put("currency", "CNY");//人民币
80
+                        }
81
+                    });
82
+                    put("description", payRequest.getBody());
83
+                }
84
+            };
85
+
86
+            if("h5".equals(tradeType)){ //h5
87
+                params.put("scene_info", new HashMap<String, Object>() {
88
+                    {
89
+                        put("payer_client_ip", "127.0.0.1");
90
+                        put("h5_info", new HashMap<String, Object>() {
91
+                            {
92
+                                put("type", "Wap");
93
+                            }
94
+                        });
95
+                    }
96
+                });
97
+            }
98
+            if ("jsapi".equals(tradeType)) {  //如果是小程序支付
99
+                params.put("payer", new HashMap<String, Object>() {
100
+                    {
101
+                        put("openid", payRequest.getOpenid());
102
+                    }
103
+                });
104
+            }
105
+
106
+
107
+            String url = WxpayConstant.createOrder + tradeType; //创建订单
108
+            log.info("elegent-pay 请求参数{}",params);
109
+            Map<String, String> map = postApiTemplate(url, params);
110
+
111
+            if("SUCCESS".equals( map.get("code") )){
112
+                payResponse.setOrder_sn(payRequest.getOrderSn());
113
+                payResponse.setSuccess(true);
114
+                payResponse.setCode_url(map.get("code_url"));
115
+                payResponse.setMessage(map.get("message"));
116
+
117
+                payResponse.setPrepay_id(map.get("prepay_id"));
118
+                payResponse.setH5_url( map.get("h5_url") );
119
+
120
+                payResponse.setExpand(map); //全部数据
121
+
122
+                if("jsapi".equals(tradeType)){//如果是小程序,需要封装到Expand
123
+                    Map<String, String> data=new HashMap<>();
124
+                    String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
125
+                    String nonceStr = IdUtil.simpleUUID();
126
+                    String packages = "prepay_id=" + payResponse.getPrepay_id();
127
+                    String privateKey = FileUtil.readToStr("wxpay_private.key");
128
+                    String paySign = this.createPaySign(wxpayConfig.getAppId(), timeStamp, nonceStr, packages, privateKey);
129
+                    data.put("appId", wxpayConfig.getAppId());// appid
130
+                    data.put("timeStamp", timeStamp);// 时间戳
131
+                    data.put("nonceStr", nonceStr);// 随机字符串
132
+                    data.put("package","prepay_id="+payResponse.getPrepay_id());
133
+                    data.put("signType", "RSA");// 签名类型,默认为RSA,仅支持RSA
134
+                    data.put("paySign", paySign);// 签名
135
+                    data.put("orderNo",payRequest.getOrderSn());
136
+                    payResponse.setJsapiData(data);
137
+                }
138
+
139
+
140
+                log.info("createOrder: {}", payResponse);
141
+
142
+            }else{
143
+                payResponse.setSuccess(false);
144
+                payResponse.setMessage( map.get("message") );
145
+            }
146
+            return payResponse;
147
+        }catch (Exception e){
148
+            e.printStackTrace();
149
+            payResponse.setSuccess(false);
150
+        }
151
+        return payResponse;
152
+    }
153
+
154
+
155
+    /**
156
+     * 关闭订单
157
+     * 参考官网代码
158
+     * https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_2.shtml 3.2.5. 【服务端】关闭订单
159
+     * @return
160
+     */
161
+    @Override
162
+    public Boolean closePay(String orderSn) throws TradeException {
163
+        // 请求body参数构建
164
+        Map<String, Object> params = new HashMap<String, Object>();
165
+        params.put("mchid", wxpayConfig.getMchId());
166
+        String url = WxpayConstant.closeOrder.replaceAll("\\{out_trade_no\\}",orderSn);
167
+        Map map = postApiTemplate(url, params);
168
+        if("SUCCESS".equals(  map.get("code"))){
169
+            return true;
170
+        }else{
171
+            return false;
172
+        }
173
+    }
174
+
175
+
176
+    /**
177
+     * 退款
178
+     * 参考官网代码 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_9.shtml
179
+     * @param refundRequest
180
+     * @return
181
+     */
182
+    @Override
183
+    public Boolean refund(RefundRequest refundRequest) {
184
+        // 请求body参数构建
185
+        // 请求body参数构建
186
+        Map<String, Object> params = new HashMap<String, Object>();
187
+        params.put("notify_url", callbackConfig.getDomain()+ PayConstant.CALLBACK_PATH +PayConstant.REFUND_NOTIFY +"/"+ Platform.WX    );  //回调地址
188
+        params.put("out_trade_no", refundRequest.getOrderSn());//订单编号
189
+        //out_refund_no
190
+        params.put("out_refund_no", refundRequest.getRequestNo());//退款申请单编号  (多次退款需要不一样才行)
191
+        params.put("amount", new HashMap<String, Object>() {
192
+            {
193
+                put("refund",refundRequest.getRefundAmount());//退款金额
194
+                put("total", refundRequest.getTotalFee());//原金额,单位:分
195
+                put("currency", "CNY");//人民币
196
+            }
197
+        });
198
+        String url = WxpayConstant.refund;  //创建订单
199
+        Map map = postApiTemplate(url, params);
200
+        if("SUCCESS".equals(  map.get("code"))){
201
+
202
+            return true;
203
+        }else{
204
+            return false;
205
+        }
206
+    }
207
+
208
+
209
+
210
+    /**
211
+     * 手动查询订单
212
+     * 参考官网代码: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_2.shtml   3.2.4. 【服务端】查询订单
213
+     * @param orderSn
214
+     * @return
215
+     */
216
+    @Override
217
+    public QueryResponse queryTradingOrderNo(String orderSn) throws TradeException {
218
+        // 请求body参数构建
219
+        Map<String, String> params = new HashMap<String, String>();
220
+        params.put("mchid", wxpayConfig.getMchId());
221
+        String url = WxpayConstant.queryOrderNo+orderSn;;
222
+        try {
223
+            Map map = getApiTemplate(url, params);
224
+            QueryResponse queryResponse=new QueryResponse();
225
+            queryResponse.setOrder_sn((String)map.get("out_trade_no")  ); //订单号
226
+            queryResponse.setTransaction_id((String)map.get("transaction_id") ); //交易单类型
227
+            queryResponse.setTrade_state(   (String) map.get("trade_state") );//交易状态
228
+            Map amount = (Map)map.get("amount");
229
+            if(amount!=null){
230
+                queryResponse.setTotal( (Integer) amount.get("total")  ); //总金额
231
+            }
232
+            Map payer= (Map)map.get("payer");
233
+            if(payer!=null){
234
+                queryResponse.setOpenid(  (String)payer.get("openid")  );
235
+            }
236
+            queryResponse.setExpand(map);//全部数据
237
+            return queryResponse;
238
+
239
+        } catch (URISyntaxException e) {
240
+            throw new RuntimeException(e);
241
+        } catch (IOException e) {
242
+            throw new RuntimeException(e);
243
+        }
244
+
245
+    }
246
+
247
+
248
+    /**
249
+     * 查询退款订单
250
+     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_10.shtml
251
+     * @param out_refund_no
252
+     * @return
253
+     * @throws TradeException
254
+     */
255
+    @Override
256
+    public QueryRefundResponse queryRefundTrading(String out_refund_no) throws TradeException {
257
+
258
+        // 请求body参数构建
259
+        Map<String, String> params = new HashMap<String, String>();
260
+        String url = WxpayConstant.queryRufundOrderNo + out_refund_no;
261
+        try {
262
+            Map map = getApiTemplate(url, params);
263
+            QueryRefundResponse queryRefundResponse=new QueryRefundResponse();
264
+            queryRefundResponse.setOrder_sn( (String) map.get("out_trade_no") );
265
+            queryRefundResponse.setTransaction_id(   (String) map.get("transaction_id") );
266
+            Map amount = (Map)map.get("amount");
267
+            queryRefundResponse.setTotal( (Integer) amount.get("total")  ); //总金额
268
+            queryRefundResponse.setRefund((Integer) amount.get("payer_refund")   ); //退款金额
269
+            queryRefundResponse.setRefund_id((String) map.get("refund_id")  );  //退款单号
270
+            queryRefundResponse.setOut_refund_no( (String) map.get("out_refund_no")    );//退款订单号
271
+
272
+            queryRefundResponse.setChannel(  (String) map.get("channel")  );  //通道
273
+            queryRefundResponse.setUser_received_account(  (String) map.get("user_received_account") ); //账号
274
+            queryRefundResponse.setStatus(   (String) map.get("status")  ); //状态
275
+            queryRefundResponse.setSuccess_time(  (String) map.get("success_time")  );
276
+            queryRefundResponse.setExpand(map);
277
+            return queryRefundResponse;
278
+        } catch (URISyntaxException e) {
279
+            throw new RuntimeException(e);
280
+        } catch (IOException e) {
281
+            throw new RuntimeException(e);
282
+        }
283
+    }
284
+
285
+    @Override
286
+    public String getOpenid(String code) {
287
+        String getOpenIdUrl = "https://api.weixin.qq.com/sns/jscode2session?" +
288
+                "appid="+wxpayConfig.getAppId()
289
+                +"&secret="+wxpayConfig.getAppSecret()
290
+                +"&js_code="+code+"&grant_type=authorization_code";
291
+        RestTemplate restTemplate = new RestTemplate();
292
+        String respResult = restTemplate.getForObject(getOpenIdUrl,String.class);
293
+        log.info("获取openid的url:{},respResult:{}",getOpenIdUrl,respResult);
294
+        if( respResult==null || "".equals(respResult)  ) return "";
295
+        try{
296
+
297
+            Map<String,String> map = JSON.parseObject(respResult, Map.class);
298
+            String errorCode = map.get("errcode") ;
299
+            if(errorCode!=null && !"".equals(errorCode)){
300
+                int errorCodeInt = Integer.valueOf(errorCode).intValue();
301
+
302
+                log.info("获取openid的errorCode,{}",errorCodeInt);
303
+                if(errorCodeInt != 0) return "";
304
+            }
305
+            return map.get("openid");
306
+        }catch (Exception ex){
307
+            ex.printStackTrace();
308
+            return "";
309
+        }
310
+    }
311
+
312
+
313
+    private Map getApiTemplate(String url, Map<String, String> params) throws URISyntaxException, IOException {
314
+        URIBuilder uriBuilder = new URIBuilder(url);
315
+        //添加参数
316
+        for (String key : params.keySet()) {
317
+            uriBuilder.addParameter(key, params.get(key));
318
+        }
319
+        //完成签名并执行请求
320
+        HttpGet httpGet = new HttpGet(uriBuilder.build());
321
+        httpGet.addHeader("Accept", "application/json");
322
+        CloseableHttpClient httpClient = getWxHttpClient();
323
+        CloseableHttpResponse response = httpClient.execute(httpGet);
324
+        return responseTemplate(response);
325
+    }
326
+
327
+
328
+    private Map responseTemplate(CloseableHttpResponse response) {
329
+        Map result = null;
330
+        try {
331
+            int statusCode = response.getStatusLine().getStatusCode();
332
+            if (statusCode == 200) { //处理成功
333
+               // log.info("success,return body = " + EntityUtils.toString(response.getEntity()));
334
+                result = JSON.parseObject(EntityUtils.toString(response.getEntity()), Map.class);
335
+                result.put("code", "SUCCESS");
336
+            } else if (statusCode == 204) { //处理成功,无返回Body
337
+                log.info("success");
338
+                result = new HashMap<String, Object>() {
339
+                    {
340
+                        put("code", "SUCCESS");
341
+                    }
342
+                };
343
+            } else {
344
+                String returnBody = EntityUtils.toString(response.getEntity());
345
+                log.error("failed,resp code = " + statusCode + ",return body = " + returnBody);
346
+                //throw new TradeException("创建本地支付订单失败!"+payDTO.getOrderSn());
347
+                Map<String, String> map = JSON.parseObject(returnBody, Map.class);
348
+                result = new HashMap<String, Object>() {
349
+                    {
350
+                        put("code", "FAIL");
351
+                        put("message", map.get("message"));
352
+                    }
353
+                };
354
+            }
355
+        } catch (Exception e) {
356
+            result = new HashMap<String, Object>() {
357
+                {
358
+                    put("code", "FAIL");
359
+                    put("message", e.getMessage());
360
+                }
361
+            };
362
+        } finally {
363
+            closeConnect(response);
364
+            return result;
365
+        }
366
+    }
367
+
368
+    private Map postApiTemplate(String url, Map<String, Object> params) {
369
+        try {
370
+            HttpPost httpPost = new HttpPost(url);
371
+            StringEntity entity = new StringEntity(JSON.toJSONString(params));
372
+            entity.setContentType("application/json");
373
+            httpPost.setEntity(entity);
374
+            httpPost.setHeader("Accept", "application/json");
375
+            //完成签名并执行请求
376
+            CloseableHttpClient httpClient = getWxHttpClient();
377
+            CloseableHttpResponse response = httpClient.execute(httpPost);
378
+            return responseTemplate( response );
379
+        } catch (IOException e) {
380
+            throw new RuntimeException(e);
381
+        }
382
+
383
+    }
384
+
385
+
386
+    /**
387
+     * 获取微信HTTP连接
388
+     *
389
+     * @return
390
+     */
391
+    private CloseableHttpClient getWxHttpClient() {
392
+        try {
393
+            //这里对秘钥进行加密使用的完全是官网上的代码
394
+            //TODO 参考官网代码 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_6_2.shtml
395
+            // 加载商户私钥(privateKey:私钥字符串)
396
+            String key = FileUtil.readToStr("wxpay_private.key");
397
+
398
+            PrivateKey merchantPrivateKey = PemUtil
399
+                    .loadPrivateKey(new ByteArrayInputStream(key.getBytes("utf-8")));
400
+            // 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
401
+            //PrivateKey merchantPrivateKey = keyManager.getPrivateKey("wxpay_private.key");//读取私钥
402
+            PrivateKeySigner privateKeySigner = new PrivateKeySigner(wxpayConfig.getMchSerialNo(), merchantPrivateKey);
403
+            WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(
404
+                    wxpayConfig.getMchId(), privateKeySigner);
405
+            // 向证书管理器增加需要自动更新平台证书的商户信息
406
+            CertificatesManager certificatesManager = CertificatesManager.getInstance();
407
+            certificatesManager.putMerchant(wxpayConfig.getMchId(), wechatPay2Credentials, wxpayConfig.getApiV3Key().getBytes("utf-8"));
408
+            // 初始化httpClient
409
+            return WechatPayHttpClientBuilder.create()
410
+                    .withMerchant(wxpayConfig.getMchId(), wxpayConfig.getMchSerialNo(), merchantPrivateKey)
411
+                    .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(wxpayConfig.getMchId()))).build();
412
+        } catch (Exception e) {
413
+            e.printStackTrace();
414
+            throw new RuntimeException("微信支付--初始化,校验系统参数失败");
415
+        }
416
+
417
+    }
418
+
419
+
420
+    /**
421
+     * 关闭资源
422
+     */
423
+    private void closeConnect(CloseableHttpResponse response) {
424
+        try {
425
+            response.close();
426
+        } catch (Exception e) {
427
+            e.printStackTrace();
428
+            throw new RuntimeException("资源回收出错");
429
+        }
430
+    }
431
+
432
+
433
+    /**
434
+     *  创建支付签名
435
+     * @param appid
436
+     * @param timeStamp
437
+     * @param nonceStr
438
+     * @param packages
439
+     * @param privateKey
440
+     * @return
441
+     * @throws Exception
442
+     */
443
+    private String createPaySign(String appid, String timeStamp, String nonceStr, String packages,String  privateKey) throws Exception {
444
+        Signature sign = Signature.getInstance("SHA256withRSA");
445
+        // 加载商户私钥
446
+        PrivateKey key = PemUtil
447
+                .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes(CharsetUtil.CHARSET_UTF_8)));
448
+        sign.initSign(key);
449
+        String message = StrUtil.format("{}\n{}\n{}\n{}\n",
450
+                appid,
451
+                timeStamp,
452
+                nonceStr,
453
+                packages);
454
+        sign.update(message.getBytes());
455
+        return Base64.getEncoder().encodeToString(sign.sign());
456
+    }
457
+
458
+
459
+}

+ 153
- 0
pay/src/main/java/com/ruoyi/wx/WxPayElegentValid.java ファイルの表示

@@ -0,0 +1,153 @@
1
+package com.ruoyi.wx;
2
+
3
+
4
+import com.alibaba.fastjson.JSON;
5
+import com.ruoyi.annotation.TradePlatform;
6
+import com.ruoyi.constant.Platform;
7
+import com.ruoyi.core.ElegentValid;
8
+import com.ruoyi.dto.ValidResponse;
9
+import com.ruoyi.exceptions.TradeException;
10
+import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
11
+import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
12
+import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
13
+import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
14
+import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
15
+import lombok.extern.slf4j.Slf4j;
16
+import org.springframework.beans.factory.annotation.Autowired;
17
+import org.springframework.http.HttpEntity;
18
+import org.springframework.http.HttpHeaders;
19
+import org.springframework.stereotype.Component;
20
+
21
+import javax.servlet.http.HttpServletRequest;
22
+import java.nio.charset.StandardCharsets;
23
+import java.util.Map;
24
+
25
+@Component
26
+@Slf4j
27
+@TradePlatform(Platform.WX)
28
+public class WxPayElegentValid implements ElegentValid {
29
+
30
+
31
+    @Autowired
32
+    private WxpayConfig wxpayConfig;
33
+
34
+    @Override
35
+    public ValidResponse validPay(HttpEntity<String> httpEntity, HttpServletRequest httpServletRequest) throws TradeException {
36
+        ValidResponse validResponse=new ValidResponse();
37
+
38
+        try {
39
+            //获取请求头
40
+            HttpHeaders headers = httpEntity.getHeaders();
41
+            //构建微信请求数据对象
42
+            NotificationRequest request = new NotificationRequest.Builder()
43
+                    .withSerialNumber(headers.getFirst("Wechatpay-Serial")) //证书序列号(微信平台)
44
+                    .withNonce(headers.getFirst("Wechatpay-Nonce"))  //随机串
45
+                    .withTimestamp(headers.getFirst("Wechatpay-Timestamp")) //时间戳
46
+                    .withSignature(headers.getFirst("Wechatpay-Signature")) //签名字符串
47
+                    .withBody(httpEntity.getBody())
48
+                    .build();
49
+
50
+
51
+            //微信通知的业务处理
52
+            //验证签名,确保请求来自微信
53
+            Map jsonData = null;
54
+            try {
55
+                //确保在管理器中存在自动更新的商户证书
56
+                CertificatesManager certificatesManager = CertificatesManager.getInstance();
57
+                Verifier verifier = certificatesManager.getVerifier(wxpayConfig.getMchId());
58
+
59
+                //验签和解析请求数据
60
+                NotificationHandler notificationHandler = new NotificationHandler(verifier, wxpayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
61
+                Notification notification = notificationHandler.parse(request);
62
+
63
+                if (!"TRANSACTION.SUCCESS".equals(notification.getEventType())) {
64
+                    validResponse.setValid(false);
65
+                    return validResponse;
66
+                }
67
+                //获取解密后的数据
68
+                jsonData =  JSON.parseObject(notification.getDecryptData(),Map.class   );
69
+                log.info("解密后的数据为:"+jsonData);
70
+            } catch (Exception e) {
71
+                throw new TradeException("验签失败");
72
+            }
73
+            if (!"SUCCESS".equals(jsonData.get("trade_state"))) {
74
+                validResponse.setValid(false);
75
+                return validResponse;
76
+            }
77
+            validResponse.setValid(true);
78
+            validResponse.setOrderSn(  (String) jsonData.get("out_trade_no")  ); //订单号
79
+            return validResponse;
80
+        } catch (Exception e) {
81
+            validResponse.setValid(false);
82
+            return validResponse;
83
+        }
84
+    }
85
+
86
+    @Override
87
+    public ValidResponse validRefund(HttpEntity<String> httpEntity, HttpServletRequest httpServletRequest) throws TradeException {
88
+
89
+        ValidResponse validResponse=new ValidResponse();
90
+        try {
91
+            //获取请求头
92
+            HttpHeaders headers = httpEntity.getHeaders();
93
+
94
+            //构建微信请求数据对象
95
+            NotificationRequest request = new NotificationRequest.Builder()
96
+                    .withSerialNumber(headers.getFirst("Wechatpay-Serial")) //证书序列号(微信平台)
97
+                    .withNonce(headers.getFirst("Wechatpay-Nonce"))  //随机串
98
+                    .withTimestamp(headers.getFirst("Wechatpay-Timestamp")) //时间戳
99
+                    .withSignature(headers.getFirst("Wechatpay-Signature")) //签名字符串
100
+                    .withBody(httpEntity.getBody())
101
+                    .build();
102
+
103
+            //微信通知的业务处理
104
+            Map jsonData = null;
105
+            //验证签名,确保请求来自微信
106
+            try {
107
+                //确保在管理器中存在自动更新的商户证书
108
+                CertificatesManager certificatesManager = CertificatesManager.getInstance();
109
+                Verifier verifier = certificatesManager.getVerifier(wxpayConfig.getMchId());
110
+
111
+                //验签和解析请求数据
112
+                NotificationHandler notificationHandler = new NotificationHandler(verifier, wxpayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8));
113
+                Notification notification = notificationHandler.parse(request);
114
+
115
+                if (!"REFUND.SUCCESS".equals(notification.getEventType())) {
116
+                    //非成功请求直接返回,理论上都是成功的请求
117
+                    validResponse.setValid(false);
118
+                    return validResponse;
119
+                }
120
+                //获取解密后的数据
121
+                jsonData = JSON.parseObject( notification.getDecryptData(),Map.class  );
122
+
123
+
124
+            } catch (Exception e) {
125
+                throw new TradeException("验签失败");
126
+            }
127
+            if (!"SUCCESS".equals(jsonData.get("refund_status"))) {
128
+                //非成功请求直接返回,理论上都是成功的请求
129
+                validResponse.setValid(false);
130
+                return validResponse;
131
+            }
132
+
133
+            //交易单号
134
+            validResponse.setValid(true);
135
+            validResponse.setOrderSn(  (String) jsonData.get("out_trade_no")  ); //订单号
136
+            return validResponse;
137
+        } catch (Exception e) {
138
+            //非成功请求直接返回,理论上都是成功的请求
139
+            validResponse.setValid(false);
140
+            return validResponse;
141
+        }
142
+    }
143
+
144
+    @Override
145
+    public String successResult() {
146
+        return  JSON.toJSONString(WxpayConstant.SUCCESS ) ;
147
+    }
148
+
149
+    @Override
150
+    public String failResult() {
151
+        return JSON.toJSONString( WxpayConstant.FAIL);
152
+    }
153
+}

+ 20
- 0
pay/src/main/java/com/ruoyi/wx/WxpayConfig.java ファイルの表示

@@ -0,0 +1,20 @@
1
+package com.ruoyi.wx;
2
+import lombok.Data;
3
+import org.springframework.boot.context.properties.ConfigurationProperties;
4
+import org.springframework.stereotype.Component;
5
+
6
+/**
7
+ * 微信权限对接类
8
+ */
9
+@Component
10
+@ConfigurationProperties("elegent.pay.wxpay")
11
+@Data
12
+public class WxpayConfig {
13
+
14
+    private String mchId; //商户号
15
+    private String appId; //APPID
16
+    private String appSecret;//app密钥
17
+    private String mchSerialNo; //商户证书序列号
18
+    private String apiV3Key; //V3密钥
19
+
20
+}

+ 48
- 0
pay/src/main/java/com/ruoyi/wx/WxpayConstant.java ファイルの表示

@@ -0,0 +1,48 @@
1
+package com.ruoyi.wx;
2
+
3
+import java.util.HashMap;
4
+import java.util.Map;
5
+
6
+public class WxpayConstant {
7
+
8
+    public static final Map SUCCESS = new HashMap<String,Object>(){
9
+        {
10
+            put("code", "SUCCESS");
11
+        }
12
+    };
13
+
14
+    public static final Map FAIL  = new HashMap<String,Object>(){
15
+        {
16
+            put("code", "FAIL");
17
+            put("message","微信回调错误结果");
18
+        }
19
+    };
20
+
21
+
22
+    public final static String domain ="https://api.mch.weixin.qq.com/v3";
23
+
24
+    /**
25
+     * 创建订单
26
+     */
27
+    public final static String createOrder = domain +"/pay/transactions/";
28
+
29
+    /**
30
+     * 关闭订单
31
+     */
32
+    public final static String closeOrder = domain+"/pay/transactions/out-trade-no/{out_trade_no}/close";
33
+
34
+    /**
35
+     * 查询订单编号
36
+     */
37
+    public static String queryOrderNo = domain+"/pay/transactions/out-trade-no/";
38
+
39
+    /**
40
+     * 查询退款订单
41
+     */
42
+    public static String queryRufundOrderNo =domain+ "/refund/domestic/refunds/";
43
+
44
+    /**
45
+     * 退款接口
46
+     */
47
+    public static String refund = domain+"/refund/domestic/refunds";
48
+}

+ 14
- 0
pay/src/main/resources/META-INF/spring.factories ファイルの表示

@@ -0,0 +1,14 @@
1
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2
+  com.ruoyi.config.CallbackConfig,\
3
+  com.ruoyi.core.CallbackWatch,\
4
+  com.ruoyi.core.ElegentPayImpl,\
5
+  com.ruoyi.core.ElegentLoader,\
6
+  com.ruoyi.core.ElegentConfig,\
7
+  com.ruoyi.key.impl.DefaultKeyManager,\
8
+  com.ruoyi.core.CallbackController,\
9
+  com.ruoyi.wx.WxpayConfig,\
10
+  com.ruoyi.wx.WxPayElegentTrade,\
11
+  com.ruoyi.wx.WxPayElegentValid,\
12
+  com.ruoyi.ali.AlipayConfig,\
13
+  com.ruoyi.ali.AlipayElegentTrade,\
14
+  com.ruoyi.ali.AlipayElegentValid

+ 1
- 0
pom.xml ファイルの表示

@@ -180,6 +180,7 @@
180 180
         <module>ruoyi-quartz</module>
181 181
         <module>ruoyi-generator</module>
182 182
         <module>ruoyi-common</module>
183
+        <module>pay</module>
183 184
     </modules>
184 185
     <packaging>pom</packaging>
185 186
 

+ 5
- 1
ruoyi-admin/pom.xml ファイルの表示

@@ -60,7 +60,11 @@
60 60
             <groupId>com.ruoyi</groupId>
61 61
             <artifactId>ruoyi-generator</artifactId>
62 62
         </dependency>
63
-
63
+        <dependency>
64
+            <groupId>com.ruoyi</groupId>
65
+            <artifactId>pay</artifactId>
66
+            <version>1.0.0-SNAPSHOT</version>
67
+        </dependency>
64 68
     </dependencies>
65 69
 
66 70
     <build>

+ 0
- 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/ArbitratorController.java ファイルの表示

@@ -3,7 +3,6 @@ package com.ruoyi.web.controller.wisdomarbitrate;
3 3
 import com.ruoyi.common.core.controller.BaseController;
4 4
 import com.ruoyi.common.core.page.TableDataInfo;
5 5
 import com.ruoyi.wisdomarbitrate.domain.Arbitrator;
6
-import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
7 6
 import com.ruoyi.wisdomarbitrate.service.IArbitratorService;
8 7
 import org.springframework.beans.factory.annotation.Autowired;
9 8
 import org.springframework.security.access.prepost.PreAuthorize;

+ 0
- 2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CaseApplicationController.java ファイルの表示

@@ -3,7 +3,6 @@ package com.ruoyi.web.controller.wisdomarbitrate;
3 3
 import com.ruoyi.common.annotation.Log;
4 4
 import com.ruoyi.common.core.controller.BaseController;
5 5
 import com.ruoyi.common.core.domain.AjaxResult;
6
-import com.ruoyi.common.core.domain.entity.SysUser;
7 6
 import com.ruoyi.common.core.page.TableDataInfo;
8 7
 import com.ruoyi.common.enums.BusinessType;
9 8
 import com.ruoyi.common.utils.SecurityUtils;
@@ -22,7 +21,6 @@ import javax.servlet.http.HttpServletResponse;
22 21
 import java.io.IOException;
23 22
 import java.util.List;
24 23
 
25
-import static com.ruoyi.common.core.domain.AjaxResult.error;
26 24
 
27 25
 
28 26
 @RestController

+ 41
- 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CaseArbitrateController.java ファイルの表示

@@ -0,0 +1,41 @@
1
+package com.ruoyi.web.controller.wisdomarbitrate;
2
+
3
+import com.ruoyi.common.core.controller.BaseController;
4
+import com.ruoyi.common.core.domain.AjaxResult;
5
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
6
+import com.ruoyi.wisdomarbitrate.service.ICaseArbitrateService;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.validation.annotation.Validated;
9
+import org.springframework.web.bind.annotation.*;
10
+
11
+@RestController
12
+@RequestMapping("/arbitrate")
13
+public class CaseArbitrateController extends BaseController {
14
+    @Autowired
15
+    private ICaseArbitrateService caseArbitrateService;
16
+
17
+    /**
18
+     * 确定仲裁方式
19
+     * @param caseApplication
20
+     * @param arbitratMethod
21
+     * @return
22
+     */
23
+    @PutMapping("/method")
24
+    public AjaxResult chooseArbitrateMethod(@Validated @RequestBody CaseApplication caseApplication
25
+            ,Integer arbitratMethod){
26
+        return caseArbitrateService.chooseArbitrateMethod(caseApplication,arbitratMethod);
27
+    }
28
+
29
+    /**
30
+     * 书面审理
31
+     * @param caseApplication
32
+     * @param accidentDescription
33
+     * @param arbitrationResult
34
+     * @return
35
+     */
36
+    @PostMapping("/writtenHear")
37
+    public AjaxResult writtenHear(@Validated @RequestBody CaseApplication caseApplication
38
+            ,String accidentDescription , String arbitrationResult){
39
+        return caseArbitrateService.writtenHear(caseApplication,accidentDescription,arbitrationResult);
40
+    }
41
+}

+ 81
- 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CaseEvidenceController.java ファイルの表示

@@ -0,0 +1,81 @@
1
+package com.ruoyi.web.controller.wisdomarbitrate;
2
+
3
+import com.ruoyi.common.core.controller.BaseController;
4
+import com.ruoyi.common.core.domain.AjaxResult;
5
+import com.ruoyi.common.core.page.TableDataInfo;
6
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
7
+import com.ruoyi.wisdomarbitrate.domain.vo.CaseEvidenceVO;
8
+import com.ruoyi.wisdomarbitrate.service.ICaseEvidenceService;
9
+import org.springframework.beans.factory.annotation.Autowired;
10
+import org.springframework.validation.annotation.Validated;
11
+import org.springframework.web.bind.annotation.*;
12
+import org.springframework.web.multipart.MultipartFile;
13
+
14
+import java.util.ArrayList;
15
+import java.util.List;
16
+
17
+/**
18
+ * 案件证据
19
+ */
20
+@RestController
21
+@RequestMapping("/evidence")
22
+public class CaseEvidenceController extends BaseController {
23
+    private final ICaseEvidenceService caseEvidenceService;
24
+
25
+    @Autowired
26
+    public CaseEvidenceController(ICaseEvidenceService caseEvidenceService) {
27
+        this.caseEvidenceService = caseEvidenceService;
28
+    }
29
+
30
+    /**
31
+     * 根据案件id查询案件详情
32
+     *
33
+     * @param id
34
+     * @return
35
+     */
36
+    @GetMapping("/{id}")
37
+    public AjaxResult getCaseDetailsById(@PathVariable Long id) {
38
+        String username = this.getUsername();
39
+        return caseEvidenceService.getCaseDetailsById(id,username);
40
+    }
41
+
42
+    /**
43
+     * 案件证据上传
44
+     *
45
+     * @param file      附件
46
+     * @param annexType 附件类型,立案申请书(1)、证据材料(2)、仲裁文书(3)、案件视频(4)、身份证件(5)
47
+     * @param id        案件申请id
48
+     * @return
49
+     */
50
+    @PostMapping("/upload")
51
+    public AjaxResult uploadEvidence(@RequestParam("file") MultipartFile file, Integer annexType, Long id) {
52
+        String username = this.getUsername();
53
+        Long userId = this.getUserId();
54
+        return caseEvidenceService.uploadEvidence(file, annexType, id,username,userId);
55
+    }
56
+
57
+    /**
58
+     * 查询当前用户案件列表
59
+     * @param identityNum
60
+     * @return
61
+     */
62
+    @GetMapping("/all")
63
+    public TableDataInfo getCaseListAll(@RequestParam String identityNum) {
64
+        startPage();
65
+        List<CaseEvidenceVO> list = caseEvidenceService.getCaseListAll(identityNum);
66
+        if (list != null) {
67
+            return getDataTable(list);
68
+        }
69
+        return getDataTable(new ArrayList<>());
70
+    }
71
+
72
+    /**
73
+     * 证据确认
74
+     * @param caseApplication 案件对象
75
+     * @return 统一返回结果
76
+     */
77
+    @PutMapping("/confirm")
78
+    public AjaxResult evidenceConfirmation(@Validated @RequestBody CaseApplication caseApplication){
79
+        return caseEvidenceService.evidenceConfirmation(caseApplication);
80
+    }
81
+}

+ 41
- 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/wisdomarbitrate/CasePaymentController.java ファイルの表示

@@ -0,0 +1,41 @@
1
+package com.ruoyi.web.controller.wisdomarbitrate;
2
+
3
+import com.ruoyi.common.core.domain.AjaxResult;
4
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
5
+import com.ruoyi.wisdomarbitrate.service.ICasePaymentService;
6
+import com.ruoyi.wisdomarbitrate.domain.dto.CasePayDTO;
7
+import org.springframework.beans.factory.annotation.Autowired;
8
+import org.springframework.validation.annotation.Validated;
9
+import org.springframework.web.bind.annotation.*;
10
+
11
+/**
12
+ * 缴费支付
13
+ */
14
+@RestController
15
+@RequestMapping("/pay")
16
+public class CasePaymentController {
17
+    private final ICasePaymentService paymentService;
18
+    @Autowired
19
+    public CasePaymentController(ICasePaymentService paymentService){
20
+       this.paymentService=paymentService;
21
+    }
22
+    /**
23
+     * 案件缴费
24
+     * @param casePayDTO 缴费传入参数
25
+     * @return 统一响应结果
26
+     */
27
+    @PostMapping("/casePay")
28
+    public AjaxResult casePay(@Validated @RequestBody CasePayDTO casePayDTO) {
29
+        return paymentService.casePay(casePayDTO);
30
+    }
31
+
32
+    /**
33
+     * 缴费确认
34
+     * @param caseApplication
35
+     * @return
36
+     */
37
+    @PutMapping("/confirm")
38
+    public AjaxResult confirmPayment(@Validated @RequestBody CaseApplication caseApplication) {
39
+        return paymentService.confirmPayment(caseApplication);
40
+    }
41
+}

+ 1
- 0
ruoyi-admin/src/main/resources/alipay_private.key ファイルの表示

@@ -0,0 +1 @@
1
+MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQC12YM9mR+HFQYTx/fHKHZbgszVtDHDB0B/ysWl3MbcPpGtjcZlDr5aynRMRLaoduRHT++A98IaNVIVGj9RHdXrX2j9I/Uz6fYDH63cdu6FZ6Pk82yPwNZW7pebprbVHInR/7gzsKQWSWEST70BgjCRqlbfAE6xzUZFTeYxciCjptm0rUQ2MC24xRdkvZByIDIYFnQ/AdmSFqNtKDR2WpEV/M8aBjyuPPomRJZ1X8oudWuJIU4ySdas04fCbDxD10TY/wyQcDHXuG1IrQpXme4DOGQeJZ0/aOFphBkDFUyPGfYMmLshOPNdBKi2IqWHPPs4XsV4Rv6+tvTSnMF2uGqHAgMBAAECggEAPa1sifPpcZN74DGupGng2uDeQI1BY3iOM8m+h6b9+61tE4RGifgaMAkCsOuNWE4a1uURwphFyUXUdTvVxdlsuMw/e7w6akUsH5sbCO99rtmcCQdXBtrM1+dMnIpK8LUhOYyWGVIMFVMGDYPmAyD5AC7aEAC2sC+DafYl4RdoYpidq1YxeE7DVw1aQHCI2mKhYjZG+3RDDGDfNFvdyH61MgdYjoGkeXNvARzEXgfWvfiTrHZ3H1SYgvOEHofzKDTrWsQL2dvaEsc55Jiw0AgNUVcgby7al8PUekTJoK3ZvrE3pSWaUirBcqsqWISHjeR7Xx501CHIha8EnZwlnDoM4QKBgQDtnYzwQ5mHg7cRHD8Z6QdTpvBvYSEPesiUT/HeI+AKQKDCVJxKiLvJagc6zZkOzV9bZDS/WLgzXWMyxUb+OTjht0jLWAMcf7NfFp3tPKq9wkmQQ/vQSBQ1lFmO6A4Zq1eoGKeUCB4pKBG6cSM+t8+ruhm7s1ZUt+6EBwCVN/izrQKBgQDD62jIm+6NFErdidUaIrGiFUrzqdR13w6JOexfk+O6Aau3wRqsr7Wz4nqQvVVxGMRpXbOH06zpeiS+vMmjwgO973VoLAmH+hJ0GZz8qj3zA2GEOFWjD2V7tqeRvGkQvz0v46pl+8sBJkrRHLN7DWNYY5NDI+b7exwqcTc/LL19gwJ/a6r4MeZvqvgD+7zQ2uy8ZSs/xzg7wsfgG1QeRIn8+qhOL8AnEZ7jeGCS5hJDSHHGw6KkRA/vZ1bpnBfIE2naXGywj3NR9Zfnry6QYO8cbt+adcRYVghTH/QYoKiFuxvonEKPrIQBJqUBY3ngforLjwTEpEie1cSCT1Dc8sBp8QKBgQCaz8fqzRyBKknGKQXVMxj+JKknRUl3IpzP3o9jLu9BqdRQzSwQzH9d91Y2TQXY6mM5hys35xG5JCUo+vCyj7p5OWCiwjl90yMFzr93/+YXwtIpsoIo6R+d1EUxKZoz+4mT7+hT0dUlwWZZOr6wO3IHBBf3c8UvbqZg+zlWmDnblQKBgEs6jwMkb5zaG2fyBJ7PJUN/8nIz8V+X0SxQfcEqIX0J+EC+7MAgFjcdZFp+lca3Vd9z+8Ksd4rMzMa5y856ositL2NZ+K0fs8i8EBaQPny61OgCFUuXEuv5keB2YuGMSns5FYRWuByrtDXl4PxzKXvq05iKWLKCaCq9v4momvKZ

+ 1
- 0
ruoyi-admin/src/main/resources/alipay_public.key ファイルの表示

@@ -0,0 +1 @@
1
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhUnjdAKwZApwZEcfq+5L0pa77Vg3mqcoXv+th8RR0SYotkPsH1f2JkbS48ySaSCM6YNWSMNfqp5qdOla2zUJOBnJ/yaBg7s7fVD6V3M2mEog8kCDYGKt/3P4VII3xYl8lFYMQ3IcFRELkxCBBCA8JDKmf5z2R4F/Z/jFFEuOwxaJvp+7Ke9OzZHYdWGNnU6QP8YYLYUeX7VNZLHEuly34ExAw6A+yJkNDsYEho2Lu31QjT2pLh9g+88MlRfiI92iN25O9NVdeM4f5RcpvBPrBQZQs9tlFmALYSFS3prIf3FAobWM+W7iwxT6J25nFIhst1DdJQfIBpaeRUJVTkn99QIDAQAB

+ 3
- 3
ruoyi-admin/src/main/resources/application-druid.yml ファイルの表示

@@ -6,9 +6,9 @@ spring:
6 6
         druid:
7 7
             # 主库数据源
8 8
             master:
9
-                url: jdbc:mysql://localhost:3306/ruyivue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
10
-                username: ruyivue
11
-                password: rybackproje13689
9
+                url: jdbc:mysql://121.40.189.20:3306/arbitrate?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&useSSL=false
10
+                username: root
11
+                password: root123456
12 12
             # 从库数据源
13 13
             slave:
14 14
                 # 从数据源开关/默认关闭

+ 22
- 4
ruoyi-admin/src/main/resources/application.yml ファイルの表示

@@ -9,7 +9,7 @@ ruoyi:
9 9
   # 实例演示开关
10 10
   demoEnabled: true
11 11
   # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
12
-  profile: D:/ruoyi/uploadPath
12
+  profile: /home/ruoyi/uploadPath
13 13
   # 获取ip地址开关
14 14
   addressEnabled: false
15 15
   # 验证码类型 math 数字计算 char 字符验证
@@ -18,7 +18,7 @@ ruoyi:
18 18
 # 开发环境配置
19 19
 server:
20 20
   # 服务器的HTTP端口,默认为8080
21
-  port: 8080
21
+  port: 9001
22 22
   servlet:
23 23
     # 应用的访问路径
24 24
     context-path: /
@@ -70,9 +70,9 @@ spring:
70 70
   # redis 配置
71 71
   redis:
72 72
     # 地址
73
-    host: localhost
73
+    host: 121.40.189.20
74 74
     # 端口,默认为6379
75
-    port: 6379
75
+    port: 6389
76 76
     # 数据库索引
77 77
     database: 0
78 78
     # 密码
@@ -129,3 +129,21 @@ xss:
129 129
   excludes: /system/notice
130 130
   # 匹配链接
131 131
   urlPatterns: /system/*,/monitor/*,/tool/*
132
+#支付相关配置
133
+elegent:
134
+  pay:
135
+    wxpay:
136
+      mchId: 1561414331
137
+      appId: wx6592a2db3f85ed25
138
+      appSecret: d9a9ff00a633cd7353a8925119063b01
139
+      mchSerialNo: 25FBDE3EFD31B03A4377EB9A4A47C517969E6620
140
+      apiV3Key: CZBK51236435wxpay435434323FFDuv3
141
+    alipay:
142
+      appId: 2021003141676135
143
+    callback:
144
+      domain: http://121.40.189.20:9000/
145
+      watch: false
146
+      cycle: 10
147
+identityAuthentication:
148
+  credentialSecretId: 123
149
+  credentialSecretKey: 367

+ 1
- 0
ruoyi-admin/src/main/resources/wxpay_private.key ファイルの表示

@@ -0,0 +1 @@
1
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBHGgIh80193GhdpD1LtMZfTRpcWI0fImyuBCyrd3gYb3rrsARebGcHdJsQA3mVjVqVp5ybhEZDPa4ecoK4Ye1hTppNpI/lmLt4/uUV/zhF5ahli7hi+116Ty6svHSbuMQBuUZeTFOwGrxjvofU/4pGIwh8ZvkcSnyOp9uX2177UVxDBkhgbZbJp9XF2b83vUa5eHo93CziPzn3hFdAlBCdTXB7DH+m0nN3Jou0szGukvq7cIgGpHku4ycKSTkIhhl9WRhN6OoSEJxq88MXzjkzTruc85PHN52aUTUifwg3T8Y4XqFQ61dTnEmgxeD2O6/pLdB9gLsp6yCGqN5Lqk7AgMBAAECggEBAL4X+WzUSbSjFS9NKNrCMjm4H1zgqTxjj6TnPkC1mGEltjAHwLgzJBw62wWGdGhWWpSIGccpBBm1wjTMZpAZfF66fEpP1t1Ta6UjtGZNyvfFIZmE3jdWZ/WXGBnsxtFQKKKBNwrBW0Fbdqq9BQjLxLitmlxbmwrgPttcy855j6vZqq4MBT1v8CtUT/gz4UWW2xWovVnmWOrRSScv7Nh0pMbRpPLkNHXrBwSSNz/keORzXB9JSm85wlkafa7n5/IJbdTml3A/uAgW3q3JZZQotHxQsYvD4Zb5Cnc9CPAXE5L2Yk877kVXZMGt5QPIVcPMj/72AMtaJT67Y0fN0RYHEGkCgYEA38BIGDY6pePgPbxB7N/l6Df0/OKPP0u8mqR4Q0aQD3VxeGiZUN1uWXEFKsKwlOxLfIFIFk1/6zQeC0xetNTKk0gTL8hpMUTNkE7vI9gFWws2LY6DE86Lm0bdFEIwh6d7Fr7zZtyQKPzMsesC3XV9sdSUExEi5o/VwAyf+xZlOXcCgYEA3PGZYlILjg3esPNkhDz2wxFw432i8l/BCPD8ZtqIV9eguu4fVtFYcUVfawBb0T11RamJkc4eiSOqayC+2ehgb+GyRLJNK4FqbFcsIT+CK0HlscZw51jrMR0MxTc4RzuOIMoYDeZqeGB6/YnNyG4pw2sD8bIwHm8406gtJsX/v10CgYAo8g3/aEUZQHcztPS3fU2cTkkl0ev24Ew2XGypmwsX2R0XtMSBuNPNyFHyvkgEKK2zrhDcC/ihuRraZHJcUyhzBViFgP5HBtk7VEaM36YzP/z9Hzw7bqu7kZ85atdoq6xpwC3Yn/o9le17jY8rqamD1mv2hUdGvAGYsHbCQxnpBwKBgHTkeaMUBzr7yZLS4p435tHje1dQVBJpaKaDYPZFrhbTZR0g+IGlNmaPLmFdCjbUjiPyA2+Znnwt227cHz0IfWUUAo3ny3419QkmwZlBkWuzbIO2mms7lwsf9G6uvV6qepKMeVd5TWEsokVbT/03k27pQmfwPxcK/wS0GFdIL/udAoGAOYdDqY5/aadWCyhzTGI6qXPLvC+fsJBPhK2RXyc+jYV0KmrEv4ewxlK5NksuFsNkyB7wlI1oMCa/xB3T/2vTBALgGFPi8BJqceUjtnTYtI4R2JIVEl08RtEJwyU5JZ2rvWcilsotVZYwfuLZ9KfdhkTrgNxlp/KKkr+UuKce4Vs=

+ 13
- 0
ruoyi-common/pom.xml ファイルの表示

@@ -126,6 +126,19 @@
126 126
             <artifactId>javax.servlet-api</artifactId>
127 127
         </dependency>
128 128
 
129
+        <dependency>
130
+            <groupId>org.projectlombok</groupId>
131
+            <artifactId>lombok</artifactId>
132
+            <version>1.18.22</version>
133
+        </dependency>
134
+
135
+        <!-- 腾讯短信sdk -->
136
+        <dependency>
137
+            <groupId>com.tencentcloudapi</groupId>
138
+            <artifactId>tencentcloud-sdk-java</artifactId>
139
+            <version>3.1.270</version>
140
+        </dependency>
141
+
129 142
         <dependency>
130 143
             <groupId>com.tencentcloudapi</groupId>
131 144
             <artifactId>tencentcloud-sdk-java-ocr</artifactId>

+ 85
- 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/SmsUtils.java ファイルの表示

@@ -0,0 +1,85 @@
1
+package com.ruoyi.common.utils;
2
+
3
+import com.tencentcloudapi.common.Credential;
4
+import com.tencentcloudapi.common.exception.TencentCloudSDKException;
5
+import com.tencentcloudapi.common.profile.ClientProfile;
6
+import com.tencentcloudapi.common.profile.HttpProfile;
7
+import com.tencentcloudapi.cvm.v20170312.CvmClient;
8
+import com.tencentcloudapi.cvm.v20170312.models.DescribeRegionsRequest;
9
+import com.tencentcloudapi.cvm.v20170312.models.DescribeRegionsResponse;
10
+import com.tencentcloudapi.sms.v20210111.SmsClient;
11
+import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
12
+import com.tencentcloudapi.sms.v20210111.models.SendStatus;
13
+import lombok.Data;
14
+import lombok.extern.slf4j.Slf4j;
15
+import lombok.var;
16
+
17
+import java.util.Objects;
18
+
19
+@Slf4j
20
+public class SmsUtils {
21
+    //应用id
22
+    private static final String SDK_APP_ID = "1400854852";
23
+    //API的SecretId
24
+    private static final String SECRET_ID = "AKIDeEf2A8uX1HSainvvnXAc3X9ZlhtyvkMp";
25
+    //API的SecretKey
26
+    private static final String SECRET_KEY = "QjphKo8zkHZigT8j9PVtFPJyfIvO3d6V";
27
+    //签名内容
28
+    private static final String SIGN_NAME = "西安云美电子科技有限公司";
29
+
30
+    public static Boolean sendSms(SendSmsRequest request) {
31
+        Credential cred = new Credential(SECRET_ID, SECRET_KEY );
32
+
33
+        SmsClient client = new SmsClient(cred, "ap-guangzhou");
34
+
35
+        final var req = new com.tencentcloudapi.sms.v20210111.models.SendSmsRequest();
36
+        req.setPhoneNumberSet(new String[]{"+86" + request.getPhone()});
37
+        req.setSmsSdkAppId(SDK_APP_ID );
38
+        req.setSignName(SIGN_NAME);
39
+        req.setTemplateId(request.getTemplateId());
40
+        req.setTemplateParamSet(request.getTemplateParamSet());
41
+        SendSmsResponse res = null;
42
+        try {
43
+            res = client.SendSms(req);
44
+        } catch (TencentCloudSDKException e) {
45
+            log.error("发送短信出错:", e);
46
+            return Boolean.FALSE;
47
+        }
48
+        SendStatus sendStatus = res.getSendStatusSet()[0];
49
+        log.info("发送短信结果:Code={}, Message={}", sendStatus.getCode(), sendStatus.getMessage());
50
+
51
+        if (Objects.nonNull(res.getSendStatusSet()) && res.getSendStatusSet().length > 0 && "Ok".equals(res.getSendStatusSet()[0].getCode())){
52
+            return Boolean.TRUE;
53
+        }
54
+        return Boolean.FALSE;
55
+    }
56
+    /**
57
+     * 参数对象
58
+     */
59
+    @Data
60
+    public static class SendSmsRequest {
61
+        /**
62
+         * 电话
63
+         */
64
+        private String phone;
65
+
66
+        /**
67
+         * 模板 ID: 必须填写已审核通过的模板 ID
68
+         */
69
+        private String templateId;
70
+
71
+        /**
72
+         * 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空
73
+         */
74
+        private String[] templateParamSet;
75
+
76
+    }
77
+
78
+    public static void main(String[] args) {
79
+        SendSmsRequest sendSmsRequest = new SendSmsRequest();
80
+        sendSmsRequest.setPhone("18792613219");
81
+        sendSmsRequest.setTemplateId("1928003");
82
+        sendSmsRequest.setTemplateParamSet(new String[]{"xxx","仲裁","编号"});
83
+        SmsUtils.sendSms(sendSmsRequest);
84
+    }
85
+}

+ 5
- 1
ruoyi-system/pom.xml ファイルの表示

@@ -22,7 +22,11 @@
22 22
             <groupId>com.ruoyi</groupId>
23 23
             <artifactId>ruoyi-common</artifactId>
24 24
         </dependency>
25
-
25
+        <dependency>
26
+            <groupId>com.ruoyi</groupId>
27
+            <artifactId>pay</artifactId>
28
+            <version>1.0.0-SNAPSHOT</version>
29
+        </dependency>
26 30
     </dependencies>
27 31
 
28 32
 </project>

+ 3
- 4
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CaseApplication.java ファイルの表示

@@ -2,7 +2,6 @@ package com.ruoyi.wisdomarbitrate.domain;
2 2
 
3 3
 import com.fasterxml.jackson.annotation.JsonFormat;
4 4
 import com.ruoyi.common.annotation.Excel;
5
-import com.ruoyi.common.annotation.Excels;
6 5
 import com.ruoyi.common.core.domain.BaseEntity;
7 6
 import java.math.BigDecimal;
8 7
 import java.util.Date;
@@ -25,7 +24,7 @@ public class CaseApplication  extends BaseEntity {
25 24
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
26 25
     private Date registerDate;
27 26
     /** 仲裁方式 */
28
-    private String arbitratMethod;
27
+    private int arbitratMethod;
29 28
     /** 案件状态 */
30 29
     private int caseStatus;
31 30
     /** 开庭日期 */
@@ -313,11 +312,11 @@ public class CaseApplication  extends BaseEntity {
313 312
         this.registerDate = registerDate;
314 313
     }
315 314
 
316
-    public String getArbitratMethod() {
315
+    public int getArbitratMethod() {
317 316
         return arbitratMethod;
318 317
     }
319 318
 
320
-    public void setArbitratMethod(String arbitratMethod) {
319
+    public void setArbitratMethod(int arbitratMethod) {
321 320
         this.arbitratMethod = arbitratMethod;
322 321
     }
323 322
 

+ 46
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CaseAttach.java ファイルの表示

@@ -0,0 +1,46 @@
1
+package com.ruoyi.wisdomarbitrate.domain;
2
+
3
+import lombok.AllArgsConstructor;
4
+import lombok.Builder;
5
+import lombok.Data;
6
+import lombok.NoArgsConstructor;
7
+
8
+@Data
9
+@Builder
10
+@AllArgsConstructor
11
+@NoArgsConstructor
12
+public class CaseAttach {
13
+    /**
14
+     *  附件id
15
+     */
16
+    private Integer annexId;
17
+    /**
18
+     * 案件申请id
19
+     */
20
+    private Long caseAppliId;
21
+    /**
22
+     * 附件名称
23
+     */
24
+    private String annexName;
25
+    /**
26
+     * 附件路径
27
+     */
28
+    private String annexPath;
29
+    /**
30
+     * 附件类型,立案申请书(1)、证据材料(2)、仲裁文书(3)、案件视频(4)、身份证件(5)
31
+     */
32
+    private Integer annexType;
33
+    /**
34
+     * 备注
35
+     */
36
+    private String note;
37
+    /**
38
+     * 用户id
39
+     */
40
+    private Long userId;
41
+    /**
42
+     * 用户账户
43
+     */
44
+    private String userName;
45
+
46
+}

+ 3
- 3
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CaseLogRecord.java ファイルの表示

@@ -14,7 +14,7 @@ public class CaseLogRecord     extends BaseEntity {
14 14
     /** 案件申请id */
15 15
     private Long caseAppliId;
16 16
     /** 案件节点 */
17
-    private String caseNode;
17
+    private Integer caseNode;
18 18
 
19 19
     /** 案件节点时间 */
20 20
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@@ -50,11 +50,11 @@ public class CaseLogRecord     extends BaseEntity {
50 50
         this.caseAppliId = caseAppliId;
51 51
     }
52 52
 
53
-    public String getCaseNode() {
53
+    public int getCaseNode() {
54 54
         return caseNode;
55 55
     }
56 56
 
57
-    public void setCaseNode(String caseNode) {
57
+    public void setCaseNode(int caseNode) {
58 58
         this.caseNode = caseNode;
59 59
     }
60 60
 

+ 41
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/CasePaymentRecord.java ファイルの表示

@@ -0,0 +1,41 @@
1
+package com.ruoyi.wisdomarbitrate.domain;
2
+
3
+import com.fasterxml.jackson.annotation.JsonFormat;
4
+import com.ruoyi.common.core.domain.BaseEntity;
5
+import lombok.Data;
6
+
7
+import java.util.Date;
8
+
9
+@Data
10
+public class CasePaymentRecord {
11
+    private static final long serialVersionUID = 1L;
12
+    /**
13
+     * 主键
14
+     */
15
+    private Integer id;
16
+    /**
17
+     * 案件id
18
+     */
19
+    private Long caseId;
20
+    /**
21
+     * 订单号
22
+     */
23
+    private String orderNumber;
24
+    /**
25
+     * 支付状态(0未支付,1已支付)
26
+     */
27
+    private Integer paymentStatus;
28
+    /**
29
+     * 支付时间
30
+     */
31
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
32
+    private Date paymentTime;
33
+
34
+    /** 创建时间 */
35
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
36
+    private Date createTime;
37
+
38
+    /** 更新时间 */
39
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
40
+    private Date updateTime;
41
+}

+ 26
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/dto/CasePayDTO.java ファイルの表示

@@ -0,0 +1,26 @@
1
+package com.ruoyi.wisdomarbitrate.domain.dto;
2
+
3
+import lombok.Data;
4
+/**
5
+ * 案件缴费传入参数
6
+ */
7
+@Data
8
+public class CasePayDTO {
9
+    /**
10
+     * 案件id
11
+     */
12
+    private Long caseId;
13
+
14
+    /**
15
+     * 订单金额 单位:分
16
+     */
17
+    private int totalFee;
18
+    /**
19
+     * 交易类型 native(扫码) / jsapi(小程序) / app / h5
20
+     */
21
+    private String tradeType;
22
+    /**
23
+     * 支付方式 wxpay(微信)  alipay(支付宝)
24
+     */
25
+    private String platform;
26
+}

+ 67
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/CaseDetailVO.java ファイルの表示

@@ -0,0 +1,67 @@
1
+package com.ruoyi.wisdomarbitrate.domain.vo;
2
+
3
+import com.ruoyi.wisdomarbitrate.domain.CaseAttach;
4
+import lombok.AllArgsConstructor;
5
+import lombok.Builder;
6
+import lombok.Data;
7
+import lombok.NoArgsConstructor;
8
+
9
+import java.math.BigDecimal;
10
+import java.util.Date;
11
+import java.util.List;
12
+
13
+@Data
14
+@Builder
15
+@NoArgsConstructor
16
+@AllArgsConstructor
17
+public class CaseDetailVO {
18
+    /**
19
+     * ID
20
+     */
21
+    private Long id;
22
+    /**
23
+     * 案件编号
24
+     */
25
+    private String caseNum;
26
+    /**
27
+     * 申请人姓名
28
+     */
29
+    private String applicantName;
30
+    /**
31
+     * 被申请人姓名
32
+     */
33
+    private String respondentName;
34
+    /**
35
+     * 借款开始日期
36
+     */
37
+    private Date loanStartDate;
38
+    /**
39
+     * 借款结束日期
40
+     */
41
+    private Date loanEndDate;
42
+    /**
43
+     * 案件标的
44
+     */
45
+    private BigDecimal caseSubjectAmount;
46
+    /**
47
+     * 申请人主张欠本金
48
+     */
49
+    private BigDecimal claimPrinciOwed;
50
+    /**
51
+     * 申请人主张欠利息
52
+     */
53
+    private BigDecimal claimInterestOwed;
54
+    /**
55
+     * 申请人主张违约金
56
+     */
57
+    private BigDecimal claimLiquidDamag;
58
+
59
+    /**
60
+     * 证据材料
61
+     */
62
+    private List<CaseAttach> evidenceMaterialList;
63
+    /**
64
+     * 当前登录人身份类型
65
+     */
66
+    private Integer identityType;
67
+}

+ 28
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/domain/vo/CaseEvidenceVO.java ファイルの表示

@@ -0,0 +1,28 @@
1
+package com.ruoyi.wisdomarbitrate.domain.vo;
2
+
3
+
4
+import lombok.Data;
5
+
6
+@Data
7
+public class CaseEvidenceVO {
8
+    /**
9
+     * 案件id
10
+     */
11
+    private Long id;
12
+    /**
13
+     * 案件编号
14
+     */
15
+    private String caseNum;
16
+    /**
17
+     * 申请人姓名
18
+     */
19
+    private String applicantName;
20
+    /**
21
+     * 被申请人姓名
22
+     */
23
+    private String respondentName;
24
+    /**
25
+     * 案件状态
26
+     */
27
+    private Integer caseStatus;
28
+}

+ 11
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/CaseAttachMapper.java ファイルの表示

@@ -0,0 +1,11 @@
1
+package com.ruoyi.wisdomarbitrate.mapper;
2
+
3
+import com.ruoyi.wisdomarbitrate.domain.CaseAttach;
4
+
5
+import java.util.List;
6
+
7
+public interface CaseAttachMapper {
8
+    int save(CaseAttach caseAttach);
9
+
10
+    List<CaseAttach> queryAnnexPathByCaseId(Long id);
11
+}

+ 15
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/CaseEvidenceMapper.java ファイルの表示

@@ -0,0 +1,15 @@
1
+package com.ruoyi.wisdomarbitrate.mapper;
2
+
3
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
4
+import com.ruoyi.wisdomarbitrate.domain.vo.CaseEvidenceVO;
5
+import org.apache.ibatis.annotations.Mapper;
6
+import org.apache.ibatis.annotations.Param;
7
+
8
+import java.util.List;
9
+
10
+@Mapper
11
+public interface CaseEvidenceMapper {
12
+    List<CaseEvidenceVO> getCaseListByRespondent(@Param(value = "identityNum" ) String identityNum
13
+            , @Param(value = "caseStatusList") List<Integer> caseStatusList
14
+            , @Param(value = "identityType" ) Integer identityType);
15
+}

+ 11
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/mapper/CasePaymentRecordMapper.java ファイルの表示

@@ -0,0 +1,11 @@
1
+package com.ruoyi.wisdomarbitrate.mapper;
2
+
3
+import com.ruoyi.wisdomarbitrate.domain.CasePaymentRecord;
4
+
5
+public interface CasePaymentRecordMapper {
6
+    int saveRecord(CasePaymentRecord casePaymentRecord);
7
+
8
+    CasePaymentRecord queryRecord(String orderNumber);
9
+
10
+    void update(CasePaymentRecord casePaymentRecord);
11
+}

+ 10
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/ICaseArbitrateService.java ファイルの表示

@@ -0,0 +1,10 @@
1
+package com.ruoyi.wisdomarbitrate.service;
2
+
3
+import com.ruoyi.common.core.domain.AjaxResult;
4
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
5
+
6
+public interface ICaseArbitrateService {
7
+    AjaxResult chooseArbitrateMethod(CaseApplication caseApplication,Integer arbitratMethod);
8
+
9
+    AjaxResult writtenHear(CaseApplication caseApplication, String accidentDescription, String arbitrationResult);
10
+}

+ 21
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/ICaseEvidenceService.java ファイルの表示

@@ -0,0 +1,21 @@
1
+package com.ruoyi.wisdomarbitrate.service;
2
+
3
+
4
+import com.ruoyi.common.core.domain.AjaxResult;
5
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
6
+import com.ruoyi.wisdomarbitrate.domain.vo.CaseEvidenceVO;
7
+import org.springframework.web.multipart.MultipartFile;
8
+
9
+import java.util.List;
10
+
11
+public interface ICaseEvidenceService {
12
+
13
+    AjaxResult getCaseDetailsById(Long id,String userName);
14
+
15
+    AjaxResult uploadEvidence(MultipartFile file, Integer annexType, Long id,String userName,Long userId);
16
+
17
+    List<CaseEvidenceVO> getCaseListAll(String identityNum);
18
+
19
+    AjaxResult evidenceConfirmation(CaseApplication caseApplication);
20
+
21
+}

+ 15
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/ICasePaymentService.java ファイルの表示

@@ -0,0 +1,15 @@
1
+package com.ruoyi.wisdomarbitrate.service;
2
+
3
+import com.ruoyi.common.core.domain.AjaxResult;
4
+import com.ruoyi.dto.PayRequest;
5
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
6
+import com.ruoyi.wisdomarbitrate.domain.dto.CasePayDTO;
7
+
8
+public interface ICasePaymentService {
9
+    /**
10
+     * 案件缴费
11
+     */
12
+    AjaxResult casePay(CasePayDTO casePayDTO);
13
+
14
+    AjaxResult confirmPayment(CaseApplication caseApplication);
15
+}

+ 35
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CallBackHandleServiceImpl.java ファイルの表示

@@ -0,0 +1,35 @@
1
+package com.ruoyi.wisdomarbitrate.service.impl;
2
+
3
+import com.ruoyi.CallBackService;
4
+import lombok.extern.slf4j.Slf4j;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.stereotype.Component;
7
+
8
+/**
9
+ * 业务回调处理
10
+ */
11
+@Component
12
+@Slf4j
13
+public class CallBackHandleServiceImpl implements CallBackService {
14
+    @Autowired
15
+    private CasePaymentServiceImpl casePaymentService;
16
+    @Override
17
+    public void successPay(String orderSn) {
18
+        casePaymentService.callback(orderSn);
19
+    }
20
+
21
+    @Override
22
+    public void failPay(String orderSn) {
23
+        log.info("支付失败回调!"+orderSn);
24
+    }
25
+
26
+    @Override
27
+    public void successRefund(String orderSn) {
28
+        log.info("退款成功回调!"+orderSn);
29
+    }
30
+
31
+    @Override
32
+    public void failRefund(String orderSn) {
33
+        log.info("退款失败回调!"+orderSn);
34
+    }
35
+}

+ 102
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CaseArbitrateServiceImpl.java ファイルの表示

@@ -0,0 +1,102 @@
1
+package com.ruoyi.wisdomarbitrate.service.impl;
2
+
3
+import com.ruoyi.common.constant.CaseApplicationConstants;
4
+import com.ruoyi.common.core.domain.AjaxResult;
5
+import com.ruoyi.common.utils.SmsUtils;
6
+import com.ruoyi.wisdomarbitrate.domain.CaseAffiliate;
7
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
8
+import com.ruoyi.wisdomarbitrate.domain.CaseLogRecord;
9
+import com.ruoyi.wisdomarbitrate.mapper.CaseAffiliateMapper;
10
+import com.ruoyi.wisdomarbitrate.mapper.CaseApplicationMapper;
11
+import com.ruoyi.wisdomarbitrate.mapper.CaseLogRecordMapper;
12
+import com.ruoyi.wisdomarbitrate.service.ICaseArbitrateService;
13
+import org.springframework.beans.factory.annotation.Autowired;
14
+import org.springframework.stereotype.Service;
15
+import org.springframework.transaction.annotation.Transactional;
16
+
17
+import java.util.List;
18
+
19
+@Service
20
+public class CaseArbitrateServiceImpl implements ICaseArbitrateService {
21
+    @Autowired
22
+    private CaseApplicationMapper caseApplicationMapper;
23
+    @Autowired
24
+    private CaseAffiliateMapper caseAffiliateMapper;
25
+    @Autowired
26
+    private CaseLogRecordMapper caseLogRecordMapper;
27
+
28
+    @Override
29
+    @Transactional
30
+    public AjaxResult chooseArbitrateMethod(CaseApplication caseApplication, Integer arbitratMethod) {
31
+        if (arbitratMethod != null) {
32
+            String arbitratMethodStr = arbitratMethod == 1 ? "开庭审理" : "书面审理";
33
+            //查询案件详细信息
34
+            CaseApplication caseApplication1 = caseApplicationMapper.selectCaseApplication(caseApplication);
35
+            if (caseApplication1 == null) {
36
+                return AjaxResult.error();
37
+            }
38
+            String caseNum = caseApplication1.getCaseNum();
39
+            //选择仲裁方式
40
+            caseApplication.setArbitratMethod(arbitratMethod);
41
+            //修改案件状态为待开庭
42
+            caseApplication.setCaseStatus(CaseApplicationConstants.PENDING_OPENCOURT);
43
+            int i = caseApplicationMapper.submitCaseApplication(caseApplication);
44
+            if (i > 0) {
45
+                //发送短信通知
46
+                SmsUtils.SendSmsRequest request = new SmsUtils.SendSmsRequest();
47
+                request.setTemplateId("1931000");
48
+                CaseAffiliate caseAffiliate = new CaseAffiliate();
49
+                caseAffiliate.setCaseAppliId(caseApplication1.getId());
50
+                List<CaseAffiliate> caseAffiliates = caseAffiliateMapper.selectCaseAffiliate(caseAffiliate);            //获取案件关联人信息
51
+                if (caseAffiliates != null && caseAffiliates.size() > 0) {
52
+                    for (CaseAffiliate affiliate : caseAffiliates) {
53
+                        //获取身份类型
54
+                        int identityType = affiliate.getIdentityType();
55
+                        if (identityType == 1) {    //申请人
56
+                            request.setPhone(affiliate.getContactTelphone());
57
+                            // 这个值,要看你的模板中是否预留了占位符,如果没有则不需要设置
58
+                            // 1931000 普通短信 确定仲裁方式通知 尊敬的{1}用户,您的{2}仲裁案件,仲裁方式已确定为{3},请知晓,如非本人操作,请忽略本短信。
59
+                            String name = affiliate.getName();
60
+                            request.setTemplateParamSet(new String[]{name, caseNum, arbitratMethodStr});
61
+                            SmsUtils.sendSms(request);
62
+                        } else {       //被申请人
63
+                            request.setPhone(affiliate.getContactTelphone());
64
+                            // 模板id1928006 普通短信 案件应诉通知 尊敬的{1}用户,您的{2}案件{3}已成功受理,请点击https://phmapp.xayunmei.com选择是否应诉。
65
+                            String name = affiliate.getName();
66
+                            request.setTemplateParamSet(new String[]{name, caseNum, arbitratMethodStr});
67
+                            SmsUtils.sendSms(request);
68
+                        }
69
+                    }
70
+                }
71
+                return AjaxResult.success("选择成功");
72
+            }
73
+
74
+        }
75
+        return AjaxResult.error("请选择开庭方式");
76
+    }
77
+
78
+    @Override
79
+    public AjaxResult writtenHear(CaseApplication caseApplication, String accidentDescription, String arbitrationResult) {
80
+        //提交仲裁结果
81
+        CaseApplication caseApplication1 = caseApplicationMapper.selectCaseApplication(caseApplication);
82
+        caseApplication1.setCaseDescribe(accidentDescription); //案情描述
83
+        caseApplication1.setCaseResult(arbitrationResult);  //仲裁结果
84
+        int i = caseApplicationMapper.updataCaseApplication(caseApplication1);
85
+        if (i>0){
86
+            //案件日志表里添加数据
87
+            CaseLogRecord caseLogRecord = new CaseLogRecord();
88
+            caseLogRecord.setCaseAppliId(caseApplication1.getId());
89
+            caseLogRecord.setCaseNode(caseApplication1.getCaseStatus());
90
+            String createBy = caseApplication1.getCreateBy();
91
+            if (createBy!=null){
92
+                caseLogRecord.setCreateBy(createBy);
93
+            }
94
+            caseLogRecordMapper.insertCaseLogRecord(caseLogRecord);
95
+            //修改案件状态
96
+            caseApplication.setCaseStatus(CaseApplicationConstants.GENERATED_ARBITRATION);
97
+            caseApplicationMapper.submitCaseApplication(caseApplication);
98
+            return AjaxResult.success("提交成功");
99
+        }
100
+        return AjaxResult.error("暂无需要提交仲裁结果的案件");
101
+    }
102
+}

+ 145
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CaseEvidenceServiceImpl.java ファイルの表示

@@ -0,0 +1,145 @@
1
+package com.ruoyi.wisdomarbitrate.service.impl;
2
+
3
+import com.ruoyi.common.config.RuoYiConfig;
4
+import com.ruoyi.common.constant.CaseApplicationConstants;
5
+import com.ruoyi.common.core.domain.AjaxResult;
6
+import com.ruoyi.common.utils.file.FileUploadUtils;
7
+import com.ruoyi.wisdomarbitrate.domain.CaseAffiliate;
8
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
9
+import com.ruoyi.wisdomarbitrate.domain.CaseAttach;
10
+import com.ruoyi.wisdomarbitrate.domain.vo.CaseDetailVO;
11
+import com.ruoyi.wisdomarbitrate.domain.vo.CaseEvidenceVO;
12
+import com.ruoyi.wisdomarbitrate.mapper.CaseAffiliateMapper;
13
+import com.ruoyi.wisdomarbitrate.mapper.CaseApplicationMapper;
14
+import com.ruoyi.wisdomarbitrate.mapper.CaseAttachMapper;
15
+import com.ruoyi.wisdomarbitrate.mapper.CaseEvidenceMapper;
16
+import com.ruoyi.wisdomarbitrate.service.ICaseEvidenceService;
17
+import org.springframework.beans.BeanUtils;
18
+import org.springframework.beans.factory.annotation.Autowired;
19
+import org.springframework.stereotype.Service;
20
+import org.springframework.transaction.annotation.Transactional;
21
+import org.springframework.web.multipart.MultipartFile;
22
+
23
+import java.io.IOException;
24
+import java.time.LocalDate;
25
+import java.time.LocalDateTime;
26
+import java.time.format.DateTimeFormatter;
27
+import java.util.Arrays;
28
+import java.util.List;
29
+
30
+@Service
31
+public class CaseEvidenceServiceImpl implements ICaseEvidenceService {
32
+    @Autowired
33
+    private CaseEvidenceMapper caseEvidenceMapper;
34
+    @Autowired
35
+    private CaseAffiliateMapper caseAffiliateMapper;
36
+    @Autowired
37
+    private CaseApplicationMapper caseApplicationMapper;
38
+    @Autowired
39
+    private CaseAttachMapper caseAttachMapper;
40
+
41
+    @Override
42
+    @Transactional
43
+    public AjaxResult getCaseDetailsById(Long id,String userName) {
44
+        CaseApplication caseApplication = new CaseApplication();
45
+        caseApplication.setId(id);
46
+        CaseApplication caseApplication1 = caseApplicationMapper.selectCaseApplication(caseApplication);
47
+        if (caseApplication1 != null) {
48
+            CaseDetailVO caseDetailVO = new CaseDetailVO();
49
+            BeanUtils.copyProperties(caseApplication1, caseDetailVO);
50
+            CaseAffiliate caseAffiliate = new CaseAffiliate();
51
+            caseAffiliate.setCaseAppliId(id);
52
+            List<CaseAffiliate> caseAffiliates = caseAffiliateMapper.selectCaseAffiliate(caseAffiliate);
53
+            for (CaseAffiliate affiliate : caseAffiliates) {
54
+                String name = affiliate.getName();
55
+                //判断当前登录人和案件关联人姓名是否一致
56
+                if (name.equals(userName)) {  //一致,将案件关联人的身份类型赋给当前登录人
57
+                    caseDetailVO.setIdentityType(affiliate.getIdentityType());
58
+                }
59
+                if (affiliate.getIdentityType() == 1) {  //申请人
60
+                    caseDetailVO.setApplicantName(affiliate.getName());
61
+                } else {
62
+                    caseDetailVO.setRespondentName(affiliate.getName());
63
+                }
64
+                //根据案件id查询案件证据材料
65
+                List<CaseAttach> evidenceMaterialList = caseAttachMapper.queryAnnexPathByCaseId(id);
66
+                caseDetailVO.setEvidenceMaterialList(evidenceMaterialList);
67
+            }
68
+            return AjaxResult.success(caseDetailVO);
69
+        }
70
+        return null;
71
+    }
72
+
73
+    @Override
74
+    @Transactional
75
+    public AjaxResult uploadEvidence(MultipartFile file, Integer annexType, Long id, String userName, Long userId) {
76
+
77
+        if (file.isEmpty()) {
78
+            return AjaxResult.error("请选择要上传的文件");
79
+        }
80
+        try {
81
+            String filePath = RuoYiConfig.getUploadPath();
82
+            // 上传
83
+            String fileName = FileUploadUtils.upload(filePath, file);
84
+            CaseAttach caseAttach = CaseAttach.builder().caseAppliId(id)
85
+                    .annexName(fileName)
86
+                    .annexPath(filePath)
87
+                    .annexType(annexType)
88
+                    .userId(userId)
89
+                    .userName(userName)
90
+                    .build();
91
+            int count = caseAttachMapper.save(caseAttach);
92
+            if (count > 0) {
93
+                //修改案件状态
94
+                CaseApplication caseApplication = new CaseApplication();
95
+                caseApplication.setId(id);
96
+                caseApplication.setCaseStatus(4);
97
+                caseApplicationMapper.submitCaseApplication(caseApplication);
98
+                return AjaxResult.success("上传成功");
99
+            }
100
+        } catch (IOException e) {
101
+            e.printStackTrace();
102
+        }
103
+
104
+        return AjaxResult.error("上传失败");
105
+    }
106
+
107
+
108
+
109
+    @Override
110
+    public List<CaseEvidenceVO> getCaseListAll(String identityNum) {
111
+        List<Integer> caseStatusList = Arrays.asList(3, 4, 5, 9);
112
+        return getCaseEvidenceVOList(identityNum, caseStatusList, null);
113
+    }
114
+
115
+    @Override
116
+    public AjaxResult evidenceConfirmation(CaseApplication caseApplication) {
117
+        caseApplication.setCaseStatus(CaseApplicationConstants.PENDING_APPOINT_ARBOTRATAR);
118
+        int i = caseApplicationMapper.submitCaseApplication(caseApplication);
119
+        if (i>0){
120
+            return AjaxResult.success("证据确认成功");
121
+        }
122
+        return AjaxResult.error("暂无需要确认的证据");
123
+    }
124
+
125
+    private List<CaseEvidenceVO> getCaseEvidenceVOList(String identityNum, List<Integer> caseStatusList, Integer identityType) {
126
+        List<CaseEvidenceVO> caseListByRespondent = caseEvidenceMapper.getCaseListByRespondent(identityNum, caseStatusList, identityType);
127
+        if (caseListByRespondent != null && caseListByRespondent.size() > 0) {
128
+            for (CaseEvidenceVO caseEvidenceVO : caseListByRespondent) {
129
+                //根据案件id查询姓名
130
+                CaseAffiliate caseAffiliate = new CaseAffiliate();
131
+                caseAffiliate.setCaseAppliId(caseEvidenceVO.getId());
132
+                List<CaseAffiliate> caseAffiliates = caseAffiliateMapper.selectCaseAffiliate(caseAffiliate);
133
+                for (CaseAffiliate affiliate : caseAffiliates) {
134
+                    if (affiliate.getIdentityType() == 1) {  //申请人
135
+                        caseEvidenceVO.setApplicantName(affiliate.getName());
136
+                    } else {
137
+                        caseEvidenceVO.setRespondentName(affiliate.getName());
138
+                    }
139
+                }
140
+            }
141
+            return caseListByRespondent;
142
+        }
143
+        return null;
144
+    }
145
+}

+ 0
- 1
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CaseLogRecordServiceImpl.java ファイルの表示

@@ -17,7 +17,6 @@ public class CaseLogRecordServiceImpl  implements ICaseLogRecordService {
17 17
     @Override
18 18
     public List<CaseLogRecord> selectCaseLogRecordList(CaseLogRecord caseLogRecord) {
19 19
         return caseLogRecordMapper.selectCaseLogRecordList(caseLogRecord);
20
-
21 20
     }
22 21
 
23 22
 

+ 135
- 0
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/CasePaymentServiceImpl.java ファイルの表示

@@ -0,0 +1,135 @@
1
+package com.ruoyi.wisdomarbitrate.service.impl;
2
+
3
+
4
+import com.ruoyi.ElegentPay;
5
+import com.ruoyi.common.constant.CaseApplicationConstants;
6
+import com.ruoyi.common.core.domain.AjaxResult;
7
+import com.ruoyi.common.utils.SmsUtils;
8
+import com.ruoyi.dto.PayRequest;
9
+import com.ruoyi.dto.PayResponse;
10
+import com.ruoyi.wisdomarbitrate.domain.CaseAffiliate;
11
+import com.ruoyi.wisdomarbitrate.domain.CaseApplication;
12
+import com.ruoyi.wisdomarbitrate.domain.CasePaymentRecord;
13
+import com.ruoyi.wisdomarbitrate.domain.dto.CasePayDTO;
14
+import com.ruoyi.wisdomarbitrate.mapper.CaseAffiliateMapper;
15
+import com.ruoyi.wisdomarbitrate.mapper.CaseApplicationMapper;
16
+import com.ruoyi.wisdomarbitrate.mapper.CasePaymentRecordMapper;
17
+import com.ruoyi.wisdomarbitrate.service.ICasePaymentService;
18
+import org.springframework.beans.factory.annotation.Autowired;
19
+import org.springframework.stereotype.Service;
20
+import org.springframework.transaction.annotation.Transactional;
21
+
22
+import java.time.LocalDateTime;
23
+import java.util.Date;
24
+import java.util.List;
25
+
26
+@Service
27
+public class CasePaymentServiceImpl implements ICasePaymentService {
28
+    private final ElegentPay elegentPay;
29
+    private final CaseApplicationMapper caseApplicationMapper;
30
+    private final CasePaymentRecordMapper casePaymentRecordMapper;
31
+    private final CaseAffiliateMapper caseAffiliateMapper;
32
+
33
+    @Autowired
34
+    public CasePaymentServiceImpl(ElegentPay elegentPay
35
+            , CaseApplicationMapper caseApplicationMapper
36
+            , CasePaymentRecordMapper casePaymentRecordMapper
37
+            , CaseAffiliateMapper caseAffiliateMapper) {
38
+        this.elegentPay = elegentPay;
39
+        this.caseApplicationMapper = caseApplicationMapper;
40
+        this.casePaymentRecordMapper = casePaymentRecordMapper;
41
+        this.caseAffiliateMapper = caseAffiliateMapper;
42
+    }
43
+
44
+    @Override
45
+    @Transactional
46
+    public AjaxResult casePay(CasePayDTO casePayDTO) {
47
+        PayRequest payRequest = new PayRequest();
48
+        payRequest.setBody("案件缴费");
49
+        payRequest.setOrderSn(System.currentTimeMillis() + "");
50
+        payRequest.setTotalFee(casePayDTO.getTotalFee());
51
+        PayResponse response = elegentPay.requestPay(payRequest, casePayDTO.getTradeType(), casePayDTO.getPlatform());
52
+        if (response.getCode_url() == null) {
53
+            return AjaxResult.error();
54
+        }
55
+        //缴费记录表里新增数据
56
+        CasePaymentRecord casePaymentRecord = new CasePaymentRecord();
57
+        casePaymentRecord.setCaseId(casePayDTO.getCaseId());
58
+        casePaymentRecord.setOrderNumber(payRequest.getOrderSn());
59
+        casePaymentRecord.setPaymentStatus(0);
60
+        casePaymentRecord.setCreateTime(new Date());
61
+        int count = casePaymentRecordMapper.saveRecord(casePaymentRecord);
62
+        if (count < 1) {
63
+            return AjaxResult.error("请检查参数是否有误");
64
+        }
65
+        return AjaxResult.success(response);
66
+    }
67
+
68
+    @Transactional
69
+    public AjaxResult callback(String orderNumber) {
70
+        //查询记录
71
+        CasePaymentRecord casePaymentRecord = casePaymentRecordMapper.queryRecord(orderNumber);
72
+        if (casePaymentRecord == null) {
73
+            return AjaxResult.error("未查询到相关记录");
74
+        }
75
+        Long caseId = casePaymentRecord.getCaseId();
76
+        //更改记录表里的支付状态和支付时间
77
+        casePaymentRecord.setPaymentStatus(1);
78
+        casePaymentRecord.setPaymentTime(new Date());
79
+        casePaymentRecord.setUpdateTime(new Date());
80
+        casePaymentRecordMapper.update(casePaymentRecord);
81
+        //根据案件id查询案件信息
82
+        CaseApplication caseApplication = new CaseApplication();
83
+        caseApplication.setId(caseId);
84
+        CaseApplication caseApplication1 = caseApplicationMapper.selectCaseApplication(caseApplication);
85
+        caseApplication1.setCaseStatus(CaseApplicationConstants.PENDING_PAYMENT_CONFIRM);
86
+        //修改案件状态
87
+        caseApplicationMapper.submitCaseApplication(caseApplication1);
88
+        return AjaxResult.success();
89
+    }
90
+
91
+    @Override
92
+    @Transactional
93
+    public AjaxResult confirmPayment(CaseApplication caseApplication) {
94
+        caseApplication.setCaseStatus(CaseApplicationConstants.CONFIRMDED_RESPOND);
95
+        int i = caseApplicationMapper.submitCaseApplication(caseApplication);
96
+        if (i > 0) {
97
+            //发送短信通知
98
+            SmsUtils.SendSmsRequest request = new SmsUtils.SendSmsRequest();
99
+            CaseAffiliate caseAffiliate = new CaseAffiliate();
100
+            caseAffiliate.setCaseAppliId(caseApplication.getId());
101
+            List<CaseAffiliate> caseAffiliates = caseAffiliateMapper.selectCaseAffiliate(caseAffiliate);            //获取案件关联人信息
102
+            if (caseAffiliates != null && caseAffiliates.size() > 0) {
103
+                for (CaseAffiliate affiliate : caseAffiliates) {
104
+                    //获取身份类型
105
+                    int identityType = affiliate.getIdentityType();
106
+                    //查询案件详细信息
107
+                    CaseApplication caseApplication1 = caseApplicationMapper.selectCaseApplication(caseApplication);
108
+                    if (caseApplication1 == null) {
109
+                        return AjaxResult.error();
110
+                    }
111
+                    String caseName = "仲裁"; //这里案件名称表里未定义,暂时写死
112
+                    String caseNum = caseApplication1.getCaseNum();
113
+                    if (identityType == 1) {    //申请人
114
+                        request.setPhone(affiliate.getContactTelphone());
115
+                        request.setTemplateId("1928003"); //传入申请人模板id
116
+                        // 这个值,要看你的模板中是否预留了占位符,如果没有则不需要设置
117
+                        // 模板id:1928003 普通短信 案件受理通知 尊敬的{1}用户,您的{2}案件{3}已成功受理。
118
+                        String name = affiliate.getName();
119
+                        request.setTemplateParamSet(new String[]{name, caseName, caseNum});
120
+                        SmsUtils.sendSms(request);
121
+                    } else {       //被申请人
122
+                        request.setPhone(affiliate.getContactTelphone());
123
+                        request.setTemplateId("1928006");
124
+                        // 模板id1928006 普通短信 案件应诉通知 尊敬的{1}用户,您的{2}案件{3}已成功受理,请点击https://phmapp.xayunmei.com选择是否应诉。
125
+                        String name = affiliate.getName();
126
+                        request.setTemplateParamSet(new String[]{name, caseName, caseNum});
127
+                        SmsUtils.sendSms(request);
128
+                    }
129
+                }
130
+                return AjaxResult.success();
131
+            }
132
+        }
133
+        return AjaxResult.error("暂无需要确认的缴费清单");
134
+    }
135
+}

+ 4
- 3
ruoyi-system/src/main/java/com/ruoyi/wisdomarbitrate/service/impl/IdentityAuthenticationServiceImpl.java ファイルの表示

@@ -40,7 +40,7 @@ public class IdentityAuthenticationServiceImpl  implements IdentityAuthenticatio
40 40
 
41 41
     @Override
42 42
     public IdentityAuthentication selectIdentityInformation() {
43
-        IdentityAuthentication identityAuthentication = new IdentityAuthentication();
43
+      /*  IdentityAuthentication identityAuthentication = new IdentityAuthentication();
44 44
         try{
45 45
             Credential credIdentityAuthentication = new Credential(credentialSecretId, credentialSecretKey);
46 46
             HttpProfile httpProfileIdentityAuthentication = new HttpProfile();
@@ -92,7 +92,8 @@ public class IdentityAuthenticationServiceImpl  implements IdentityAuthenticatio
92 92
             log.error("身份认证失败", e);
93 93
         }
94 94
 
95
-        return identityAuthentication;
96
-
95
+        return identityAuthentication;*/
96
+        return null;
97 97
     }
98
+
98 99
 }

+ 1
- 0
ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CaseApplicationMapper.xml ファイルの表示

@@ -145,6 +145,7 @@
145 145
             <if test="arbitratorId != null and arbitratorId != ''">arbitrator_id = #{arbitratorId},</if>
146 146
             <if test="arbitratorName != null and arbitratorName != ''">arbitrator_name = #{arbitratorName},</if>
147 147
             <if test="pendingAppointArbotrar != null ">pending_appoint_arbotrar = #{pendingAppointArbotrar},</if>
148
+            <if test="arbitratMethod != null ">arbitrat_method = #{arbitratMethod},</if>
148 149
             <if test="caseName != null  and caseName != ''">case_name = #{caseName},</if>
149 150
             <if test="caseDescribe != null  and caseDescribe != ''">case_describe = #{caseDescribe},</if>
150 151
             <if test="caseResult != null  and caseResult != ''">case_result = #{caseResult},</if>

+ 25
- 0
ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CaseAttachMapper.xml ファイルの表示

@@ -0,0 +1,25 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper
3
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
+<mapper namespace="com.ruoyi.wisdomarbitrate.mapper.CaseAttachMapper">
6
+    <resultMap type="CaseAttach" id="CaseAttachResult">
7
+        <id     property="annexId"       column="annex_id"      />
8
+        <result property="caseAppliId"       column="case_appli_id"      />
9
+        <result property="annexName"     column="annex_name"    />
10
+        <result property="annexPath"     column="annex_path"    />
11
+        <result property="annexType"     column="annex_type"    />
12
+        <result property="note"     column="note"    />
13
+        <result property="userId"     column="use_id"    />
14
+        <result property="userName"     column="use_account"    />
15
+    </resultMap>
16
+    <insert id="save">
17
+        INSERT INTO case_attach (case_appli_id, annex_name, annex_path , annex_type,note,use_id,use_account)
18
+        VALUES (#{caseAppliId}, #{annexName}, #{annexPath},#{annexType},#{note},#{userId},#{userName})
19
+    </insert>
20
+    <select id="queryAnnexPathByCaseId" resultType="com.ruoyi.wisdomarbitrate.domain.CaseAttach" resultMap="CaseAttachResult">
21
+        select annex_id,case_appli_id,annex_name,annex_path,annex_type,note,use_id,use_account
22
+        from case_attach
23
+        where case_appli_id =#{id}
24
+    </select>
25
+</mapper>

+ 28
- 0
ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CaseEvidenceMapper.xml ファイルの表示

@@ -0,0 +1,28 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper
3
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
+<mapper namespace="com.ruoyi.wisdomarbitrate.mapper.CaseEvidenceMapper">
6
+    <resultMap type="CaseEvidenceVO" id="CaseEvidenceVOResult">
7
+        <id     property="id"       column="id"      />
8
+        <result property="caseNum"       column="case_num"      />
9
+        <result property="caseStatus"     column="case_status"    />
10
+    </resultMap>
11
+    <select id="getCaseListByRespondent" resultType="CaseEvidenceVO" resultMap="CaseEvidenceVOResult">
12
+        select c.id, c.case_num,c.case_status
13
+        from case_application as c  ,case_affiliate as d
14
+        where c.id = d.case_appli_id
15
+        <if test="identityNum != null and identityNum != ''">
16
+            and d.identity_num = #{identityNum}
17
+        </if>
18
+        <if test="identityType != null ">
19
+            and identity_type = #{identityType}
20
+        </if>
21
+        <if test="caseStatusList != null and caseStatusList.size() > 0">
22
+            and c.case_status in
23
+            <foreach item="caseStatus" collection="caseStatusList" open="(" separator="," close=")">
24
+                #{caseStatus}
25
+            </foreach>
26
+        </if>
27
+    </select>
28
+</mapper>

+ 39
- 0
ruoyi-system/src/main/resources/mapper/wisdomarbitrate/CasePaymentRecordMapper.xml ファイルの表示

@@ -0,0 +1,39 @@
1
+<?xml version="1.0" encoding="UTF-8" ?>
2
+<!DOCTYPE mapper
3
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
+<mapper namespace="com.ruoyi.wisdomarbitrate.mapper.CasePaymentRecordMapper">
6
+    <resultMap type="CasePaymentRecord" id="CasePaymentRecordResult">
7
+        <id     property="id"       column="id"      />
8
+        <result property="caseId"       column="case_id"      />
9
+        <result property="orderNumber"     column="order_number"    />
10
+        <result property="paymentStatus"     column="payment_status"    />
11
+        <result property="paymentTime"        column="payment_time"        />
12
+        <result property="createTime"   column="create_time"  />
13
+        <result property="updateTime"   column="update_time"  />
14
+    </resultMap>
15
+    <insert id="saveRecord">
16
+        INSERT INTO case_payment_record (case_id, order_number, payment_status , create_time)
17
+        VALUES (#{caseId}, #{orderNumber}, #{paymentStatus},#{createTime})
18
+    </insert>
19
+    <update id="update">
20
+        update case_payment_record
21
+        <set>
22
+            <if test="caseId != null">case_id= #{caseId},</if>
23
+            <if test="orderNumber != null and orderNumber != ''">order_number = #{orderNumber},</if>
24
+            <if test="paymentTime != null ">payment_time = #{paymentTime},</if>
25
+            <if test="paymentStatus != null ">payment_status = #{paymentStatus},</if>
26
+            <if test="updateTime != null ">update_time = #{updateTime},</if>
27
+        </set>
28
+        where id = #{id}
29
+    </update>
30
+    <select id="queryRecord" resultType="com.ruoyi.wisdomarbitrate.domain.CasePaymentRecord" resultMap="CasePaymentRecordResult">
31
+        select c.id ,c.case_id ,c.order_number ,c.payment_time ,c.create_time ,c.update_time ,c.payment_status
32
+        from case_payment_record c
33
+        <where>
34
+            <if test="orderNumber != null ">
35
+                AND c.order_number = #{orderNumber}
36
+            </if>
37
+        </where>
38
+    </select>
39
+</mapper>