From 5e2faddb34e79918b73dc75aca8f63048dd4526d Mon Sep 17 00:00:00 2001
From: liurunyu <lry9898@163.com>
Date: 星期一, 15 七月 2024 20:53:33 +0800
Subject: [PATCH] Merge branch 'master' of http://8.140.179.55:20000/r/pipIrr-SV
---
pipIrr-platform/pipIrr-global/src/main/resources/application-database-sp.yml | 3
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java | 26
pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaBlockMapper.xml | 4
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/CardOperateCtrl.java | 8
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java | 26
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java | 26
pipIrr-platform/pipIrr-global/src/main/resources/application-database-pj.yml | 3
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/dto/ActiveCard.java | 6
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/client/ClientCtrl.java | 3
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java | 23
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml | 7
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrIntakeMapper.java | 12
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java | 9
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeCardOperateMapper.xml | 2
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/AesUtil.java | 50 +
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/Refund.java | 39 +
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/ToRefund.java | 35 +
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeSv.java | 45
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrIntakeMapper.xml | 29
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundRequest.java | 70 ++
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/result/WechatResultCode.java | 15
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/PayHelper.java | 508 +++++++++++++++
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardCtrl.java | 269 ++++++++
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundResponse.java | 114 +++
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/HmacSha256.java | 43 +
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/PayInfo.java | 176 +++++
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeCtrl.java | 7
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardSv.java | 352 +++++++++++
pipIrr-platform/pipIrr-global/src/main/resources/application-database-ym.yml | 4
29 files changed, 1,868 insertions(+), 46 deletions(-)
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java
index 6275ab9..f35cd89 100644
--- a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java
@@ -19,7 +19,6 @@
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -46,8 +45,8 @@
*/
public class ComSupport {
- @Value("${mw.comSendUrl}")
- private String comSendUrl;
+ //@Value("${mw.comSendUrl}")
+ protected String comSendUrl;
protected static String controllerType = null;
protected static Integer projectNo = null;
@@ -73,6 +72,9 @@
private SeVirtualCardMapper seVirtualCardMapper;
public static ComSupport comSupport;
+
+ public ComSupport() {
+ }
/**
* 寮曞叆BaSettingsMapper
@@ -124,6 +126,7 @@
job_rtu.put("rtuAddr", prController.getRtuAddr());
job_rtu.put("protocol", prController.getProtocol());
job_rtu.put("intakeId", prController.getIntakeId());
+ job_rtu.put("orgTag", prController.getOrgTag());
return job_rtu;
}
diff --git a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrIntakeMapper.java b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrIntakeMapper.java
index bbdc3d0..c5c2f24 100644
--- a/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrIntakeMapper.java
+++ b/pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrIntakeMapper.java
@@ -113,14 +113,14 @@
List<Map<String, Object>> getNoBindingIntakes();
/**
- * 鑾峰彇鍙栨按鍙f暟閲忥紙鍦ㄧ嚎鍜屼笉鍦ㄧ嚎锛�
+ * 鑾峰彇鍙栨按鍙f暟閲忥紙鍦ㄧ嚎鍜屼笉鍦ㄧ嚎锛夊簾寮�
* @param params
* @return
*/
Long getOnLineIntakesCount(Map<?, ?> params);
/**
- * 鑾峰彇鍙栨按鍙e垪琛紙鍦ㄧ嚎鍜屼笉鍦ㄧ嚎锛�
+ * 鑾峰彇鍙栨按鍙e垪琛紙鍦ㄧ嚎鍜屼笉鍦ㄧ嚎锛夊簾寮�
* @param params
* @return
*/
@@ -128,6 +128,14 @@
List<VoOnLineIntake> getOnLineIntakes(Map<?, ?> params);
/**
+ * 鏍规嵁鍙栨按鍙g紪鍙疯幏鍙栧彇姘村彛瀵硅薄
+ * @param params
+ * @return
+ */
+ VoOnLineIntake getIntakeByName(Map<?, ?> params);
+
+
+ /**
* 鏍规嵁鎿嶄綔鍛樿幏鍙栧父鐢ㄥ彇姘村彛
* @return
*/
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/application-database-pj.yml b/pipIrr-platform/pipIrr-global/src/main/resources/application-database-pj.yml
index c564354..76dece8 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/application-database-pj.yml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/application-database-pj.yml
@@ -6,7 +6,8 @@
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://192.168.40.166:3306/pipIrr_pj?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
- url: jdbc:mysql://8.140.179.55:3306/pipIrr_pj?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
+ url: jdbc:mysql://127.0.0.1:3306/pipIrr_pj?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
+# url: jdbc:mysql://8.140.179.55:3306/pipIrr_pj?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
username: root
password: dysql,;.abc!@#
druid:
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/application-database-sp.yml b/pipIrr-platform/pipIrr-global/src/main/resources/application-database-sp.yml
index f9678d7..1bbe4e2 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/application-database-sp.yml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/application-database-sp.yml
@@ -6,7 +6,8 @@
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://192.168.40.166:3306/pipIrr_sp?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
- url: jdbc:mysql://127.0.0.1:3306/pipIrr_sp?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
+# url: jdbc:mysql://127.0.0.1:3306/pipIrr_sp?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
+ url: jdbc:mysql://8.140.179.55:3306/pipIrr_sp?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
username: root
password: dysql,;.abc!@#
druid:
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/application-database-ym.yml b/pipIrr-platform/pipIrr-global/src/main/resources/application-database-ym.yml
index ab10469..3b1c640 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/application-database-ym.yml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/application-database-ym.yml
@@ -5,8 +5,8 @@
#name: ym
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
-# url: jdbc:mysql://192.168.40.166:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
- url: jdbc:mysql://127.0.0.1:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
+ url: jdbc:mysql://192.168.40.166:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
+# url: jdbc:mysql://127.0.0.1:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
# url: jdbc:mysql://8.140.179.55:3306/pipIrr_ym?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
username: root
password: dysql,;.abc!@#
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaBlockMapper.xml b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaBlockMapper.xml
index 93e6e80..4b4bcd7 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaBlockMapper.xml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaBlockMapper.xml
@@ -26,7 +26,7 @@
select
<include refid="Base_Column_List" />
from ba_block
- where id = #{id,jdbcType=BIGINT}
+ where id = #{id,jdbcType=BIGINT} and deleted = 0
</select>
<select id="selectAll" resultMap="BaseResultMap">
@@ -34,6 +34,7 @@
<!-- <include refid="part_Column_List" />-->
<include refid="Base_Column_List" />
from ba_block
+ WHERE deleted = 0
</select>
<select id="selectTotal" parameterType="java.util.Map" resultType="java.lang.Long">
@@ -61,6 +62,7 @@
<include refid="Base_Column_List" />
from ba_block
<trim prefix="where " suffixOverrides="and">
+ deleted = 0 and
<if test="name != null and name != ''">
name like concat('%', #{name}, '%') and
</if>
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrIntakeMapper.xml b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrIntakeMapper.xml
index af30365..3099a55 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrIntakeMapper.xml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrIntakeMapper.xml
@@ -358,7 +358,7 @@
WHERE id NOT IN(SELECT intakeId FROM pr_controller) AND deleted = 0
</select>
- <!--鑾峰彇鍙栨按鍙f暟閲忥紙鍦ㄧ嚎鍜屼笉鍦ㄥ厛锛�-->
+ <!--鑾峰彇鍙栨按鍙f暟閲忥紙鍦ㄧ嚎鍜屼笉鍦ㄥ厛锛� 搴熷純-->
<select id="getOnLineIntakesCount" resultType="java.lang.Long">
SELECT
COUNT(*) AS recordCount
@@ -382,7 +382,7 @@
</where>
</select>
- <!--鑾峰彇鍙栨按鍙e垪琛紙鍦ㄧ嚎鍜屼笉鍦ㄥ厛锛�-->
+ <!--鑾峰彇鍙栨按鍙e垪琛紙鍦ㄧ嚎鍜屼笉鍦ㄥ厛锛� 搴熷純-->
<select id="getOnLineIntakes" resultType="com.dy.pipIrrGlobal.voPr.VoOnLineIntake">
SELECT
con.intakeId,
@@ -413,6 +413,31 @@
</if>
</select>
+ <!--鏍规嵁鍙栨按鍙g紪鍙疯幏鍙栧彇姘村彛瀵硅薄-->
+ <select id="getIntakeByName" resultType="com.dy.pipIrrGlobal.voPr.VoOnLineIntake">
+ SELECT
+ con.intakeId,
+ con.rtuAddr,
+ inta.name AS intakeNum,
+ rtus.isOnLine
+ FROM pr_controller con
+ INNER JOIN pr_intake inta ON con.intakeId = inta.id
+ left JOIN JSON_TABLE(
+ #{onLineMap},
+ '$[*]' COLUMNS(
+ rtuAddr VARCHAR(20) PATH '$.rtuAddr',
+ isOnLine BOOLEAN PATH '$.isOnLine'
+ )
+ ) rtus ON con.rtuAddr = rtus.rtuAddr
+ <where>
+ <if test="intakeNum != null and intakeNum != ''">
+ AND LOWER(inta.name) = #{intakeNum}
+ </if>
+ </where>
+ LIMIT 0,1
+
+ </select>
+
<!--鏍规嵁鎿嶄綔鍛樿幏鍙栧父鐢ㄥ彇姘村彛-->
<select id="getUsedIntakes" resultType="com.dy.pipIrrGlobal.voPr.VoOnLineIntake">
SELECT
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeCardOperateMapper.xml b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeCardOperateMapper.xml
index b39aad5..8baa1e8 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeCardOperateMapper.xml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeCardOperateMapper.xml
@@ -690,5 +690,7 @@
AND ope.operate_type = 6
AND card.cardNum = #{cardNum}
</where>
+ ORDER BY ope.operate_dt DESC
+ LIMIT 0,1
</select>
</mapper>
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml
index d828d9e..71d1989 100644
--- a/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml
+++ b/pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml
@@ -56,9 +56,10 @@
<select id="getCardIdAndClientNum" resultType="java.util.Map">
<!-- SELECT id AS cardId, clientNum FROM se_client_card WHERE cardNum = #{cardNum}-->
SELECT
- card.id AS cardId,
- cli.clientNum,
- cli.id AS clientId
+ card.id AS cardId,
+ cli.clientNum,
+ cli.id AS clientId,
+ protocol
FROM se_client_card card
INNER JOIN se_client cli ON card.clientId = cli.id
WHERE card.cardNum = #{cardNum}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java b/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java
index 0fc696d..93cd402 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
+import com.dy.common.multiDataSource.DataSourceContext;
import com.dy.common.mw.protocol.Command;
import com.dy.common.webUtil.QueryResultVo;
import com.dy.pipIrrGlobal.command.ComSupport;
@@ -23,6 +24,8 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.PojoUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.time.format.DateTimeFormatter;
@@ -48,6 +51,25 @@
private final PrWaterPriceMapper prWaterPriceMapper;
private final PrIntakeVcMapper prIntakeVcMapper;
private final SeClientCardMapper seClientCardMapper;
+
+ /**
+ * pro_mw锛氬睘鎬�
+ * tag浠庢帶鍒跺櫒涓幏鍙�
+ * key_mw锛歶rl鐨刱ey
+ */
+ private Environment env = null;
+ private String pro_mw = "mw";
+ private String key_mw = "comSendUrl";
+ @Autowired
+ public CommandSv(RmCommandHistoryMapper rmCommandHistoryMapper, SeVirtualCardMapper seVirtualCardMapper, PrIntakeMapper prIntakeMapper, PrWaterPriceMapper prWaterPriceMapper, PrIntakeVcMapper prIntakeVcMapper, SeClientCardMapper seClientCardMapper, Environment env) {
+ this.rmCommandHistoryMapper = rmCommandHistoryMapper;
+ this.seVirtualCardMapper = seVirtualCardMapper;
+ this.prIntakeMapper = prIntakeMapper;
+ this.prWaterPriceMapper = prWaterPriceMapper;
+ this.prIntakeVcMapper = prIntakeVcMapper;
+ this.seClientCardMapper = seClientCardMapper;
+ this.env = env;
+ }
/**
* 铏氭嫙鍗D鎹㈣櫄鎷熷崱瀵硅薄
@@ -95,9 +117,9 @@
com.id = Command.defaultId;
com.code = "LCD0001";
com.type = "innerCommand";
+ comSendUrl = env.getProperty(pro_mw + "." + DataSourceContext.get() + "." + key_mw);
JSONObject response = (JSONObject) JSON.toJSON(sendCom2Mw(com));
-
if(response != null && response.getString("code").equals("0001")) {
JSONObject attachment = response.getJSONObject("content").getJSONObject("attachment").getJSONObject("onLineMap");
HashMap<String, Boolean> onLineMap = JSON.parseObject(attachment.toJSONString(), HashMap.class);
@@ -151,9 +173,9 @@
com.id = Command.defaultId;
com.code = "LCD0001";
com.type = "innerCommand";
+ comSendUrl = env.getProperty(pro_mw + "." + DataSourceContext.get() + "." + key_mw);
JSONObject response = (JSONObject) JSON.toJSON(sendCom2Mw(com));
-
if(response != null && response.getString("code").equals("0001")) {
JSONObject attachment = response.getJSONObject("content").getJSONObject("attachment").getJSONObject("onLineMap");
HashMap<String, Boolean> onLineMap = JSON.parseObject(attachment.toJSONString(), HashMap.class);
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java
index 84668b9..279d91c 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java
@@ -22,10 +22,11 @@
import com.dy.pipIrrRemote.result.RemoteResultCode;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
@@ -47,7 +48,7 @@
@Tag(name = "骞冲彴闃�鎺у櫒鎺у埗", description = "骞冲彴闃�鎺у櫒鎺у埗")
@RestController
@RequestMapping(path="valve")
-@RequiredArgsConstructor
+//@RequiredArgsConstructor
public class ValveCtrl extends ComSupport {
private final CommandSv commandSv;
private final SeVirtualCardMapper seVirtualCardMapper;
@@ -55,6 +56,23 @@
@Value("${mw.rtuCallbackUrl_rm}")
private String rtuCallbackUrl_rm;
+
+ /**
+ * pro_mw锛氬睘鎬�
+ * tag浠庢帶鍒跺櫒涓幏鍙�
+ * key_mw锛歶rl鐨刱ey
+ */
+ private Environment env = null;
+ private String pro_mw = "mw";
+ private String key_mw = "comSendUrl";
+
+ @Autowired
+ public ValveCtrl(CommandSv commandSv, SeVirtualCardMapper seVirtualCardMapper, IDLongGenerator idLongGenerator, Environment env) {
+ this.commandSv = commandSv;
+ this.seVirtualCardMapper = seVirtualCardMapper;
+ this.idLongGenerator = idLongGenerator;
+ this.env = env;
+ }
/**
* 骞冲彴杩滅▼寮�闃�
@@ -112,6 +130,8 @@
}
String rtuAddr = job_rtu.getString("rtuAddr");
String protocol = job_rtu.getString("protocol");
+ String orgTag = job_rtu.getString("orgTag");
+ comSendUrl = env.getProperty(pro_mw + "." + orgTag + "." + key_mw);
// 鐢熸垚璁㈠崟鍙�
String orderNo = generateOrderNo();
@@ -229,6 +249,8 @@
}
//Long intakeId = job_rtu.getLong("intakeId");
String protocol = job_rtu.getString("protocol");
+ String orgTag = job_rtu.getString("orgTag");
+ comSendUrl = env.getProperty(pro_mw + "." + orgTag + "." + key_mw);
String commandCode = null;
if(protocol.equals("p206V202404")) {
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/CardOperateCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/CardOperateCtrl.java
index b607fb5..5cb744f 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/CardOperateCtrl.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/CardOperateCtrl.java
@@ -107,6 +107,7 @@
* operator 鎿嶄綔浜虹紪鍙�
* activeTime 寮�鍗℃椂闂�
*/
+ String protocol = po.getProtocol();
String cardAddr = po.getCardAddr();
Integer cardCost = po.getCardCost();
Long originalCardId = po.getOriginalCardId();
@@ -120,6 +121,7 @@
* 娣诲姞鍐滄埛鍗¤褰曪紝閫�杩橀噾棰濅綔涓哄綋鍓嶄綑棰�
*/
SeClientCard seClientCard = new SeClientCard();
+ seClientCard.setProtocol(protocol);
seClientCard.setCardaddr(cardAddr);
seClientCard.setCardnum(cardNum);
seClientCard.setClientid(clientId);
@@ -207,6 +209,7 @@
* operator 鎿嶄綔浜虹紪鍙�
*/
+ String protocol;
String cardAddr = po.getCardAddr();
String clientNum = "";
Long clientId = 0L;
@@ -226,7 +229,7 @@
// 濡傛灉浼犲叆浜嗛��杩橀噾棰濓紝闇�瑕佸垽鏂�佸崱锛堣鎸傚け鐨勬按鍗★級鎸傚け鏃舵槸鍚﹀凡缁忛��娆撅紝鏃犺閫�娆惧灏戦兘鎻愮ず鐢ㄦ埛鎸傚け鏃跺凡閫�娆�
if(reissueAmount != null && reissueAmount > 0) {
Double tradeAmount = cardOperateSv.getTradeAmountByCardNo(cardNum);
- if(tradeAmount != null) {
+ if(tradeAmount != null && tradeAmount > 0) {
return BaseResponseUtils.buildErrorMsg(SellResultCode.THE_FEE_CANNOT_BE_REFUNDED.getMessage());
}
}
@@ -241,6 +244,7 @@
clientNum = map.get("clientNum").toString();
cardId = Long.parseLong(map.get("cardId").toString());
clientId = Long.parseLong(map.get("clientId").toString());
+ protocol = map.get("protocol").toString();
/**
* 濡傛灉鏄ˉ鍗¤皟鐢ㄧ殑寮�鍗′笖杞Щ浜嗛��杩橀噾棰濓紝闇�淇敼鎸傚け鍗′綑棰濅负0
@@ -256,6 +260,7 @@
* 娣诲姞寮�鍗¤褰曪紝閫�杩橀噾棰濆啿鍒版柊鍗′腑
*/
ActiveCard activeCard = new ActiveCard();
+ activeCard.setProtocol(protocol);
activeCard.setCardAddr(cardAddr);
activeCard.setClientId(clientId);
activeCard.setOriginalCardId(cardId);
@@ -279,6 +284,7 @@
map_response.put("projectNo", projectNo);
map_response.put("orderNumber", orderNumber);
map_response.put("cardNum", cardNum);
+ map_response.put("protocol", protocol);
return BaseResponseUtils.buildSuccess(map_response) ;
}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/dto/ActiveCard.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/dto/ActiveCard.java
index 2cbc5a0..2c3ff91 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/dto/ActiveCard.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/cardOperate/dto/ActiveCard.java
@@ -17,6 +17,12 @@
public static final long serialVersionUID = 202407111129001L;
/**
+ * 鍗忚鍚嶇О
+ */
+ @NotBlank(message = "鍗忚涓嶈兘涓虹┖")
+ private String protocol;
+
+ /**
* 姘村崱鍦板潃锛屼粎淇濆瓨锛屾棤涓氬姟
*/
@NotBlank(message = "姘村崱鍦板潃涓嶈兘涓虹┖")
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/client/ClientCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/client/ClientCtrl.java
index 447a341..48d718c 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/client/ClientCtrl.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/client/ClientCtrl.java
@@ -253,7 +253,8 @@
String villageName = map_districts.get("villageName").toString();
// 鐢熸垚8浣嶈鏀垮尯鍒掔紪鐮侊紝鐢熸垚鍐滄埛缂栧彿鐢�
- String district8 = countyNum + townNum + villageNum;
+ //String district8 = countyNum + townNum + villageNum;
+ String district8 = String.format("%02d", Integer.parseInt(countyNum)) + String.format("%03d", Integer.parseInt(townNum)) + String.format("%03d", Integer.parseInt(villageNum));
// 鐢熸垚鍐滄埛缂栧彿
String clientNum = generateClientNum(district8);
// 鐢熸垚12浣�5绾ц鏀垮尯鍒掔紪鐮佷覆鍙婂悕绉颁覆
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java
index 1bc71bc..8aedcb7 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandSv.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
+import com.dy.common.multiDataSource.DataSourceContext;
import com.dy.common.mw.protocol.Command;
import com.dy.common.webUtil.QueryResultVo;
import com.dy.pipIrrGlobal.command.ComSupport;
@@ -19,6 +20,8 @@
import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -44,6 +47,24 @@
private final PrIntakeVcMapper prIntakeVcMapper;
private final SeClientCardMapper seClientCardMapper;
+ /**
+ * pro_mw锛氬睘鎬�
+ * tag浠庢帶鍒跺櫒涓幏鍙�
+ * key_mw锛歶rl鐨刱ey
+ */
+ private Environment env = null;
+ private String pro_mw = "mw";
+ private String key_mw = "comSendUrl";
+ @Autowired
+ public CommandSv(RmCommandHistoryMapper rmCommandHistoryMapper, SeVirtualCardMapper seVirtualCardMapper, PrIntakeMapper prIntakeMapper, PrWaterPriceMapper prWaterPriceMapper, PrIntakeVcMapper prIntakeVcMapper, SeClientCardMapper seClientCardMapper, Environment env) {
+ this.rmCommandHistoryMapper = rmCommandHistoryMapper;
+ this.seVirtualCardMapper = seVirtualCardMapper;
+ this.prIntakeMapper = prIntakeMapper;
+ this.prWaterPriceMapper = prWaterPriceMapper;
+ this.prIntakeVcMapper = prIntakeVcMapper;
+ this.seClientCardMapper = seClientCardMapper;
+ this.env = env;
+ }
/**
* 铏氭嫙鍗D鎹㈣櫄鎷熷崱瀵硅薄
* @param vcId
@@ -71,9 +92,9 @@
com.id = Command.defaultId;
com.code = "LCD0001";
com.type = "innerCommand";
+ comSendUrl = env.getProperty(pro_mw + "." + DataSourceContext.get() + "." + key_mw);
JSONObject response = (JSONObject) JSON.toJSON(sendCom2Mw(com));
-
if(response != null && response.getString("code").equals("0001")) {
JSONObject attachment = response.getJSONObject("content").getJSONObject("attachment").getJSONObject("onLineMap");
HashMap<String, Boolean> onLineMap = JSON.parseObject(attachment.toJSONString(), HashMap.class);
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java
index 6ad9ae6..aa0ef5e 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/ValveCtrl.java
@@ -23,10 +23,11 @@
import com.dy.pipIrrWechat.result.WechatResultCode;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
@@ -47,7 +48,7 @@
@Tag(name = "灏忕▼搴忛榾鎺у櫒鎺у埗", description = "灏忕▼搴忛榾鎺у櫒鎺у埗")
@RestController
@RequestMapping(path = "valve")
-@RequiredArgsConstructor
+//@RequiredArgsConstructor
public class ValveCtrl extends ComSupport {
private final CommandSv commandSv;
private final SeVirtualCardMapper seVirtualCardMapper;
@@ -55,6 +56,23 @@
@Value("${mw.rtuCallbackUrl_wx}")
private String rtuCallbackUrl_wx;
+
+ /**
+ * pro_mw锛氬睘鎬�
+ * tag浠庢帶鍒跺櫒涓幏鍙�
+ * key_mw锛歶rl鐨刱ey
+ */
+ private Environment env = null;
+ private String pro_mw = "mw";
+ private String key_mw = "comSendUrl";
+
+ @Autowired
+ public ValveCtrl(CommandSv commandSv, SeVirtualCardMapper seVirtualCardMapper, IDLongGenerator idLongGenerator, Environment env) {
+ this.commandSv = commandSv;
+ this.seVirtualCardMapper = seVirtualCardMapper;
+ this.idLongGenerator = idLongGenerator;
+ this.env = env;
+ }
/**
* 灏忕▼搴忚繙绋嬪紑闃�
@@ -126,6 +144,8 @@
}
String rtuAddr = job_rtu.getString("rtuAddr");
String protocol = job_rtu.getString("protocol");
+ String orgTag = job_rtu.getString("orgTag");
+ comSendUrl = env.getProperty(pro_mw + "." + orgTag + "." + key_mw);
// 鐢熸垚璁㈠崟鍙�
String orderNo = generateOrderNo();
@@ -232,6 +252,8 @@
}
Long intakeId = job_rtu.getLong("intakeId");
String protocol = job_rtu.getString("protocol");
+ String orgTag = job_rtu.getString("orgTag");
+ comSendUrl = env.getProperty(pro_mw + "." + orgTag + "." + key_mw);
String commandCode = null;
if (protocol.equals("p206V202404")) {
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeCtrl.java
index 45ee4ed..5ddabb6 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeCtrl.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeCtrl.java
@@ -30,15 +30,14 @@
private final IntakeSv intakeSv;
/**
- * 鑾峰彇鍙栨按鍙e垪琛紙鍦ㄧ嚎鍜屼笉鍦ㄧ嚎锛�
+ * 鑾峰彇鍙栨按鍙o紙鍦ㄧ嚎鍜屼笉鍦ㄧ嚎锛�
* @param qo
* @return
*/
@GetMapping(path = "all_intakes")
- public BaseResponse<QueryResultVo<List<VoOnLineIntake>>> getAllIntakes(OnLineIntakesQO qo) {
+ public BaseResponse<QueryResultVo<VoOnLineIntake>> getAllIntakes(OnLineIntakesQO qo) {
try {
- QueryResultVo<List<VoOnLineIntake>> res = intakeSv.selectOnLineIntakes(qo);
- return BaseResponseUtils.buildSuccess(res);
+ return BaseResponseUtils.buildSuccess(intakeSv.selectOnLineIntakes(qo));
} catch (Exception e) {
log.error("鏌ヨ鍙栨按鍙e紓甯�", e);
return BaseResponseUtils.buildException(e.getMessage());
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeSv.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeSv.java
index 0e6fd7f..32c3ed8 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeSv.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/intake/IntakeSv.java
@@ -3,15 +3,16 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
+import com.dy.common.multiDataSource.DataSourceContext;
import com.dy.common.mw.protocol.Command;
import com.dy.common.webUtil.BaseResponse;
-import com.dy.common.webUtil.QueryResultVo;
import com.dy.pipIrrGlobal.daoPr.PrIntakeMapper;
import com.dy.pipIrrGlobal.voPr.VoOnLineIntake;
import com.dy.pipIrrWechat.intake.qo.OnLineIntakesQO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.PojoUtils;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -41,20 +42,33 @@
@Autowired
private RestTemplate restTemplate;
- protected static String mwUrlSendCom = "http://127.0.0.1:8070/rtuMw/com/send" ;
+ //protected static String mwUrlSendCom = "http://127.0.0.1:8070/rtuMw/com/send" ;
+ protected String comSendUrl;
+ /**
+ * pro_mw锛氬睘鎬�
+ * tag浠庢帶鍒跺櫒涓幏鍙�
+ * key_mw锛歶rl鐨刱ey
+ */
+ private Environment env = null;
+ private String pro_mw = "mw";
+ private String key_mw = "comSendUrl";
+ @Autowired
+ public IntakeSv(Environment env) {
+ this.env = env;
+ }
/**
- * 鑾峰彇鍙栨按鍙e垪琛�
+ * 鑾峰彇鍙栨按鍙�
* @return
*/
- public QueryResultVo<List<VoOnLineIntake>> selectOnLineIntakes(OnLineIntakesQO qo) {
+ public VoOnLineIntake selectOnLineIntakes(OnLineIntakesQO qo) {
Command com = new Command() ;
com.id = Command.defaultId;
com.code = "LCD0001";
com.type = "innerCommand";
+ comSendUrl = env.getProperty(pro_mw + "." + DataSourceContext.get() + "." + key_mw);
JSONObject response = (JSONObject) JSON.toJSON(sendCom2Mw(com));
-
if(response != null && response.getString("code").equals("0001")) {
JSONObject attachment = response.getJSONObject("content").getJSONObject("attachment").getJSONObject("onLineMap");
HashMap<String, Boolean> onLineMap = JSON.parseObject(attachment.toJSONString(), HashMap.class);
@@ -68,18 +82,16 @@
}
qo.setOnLineMap(jsonArray.toJSONString());
- Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(qo) ;
- Long itemTotal = prIntakeMapper.getOnLineIntakesCount(params);
+ // 濡傛灉 intakeNum 涓嶄负绌猴紝鍒欒浆涓哄皬鍐欏啀鍐欏叆qo瀵硅薄
+ String intakeNum = qo.getIntakeNum();
+ if(intakeNum != null) {
+ qo.setIntakeNum(intakeNum.toLowerCase());
+ }
- QueryResultVo<List<VoOnLineIntake>> rsVo = new QueryResultVo<>() ;
- rsVo.pageSize = qo.pageSize ;
- rsVo.pageCurr = qo.pageCurr ;
- rsVo.calculateAndSet(itemTotal, params);
- rsVo.obj = prIntakeMapper.getOnLineIntakes(params);
- return rsVo;
+ Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(qo) ;
+ return prIntakeMapper.getIntakeByName(params);
} else {
- QueryResultVo<List<VoOnLineIntake>> rsVo = new QueryResultVo<>();
- return rsVo;
+ return new VoOnLineIntake();
}
}
@@ -93,6 +105,7 @@
com.id = Command.defaultId;
com.code = "LCD0001";
com.type = "innerCommand";
+ comSendUrl = env.getProperty(pro_mw + "." + DataSourceContext.get() + "." + key_mw);
JSONObject response = (JSONObject) JSON.toJSON(sendCom2Mw(com));
if(response != null && response.getString("code").equals("0001")) {
@@ -117,7 +130,7 @@
* @return
*/
protected BaseResponse sendCom2Mw(Command com){
- String url = UriComponentsBuilder.fromUriString(mwUrlSendCom)
+ String url = UriComponentsBuilder.fromUriString(comSendUrl)
.build()
.toUriString();
HttpHeaders headers = new HttpHeaders();
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/result/WechatResultCode.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/result/WechatResultCode.java
index df5e385..ee429dc 100644
--- a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/result/WechatResultCode.java
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/result/WechatResultCode.java
@@ -29,7 +29,6 @@
*/
RTU_NOT_EXIST(20001, "闃�鎺у櫒涓嶅瓨鍦�"),
//RTU_ADDR_CANNOT_BE_NULL(20002, "闃�鎺у櫒鍦板潃涓嶈兘涓虹┖");
-
CLIENT_CARD_NOT_EXIST(30001, "姘村崱涓嶅瓨鍦�"),
/**
@@ -45,7 +44,19 @@
VALIDATION_TIMEOUT(20004, "楠岃瘉瓒呮椂"),
PHONE_NUMBER_IS_ERROR(20004, "鎵嬫満鍙烽敊璇紝闈炴敞鍐屽啘鎴�"),
INVALID_CODE(20004, "鏃犳晥鐨勪复鏃剁櫥褰曞嚟璇�"),
- LOGIN_FAIL(20004, "鐧诲綍澶辫触");
+ LOGIN_FAIL(20004, "鐧诲綍澶辫触"),
+
+ /**
+ * 铏氭嫙鍗�
+ */
+ ABNORMAL(10001, "閫�娆惧紓甯�"),
+ PROCESSING(10001, "閫�娆惧鐞嗕腑"),
+ VC_OPEN_ACCOUNT_FAIL(90002, "铏氭嫙鍗¤处鎴锋敞鍐屽け璐�"),
+ CARD_NUMBER_OVERRUN(10002, "姘村崱缂栧彿宸叉弧"),
+ VIRTUAL_CARD_NOT_EXIST(90006, "铏氭嫙鍗¤处鎴蜂笉瀛樺湪"),
+ RECHARGE_NOT_EXIST(90006, "鍏呭�艰褰曚笉瀛樺湪"),
+ RECHARGE_FAIL(90006, "鍏呭�煎け璐�"),
+ NO_ACCOUNT(40001, "鎮ㄦ寚瀹氱殑铏氭嫙鍗℃湭娉ㄥ唽");
private final Integer code;
private final String message;
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/AesUtil.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/AesUtil.java
new file mode 100644
index 0000000..7a629c2
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/AesUtil.java
@@ -0,0 +1,50 @@
+package com.dy.pipIrrWechat.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:18
+ * @LastEditTime 2024-07-15 10:18
+ * @Description
+ */
+public class AesUtil {
+ static final int KEY_LENGTH_BYTE = 32;
+ static final int TAG_LENGTH_BIT = 128;
+
+ /**
+ * 瑙e瘑
+ * @param apiV3Key apiV3瀵嗛挜
+ * @param associatedData 闄勫姞鏁版嵁
+ * @param nonce 闅忔満涓�
+ * @param ciphertext 鏁版嵁瀵嗘枃
+ * @return 瑙e瘑鍚庡瓧绗︿覆
+ * @throws GeneralSecurityException
+ * @throws IOException
+ */
+ public static String decryptToString(byte[] apiV3Key, byte[] associatedData, byte[] nonce, String ciphertext) throws GeneralSecurityException, IOException {
+ try {
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ SecretKeySpec key = new SecretKeySpec(apiV3Key, "AES");
+ GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
+
+ cipher.init(Cipher.DECRYPT_MODE, key, spec);
+ cipher.updateAAD(associatedData);
+
+ return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
+ } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+ throw new IllegalStateException(e);
+ } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/HmacSha256.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/HmacSha256.java
new file mode 100644
index 0000000..9f5e7c2
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/HmacSha256.java
@@ -0,0 +1,43 @@
+package com.dy.pipIrrWechat.util;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:19
+ * @LastEditTime 2024-07-15 10:19
+ * @Description
+ */
+public class HmacSha256 {
+ public static String getSignature(String secretKey, String data) throws NoSuchAlgorithmException, InvalidKeyException {
+ // 鍒涘缓瀵嗛挜瀵硅薄
+ byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
+ SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
+
+ // 鍒涘缓Mac瀵硅薄骞跺垵濮嬪寲
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(secretKeySpec);
+
+ // 灏嗗緟鍔犲瘑鐨勬暟鎹浆鎹负瀛楄妭鏁扮粍
+ byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
+
+ // 浣跨敤瀵嗛挜瀵规暟鎹繘琛屽姞瀵�
+ byte[] encryptedBytes = mac.doFinal(dataBytes);
+
+ // 灏嗗姞瀵嗗悗鐨勭粨鏋滆浆鎹负鍗佸叚杩涘埗瀛楃涓�
+ StringBuilder hexString = new StringBuilder();
+ for (byte b : encryptedBytes) {
+ String hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ String hmacSha256 = hexString.toString();
+ return hmacSha256;
+ }
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/PayHelper.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/PayHelper.java
new file mode 100644
index 0000000..3aa2522
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/util/PayHelper.java
@@ -0,0 +1,508 @@
+package com.dy.pipIrrWechat.util;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.dy.common.webUtil.BaseResponse;
+import com.dy.common.webUtil.BaseResponseUtils;
+import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
+import com.dy.pipIrrGlobal.voSe.VoOrders;
+import com.dy.pipIrrWechat.result.WechatResultCode;
+import com.dy.pipIrrWechat.virtualCard.VirtualCardSv;
+import com.dy.pipIrrWechat.wechatpay.PayInfo;
+import com.dy.pipIrrWechat.wechatpay.dto.Refund;
+import com.dy.pipIrrWechat.wechatpay.dto.RefundRequest;
+import com.dy.pipIrrWechat.wechatpay.dto.RefundResponse;
+import com.dy.pipIrrWechat.wechatpay.dto.ToRefund;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.NoSuchPaddingException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.*;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:11
+ * @LastEditTime 2024-07-15 10:11
+ * @Description
+ */
+
+@Component
+@RequiredArgsConstructor
+public class PayHelper {
+ private final VirtualCardSv virtualCardSv;
+ private final RestTemplateUtil restTemplateUtil;
+
+ private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+ private String checkSessionUrl = PayInfo.checkSessionUrl;
+ private String tokenUrl = PayInfo.tokenUrl;
+ private String resetUserSessionKeyUrl = PayInfo.resetUserSessionKeyUrl;
+ private String notifyUrl = PayInfo.notifyUrl;
+ private String schema = PayInfo.schema;
+ private String privateCertFileName = PayInfo.privateCertFileName;
+ private String refundUrl = PayInfo.refundUrl;
+
+ // 骞冲彴璇佷功鍏挜
+ public Map<String, Certificate> CERTIFICATE_MAP = new HashMap();
+
+ /**
+ * 鑾峰彇32浣嶉殢鏈哄瓧绗︿覆
+ * @return 闅忔満涓�
+ */
+ public String generateRandomString() {
+ Random random = new Random();
+ StringBuilder sb = new StringBuilder(32);
+ for (int i = 0; i < 32; i++) {
+ int index = random.nextInt(CHARACTERS.length());
+ sb.append(CHARACTERS.charAt(index));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 鑾峰彇鍟嗘埛璇佷功绉侀挜瀵硅薄
+ * @param filename 绉侀挜鏂囦欢璺緞
+ * @return 绉侀挜瀵硅薄
+ * @throws IOException
+ */
+ public PrivateKey getPrivateKey(String filename) throws IOException {
+ String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
+ try {
+ String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
+ .replace("-----END PRIVATE KEY-----", "")
+ .replaceAll("\\s+", "");
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("褰撳墠Java鐜涓嶆敮鎸丷SA", e);
+ } catch (InvalidKeySpecException e) {
+ throw new RuntimeException("鏃犳晥鐨勫瘑閽ユ牸寮�");
+ }
+ }
+
+ /**
+ * 妫�楠岀櫥褰曟��
+ * @param appid 灏忕▼搴� appId
+ * @param secret 灏忕▼搴� appSecret
+ * @param openid 鐢ㄦ埛鍞竴鏍囪瘑绗�
+ * @param sessionKey 浼氳瘽瀵嗛挜
+ * @return
+ * @throws IOException
+ */
+ public JSONObject checkSessionKey(String appid, String secret, String openid, String sessionKey) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
+ String accessToken = "";
+ Integer expiresIn = 0;
+ String signature = HmacSha256.getSignature(sessionKey, "");
+ String sigMethod = "hmac_sha256";
+
+ JSONObject job_token = getAccessToken(appid, secret);
+ if(job_token != null) {
+ accessToken = job_token.getString("access_token");
+ expiresIn = job_token.getInteger("expires_in");
+ }
+
+ Map<String, Object> queryParams = new HashMap<>();
+ queryParams.put("access_token", accessToken);
+ queryParams.put("openid", openid);
+ queryParams.put("signature", signature);
+ queryParams.put("sig_method", sigMethod);
+ Map<String, String> headerParams = new HashMap<>();
+ JSONObject result = restTemplateUtil.get(checkSessionUrl, queryParams, headerParams);
+ return result;
+ }
+
+ /**
+ * 閲嶇疆鐧诲綍鎬�
+ * @param appid 灏忕▼搴� appId
+ * @param secret 灏忕▼搴� appSecret
+ * @param openid 鐢ㄦ埛鍞竴鏍囪瘑绗�
+ * @param sessionKey 浼氳瘽瀵嗛挜
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws IOException
+ */
+ public JSONObject resetUserSessionKey(String appid, String secret, String openid, String sessionKey) throws NoSuchAlgorithmException, InvalidKeyException, IOException {
+ String accessToken = "";
+ Integer expiresIn = 0;
+ String signature = HmacSha256.getSignature(sessionKey, "");
+ String sigMethod = "hmac_sha256";
+
+ JSONObject job_token = getAccessToken(appid, secret);
+ if(job_token != null) {
+ accessToken = job_token.getString("access_token");
+ expiresIn = job_token.getInteger("expires_in");
+ }
+
+ Map<String, Object> queryParams = new HashMap<>();
+ queryParams.put("access_token", accessToken);
+ queryParams.put("openid", openid);
+ queryParams.put("signature", signature);
+ queryParams.put("sig_method", sigMethod);
+ Map<String, String> headerParams = new HashMap<>();
+ JSONObject result = restTemplateUtil.get(resetUserSessionKeyUrl, queryParams, headerParams);
+ return result;
+ }
+
+ /**
+ * 鑾峰彇鎺ュ彛璋冪敤鍑嵁
+ * @param appid 灏忕▼搴� appId
+ * @param secret 灏忕▼搴� appSecret
+ * @return 鍑嵁鍙婂嚟鎹湁鏁堟椂闂�
+ * @throws IOException
+ */
+ public JSONObject getAccessToken(String appid, String secret) throws IOException {
+ Map<String, Object> queryParams = new HashMap<>();
+ queryParams.put("grant_type", "client_credential");
+ queryParams.put("appid", appid);
+ queryParams.put("secret", secret);
+ Map<String, String> headerParams = new HashMap<>();
+ JSONObject job_result = restTemplateUtil.get(tokenUrl, queryParams, headerParams);
+ return job_result;
+ }
+
+ /**
+ * 鏋勯�犵鍚嶄覆_涓嬪崟
+ * @param method HTTP璇锋眰鏂规硶
+ * @param url URL
+ * @param timestamp 鏃堕棿鎴�
+ * @param nonceStr 闅忔満涓�
+ * @param body 鎶ユ枃涓婚
+ * @return 绛惧悕涓�
+ */
+ public String buildMessage_order(String method, String url, long timestamp, String nonceStr, String body) {
+ return method + "\n"
+ + url + "\n"
+ + timestamp + "\n"
+ + nonceStr + "\n"
+ + body + "\n";
+ }
+
+ /**
+ * 鏋勯�犵鍚嶄覆_鍐嶆涓嬪崟
+ * @param appid 灏忕▼搴忓敮涓�鏍囪瘑
+ * @param timestamp 鏃堕棿鎴�
+ * @param nonceStr 闅忔満涓�
+ * @param pkg package
+ * @return 绛惧悕涓�
+ */
+ public String buildMessage_signAgain(String appid, String timestamp, String nonceStr, String pkg) {
+ return appid + "\n"
+ + timestamp + "\n"
+ + nonceStr + "\n"
+ + pkg + "\n";
+ }
+
+ /**
+ * 绛惧悕
+ * @param message 琚鍚嶄俊鎭�
+ * @param certFileName 绉侀挜璇佷功鏂囦欢璺緞
+ * @return signature绛惧悕鍊硷紝绛惧悕淇℃伅涓殑涓�椤癸紝鍙備笌鐢熸垚绛惧悕淇℃伅
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws SignatureException
+ * @throws IOException
+ */
+ public String sign(byte[] message, String certFileName) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, IOException {
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initSign(getPrivateKey(certFileName));
+ sign.update(message);
+ return Base64.getEncoder().encodeToString(sign.sign());
+ }
+
+ /**
+ * 鑾峰彇绛惧悕淇℃伅
+ * @param method
+ * @param url
+ * @param body
+ * @return 绛惧悕淇℃伅锛孒TTP澶翠腑鐨勭鍚嶄俊鎭�
+ * HTTP澶达細Authorization: 璁よ瘉绫诲瀷 绛惧悕淇℃伅
+ * 璁よ瘉绫诲瀷锛學ECHATPAY2-SHA256-RSA2048
+ */
+ public String getToken(String method, String url, String body, String nonceStr, Long timestamp, String certFileName) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException, NoSuchPaddingException {
+ String message = buildMessage_order(method, url, timestamp, nonceStr, body);
+ String signature = sign(message.getBytes("utf-8"), certFileName);
+
+ return "mchid=\"" + PayInfo.mchid + "\","
+ + "nonce_str=\"" + nonceStr + "\","
+ + "timestamp=\"" + timestamp + "\","
+ + "serial_no=\"" + PayInfo.serial_no + "\","
+ + "signature=\"" + signature + "\"";
+ }
+
+ /**
+ * 鏋勯�犻獙閫犵鍚嶄覆
+ * @param wechatpayTimestamp 璇锋眰澶翠腑杩斿洖鐨勬椂闂存埑
+ * @param wechatpayNonce 璇锋眰澶翠腑杩斿洖鐨勯殢鏈轰覆
+ * @param boey 璇锋眰杩斿洖鐨刡ody
+ * @return signatureStr鏋勯�犵殑楠岀鍚嶄覆
+ */
+ public String responseSign(String wechatpayTimestamp, String wechatpayNonce, String boey) {
+ String signatureStr = wechatpayTimestamp + "\n"
+ + wechatpayNonce + "\n"
+ + boey + "\n";
+ return signatureStr;
+ }
+
+ /**
+ * 閲嶆柊涓嬭浇璇佷功
+ */
+ public void refreshCertificate() throws GeneralSecurityException, IOException {
+ String method = "GET";
+ String httpUrl = "/v3/certificates";
+ String nonceStr = generateRandomString();
+ Long timestamp = System.currentTimeMillis() / 1000;
+
+ String header = PayInfo.schema + " " + getToken(method, httpUrl, "", nonceStr, timestamp, PayInfo.privateCertFileName);
+
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Authorization", header);
+ headers.put("Accept", "application/json");
+ //headers.put("User-Agent", "https://zh.wikipedia.org/wiki/User_agent");
+
+ JSONObject job_result = restTemplateUtil.getHeaders(PayInfo.certificates,null, headers);
+ JSONObject job_headers = job_result.getJSONObject("headers");
+
+ String wechatpayNonce = job_headers.getJSONArray("Wechatpay-Nonce").getString(0);
+ String wechatpaySerial = job_headers.getJSONArray("Wechatpay-Serial").getString(0);
+ String signature_h = job_headers.getJSONArray("Wechatpay-Signature").getString(0);
+ String signatureType_h = job_headers.getJSONArray("Wechatpay-Signature-Type").getString(0);
+ String wechatpayTimestamp = job_headers.getJSONArray("Wechatpay-Timestamp").getString(0);
+
+ JSONObject job_body = job_result.getJSONObject("body");
+ if(job_body != null) {
+ JSONArray array = job_body.getJSONArray("data");
+ if(array != null && array.size() > 0) {
+ for(int i = 0; i < array.size(); i++) {
+ JSONObject job_data = array.getJSONObject(i);
+ String certificateSerial = job_data.getString("serial_no");
+ String effective_time = job_data.getString("effective_time");
+ String expire_time = job_data.getString("expire_time");
+ JSONObject job_certificate = job_data.getJSONObject("encrypt_certificate");
+ String algorithm = job_certificate.getString("algorithm");
+ String nonce = job_certificate.getString("nonce");
+ String associated_data = job_certificate.getString("associated_data");
+ String ciphertext = job_certificate.getString("ciphertext");
+
+ //瀵硅瘉涔﹀瘑鏂囪繘琛岃В瀵嗗緱鍒板钩鍙拌瘉涔﹀叕閽�
+ String publicKey = AesUtil.decryptToString(PayInfo.key.getBytes("utf-8"), associated_data.getBytes("utf-8"), nonce.getBytes("utf-8"), ciphertext);
+
+ // 灏嗗钩鍙板叕閽ュ瓧绗︿覆杞垚Certificate瀵硅薄
+ final CertificateFactory cf = CertificateFactory.getInstance("X509");
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(publicKey.getBytes(StandardCharsets.UTF_8));
+ Certificate certificate = null;
+ try {
+ certificate = cf.generateCertificate(inputStream);
+ } catch (CertificateException e) {
+ e.printStackTrace();
+ }
+
+ // 鍝嶅簲澶磋瘉涔﹀簭鍙蜂笌鍝嶅簲浣撹瘉涔﹀簭鍒楀彿涓�鑷达紝涓旀椂闂村樊灏忎簬5鍒嗛挓鏃舵墠灏嗚瘉涔﹀瓨鍌╩ap
+ Long timeDiff = (System.currentTimeMillis() / 1000 - Long.parseLong(wechatpayTimestamp))/60;
+ if(wechatpaySerial.equals(certificateSerial) && timeDiff <= 5) {
+ // 璇佷功鏀惧叆MAP
+ CERTIFICATE_MAP.put(certificateSerial, certificate);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 浣跨敤寰俊骞冲彴璇佷功杩涜鍝嶅簲楠岀
+ * @param wechatpaySerial 鏉ヨ嚜鍝嶅簲澶寸殑寰俊骞冲彴璇佷功搴忓垪鍙�
+ * @param signatureStr 鏋勯�犵殑楠岀鍚嶄覆
+ * @param wechatpaySignature 鏉ヨ嚜鍝嶅簲澶寸殑寰俊骞冲彴绛惧悕
+ * @return
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeyException
+ * @throws SignatureException
+ */
+ public Boolean responseSignVerify(String wechatpaySerial, String signatureStr, String wechatpaySignature) throws GeneralSecurityException, IOException {
+ if(CERTIFICATE_MAP.isEmpty() || !CERTIFICATE_MAP.containsKey(wechatpaySerial)) {
+ CERTIFICATE_MAP.clear();
+ refreshCertificate();
+ }
+ Certificate certificate = (Certificate)CERTIFICATE_MAP.get(wechatpaySerial);
+ if(certificate == null) {
+ return false;
+ }
+
+ // 鑾峰彇鍏挜
+ PublicKey publicKey = certificate.getPublicKey();
+
+ // 鍒濆鍖朣HA256withRSA鍓嶉潰鍣�
+ Signature signature = Signature.getInstance("SHA256withRSA");
+ // 鐢ㄥ井淇″钩鍙板叕閽ュ鍓嶉潰鍣ㄨ繘琛屽垵濮嬪寲
+ signature.initVerify(certificate);
+
+ // 灏嗘瀯閫犵殑楠岀鍚嶄覆鏇存柊鍒扮鍚嶅櫒涓�
+ signature.update(signatureStr.getBytes(StandardCharsets.UTF_8));
+
+ // 璇锋眰澶翠腑寰俊鏈嶅姟鍣ㄨ繑鍥炵殑绛惧悕鐢˙ase64瑙g爜锛屼娇鐢ㄧ鍚嶅櫒杩涜楠岃瘉
+ boolean valid = signature.verify(Base64.getDecoder().decode(wechatpaySignature));
+ return valid;
+ }
+
+
+ /**
+ * 鑾峰彇寰呴��娆惧璞″垪琛�
+ * 寰呴��娆惧璞″寘鍚鍗曞彿鍜屽彲閫�娆鹃噾棰�
+ * 璁㈠崟瀵硅薄鍖呭惈璁㈠崟鍙枫�佸厖鍊奸噾棰濄�佸厖鍊煎畬鎴愭椂闂�
+ * 1. 鏍规嵁铏氭嫙鍗″彿鍒拌櫄鎷熷崱琛ㄤ腑鍙栧嚭璇ュ崱浣欓
+ * 2. 鏍规嵁铏氭嫙鍗″彿鍒板厖鍊艰〃鍙栧嚭璁㈠崟瀵硅薄鍒楄〃
+ * @param virtualId
+ * @param refundAmount
+ * @return
+ */
+ public List<ToRefund> getToRefunds(Long virtualId, Integer refundAmount) {
+ ToRefund toRefund = new ToRefund();
+ List<ToRefund> list = new ArrayList<>();
+ Double money = 0d;
+
+ // 鏍规嵁铏氭嫙鍗″彿鑾峰彇褰撳墠铏氭嫙鍗′綑棰�
+ SeVirtualCard seVirtualCard = virtualCardSv.selectVirtuCardById(virtualId);
+ if(seVirtualCard != null) {
+ money = seVirtualCard.getMoney();
+ }
+
+ // 瑕侀��閲戦澶т簬璇ュ崱浣欓锛岃繑鍥炵┖鍒楄〃
+ if(refundAmount > money) {
+ return list;
+ }
+
+ // 鏍规嵁铏氭嫙鍗″彿鑾峰彇璁㈠崟鍒楄〃锛堜粎闄愬厖鍊兼垚鍔熺殑锛�
+ List<VoOrders> list_Orders = virtualCardSv.selectOrders(virtualId);
+ // 閬嶅巻璁㈠崟鍒楄〃锛岃幏鍙�
+ if(list_Orders != null && list_Orders.size() > 0) {
+ JSONArray array_Orders = (JSONArray) JSON.toJSON(list_Orders);
+ for(int i = 0; i < array_Orders.size(); i++) {
+ JSONObject job_order = array_Orders.getJSONObject(i);
+ String orderNumber = job_order.getString("orderNumber");
+ Integer rechargeAmount = job_order.getInteger("rechargeAmount");
+ Date rechargeTime = job_order.getDate("rechargeTime");
+
+ // 璁$畻鍏呭�艰嚦浠婃椂闂村樊锛堝垎閽燂級
+ Long timestamp_Recharge = rechargeTime.getTime() / 1000;
+ Long timestamp_Current = System.currentTimeMillis() / 1000;
+ Long timeDiff_Minute = (timestamp_Current - timestamp_Recharge)/60;
+
+ // 鑾峰彇璇ヨ鍗曞凡閫�娆剧瑪鏁�
+ Integer refundCount = 0;
+ List<Integer> list_RefundAmount = virtualCardSv.selectRefundAmount(orderNumber);
+ if(list_RefundAmount != null && list_RefundAmount.size() > 0) {
+ refundCount = list_RefundAmount.size();
+ }
+
+ // 鍏呭�艰嚦浠婃湭瓒呰繃涓�骞翠笖璇ヨ鍗曢��娆炬�绘鏁版湭瓒呰繃50娆�
+ if(timeDiff_Minute/(365*24*60) >= 1 && (refundCount + 1) > 50)
+ return list;
+
+ /**
+ * 1. 濡傛灉瑕侀��閲戦灏忎簬褰撳墠璁㈠崟鐨勫厖鍊奸噾棰濓紝瑕侀��閲戦鍗充负搴旈��閲戦骞惰繑鍥�
+ * 2. 濡傛灉瑕佹帹閲戦澶т簬褰撳墠璁㈠崟鍏呭�奸噾棰濓紝褰撳墠璁㈠崟鍏呭�奸噾棰濆嵆涓哄簲閫�閲戦
+ * a. 鐢熸垚搴旈��娆惧璞�
+ * b. 璁$畻鏂扮殑浣欓
+ * c. 閲戣挏鏂扮殑瑕侀��娆鹃噾棰�
+ * d. 濡傛灉瑕侀��閲戦澶т簬0锛岄亶鍘嗕笅涓�涓鍗�
+ */
+ if(refundAmount <= rechargeAmount) {
+ toRefund = new ToRefund();
+ toRefund.setOrderNumber(orderNumber);
+ toRefund.setRefundAmount(refundAmount);
+ list.add(toRefund);
+ // 璁$畻鏂扮殑浣欓鍜屾柊鐨勮閫�閲戦
+ money = money - refundAmount;
+ refundAmount = refundAmount - refundAmount;
+ return list;
+ }else {
+ toRefund = new ToRefund();
+ toRefund.setOrderNumber(orderNumber);
+ toRefund.setRefundAmount(rechargeAmount);
+ list.add(toRefund);
+ // 璁$畻鏂扮殑浣欓鍜屾柊鐨勮閫�閲戦
+ money = money - rechargeAmount;
+ refundAmount = refundAmount - rechargeAmount;
+ if(refundAmount > 0) {
+ continue;
+ }else {
+ return list;
+ }
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * 閫�娆剧敵璇凤紝璋冪敤寰俊鏀粯閫�娆剧敵璇锋帴鍙�
+ * @param po 閫�娆捐姹傚璞★紝鍖呭惈璁㈠崟鍙枫�侀��娆惧崟鍙枫�侀��娆鹃噾棰�
+ * @return
+ * @throws NoSuchPaddingException
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ * @throws IOException
+ * @throws SignatureException
+ * @throws InvalidKeyException
+ */
+ public BaseResponse<Boolean> refunds(Refund po) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException {
+ String tradeNo = po.getTradeNo();
+ String refundNo = po.getRefundNo();
+ Integer refund = po.getRefund();
+
+ // 鐢熸垚body
+ Integer total = virtualCardSv.getRechargeAmountByOrderNumber(tradeNo);
+ RefundRequest.Amount amount = new RefundRequest.Amount();
+ amount.setRefund(refund);
+ amount.setTotal(total);
+ amount.setCurrency("CNY");
+
+ RefundRequest refundRequest = new RefundRequest();
+ refundRequest.setOut_trade_no(tradeNo);
+ refundRequest.setOut_refund_no(refundNo);
+ refundRequest.setNotify_url(notifyUrl);
+ refundRequest.setAmount(amount);
+
+ // 鐢熸垚header
+ String nonceStr = generateRandomString();
+ Long timestamp = System.currentTimeMillis() / 1000;
+
+ String method = "POST";
+ String httpUrl = "/v3/refund/domestic/refunds";
+
+ String body = JSONObject.toJSONString(refundRequest);
+ String header = schema + " " + getToken(method, httpUrl, body, nonceStr, timestamp, privateCertFileName);
+
+ Map<String, String> headers = new HashMap<>();
+ headers.put("Authorization", header);
+ headers.put("Accept", "application/json");
+ headers.put("Content-Type", "application/json");
+
+ JSONObject job_refundResponse = restTemplateUtil.post(PayInfo.refundUrl, body, headers);
+ RefundResponse refundResponse = JSON.parseObject(job_refundResponse.toJSONString(), RefundResponse.class);
+
+ String status = refundResponse.getStatus();
+ if(status != null && status.equals("SUCCESS")) {
+ // 閫�娆剧敵璇峰凡鍙楃悊
+ return BaseResponseUtils.buildSuccess(true) ;
+ } else if(status != null && status.equals("PROCESSING")) {
+ // 閫�娆惧鐞嗕腑
+ return BaseResponseUtils.buildFail(WechatResultCode.PROCESSING.getMessage());
+ } else {
+ // 閫�娆惧紓甯�
+ return BaseResponseUtils.buildError(WechatResultCode.ABNORMAL.getMessage());
+ }
+ }
+}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardCtrl.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardCtrl.java
new file mode 100644
index 0000000..e53ea94
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardCtrl.java
@@ -0,0 +1,269 @@
+package com.dy.pipIrrWechat.virtualCard;
+
+import com.dy.common.aop.SsoAop;
+import com.dy.common.webUtil.BaseResponse;
+import com.dy.common.webUtil.BaseResponseUtils;
+import com.dy.common.webUtil.QueryResultVo;
+import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
+import com.dy.pipIrrGlobal.voSe.VoVcRecharge;
+import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
+import com.dy.pipIrrWechat.util.PayHelper;
+import com.dy.pipIrrWechat.virtualCard.enums.LastOperateENUM;
+import com.dy.pipIrrWechat.result.WechatResultCode;
+import com.dy.pipIrrWechat.virtualCard.dto.DtoRegist;
+import com.dy.pipIrrWechat.virtualCard.dto.DtoVcRecharge;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 9:55
+ * @LastEditTime 2024-07-15 9:55
+ * @Description
+ */
+
+@Slf4j
+@Tag(name = "铏氭嫙鍗$鐞�", description = "铏氭嫙鍗$鐞�")
+@RestController
+@RequestMapping(path="virtual_card")
+@RequiredArgsConstructor
+@Validated
+public class VirtualCardCtrl {
+ private final VirtualCardSv virtualCardSv;
+ private final PayHelper payHelper;
+
+ /**
+ * 鑾峰彇鍐滄埛鍏ㄩ儴铏氭嫙鍗�
+ * @return
+ */
+ @GetMapping(path = "/get")
+ @SsoAop()
+ public BaseResponse<List<VoVirtualCard>> getVCs(Long clientId){
+ try {
+ List<VoVirtualCard> res = virtualCardSv.getVCs(clientId);
+ return BaseResponseUtils.buildSuccess(res);
+ } catch (Exception e) {
+ log.error("鑾峰彇鏀粯鏂瑰紡璁板綍寮傚父", e);
+ return BaseResponseUtils.buildException(e.getMessage()) ;
+ }
+ }
+
+ /**
+ * 鏍规嵁铏氭嫙鍗D鑾峰彇铏氭嫙鍗″璞�
+ * @param vcId
+ * @return
+ */
+ @GetMapping(path = "/getVcById")
+ @SsoAop()
+ public BaseResponse<VoVirtualCard> getVcById(@RequestParam Long vcId){
+ try {
+ return BaseResponseUtils.buildSuccess(virtualCardSv.getVcById(vcId));
+ } catch (Exception e) {
+ log.error("鑾峰彇鏀粯鏂瑰紡璁板綍寮傚父", e);
+ return BaseResponseUtils.buildException(e.getMessage()) ;
+ }
+ }
+
+ /**
+ * 铏氭嫙鍗¤处鍙锋敞鍐�
+ * @param po
+ * @param bindingResult
+ * @return
+ */
+ @PostMapping(path = "add_vc")
+ @SsoAop()
+ public BaseResponse<Boolean> addVC(@RequestBody @Valid DtoRegist po, BindingResult bindingResult){
+ if(bindingResult != null && bindingResult.hasErrors()){
+ return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
+ }
+ Long clientId = po.getClientId();
+
+ // 鑾峰彇5绾ц鏀垮尯鍒掍覆areaCode
+ String areaCode = String.valueOf(virtualCardSv.getAreaCodeById(clientId));
+ /**
+ * 鏍规嵁琛屾斂鍖哄垝涓诧紙areaCode锛夊湪铏氭嫙鍗¤〃涓拡瀵硅櫄鎷熷崱缂栧彿锛坴cNum锛夎繘琛屾ā绯婃煡璇�
+ * 濡傛灉5浣嶉『搴忓彿宸茬粡杈惧埌鏈�澶у�硷紝鎻愮ず鐢ㄦ埛鑱旂郴绯荤粺绠$悊鍛�
+ * 濡傛灉5浣嶉『搴忓彿鏈揪鍒版渶澶у�硷紝鍒欏姞1
+ * cardNum涓烘柊鐨勫崱鍙�
+ */
+ String vcNum = Optional.ofNullable(virtualCardSv.getVcCardNumOfMax(areaCode)).orElse("");
+ if(vcNum != null && vcNum.trim().length() > 0) {
+ Integer number = Integer.parseInt(vcNum.substring(12));
+ number = number + 1;
+ if(number > 65535) {
+ return BaseResponseUtils.buildFail(WechatResultCode.CARD_NUMBER_OVERRUN.getMessage());
+ }
+ vcNum = vcNum.substring(0, 12) + String.format("%05d", number);
+ } else {
+ vcNum = areaCode + "00001";
+ }
+
+ SeVirtualCard seVirtualCard = new SeVirtualCard();
+ seVirtualCard.setVcNum(Long.parseLong(vcNum));
+ seVirtualCard.setClientId(clientId);
+ seVirtualCard.setMoney(0d);
+ seVirtualCard.setLastOperate(LastOperateENUM.OPEN_ACCOUNT.getCode());
+ seVirtualCard.setLastOperateTime(new Date());
+ seVirtualCard.setInUse((byte) 0);
+ seVirtualCard.setCreateTime(new Date());
+ Long rec = virtualCardSv.insertVirtualCard(seVirtualCard);
+ if(rec == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.VC_OPEN_ACCOUNT_FAIL.getMessage());
+ }
+ return BaseResponseUtils.buildSuccess(true) ;
+ }
+
+ /**
+ * 鐢ㄦ埛鐢宠閫�娆�
+ * @param po
+ * @param bindingResult
+ * @return
+ */
+ //@Operation(summary = "铏氭嫙鍗$敵璇烽��娆�", description = "铏氭嫙鍗$敵璇烽��娆�")
+ //@ApiResponses(value = {
+ // @ApiResponse(
+ // responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
+ // description = "鎿嶄綔缁撴灉锛歵rue锛氭垚鍔燂紝false锛氬け璐ワ紙BaseResponse.content锛�",
+ // content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
+ // schema = @Schema(implementation = Boolean.class))}
+ // )
+ //})
+ //@PostMapping(path = "add_refund", consumes = MediaType.APPLICATION_JSON_VALUE)
+ //@Transactional(rollbackFor = Exception.class)
+ //@SsoAop()
+ //public BaseResponse<Boolean> addRefund(@RequestBody @Valid DtoRefund po, BindingResult bindingResult){
+ // if(bindingResult != null && bindingResult.hasErrors()){
+ // return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
+ // }
+ //
+ // Long virtualId = po.getVirtualId();
+ // Integer refundAmount = po.getRefundAmount();
+ //
+ // // 鏍规嵁铏氭嫙鍗D鑾峰彇铏氭嫙鍗″璞�
+ // SeVirtualCard seVirtualCard = virtualCardSv.selectVirtuCardById(virtualId);
+ // if(seVirtualCard == null) {
+ // return BaseResponseUtils.buildFail(WechatResultCode.VIRTUAL_CARD_NOT_EXIST.getMessage());
+ // }
+ // Long clientId = seVirtualCard.getClientId();
+ // Double money = seVirtualCard.getMoney();
+ //
+ // // 楠岃瘉閫�娆鹃噾棰濇槸鍚﹀ぇ浜庝綑棰�
+ // if(refundAmount > money) {
+ // return BaseResponseUtils.buildFail(WechatResultCode.REFUND_AMOUNT_CANNOT_GREATER_THAN_MONEY.getMessage());
+ // }
+ //
+ // // 璁$畻娑堣垂鍚庝綑棰�
+ // Double afterRefund = money - refundAmount;
+ //
+ // SeVcRefund seVcRefund = new SeVcRefund();
+ // seVcRefund.setVcId(virtualId);
+ // seVcRefund.setClientId(clientId);
+ // seVcRefund.setMoney(money);
+ // seVcRefund.setRefundAmount(refundAmount);
+ // seVcRefund.setAfterRefund(afterRefund);
+ // seVcRefund.setApplicationTime(new Date());
+ // seVcRefund.setRefundStatus(RefundStateENUM.TO_AUDIT.getCode());
+ //
+ // Long rec = virtualCardSv.addRefund(seVcRefund);
+ // if(rec == 0) {
+ // return BaseResponseUtils.buildFail(WechatResultCode.APPLICATION_REFUND_FAIL.getMessage());
+ // }
+ // return BaseResponseUtils.buildSuccess(true) ;
+ //}
+
+ /**
+ * 瀹℃牳閫�娆剧敵璇�
+ * @param po
+ * @param bindingResult
+ * @return
+ */
+ //@Operation(summary = "瀹℃牳閫�娆剧敵璇�", description = "瀹℃牳閫�娆剧敵璇�")
+ //@ApiResponses(value = {
+ // @ApiResponse(
+ // responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
+ // description = "鎿嶄綔缁撴灉锛歵rue锛氭垚鍔燂紝false锛氬け璐ワ紙BaseResponse.content锛�",
+ // content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
+ // schema = @Schema(implementation = Boolean.class))}
+ // )
+ //})
+ //@PostMapping(path = "audit_refund", consumes = MediaType.APPLICATION_JSON_VALUE)
+ //@Transactional(rollbackFor = Exception.class)
+ //@SsoAop()
+ //public BaseResponse<Boolean> auditRefund(@RequestBody @Valid DtoAudit po, BindingResult bindingResult) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException {
+ // if(bindingResult != null && bindingResult.hasErrors()){
+ // return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
+ // }
+ //
+ // // 鏍规嵁閫�娆綢D鑾峰彇閫�娆惧璞★紝骞舵洿鏂板鏍镐汉銆佸鏍告椂闂淬�佸鏍稿娉ㄣ�侀��娆剧姸鎬佸瓧娈�
+ // SeVcRefund seVcRefund = virtualCardSv.selectRefundByRefundId(po.getRefundId());
+ // Long virtualId = seVcRefund.getVcId();
+ // Integer refundAmount = seVcRefund.getRefundAmount();
+ // seVcRefund.setAuditor(po.getAuditor());
+ // seVcRefund.setAuditTime(new Date());
+ // seVcRefund.setRemarks(po.getRemarks());
+ // seVcRefund.setRefundStatus(RefundStateENUM.TO_REFUND.getCode());
+ // Integer rec = virtualCardSv.updateRefund(seVcRefund);
+ // if(rec == 0) {
+ // return BaseResponseUtils.buildFail(WechatResultCode.AUDIT_REFUND_FAIL.getMessage());
+ // }
+ //
+ // // 瀹屾垚瀹℃牳鍚庤幏鍙栧緟閫�娆捐鍗曞垪琛�
+ // List<ToRefund> list_ToRefund = payHelper.getToRefunds(virtualId, refundAmount);
+ // if(list_ToRefund == null || list_ToRefund.size() <=0)
+ // return BaseResponseUtils.buildFail(WechatResultCode.NOT_SUFFICIENT_FUNDS.getMessage());
+ //
+ // //閬嶅巻寰呴��娆惧垪琛�
+ // JSONArray array_ToRefund = (JSONArray) JSON.toJSON(list_ToRefund);
+ // for(int i = 0; i < array_ToRefund.size(); i++) {
+ // JSONObject job_ToRefund = array_ToRefund.getJSONObject(i);
+ // String orderNumber_ToRefund = job_ToRefund.getString("orderNumber");
+ // Integer refundAmount_ToRefund = job_ToRefund.getInteger("refundAmount");
+ //
+ // // 鐢熸垚閫�娆惧垎椤硅褰�
+ // SeVcRefundItem seVcRefundItem = new SeVcRefundItem();
+ // seVcRefundItem.setRefundId(po.getRefundId());
+ // seVcRefundItem.setOrderNumber(orderNumber_ToRefund);
+ // String refundNumber = virtualCardSv.generateRefundNumber(orderNumber_ToRefund);
+ // seVcRefundItem.setRefundNumber(refundNumber);
+ // seVcRefundItem.setRefundAmount(refundAmount_ToRefund);
+ // seVcRefundItem.setCreateTime(new Date());
+ // seVcRefundItem.setRefundStatus(RefundItemStateENUM.NO_REFUND.getCode());
+ // Long refundItemId = virtualCardSv.addRefundItem(seVcRefundItem);
+ //
+ // // 璋冪敤寰俊閫�娆剧敵璇锋帴鍙�
+ // Refund refund = new Refund();
+ // refund.setTradeNo(orderNumber_ToRefund);
+ // refund.setRefundNo(refundNumber);
+ // refund.setRefund(refundAmount_ToRefund);
+ // BaseResponse rep = payHelper.refunds(refund);
+ // }
+ //
+ // return BaseResponseUtils.buildSuccess(true) ;
+ //}
+
+ /**
+ * 鑾峰彇铏氭嫙鍗″厖鍊艰褰�
+ * @return
+ */
+ @GetMapping(path = "/getVcRechargeRecords")
+ @SsoAop()
+ public BaseResponse<QueryResultVo<List<VoVcRecharge>>> getVcRechargeRecords(DtoVcRecharge dtoVcRecharge){
+ try {
+ QueryResultVo<List<VoVcRecharge>> res = virtualCardSv.getVcRechargeRecords(dtoVcRecharge);
+ return BaseResponseUtils.buildSuccess(res);
+ } catch (Exception e) {
+ log.error("鑾峰彇铏氭嫙鍗″厖鍊艰褰曞紓甯�", e);
+ return BaseResponseUtils.buildException(e.getMessage()) ;
+ }
+ }
+}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardSv.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardSv.java
new file mode 100644
index 0000000..2f4a5ff
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/virtualCard/VirtualCardSv.java
@@ -0,0 +1,352 @@
+package com.dy.pipIrrWechat.virtualCard;
+
+import com.dy.common.webUtil.BaseResponse;
+import com.dy.common.webUtil.BaseResponseUtils;
+import com.dy.common.webUtil.QueryResultVo;
+import com.dy.pipIrrGlobal.daoSe.*;
+import com.dy.pipIrrGlobal.pojoSe.SeVcRecharge;
+import com.dy.pipIrrGlobal.pojoSe.SeVcRefund;
+import com.dy.pipIrrGlobal.pojoSe.SeVcRefundItem;
+import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
+import com.dy.pipIrrGlobal.voSe.VoOrders;
+import com.dy.pipIrrGlobal.voSe.VoVcRecharge;
+import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
+import com.dy.pipIrrWechat.virtualCard.dto.DtoVcRecharge;
+import com.dy.pipIrrWechat.virtualCard.dto.DtoVirtualCard;
+import com.dy.pipIrrWechat.virtualCard.enums.LastOperateENUM;
+import com.dy.pipIrrWechat.virtualCard.enums.OrderStateENUM;
+import com.dy.pipIrrWechat.result.WechatResultCode;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.common.utils.PojoUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 9:39
+ * @LastEditTime 2024-07-15 9:39
+ * @Description
+ */
+
+@Slf4j
+@Service
+public class VirtualCardSv {
+ @Autowired
+ private SeVirtualCardMapper seVirtualCardMapper;
+
+ @Autowired
+ private SeVcRechargeMapper seVcRechargeMapper;
+
+ @Autowired
+ private SeVcRefundMapper seVcRefundMapper;
+
+ @Autowired
+ private SeVcRefundItemMapper seVcRefundItemMapper;
+
+ @Autowired
+ private SeClientMapper seClientMapper;
+
+ /**
+ * 鏍规嵁鍐滄埛ID鑾峰彇5绾ц鏀垮尯鍒掍唬鐮侊紝娉ㄥ唽铏氭嫙鍗′娇鐢�
+ * @param clientId 鍐滄埛ID
+ * @return 5绾ц鏀垮尯鍒掍唬鐮�
+ */
+ public Long getAreaCodeById(Long clientId) {
+ return seClientMapper.getAreaCodeById(clientId);
+ }
+
+ /**
+ * 鑾峰彇鍐滄埛鍏ㄩ儴铏氭嫙鍗�
+ * @return
+ */
+ public List<VoVirtualCard> getVCs(Long clientId) {
+ return seVirtualCardMapper.getVCs(clientId);
+ }
+
+ /**
+ * 鏍规嵁铏氭嫙鍗D鑾峰彇铏氭嫙鍗″璞�
+ * @param vcId
+ * @return
+ */
+ public VoVirtualCard getVcById(Long vcId) {
+ return seVirtualCardMapper.getVcById(vcId);
+ }
+
+ /**
+ * 娉ㄥ唽铏氭嫙鍗�
+ * @param po
+ * @return
+ */
+ public Long insertVirtualCard(SeVirtualCard po) {
+ seVirtualCardMapper.insert(po);
+ return po.getId();
+ }
+
+ /**
+ * 鏍规嵁琛屾斂鍖哄垝涓叉ā绯婃煡璇㈣櫄鎷熷崱缂栧彿锛屾敞鍐岃櫄鎷熷崱浣跨敤
+ * @param areaCode
+ * @return
+ */
+ String getVcCardNumOfMax(String areaCode) {
+ return seVirtualCardMapper.getVcCardNumOfMax(areaCode);
+ }
+
+ /** 搴熷純
+ * 楠岃瘉鍐滄埛鏄惁鎷ユ湁鎸囧畾鍚嶇О鐨勮櫄鎷熷崱
+ * @param po
+ * @return
+ */
+ //public Integer getRecordCountByName(DtoRegist po) {
+ // return seVirtualCardMapper.getRecordCountByName(po.getClientId(), po.getVcName());
+ //}
+
+ /**
+ * 淇敼铏氭嫙鍗�
+ * 鍏呭�笺�佹秷璐广�佺敵璇烽��娆俱�佸鏍搁��娆炬椂闇�瑕佷慨鏀硅櫄鎷熷崱鐨勶細浣欓銆佹渶鍚庢搷浣溿�佹渶鍚庢搷浣滄椂闂�
+ * @param po
+ * @return
+ */
+ public Integer updateVirtualCard(SeVirtualCard po) {
+ return seVirtualCardMapper.updateByPrimaryKeySelective(po);
+ }
+
+ /**
+ * 鏍规嵁铏氭嫙鍗$紪鍙疯幏鍙栬櫄鎷熷崱瀵硅薄
+ * @param virtualId
+ * @return
+ */
+ public SeVirtualCard selectVirtuCardById(Long virtualId) {
+ return seVirtualCardMapper.selectByPrimaryKey(virtualId);
+ }
+
+ /**
+ * 娣诲姞铏氭嫙鍗″厖鍊艰褰�
+ * JSAPI涓嬪崟鍚庣敓鎴愰儴鍒嗗厖鍊艰褰�
+ * @param po
+ * @return
+ */
+ public BaseResponse<Boolean> insertVCRecharge(DtoVirtualCard po) {
+ String orderNumber = po.getOrderNumber();
+ Long virtualId = po.getVirtualId();
+ Long clientId = po.getClientId();
+ Integer rechargeAmount = po.getRechargeAmount();
+
+ // 楠岃瘉璇ヨ櫄鎷熷崱璐︽埛鏄惁瀛樺湪骞跺彇鍑哄綋鍓嶈处鎴蜂綑棰�
+ SeVirtualCard seVirtualCard = seVirtualCardMapper.selectByPrimaryKey(virtualId);
+ if(seVirtualCard == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.NO_ACCOUNT.getMessage());
+ }
+ Double money = seVirtualCard.getMoney();
+
+ // 娣诲姞鍏呭�艰褰�
+ SeVcRecharge seVcRecharge = new SeVcRecharge();
+ seVcRecharge.setVcId(virtualId);
+ seVcRecharge.setClientId(clientId);
+ seVcRecharge.setMoney(money);
+ seVcRecharge.setOrderNumber(orderNumber);
+ seVcRecharge.setRechargeAmount(rechargeAmount);
+ seVcRecharge.setOrderTime(new Date());
+ seVcRecharge.setOrderState(OrderStateENUM.NON_PAYMENT.getCode());
+ Integer rec = seVcRechargeMapper.insert(seVcRecharge);
+ if(rec == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.RECHARGE_FAIL.getMessage());
+ }
+ return BaseResponseUtils.buildSuccess(true) ;
+ }
+
+ /**
+ * 鏍规嵁璁㈠崟鍙疯幏鍙栬櫄鎷熷崱鍏呭�煎璞�
+ * @param orderNumber
+ * @return
+ */
+ public SeVcRecharge getVCRechargeByorderNumber(String orderNumber) {
+ return seVcRechargeMapper.getVCRechargeByorderNumber(orderNumber);
+ }
+
+ /**
+ * 淇敼铏氭嫙鍗″厖鍊艰褰�
+ * 寰俊鏀粯閫氱煡鍚庯細
+ * 1. 鏇存柊鍏呭�艰〃锛氬厖鍊煎悗浣欓銆佹敮浠樺畬鎴愭椂闂淬�佽鍗曠姸鎬�
+ * 2. 鏇存柊铏氭嫙鍗¤〃锛氳处鎴蜂綑棰濄�佹渶鍚庢搷浣溿�佹渶鍚庢搷浣滄椂闂�
+ * @param orderNumber 璁㈠崟缂栧彿
+ * @return
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public BaseResponse<Boolean> updateVCRecharge(String orderNumber, Date rechargeTime) {
+ SeVcRecharge seVcRecharge = seVcRechargeMapper.getVCRechargeByorderNumber(orderNumber);
+ if(seVcRecharge == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.RECHARGE_NOT_EXIST.getMessage());
+ }
+
+ Long virtualId = seVcRecharge.getVcId();
+ Double money = seVcRecharge.getMoney();
+ Integer rechargeAmount = seVcRecharge.getRechargeAmount();
+ Double afterRrecharge = money + rechargeAmount;
+
+ seVcRecharge.setAfterRecharge(afterRrecharge);
+ seVcRecharge.setRechargeTime(rechargeTime);
+ seVcRecharge.setOrderState(OrderStateENUM.PAID.getCode());
+ Integer rec = seVcRechargeMapper.updateByPrimaryKeySelective(seVcRecharge);
+ if(rec == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.RECHARGE_FAIL.getMessage());
+ }
+
+ SeVirtualCard seVirtualCard = seVirtualCardMapper.selectByPrimaryKey(virtualId);
+ if(seVirtualCard == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.VIRTUAL_CARD_NOT_EXIST.getMessage());
+ }
+ seVirtualCard.setMoney(afterRrecharge);
+ seVirtualCard.setLastOperate(LastOperateENUM.RECHARGE.getCode());
+ seVirtualCard.setLastOperateTime(new Date());
+ Integer rec2 = seVirtualCardMapper.updateByPrimaryKeySelective(seVirtualCard);
+ if(rec2 == null) {
+ return BaseResponseUtils.buildFail(WechatResultCode.RECHARGE_FAIL.getMessage());
+ }
+ return BaseResponseUtils.buildSuccess(true) ;
+ }
+
+ /**
+ * 淇敼铏氭嫙鍗″厖鍊艰褰曪紙搴熷純锛�
+ * 寰俊灏忕▼搴忔敮浠橀�氱煡鍚庝慨鏀癸細浣欓銆佸厖鍊煎悗浣欓銆佸厖鍊煎畬鎴愭椂闂�
+ * @param po
+ * @return
+ */
+ public Integer updateVCRecharge(SeVcRecharge po) {
+ return seVcRechargeMapper.updateByPrimaryKeySelective(po);
+ }
+
+ /**
+ * 鏍规嵁铏氭嫙鍗″彿鑾峰彇璁㈠崟鍒楄〃
+ * @param virtualId
+ * @return
+ */
+ public List<VoOrders> selectOrders(Long virtualId) {
+ List<VoOrders> rsVo = seVcRechargeMapper.getOrders(virtualId);
+ return rsVo ;
+ }
+
+ /**
+ * 鏍规嵁閫�娆綢D鑾峰彇閫�娆惧璞�
+ * @param refundId
+ * @return
+ */
+ public SeVcRefund selectRefundByRefundId(Long refundId) {
+ return seVcRefundMapper.selectByPrimaryKey(refundId);
+ }
+
+ /**
+ * 娣诲姞閫�娆剧敵璇�
+ * @param po
+ * @return
+ */
+ public Long addRefund(SeVcRefund po) {
+ seVcRefundMapper.insert(po);
+ return po.getId();
+ }
+
+ /**
+ * 淇敼閫�娆捐褰�
+ * @param po
+ * @return
+ */
+ public Integer updateRefund(SeVcRefund po) {
+ return seVcRefundMapper.updateByPrimaryKeySelective(po);
+ }
+
+ /**
+ * 鏍规嵁璁㈠崟鍙疯幏鍙栧叾鍚勭瑪閫�娆鹃噾棰�
+ * @param orderNumber
+ * @return
+ */
+ public List<Integer> selectRefundAmount(String orderNumber) {
+ List<Integer> rsVo = seVcRefundMapper.getRefundAmount(orderNumber);
+ return rsVo;
+ }
+
+ /**
+ * 娣诲姞閫�娆惧垎椤�
+ * @param po
+ * @return
+ */
+ public Long addRefundItem(SeVcRefundItem po) {
+ seVcRefundItemMapper.insert(po);
+ return po.getRefundId();
+ }
+
+ /**
+ * 缂栬緫閫�娆惧垎椤�
+ * @param po
+ * @return
+ */
+ public Integer updateRefundItem(SeVcRefundItem po) {
+ return seVcRefundItemMapper.updateByPrimaryKeySelective(po);
+ }
+
+ /**
+ * 鏍规嵁璁㈠崟鍙风敓鎴愰��娆惧崟鍙�
+ * @param orderNumber
+ * @return
+ */
+ public String generateRefundNumber(String orderNumber) {
+ String refundNumber = seVcRefundItemMapper.getLastRefundNumber(orderNumber);
+ if(refundNumber == null) {
+ refundNumber = orderNumber + "01";
+ return refundNumber;
+ }
+
+ String a = String.format("%02d", (Integer.parseInt(refundNumber.substring(29,30).trim()) + 1));
+ return a;
+ }
+
+ /**
+ * 鏍规嵁璁㈠崟鍙疯幏鍙栧厖鍊奸噾棰濓紝璋冪敤閫�娆剧敵璇锋帴鍙d娇鐢�
+ * @param orderNumber
+ * @return
+ */
+ public Integer getRechargeAmountByOrderNumber(String orderNumber) {
+ return seVcRechargeMapper.getRechargeAmountByOrderNumber(orderNumber);
+
+ }
+
+ /**
+ * 鏍规嵁閫�娆鹃�氱煡鎺ュ彛杩斿洖鐨勯��娆惧崟鍙峰弽鏌ラ��娆綢D锛屾煡璇㈣閫�娆綢D涓嬫湭閫�娆捐褰曟暟閲�
+ * @param refundNumber
+ * @return
+ */
+ public Integer getNoRefundedCount(String refundNumber) {
+ return seVcRefundItemMapper.getNoRefundedCount(refundNumber);
+ }
+
+ /**
+ * 鏍规嵁閫�娆惧崟鍙疯幏鍙栭��娆綢D锛岄��娆鹃�氱煡鍚庢洿鏂伴��娆捐〃鎵�闇�
+ * @param refundNumber
+ * @return
+ */
+ public Long getRefundIdByRefundNumber(String refundNumber) {
+ return seVcRefundItemMapper.getRefundIdByRefundNumber(refundNumber);
+ }
+
+ /**
+ * 鑾峰彇铏氭嫙鍗″厖鍊艰褰�
+ * @param dtoVcRecharge
+ * @return
+ */
+ public QueryResultVo<List<VoVcRecharge>> getVcRechargeRecords(DtoVcRecharge dtoVcRecharge){
+ Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(dtoVcRecharge);
+ Long itemTotal = seVirtualCardMapper.getRechargeRecordCount(params);
+
+ QueryResultVo<List<VoVcRecharge>> rsVo = new QueryResultVo<>();
+ rsVo.pageSize = dtoVcRecharge.pageSize;
+ rsVo.pageCurr = dtoVcRecharge.pageCurr;
+
+ rsVo.calculateAndSet(itemTotal, params);
+ rsVo.obj = seVirtualCardMapper.getVcRechargeRecords(params);
+
+ return rsVo;
+ }
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/PayInfo.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/PayInfo.java
new file mode 100644
index 0000000..690e30a
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/PayInfo.java
@@ -0,0 +1,176 @@
+package com.dy.pipIrrWechat.wechatpay;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:26
+ * @LastEditTime 2024-07-15 10:26
+ * @Description
+ */
+public class PayInfo {
+ /**
+ * 灏忕▼搴忕櫥褰旳PI
+ */
+ public static String loginUrl = "https://api.weixin.qq.com/sns/jscode2session";
+
+ /**
+ * 妫�楠岀櫥褰曟��
+ */
+ public static String checkSessionUrl = "https://api.weixin.qq.com/wxa/checksession";
+
+ /**
+ * 閲嶇疆鐧诲綍鎬�
+ */
+ public static String resetUserSessionKeyUrl = "https://api.weixin.qq.com/wxa/resetusersessionkey";
+
+ /**
+ * 鑾峰彇鎺ュ彛璋冪敤鍑嵁
+ */
+ public static String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
+
+ /**
+ * 缁熶竴涓嬪崟API
+ */
+ //public static String orderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+ public static String orderUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
+
+ /**
+ * 骞冲彴璇佷功涓嬭浇URL
+ */
+ public static String certificates = "https://api.mch.weixin.qq.com/v3/certificates";
+
+ /*
+ * 鏀粯缁撴灉閫氱煡API
+ */
+ public static String notifyUrl = "https://44978f7456.imdo.co/sell/payment/orderNotify";
+
+ /*
+ * 鏌ヨ璁㈠崟API
+ */
+ public static String queryUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
+
+ /**
+ * 鐢宠閫�娆続PI
+ */
+ public static String refundUrl = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
+
+ /*
+ * 閫�娆鹃�氱煡API
+ */
+ public static String refundNotifyUrl = "https://www.muxiaobao.com/wxpay/pay.action";
+
+ /*
+ * 閫�娆炬煡璇PI
+ */
+ public static String refundQueryUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
+
+ /*
+ * 灏忕▼搴忓敮涓�鏍囪瘑
+ */
+ //public static String appid = "wxbc2b6a00dd904ead";
+ public static String appid = "wxf773810cd5643196";
+
+ /*
+ * 灏忕▼搴忕殑 app secret
+ */
+ //public static String secret = "796ffe3e9921f756db0499e80d6ed0cd";
+ public static String secret = "080d4f947095551e988cfe9338e27f15";
+
+ /*
+ * 灏忕▼搴忕殑鎺堟潈绫诲瀷锛岀櫥褰曞嚟璇佹牎楠屼娇鐢�
+ */
+ public static String grantType = "authorization_code";
+
+ /*
+ * 鍟嗘埛鍙�(寰俊鏀粯鍒嗛厤鐨勫晢鎴峰彿)
+ */
+ public static String mchid = "1640721520";
+
+ /*
+ * 鍟嗘埛骞冲彴璁剧疆鐨勫瘑閽ey
+ */
+ public static String key = "DaYuJieShuiYanJiuYuan20230412ABC";
+
+ /**
+ * 鍟嗘埛API璇佷功搴忓垪鍙�
+ */
+ public static String serial_no = "52D65AA66405C738670377F467178F4C950E1606";
+
+ /*
+ * 缁堢IP锛岃皟鐢ㄥ井淇℃敮浠楢PI鐨勬満鍣↖P
+ */
+ public static String addrIp = "47.104.211.89";
+
+ /*
+ * 闅忔満瀛楃涓诧紝闀垮害瑕佹眰鍦�32浣嶄互鍐�
+ */
+ //public static String nonceStr = PayHelper.generateRandomString();
+
+ /*
+ * 鏃堕棿鎴� 浠�1970骞�1鏈�1鏃�00:00:00鑷充粖鐨勭鏁�,鍗冲綋鍓嶇殑鏃堕棿
+ */
+ //public static Long timeStamp = PayHelper.getTimeStamp();
+
+ /*
+ * 浜ゆ槗绫诲瀷锛屽皬绋嬪簭鍙栧�糐SAPI
+ */
+ public static String tradeType = "JSAPI";
+
+ /*
+ * 绛惧悕绫诲瀷
+ */
+ //public static String signType = "MD5";
+ public static String signType = "RSA";
+
+ /*
+ * 鍟嗗搧鎻忚堪 鍟嗗搧绠�鍗曟弿杩帮紝璇ュ瓧娈佃鎸夌収瑙勮寖浼犻��
+ */
+ //public static String body = "澶х鐮旂┒闄�-姘磋垂";
+ public static String description = "澶х鐮旂┒闄�-姘磋垂";
+
+ /*
+ * 闄勫姞鏁版嵁锛屽湪鏌ヨAPI鍜屾敮浠橀�氱煡涓師鏍疯繑鍥烇紝鍙綔涓鸿嚜瀹氫箟鍙傛暟浣跨敤
+ */
+ public static String attach = "澶╂触";
+
+ /*
+ * 绛惧悕锛屽弬涓庣鍚嶅弬鏁帮細appid銆乤ttach銆乵ch_id銆乶once_str銆乥ody銆乷ut_trade_no銆乼otal_fee銆乻pbill_create_ip銆乶otify_url銆乼rade_type銆乷penid
+ */
+ public String sign = "";
+
+ /**
+ * HTTP澶磋璇佺被鍨�
+ */
+ public static String schema = "WECHATPAY2-SHA256-RSA2048";
+
+ /**
+ * 绉侀挜鏂囦欢璺緞
+ */
+ public static String privateCertFileName = "C:\\webchat\\apiclient_key.pem";
+
+ public static String publicCertFileName = "C:\\webchat\\wxp_cert.pem";
+
+ /*
+ * 寰俊璁㈠崟鍙凤紝浼樺厛浣跨敤
+ */
+ public static String transactionid = "";
+
+ /*
+ * 鍟嗘埛绯荤粺鍐呴儴璁㈠崟鍙�
+ */
+ public static String out_trade_no = "";
+
+ /*
+ * 鍟嗘埛閫�娆惧崟鍙�
+ */
+ public static String out_refund_no = "";
+
+ /*
+ * 閫�娆鹃噾棰�
+ */
+ public static Float refundfee;
+
+ /*
+ * 璁㈠崟閲戦
+ */
+ public static Float totalfee;
+}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/Refund.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/Refund.java
new file mode 100644
index 0000000..cfdff37
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/Refund.java
@@ -0,0 +1,39 @@
+package com.dy.pipIrrWechat.wechatpay.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:28
+ * @LastEditTime 2024-07-15 10:28
+ * @Description
+ */
+
+@Data
+@Schema(name = "閫�娆捐姹傚璞�")
+public class Refund {
+ public static final long serialVersionUID = 202403011607001L;
+
+ /**
+ * 鍟嗘埛璁㈠崟鍙�
+ */
+ @Schema(description = "鍟嗘埛璁㈠崟鍙�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotBlank(message = "鍟嗘埛璁㈠崟鍙蜂笉鑳戒负绌�")
+ private String tradeNo;
+
+ /**
+ * 閫�娆惧崟鍙�
+ */
+ @Schema(description = "閫�娆惧崟鍙�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ private String refundNo;
+
+ /**
+ * 閫�娆鹃噾棰�
+ */
+ @Schema(description = "閫�娆鹃噾棰�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotNull(message = "閫�娆鹃噾棰濅笉鑳戒负绌�")
+ private Integer refund;
+}
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundRequest.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundRequest.java
new file mode 100644
index 0000000..bf1f6f0
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundRequest.java
@@ -0,0 +1,70 @@
+package com.dy.pipIrrWechat.wechatpay.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:29
+ * @LastEditTime 2024-07-15 10:29
+ * @Description
+ */
+
+@Data
+@Schema(name = "閫�娆捐姹傚璞�")
+public class RefundRequest {
+ public static final long serialVersionUID = 202403011540001L;
+
+ /**
+ * 鍟嗘埛璁㈠崟鍙凤紝涓嬪崟鏃剁殑璁㈠崟鍙�
+ */
+ @Schema(description = "鍟嗘埛璁㈠崟鍙�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotBlank(message = "鍟嗘埛璁㈠崟鍙蜂笉鑳戒负绌�")
+ private String out_trade_no;
+
+ /**
+ * 鍟嗘埛閫�娆惧崟鍙凤紝璁㈠崟鍙峰墠鍔犲墠缂�鈥淩鈥�
+ */
+ @Schema(description = "鍟嗘埛閫�娆惧崟鍙�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotBlank(message = "鍟嗘埛閫�娆惧崟鍙蜂笉鑳戒负绌�")
+ private String out_refund_no;
+
+ /**
+ * 閫�娆剧粨鏋滃洖璋僽rl锛宺efundUrl
+ */
+ @Schema(description = "閫�娆剧粨鏋滃洖璋僽rl", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotBlank(message = "閫�娆剧粨鏋滃洖璋僽rl涓嶈兘涓虹┖")
+ private String notify_url;
+
+ /**
+ * 閲戦淇℃伅
+ */
+ @Schema(description = "閲戦淇℃伅", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ private RefundRequest.Amount amount;
+
+ @Data
+ public static class Amount {
+ /**
+ * 閫�娆鹃噾棰�
+ */
+ @Schema(description = "閫�娆鹃噾棰�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotNull(message = "閫�娆鹃噾棰濅笉鑳戒负绌�")
+ private Integer refund;
+
+ /**
+ * 鍘熻鍗曢噾棰濓紝鏍规嵁璁㈠崟鍙锋煡璇�
+ */
+ @Schema(description = "鍘熻鍗曢噾棰�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotNull(message = "鍘熻鍗曢噾棰濅笉鑳戒负绌�")
+ private Integer total;
+
+ /**
+ * 閫�娆惧竵绉嶏紝鍥哄畾涓衡�淐NY鈥�
+ */
+ @Schema(description = "閫�娆惧竵绉�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotBlank(message = "閫�娆惧竵绉嶄笉鑳戒负绌�")
+ private String currency;
+ }
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundResponse.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundResponse.java
new file mode 100644
index 0000000..6144eef
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/RefundResponse.java
@@ -0,0 +1,114 @@
+package com.dy.pipIrrWechat.wechatpay.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:30
+ * @LastEditTime 2024-07-15 10:30
+ * @Description
+ */
+
+@Data
+@Schema(name = "閫�娆剧敵璇疯繑鍥炲璞�")
+public class RefundResponse {
+ public static final long serialVersionUID = 202403011431001L;
+
+ /**
+ * 寰俊鏀粯閫�娆惧彿
+ */
+ private String refund_id;
+
+ /**
+ * 鍟嗘埛閫�娆惧崟鍙�
+ */
+ private String out_refund_no;
+
+ /**
+ * 寰俊鏀粯璁㈠崟鍙�
+ */
+ private String transaction_id;
+
+ /**
+ * 鍟嗘埛璁㈠崟鍙�
+ */
+ private String out_trade_no;
+
+ /**
+ * 閫�娆炬笭閬�
+ */
+ private String channel;
+
+ /**
+ * 閫�娆惧叆璐﹁处鎴�
+ */
+ private String user_received_account;
+
+ /**
+ * 閫�娆炬垚鍔熸椂闂�
+ */
+ private String success_time;
+
+ /**
+ * 閫�娆惧垱寤烘椂闂�
+ */
+ private String create_time;
+
+ /**
+ * 閫�娆剧姸鎬�
+ */
+ private String status;
+
+ /**
+ * 閲戦淇℃伅
+ */
+ private RefundResponse.Amount amount;
+
+
+ @Data
+ private static class Amount {
+
+ /**
+ * 璁㈠崟鎬婚噾棰�
+ */
+ private Integer total;
+
+ /**
+ * 閫�娆鹃噾棰�
+ */
+ private Integer refund;
+
+ /**
+ * 鐢ㄦ埛鏀粯閲戦
+ */
+ private Integer payer_total;
+
+ /**
+ * 鐢ㄦ埛閫�娆鹃噾棰�
+ */
+ private Integer payer_refund;
+
+ /**
+ * 搴旂粨閫�娆鹃噾棰�
+ */
+ private Integer settlement_refund;
+
+ /**
+ * 搴旂粨璁㈠崟閲戦
+ */
+ private Integer settlement_total;
+
+ /**
+ * 浼樻儬閫�娆鹃噾棰�
+ */
+ private Integer discount_refund;
+
+ /**
+ * 閫�娆惧竵绉�
+ */
+ private String currency;
+
+ }
+
+}
\ No newline at end of file
diff --git a/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/ToRefund.java b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/ToRefund.java
new file mode 100644
index 0000000..95765d5
--- /dev/null
+++ b/pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/wechatpay/dto/ToRefund.java
@@ -0,0 +1,35 @@
+package com.dy.pipIrrWechat.wechatpay.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import lombok.Data;
+
+/**
+ * @author ZhuBaoMin
+ * @date 2024-07-15 10:32
+ * @LastEditTime 2024-07-15 10:32
+ * @Description
+ */
+
+@Data
+@Schema(name = "寰呴��娆惧璞�")
+public class ToRefund {
+ public static final long serialVersionUID = 202403072144001L;
+
+ /**
+ * 璁㈠崟鍙�
+ */
+ @Schema(description = "璁㈠崟鍙�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotBlank(message = "璁㈠崟鍙蜂笉鑳戒负绌�")
+ private String orderNumber;
+
+ /**
+ * 閫�娆鹃噾棰�
+ */
+ @Schema(description = "閫�娆鹃噾棰�", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
+ @NotNull(message = "閫�娆鹃噾棰濅笉鑳戒负绌�")
+ @Positive(message = "閫�娆鹃噾棰濆繀椤讳负澶т簬0鐨勬暣鏁�")
+ private Integer refundAmount;
+}
--
Gitblit v1.8.0