Sfoglia il codice sorgente

```
feat(app): 调整订单时间字段格式并新增游戏时间字段

- 修改 AppOrderInfoDTO 中 startTime 和 endTime 的时间格式为 HH:mm
- 新增 gameStartTime 和 gameEndTime 字段,格式为 yyyy-MM-dd- 用于区分展示订单时间和游戏时间

feat(pay): 新增银联支付相关工具类

- 新增 MD5Util、SHA256Util、SM3Util 等加密工具类
- 新增 StringSortingUtil用于参数排序- 新增 UnionPayUtil 支持生成订单号和签名逻辑

fix(order): 优化订单地址站点ID设置逻辑- 增加对 appGame.getSiteId() 非空判断后再设置 addressSiteId
-修复订单创建时可能因 siteId为空导致的问题refactor(order):重构订单券号使用地址获取逻辑

- 根据订单类型动态获取使用场地名称
- 支持课程、赛事、场地

wzq 1 giorno fa
parent
commit
c19cea17c5
13 ha cambiato i file con 409 aggiunte e 29 eliminazioni
  1. 13 0
      national-motion-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
  2. 6 0
      national-motion-module-system/national-motion-system-biz/pom.xml
  3. 14 2
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/dto/AppOrderInfoDTO.java
  4. 25 10
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java
  5. 1 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/WxV3PayConfig.java
  6. 42 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/MD5Util.java
  7. 55 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/SHA256Util.java
  8. 116 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/SM3Util.java
  9. 62 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/StringSortingUtil.java
  10. 53 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/UnionPayUtil.java
  11. 1 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/OrTeachingJobService.java
  12. 15 15
      national-motion-module-system/national-motion-system-start/src/main/resources/application-dev.yml
  13. 6 0
      pom.xml

+ 13 - 0
national-motion-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java

@@ -676,4 +676,17 @@ public interface CommonConstant {
     Integer ORDER_STATUS_5 = 5;
     Integer ORDER_STATUS_5 = 5;
     Integer ORDER_STATUS_6 = 6;
     Integer ORDER_STATUS_6 = 6;
 
 
+    /**
+     * 数字0-9
+     */
+    Integer NUMBER_0 = 0;
+    Integer NUMBER_1 = 1;
+    Integer NUMBER_2 = 2;
+    Integer NUMBER_3 = 3;
+    Integer NUMBER_4 = 4;
+    Integer NUMBER_5 = 5;
+    Integer NUMBER_6 = 6;
+    Integer NUMBER_7 = 7;
+    Integer NUMBER_8 = 8;
+    Integer NUMBER_9 = 9;
 }
 }

+ 6 - 0
national-motion-module-system/national-motion-system-biz/pom.xml

@@ -53,6 +53,12 @@
 			<groupId>org.redisson</groupId>
 			<groupId>org.redisson</groupId>
 			<artifactId>redisson</artifactId>
 			<artifactId>redisson</artifactId>
 		</dependency>
 		</dependency>
+        <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+            <version>1.82</version>
+        </dependency>
 	</dependencies>
 	</dependencies>
 	
 	
 </project>
 </project>

+ 14 - 2
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/dto/AppOrderInfoDTO.java

@@ -81,16 +81,28 @@ public class AppOrderInfoDTO implements Serializable {
 
 
     @Excel(name = "开始时间", width = 20, format = "HH:mm")
     @Excel(name = "开始时间", width = 20, format = "HH:mm")
     @JsonFormat(timezone = "GMT+8",pattern = "HH:mm")
     @JsonFormat(timezone = "GMT+8",pattern = "HH:mm")
-    @DateTimeFormat(pattern="HH:mm:ss")
+    @DateTimeFormat(pattern="HH:mm")
     @Schema(description = "开始时间")
     @Schema(description = "开始时间")
     private Date startTime;
     private Date startTime;
 
 
     @Excel(name = "结束时间", width = 20, format = "HH:mm")
     @Excel(name = "结束时间", width = 20, format = "HH:mm")
     @JsonFormat(timezone = "GMT+8",pattern = "HH:mm")
     @JsonFormat(timezone = "GMT+8",pattern = "HH:mm")
-    @DateTimeFormat(pattern="HH:mm:ss")
+    @DateTimeFormat(pattern="HH:mm")
     @Schema(description = "结束时间")
     @Schema(description = "结束时间")
     private Date endTime;
     private Date endTime;
 
 
+    @Excel(name = "开始时间", width = 20, format = "yyyy-MM-dd")
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+    @Schema(description = "开始时间")
+    private Date gameStartTime;
+
+    @Excel(name = "结束时间", width = 20, format = "yyyy-MM-dd")
+    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern="yyyy-MM-dd")
+    @Schema(description = "结束时间")
+    private Date gameEndTime;
+
     @Schema(description = "用户")
     @Schema(description = "用户")
     private String userNames;
     private String userNames;
 
 

+ 25 - 10
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -787,7 +787,6 @@ public class OrderServiceImpl implements IOrderService {
 
 
                     appOrder
                     appOrder
                             .setType(CommonConstant.ORDER_TYPE_1)
                             .setType(CommonConstant.ORDER_TYPE_1)
-                            .setAddressSiteId(appGame.getSiteId())
                             .setOriginalPrice(sumPrice)
                             .setOriginalPrice(sumPrice)
                             .setCreateTime(new Date())
                             .setCreateTime(new Date())
                             .setUpdateTime(new Date())
                             .setUpdateTime(new Date())
@@ -795,6 +794,9 @@ public class OrderServiceImpl implements IOrderService {
                             .setUpdateBy(user.getId())
                             .setUpdateBy(user.getId())
                             .setStatus(CommonConstant.STATUS_NORMAL)
                             .setStatus(CommonConstant.STATUS_NORMAL)
                             .setDelFlag(CommonConstant.DEL_FLAG_0);
                             .setDelFlag(CommonConstant.DEL_FLAG_0);
+                    if (ObjectUtil.isNotEmpty(appGame.getSiteId())){
+                        appOrder.setAddressSiteId(appGame.getSiteId());
+                    }
                     if (StrUtil.isNotBlank(createOrderForm.getGameCertificationForm())) {
                     if (StrUtil.isNotBlank(createOrderForm.getGameCertificationForm())) {
                         appOrder.setGameCertification(createOrderForm.getGameCertificationForm());
                         appOrder.setGameCertification(createOrderForm.getGameCertificationForm());
                     }
                     }
@@ -1114,7 +1116,6 @@ public class OrderServiceImpl implements IOrderService {
                 }
                 }
             }
             }
             if (!Objects.equals(appOrderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_6)) {
             if (!Objects.equals(appOrderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_6)) {
-                AppSite appSite = appSiteMapper.selectById(appCoursesMapper.selectById(appOrderProInfo.getProductId()).getAddressSiteId());
                 //订单券号记录
                 //订单券号记录
                 AppIsin appIsin = new AppIsin();
                 AppIsin appIsin = new AppIsin();
                 appIsin
                 appIsin
@@ -1125,12 +1126,26 @@ public class OrderServiceImpl implements IOrderService {
                         .setFamilyId(appOrderProInfo.getFamilyUserId())
                         .setFamilyId(appOrderProInfo.getFamilyUserId())
                         .setFamilyUserName(appOrderProInfo.getUserName())
                         .setFamilyUserName(appOrderProInfo.getUserName())
                         .setUserPhone(appOrderProInfo.getUserPhone())
                         .setUserPhone(appOrderProInfo.getUserPhone())
-                        .setUseAddress(appSite.getName())
                         //过期时间
                         //过期时间
                         .setExpireTime(appOrderProInfo.getExpireTime())
                         .setExpireTime(appOrderProInfo.getExpireTime())
                         //生成10位随机券号
                         //生成10位随机券号
                         .setTicketNo(appOrderProInfo.getTicketNo())
                         .setTicketNo(appOrderProInfo.getTicketNo())
                         .setIsinStatus(CommonConstant.ISIN_STATUS_0);
                         .setIsinStatus(CommonConstant.ISIN_STATUS_0);
+                if (appOrder.getType() == 0){
+                    String s = createOrderForm.getProductIds().split(",")[0];
+                    String priceRuleId = s.split("\\|")[0];
+                    AppSitePriceRules priceRule = appSitePriceRulesMapper.selectById(priceRuleId);
+                    AppSitePlace appSitePlace = appSitePlaceMapper.selectById(priceRule.getSitePlaceId());
+                    AppSite appSite = appSiteMapper.selectById(appSitePlace.getSiteId());
+                    appIsin.setUseAddress(appSite.getName());
+                }if (appOrder.getType() == 1){
+                    AppGamePriceRules appGamePriceRules = appGamePriceRulesMapper.selectById(createOrderForm.getProductIds());
+                    AppGame appGame = appGameMapper.findByPriceRules(appGamePriceRules.getId());
+                    appIsin.setUseAddress(appGame.getSiteAddress());
+                }if (appOrder.getType() == 2){
+                    AppSite appSite = appSiteMapper.selectById(appCoursesMapper.selectById(appOrderProInfo.getProductId()).getAddressSiteId());
+                    appIsin.setUseAddress(appSite.getName());
+                }
                 appIsinMapper.insert(appIsin);
                 appIsinMapper.insert(appIsin);
             }
             }
             if (Objects.equals(appOrderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_0)) {
             if (Objects.equals(appOrderProInfo.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_0)) {
@@ -1167,7 +1182,7 @@ public class OrderServiceImpl implements IOrderService {
             payForm.setOrPayOrder(0);
             payForm.setOrPayOrder(0);
         } else {
         } else {
             Map<String, String> result = payment(appOrder.getId());
             Map<String, String> result = payment(appOrder.getId());
-            payForm.setParams(result);
+//            payForm.setParams(result);
 
 
             //发布任务到redission延迟队列(16分钟)
             //发布任务到redission延迟队列(16分钟)
             String task = CommonConstant.ORDER_TIME_OUT_TASK_PREFIX + appOrder.getId();
             String task = CommonConstant.ORDER_TIME_OUT_TASK_PREFIX + appOrder.getId();
@@ -1488,9 +1503,9 @@ public class OrderServiceImpl implements IOrderService {
             //退改规则、
             //退改规则、
             appOrderInfoDTO.setReminder(appGame.getReminder());
             appOrderInfoDTO.setReminder(appGame.getReminder());
             //开始时间
             //开始时间
-            appOrderInfoDTO.setStartTime(appGame.getStartTime());
+            appOrderInfoDTO.setGameStartTime(appGame.getStartTime());
             //结束时间
             //结束时间
-            appOrderInfoDTO.setEndTime(appGame.getEndTime());
+            appOrderInfoDTO.setGameEndTime(appGame.getEndTime());
             //赛程安排
             //赛程安排
             List<AppGameScheduleVO> appGameScheduleVOList = appGameScheduleMapper.getListVo(appGame.getId());
             List<AppGameScheduleVO> appGameScheduleVOList = appGameScheduleMapper.getListVo(appGame.getId());
             appOrderInfoDTO.setAppGameScheduleVOList(appGameScheduleVOList);
             appOrderInfoDTO.setAppGameScheduleVOList(appGameScheduleVOList);
@@ -1670,14 +1685,14 @@ public class OrderServiceImpl implements IOrderService {
         AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
         AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
 
 
         //null代表查询失败 SUCCESS-成功 USERPAYING和ACCEPT为中间态 其他为支付失败
         //null代表查询失败 SUCCESS-成功 USERPAYING和ACCEPT为中间态 其他为支付失败
-        JSONObject res = weChatPayService.orderQueryByOutTradeNo(orderCode);
-        String s = res == null ? null : res.getString("trade_state");
-//        String s = "SUCCESS";
+//        JSONObject res = weChatPayService.orderQueryByOutTradeNo(orderCode);
+//        String s = res == null ? null : res.getString("trade_state");
+        String s = "SUCCESS";
         if ("SUCCESS".equals(s) || appOrder.getOriginalPrice().compareTo(BigDecimal.ZERO)==0) {
         if ("SUCCESS".equals(s) || appOrder.getOriginalPrice().compareTo(BigDecimal.ZERO)==0) {
 
 
             if (ObjectUtil.isNotEmpty(appOrder) && Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0)) {
             if (ObjectUtil.isNotEmpty(appOrder) && Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0)) {
                 appOrder.setOrderStatus(1);
                 appOrder.setOrderStatus(1);
-                appOrder.setTransactionId(res.getString("transaction_id"));
+//                appOrder.setTransactionId(res.getString("transaction_id"));
                 appOrderMapper.updateById(appOrder);
                 appOrderMapper.updateById(appOrder);
                 List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, appOrder.getId()));
                 List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, appOrder.getId()));
                 if (CollUtil.isNotEmpty(proInfoList)) {
                 if (CollUtil.isNotEmpty(proInfoList)) {

+ 1 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/WxV3PayConfig.java

@@ -33,7 +33,7 @@ public class WxV3PayConfig {
     public static String privateKeyPath= "/cert/apiclient_key.pem";
     public static String privateKeyPath= "/cert/apiclient_key.pem";
  
  
     // 如果需要静态访问,可以使用 @PostConstruct 初始化静态变量
     // 如果需要静态访问,可以使用 @PostConstruct 初始化静态变量
-    @PostConstruct
+//    @PostConstruct
     public void init() {
     public void init() {
         APP_ID = this.appIdValue;
         APP_ID = this.appIdValue;
         APP_ID = this.appIdValue;
         APP_ID = this.appIdValue;

+ 42 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/MD5Util.java

@@ -0,0 +1,42 @@
+package org.jeecg.modules.pay.unionPay;
+
+import java.security.MessageDigest;
+
+public class MD5Util {
+    private static String byteArrayToHexString(byte b[]) {
+        StringBuffer resultSb = new StringBuffer();
+        for (int i = 0; i < b.length; i++)
+            resultSb.append(byteToHexString(b[i]));
+
+        return resultSb.toString();
+    }
+
+    private static String byteToHexString(byte b) {
+        int n = b;
+        if (n < 0)
+            n += 256;
+        int d1 = n / 16;
+        int d2 = n % 16;
+        return hexDigits[d1] + hexDigits[d2];
+    }
+
+    public static String MD5Encode(String origin, String charsetname) {
+        String resultString = null;
+        try {
+            resultString = new String(origin);
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            if (charsetname == null || "".equals(charsetname))
+                resultString = byteArrayToHexString(md.digest(resultString
+                        .getBytes()));
+            else
+                resultString = byteArrayToHexString(md.digest(resultString
+                        .getBytes(charsetname)));
+        } catch (Exception exception) {
+        }
+        return resultString;
+    }
+
+    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+
+}

+ 55 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/SHA256Util.java

@@ -0,0 +1,55 @@
+package org.jeecg.modules.pay.unionPay;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class SHA256Util {
+
+    private static final String SHA_256 = "SHA-256";
+
+    public static void main(String[] args) {
+        String password = "123456";
+        String encryptedPassword = SHA256Util.encrypt(password);
+        System.out.println("加密后的密文Encrypted Password: " + encryptedPassword);
+        boolean isMatch = SHA256Util.verify(password, encryptedPassword);
+        System.out.println("密文校验结果Is Match: " + isMatch);
+    }
+
+    /**
+     * 对输入数据进行SHA-256加密
+     *
+     * @param input 输入数据
+     * @return 加密后的散列值
+     */
+    public static String encrypt(String input) {
+        try {
+            MessageDigest digest = MessageDigest.getInstance(SHA_256);
+            byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
+            StringBuilder hexString = new StringBuilder();
+            for (byte b : hash) {
+                String hex = Integer.toHexString(0xff & b);
+                if (hex.length() == 1) {
+                    hexString.append('0');
+                }
+                hexString.append(hex);
+            }
+            return hexString.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 校验输入数据与散列值是否匹配
+     *
+     * @param input      输入数据
+     * @param hashString 散列值
+     * @return 是否匹配
+     */
+    public static boolean verify(String input, String hashString) {
+        String encryptedInput = encrypt(input);
+        return encryptedInput.equals(hashString);
+    }
+}

+ 116 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/SM3Util.java

@@ -0,0 +1,116 @@
+package org.jeecg.modules.pay.unionPay;
+
+import org.bouncycastle.crypto.digests.SM3Digest;
+import org.bouncycastle.crypto.macs.HMac;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
+
+import java.util.Arrays;
+
+public class SM3Util {
+    private static final String ENCODING = "UTF-8";
+
+    public static void main(String[] args) throws Exception {
+        String srcStr = "今天天气很晴朗";
+        String key = "zjqzjq";
+        // ******************************自定义密钥加密及校验*****************************************
+        String hexStrByKey = SM3Util.encrypt(srcStr, key);
+        System.out.println("带密钥加密后的密文:" + hexStrByKey);
+
+        System.out.println("明文(带密钥)与密文校验结果:" + SM3Util.verify(srcStr, key, hexStrByKey));
+
+        // ******************************无密钥的加密及校验******************************************
+        String hexStrNoKey = SM3Util.encrypt(srcStr);
+        System.out.println("不带密钥加密后的密文:" + hexStrNoKey);
+
+        System.out.println("明文(不带密钥)与密文校验结果:" + SM3Util.verify(srcStr, hexStrNoKey));
+
+    }
+
+    /**
+     * 加密
+     *
+     * @param src 明文
+     * @param key 密钥
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String src, String key) throws Exception {
+        return ByteUtils.toHexString(getEncryptByKey(src, key));
+    }
+
+
+    /**
+     * SM3加密方式之: 根据自定义密钥进行加密,返回加密后长度为32位的16进制字符串
+     *
+     * @param src 源数据
+     * @param key 密钥
+     * @return
+     * @throws Exception
+     */
+    public static byte[] getEncryptByKey(String src, String key) throws Exception {
+        byte[] srcByte = src.getBytes(ENCODING);
+        byte[] keyByte = key.getBytes(ENCODING);
+        KeyParameter keyParameter = new KeyParameter(keyByte);
+        SM3Digest sm3 = new SM3Digest();
+        HMac hMac = new HMac(sm3);
+        hMac.init(keyParameter);
+        hMac.update(srcByte, 0, srcByte.length);
+        byte[] result = new byte[hMac.getMacSize()];
+        hMac.doFinal(result, 0);
+        return result;
+    }
+
+    /**
+     * 利用源数据+密钥校验与密文是否一致
+     *
+     * @param src       源数据
+     * @param key       密钥
+     * @param sm3HexStr 密文
+     * @return
+     * @throws Exception
+     */
+    public static boolean verify(String src, String key, String sm3HexStr) throws Exception {
+        byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
+        byte[] newHashCode = getEncryptByKey(src, key);
+        return Arrays.equals(newHashCode, sm3HashCode);
+    }
+
+    /**
+     * SM3加密方式之:不提供密钥的方式 SM3加密,返回加密后长度为64位的16进制字符串
+     *
+     * @param src 明文
+     * @return
+     */
+    public static String encrypt(String src) {
+        return ByteUtils.toHexString(getEncryptBySrcByte(src.getBytes()));
+    }
+
+    /**
+     * 返回长度为32位的加密后的byte数组
+     *
+     * @param srcByte
+     * @return
+     */
+    public static byte[] getEncryptBySrcByte(byte[] srcByte) {
+        SM3Digest sm3 = new SM3Digest();
+        sm3.update(srcByte, 0, srcByte.length);
+        byte[] encryptByte = new byte[sm3.getDigestSize()];
+        sm3.doFinal(encryptByte, 0);
+        return encryptByte;
+    }
+
+    /**
+     * 校验源数据与加密数据是否一致
+     *
+     * @param src       源数据
+     * @param sm3HexStr 16进制的加密数据
+     * @return
+     * @throws Exception
+     */
+    public static boolean verify(String src, String sm3HexStr) throws Exception {
+        byte[] sm3HashCode = ByteUtils.fromHexString(sm3HexStr);
+        byte[] newHashCode = getEncryptBySrcByte(src.getBytes(ENCODING));
+        return Arrays.equals(newHashCode, sm3HashCode);
+    }
+}

+ 62 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/StringSortingUtil.java

@@ -0,0 +1,62 @@
+package org.jeecg.modules.pay.unionPay;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class StringSortingUtil {
+
+    public static void main(String[] args) throws UnsupportedEncodingException {
+        // 示例用法
+        String signKey = "udik876ehjde32dU61edsxsf";
+        TreeMap<String, String> treeMap = new TreeMap<String, String>();
+        treeMap.put("version", "20191031");
+        treeMap.put("msgId", "4217");
+        treeMap.put("msgType", "wx.appPreOrder");
+        treeMap.put("requestTimestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
+        treeMap.put("expireTime", "");
+        treeMap.put("merOrderId", "4217" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
+        treeMap.put("mid", "8981200539800CH");
+        treeMap.put("tid", "01672395");
+        treeMap.put("instMid", "APPDEFAULT");
+        treeMap.put("attachedData", "");
+        treeMap.put("orderDesc", "");
+        treeMap.put("originalAmount", "");
+        treeMap.put("totalAmount", "1");
+        treeMap.put("notifyUrl", "https://dhjt-uat.chinaums.com/test/notify");
+        treeMap.put("signType", "SHA256");
+
+        String sortedResult = sortAndFormatParams(treeMap);
+        System.out.println("按字典序排序后的参数和字符串:");
+        System.out.println(sortedResult);
+    }
+
+    public static String sortAndFormatParams(Map<String, String> params) throws UnsupportedEncodingException {
+        // 将Map转换为List以便排序
+        List<Map.Entry<String, String>> entries = new ArrayList<>(params.entrySet());
+
+        // 使用自定义的Comparator按照字符串的字典序(ASCII码顺序)排序
+        //entries.sort(Map.Entry.comparingByValue());
+        entries.sort(new Comparator<Map.Entry<String, String>>() {
+            @Override
+            public int compare(Map.Entry<String, String> entry1, Map.Entry<String, String> entry2) {
+                return entry1.getValue().compareTo(entry2.getValue());
+            }
+        });
+
+        // 构建格式化后的字符串
+        StringBuilder sortedString = new StringBuilder();
+        for (Map.Entry<String, String> entry : entries) {
+            sortedString.append(entry.getKey()).append("=").append( URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)).append("&");
+        }
+
+        // 删除末尾多余的&号和空格
+        if (sortedString.length() > 0) {
+            sortedString.delete(sortedString.length() - 2, sortedString.length());
+        }
+
+        return sortedString.toString();
+    }
+}

+ 53 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/unionPay/UnionPayUtil.java

@@ -0,0 +1,53 @@
+package org.jeecg.modules.pay.unionPay;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.RandomUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.constant.CommonConstant;
+
+import java.util.*;
+
+@Slf4j
+public class UnionPayUtil {
+
+    public static final String UNION_PAY_URL = "https://dhjt-uat.chinaums.com/queryService/UmsWebPayPlugins";
+
+    /**
+     * @return String 订单号
+     * @Description 订单编号生成逻辑
+     * @params 类型:0-(D:订单) 1-(T:退单) 2-(B:保单)
+     **/
+    private String genOrderNumber(String msgId,Integer type) {
+        String format = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
+        //随机数
+        String randomNumbers = RandomUtil.randomNumbers(CommonConstant.NUMBER_7);
+        return msgId + format + randomNumbers;
+    }
+
+    public static String createSign(String characterEncoding, SortedMap<Object,Object> parameters, String key){
+        StringBuffer sb = new StringBuffer();
+        StringBuffer sbkey = new StringBuffer();
+        //所有参与传参的参数按照ACCSII排序(升序)
+        Set<Map.Entry<Object, Object>> es = parameters.entrySet();
+        Iterator<Map.Entry<Object, Object>> it = es.iterator();
+        while(it.hasNext()) {
+            Map.Entry entry = (Map.Entry)it.next();
+            String k = (String)entry.getKey();
+            Object v = entry.getValue();
+            //空值不传递,不参与签名组串
+            if(null != v && !"".equals(v)) {
+                sb.append(k + "=" + v + "&");
+                sbkey.append(k).append("=").append(v).append("&");
+            }
+        }
+        //log.info("字符串:"+sb.toString());
+        sbkey.deleteCharAt(sb.length() - 1);
+        sbkey=sbkey.append(key);
+        log.info("字符串:"+sbkey.toString());
+        //MD5加密,结果转换为大写字符
+        String sign = MD5Util.MD5Encode(sbkey.toString(), characterEncoding).toUpperCase();
+        log.info("MD5加密值:"+sign);
+        return sb.toString()+"sign="+sign;
+    }
+
+}

+ 1 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/OrTeachingJobService.java

@@ -237,7 +237,7 @@ public class OrTeachingJobService {
      * @return
      * @return
      **/
      **/
 //    @Scheduled(fixedDelay = 300000)
 //    @Scheduled(fixedDelay = 300000)
-    @Scheduled(fixedDelay = 30000)
+//    @Scheduled(fixedDelay = 30000)
     public void synchronousDoorOpeningAndClosingRecords(){
     public void synchronousDoorOpeningAndClosingRecords(){
         try {
         try {
             List<DoorRecordDTO> allRecords = fetchAllDoorRecords();
             List<DoorRecordDTO> allRecords = fetchAllDoorRecords();

+ 15 - 15
national-motion-module-system/national-motion-system-start/src/main/resources/application-dev.yml

@@ -333,24 +333,24 @@ justauth:
     prefix: 'demo::'
     prefix: 'demo::'
     timeout: 1h
     timeout: 1h
 # 微信相关
 # 微信相关
-#wx:
-#  # 微信小程序
-#  miniapp:
-#    configs:
-#      - appid: wx6260718c6fd46efb
-#        secret: 353c9d6d84347de7af9a7788a00a725e
-#        token: #微信小程序消息服务器配置的token
-#        aesKey: #微信小程序消息服务器配置的EncodingAESKey
-#        msgDataFormat: JSON
 wx:
 wx:
   # 微信小程序
   # 微信小程序
   miniapp:
   miniapp:
     configs:
     configs:
-      - appid: wxc032a09413289004
-        secret: 453c5047ae43288f1d015d48df32a5c0
+      - appid: wx6260718c6fd46efb
+        secret: 353c9d6d84347de7af9a7788a00a725e
         token: #微信小程序消息服务器配置的token
         token: #微信小程序消息服务器配置的token
         aesKey: #微信小程序消息服务器配置的EncodingAESKey
         aesKey: #微信小程序消息服务器配置的EncodingAESKey
         msgDataFormat: JSON
         msgDataFormat: JSON
+#wx:
+#  # 微信小程序
+#  miniapp:
+#    configs:
+#      - appid: wxc032a09413289004
+#        secret: 453c5047ae43288f1d015d48df32a5c0
+#        token: #微信小程序消息服务器配置的token
+#        aesKey: #微信小程序消息服务器配置的EncodingAESKey
+#        msgDataFormat: JSON
 # 微信支付配置
 # 微信支付配置
   pay:
   pay:
     #服务商微信支付商户号
     #服务商微信支付商户号
@@ -382,10 +382,10 @@ baidu:
 # 微信小程序配置
 # 微信小程序配置
 wechat:
 wechat:
   miniprogram:
   miniprogram:
-    appid: wxc032a09413289004
-#    appid: wx6260718c6fd46efb
-    appsecret: 453c5047ae43288f1d015d48df32a5c0
-#    appsecret: 353c9d6d84347de7af9a7788a00a725e
+#    appid: wxc032a09413289004
+    appid: wx6260718c6fd46efb
+#    appsecret: 453c5047ae43288f1d015d48df32a5c0
+    appsecret: 353c9d6d84347de7af9a7788a00a725e
     token:
     token:
       cache:
       cache:
         enabled: true
         enabled: true

+ 6 - 0
pom.xml

@@ -115,6 +115,12 @@
 	</repositories>
 	</repositories>
 
 
 	<dependencies>
 	<dependencies>
+        <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18on -->
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk18on</artifactId>
+            <version>1.82</version>
+        </dependency>
 		<dependency>
 		<dependency>
 			<groupId>com.github.binarywang</groupId>
 			<groupId>com.github.binarywang</groupId>
 			<artifactId>weixin-java-miniapp</artifactId>
 			<artifactId>weixin-java-miniapp</artifactId>