From dda9ffb76b585bb5bcf5282def424999448fa915 Mon Sep 17 00:00:00 2001 From: liujie <1793218484@qq.com> Date: 星期一, 28 七月 2025 17:57:42 +0800 Subject: [PATCH] Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/QianYunTong --- DriverQYTTravel/guns-admin/src/main/resources/application-dev.yml | 5 DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/TokenRequest.java | 2 DriverQYTTravel/guns-admin/lib/zl-util-security-1.2.2.jar | 0 DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java | 94 ++++--- DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZLHttpClientUtil.java | 129 ++++++++++ DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianConfig.java | 29 ++ DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OrderServiceImpl.java | 16 DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/CallbackUtil.java | 47 +++ DriverQYTTravel/guns-admin/pom.xml | 52 +-- UserQYTTravel/guns-admin/pom.xml | 6 DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/OpenAccountCallbackRequest.java | 11 DriverQYTTravel/pom.xml | 2 /dev/null | 95 ------- DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/MessageBody.java | 23 + DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/TokenUtil.java | 93 +++++-- DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianUtil.java | 108 +++++++++ 16 files changed, 507 insertions(+), 205 deletions(-) diff --git a/DriverQYTTravel/guns-admin/lib/ncoss-java-sdk-1.0.5.jar b/DriverQYTTravel/guns-admin/lib/ncoss-java-sdk-1.0.5.jar deleted file mode 100644 index fbb6562..0000000 --- a/DriverQYTTravel/guns-admin/lib/ncoss-java-sdk-1.0.5.jar +++ /dev/null Binary files differ diff --git a/DriverQYTTravel/guns-admin/lib/zl-util-security-1.2.2.jar b/DriverQYTTravel/guns-admin/lib/zl-util-security-1.2.2.jar new file mode 100644 index 0000000..6ab869f --- /dev/null +++ b/DriverQYTTravel/guns-admin/lib/zl-util-security-1.2.2.jar Binary files differ diff --git a/DriverQYTTravel/guns-admin/pom.xml b/DriverQYTTravel/guns-admin/pom.xml index 6c63e22..4326663 100644 --- a/DriverQYTTravel/guns-admin/pom.xml +++ b/DriverQYTTravel/guns-admin/pom.xml @@ -80,19 +80,6 @@ <optional>true</optional> </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-tomcat</artifactId> - <scope>compile</scope> -<!-- <scope>provided</scope>--> - </dependency> - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <version>3.1.0</version> - <scope>provided</scope> - </dependency> - <!--shiro依赖--> <dependency> <groupId>org.apache.shiro</groupId> @@ -132,11 +119,11 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> - <dependency> - <groupId>org.redisson</groupId> - <artifactId>redisson-spring-boot-starter</artifactId> - <version>3.16.8</version> - </dependency> +<!-- <dependency>--> +<!-- <groupId>org.redisson</groupId>--> +<!-- <artifactId>redisson-spring-boot-starter</artifactId>--> +<!-- <version>3.14.0</version>--> +<!-- </dependency>--> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> @@ -145,7 +132,7 @@ <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> - + <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> @@ -228,19 +215,19 @@ <artifactId>commons-codec</artifactId> <version>1.13</version> </dependency> - + <!--hutool--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency> - + <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> - + <!--中台sdk--> <dependency> <groupId>com.zhongtai</groupId> @@ -261,21 +248,20 @@ <scope>system</scope> <systemPath>${pom.basedir}/lib/javabase64-1.3.1.jar</systemPath> </dependency> + <!--证联sdk--> <dependency> - <groupId>cn.hutool</groupId> - <artifactId>hutool-all</artifactId> + <groupId>zl</groupId> + <artifactId>security</artifactId> + <version>1.2.2</version> + <scope>system</scope> + <systemPath>${pom.basedir}/lib/zl-util-security-1.2.2.jar</systemPath> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> - <dependency> - <groupId>org.bouncycastle</groupId> - <artifactId>bcprov-jdk15on</artifactId> - <version>1.70</version> - </dependency> </dependencies> - + <build> <!--打包jar包方式--> <plugins> @@ -288,7 +274,7 @@ </configuration> </plugin> </plugins> - + <!--打包war包引入本地jar的打包方式--> <!-- <plugins>--> <!-- <plugin>--> @@ -317,8 +303,8 @@ <!-- </configuration>--> <!-- </plugin>--> <!-- </plugins>--> - - + + <resources> <resource> <directory>${project.basedir}/lib</directory> diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java index ff87e05..f459621 100644 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/DriverController.java @@ -25,6 +25,11 @@ import com.stylefeng.guns.modular.system.util.ResultUtil; import com.stylefeng.guns.modular.system.util.WeChatUtil; import com.stylefeng.guns.modular.system.util.qianyuntong.QianYunTongConfig; +import com.stylefeng.guns.modular.system.util.zhenglian.CallbackUtil; +import com.stylefeng.guns.modular.system.util.zhenglian.TokenUtil; +import com.stylefeng.guns.modular.system.util.zhenglian.model.MessageBody; +import com.stylefeng.guns.modular.system.util.zhenglian.model.TokenRequest; +import com.stylefeng.guns.modular.system.util.zhenglian.model.TradeTerminalInfo; import com.stylefeng.guns.modular.system.warpper.*; import com.stylefeng.guns.modular.taxi.model.OrderTaxi; import com.stylefeng.guns.modular.taxi.service.IOrderTaxiService; @@ -128,6 +133,9 @@ @Autowired private MongoTemplate mongoTemplate; + + @Autowired + private WeChatUtil weChatUtil; /** * 获取短信验证码 @@ -1737,8 +1745,7 @@ } } - @Autowired - private WeChatUtil weChatUtil; + @ResponseBody @PostMapping("/api/driver/getDriverCode") @@ -1817,40 +1824,51 @@ } } - - -// @ResponseBody -// @RequestMapping(value = "/base/driver/uploadImg", method = RequestMethod.POST) -// @ApiOperation(value = "上传图片", tags = {"司机端-注册"}, notes = "") -// public ResultUtil uploadImg(MultipartFile file) { -// try { -// String bucketName = "grjy_test"; -// Bucket grjyTest = NCOSSUtil.getBucketInfo(bucketName); -// if (null == grjyTest) { -// //创建桶 -// Boolean bucket = NCOSSUtil.createBucket(bucketName); -// if (!bucket) { -// return ResultUtil.error("创建存储桶失败"); -// } -// //设置桶策略 -// String policyText = "{\"Version\":\"2025-06-23\",\"Statement\":[{\"Sid\":\"Stmt20250623\",\"Action\":[\"GetObject\"]" + -// ",\"Effect\":\"Allow\",\"Resource\":[\"" + bucketName + "\"/*],\"Principal\":{*}}]}"; -// Boolean bucketPolicy = NCOSSUtil.setBucketPolicy(bucketName, policyText); -// if (!bucketPolicy) { -// return ResultUtil.error("设置桶策略失败"); -// } -// } -// //上传对象 -// String key = "image/driver/" + UUID.randomUUID().toString() + ".png"; -// String object = NCOSSUtil.putObject(bucketName, key, file.getInputStream()); -// if (null == object) { -// return ResultUtil.error("上传图片失败"); -// } -// -// return ResultUtil.success("http://" + QianYunTongProperties.endPoint + "/" + key); -// } catch (Exception e) { -// e.printStackTrace(); -// return ResultUtil.runErr(); -// } -// } + @ResponseBody + @PostMapping("/api/driver/getZLToken") + @ApiOperation(value = "获取证联token(黔云通)", tags = {"司机端-首页"}, notes = "") + @ApiImplicitParams({ + @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."), + @ApiImplicitParam(value = "当前设备IP地址", name = "ip", required = true, dataType = "String"), + @ApiImplicitParam(value = "当前设备mac地址", name = "mac", required = true, dataType = "String"), + }) + public ResultUtil<String> getZLToken(String ip, String mac, HttpServletRequest request){ + try { + Integer driverId = driverService.getUserIdFormRedis(request); + if (null == driverId) { + return ResultUtil.tokenErr(); + } + Driver driver = driverService.selectById(driverId); + TokenRequest tokenRequest = new TokenRequest(); + tokenRequest.setAppUserId(driver.getEmpId().toString()); + tokenRequest.setUserName(driver.getName()); + tokenRequest.setCertNo(driver.getIdCard()); + tokenRequest.setPhone(driver.getPhone()); + TradeTerminalInfo tradeTerminalInfo = new TradeTerminalInfo(); + tradeTerminalInfo.setIp(ip); + tradeTerminalInfo.setTerminal("1"); + tradeTerminalInfo.setMac(mac); + tokenRequest.setTradeTerminalInfo(tradeTerminalInfo); + String token = TokenUtil.getToken(tokenRequest); + return ResultUtil.success(token); + }catch (Exception e){ + e.printStackTrace(); + return ResultUtil.runErr(); + } + } + + + /** + * 证联通知回调 + * @param messageBody + * @param request + * @return + */ + @ResponseBody + @PostMapping("/base/driver/zlCallback") + public void zlCallback(@RequestBody MessageBody messageBody, HttpServletRequest request){ + String callback = CallbackUtil.callback(messageBody); + System.err.println("证联通知回调:" + callback); + log.info("证联通知回调:" + callback); + } } diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OrderServiceImpl.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OrderServiceImpl.java index 49c8fb3..72db972 100644 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OrderServiceImpl.java +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OrderServiceImpl.java @@ -27,8 +27,6 @@ import com.stylefeng.guns.modular.system.warpper.OrderListWarpper; import com.stylefeng.guns.modular.taxi.model.OrderTaxi; import com.stylefeng.guns.modular.taxi.service.IOrderTaxiService; -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; @@ -97,8 +95,8 @@ @Autowired private IAdditionalFeeService additionalFeeService; - @Autowired - private RedissonClient redissonClient; +// @Autowired +// private RedissonClient redissonClient; @Autowired private IOpenCityService openCityService; @@ -511,10 +509,10 @@ public ResultUtil grabOrder(Integer orderId, Integer orderType, Integer uid) throws Exception { //专车和出租是批量下单,所以这里需要将两种类型的抢单操作通过一个锁来一起控制 if(1 == orderType || 2 == orderType){ - RLock lock = redissonClient.getLock("grabOrder:" + orderId); - if(!lock.tryLock()){ - return ResultUtil.error("抢单失败,请稍后重试"); - } +// RLock lock = redissonClient.getLock("grabOrder:" + orderId); +// if(!lock.tryLock()){ +// return ResultUtil.error("抢单失败,请稍后重试"); +// } try { if(1 == orderType){ return orderPrivateCarService.grabOrder(orderId, uid); @@ -525,7 +523,7 @@ }catch (Exception e){ e.printStackTrace(); }finally { - lock.unlock(); +// lock.unlock(); } } switch (orderType){ diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/qianyuntong/NCOSSUtil.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/qianyuntong/NCOSSUtil.java deleted file mode 100644 index b4b768f..0000000 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/qianyuntong/NCOSSUtil.java +++ /dev/null @@ -1,243 +0,0 @@ -//package com.stylefeng.guns.modular.system.util.qianyuntong; -// -//import com.heredata.hos.HOS; -//import com.heredata.hos.HOSClientBuilder; -//import com.heredata.hos.model.CreateBucketRequest; -//import com.heredata.hos.model.HOSObject; -//import com.heredata.hos.model.PutObjectRequest; -//import com.heredata.hos.model.PutObjectResult; -//import com.heredata.hos.model.bucket.Bucket; -//import com.heredata.model.VoidResult; -//import com.stylefeng.guns.modular.system.util.SpringContextsUtil; -//import lombok.extern.slf4j.Slf4j; -// -//import java.io.InputStream; -// -///** -// * OSS 工具类 -// * @author zhibing.pu -// * @Date 2025/6/23 17:50 -// */ -//@Slf4j -//public class NCOSSUtil { -// -// private static QianYunTongConfig qianYunTongConfig = SpringContextsUtil.getBean(QianYunTongConfig.class).getQianYunTongConfig();; -// -// /** -// * 创建桶 -// * @param bucketName -// * @return -// */ -// public static Boolean createBucket(String bucketName) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// try { -// // 创建请求对象,并且设置创建桶名为"example"的桶 -// CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); -// VoidResult result = hos.createBucket(createBucketRequest); -// if (result.getResponse().isSuccessful()) { -// log.info("创建桶成功:" + bucketName); -// return true; -// } -// } catch (Exception e){ -// log.info("创建桶失败:" + bucketName); -// e.printStackTrace(); -// } -// return false; -// } -// -// -// /** -// * 查询桶详情 -// * @param bucketName -// * @return -// */ -// public static Bucket getBucketInfo(String bucketName) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// try { -// // 查询桶名为"example"的详情 -// Bucket bucket = hos.getBucketInfo(bucketName); -// return bucket; -// } catch (Exception e){ -// e.printStackTrace(); -// } -// return null; -// } -// -// -// /** -// * 删除桶 -// * @param bucketName -// * @return -// */ -// public static Boolean deleteBucket(String bucketName) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// try { -// VoidResult result = hos.deleteBucket(bucketName); -// if (result.getResponse().isSuccessful()) { -// log.info("删除桶成功:" + bucketName); -// return true; -// } -// } catch (Exception e){ -// log.info("删除桶成功:" + bucketName); -// e.printStackTrace(); -// } -// return false; -// } -// -// -// /** -// * 设置桶策略 -// * @param bucketName 桶名 -// * @param policyText 策略规则字符串 -// * { -// * // 策略配置的版本号,由用户定义 -// * "Version": "2012-10-17", -// * // 策略规则配置,可指定多条策略规则 -// * "Statement": [{ -// * // 策略规则ID,可用户指定,如不指定则服务自动生成一条 -// * "Sid": "sid", -// * // 策略规则指定的HOS API接口标识,可参照下表填写 -// * "Action": [ -// * "action" -// * ], -// * // 策略规则效果,具体表现为允许或拒绝,有效值为Allow(允许),Deny(拒绝); -// * "Effect": "Allow", -// * // 策略规则指定的资源参照下面resource配置 -// * "Resource": "resource", -// * // 策略规则指定的授权人 参照下面Principal配置 -// * "Principal": { -// * "HWS": [ -// * "account_id:root" -// * ] -// * } -// * } -// * ] -// * } -// * @return -// */ -// public static Boolean setBucketPolicy(String bucketName, String policyText) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// // 桶策略字符串 -// try { -// VoidResult result = hos.setBucketPolicy(bucketName, policyText); -// if (result.getResponse().isSuccessful()) { -// log.info("设置桶策略成功:" + bucketName); -// return true; -// } -// } catch (Exception e) { -// log.info("设置桶策略失败:" + bucketName); -// e.printStackTrace(); -// } -// return false; -// } -// -// -// /** -// * 上传对象 -// * @param bucketName 桶名称 -// * @param key 存储文件名 -// * @param inputStream 上传文件流 -// * @return 对象唯一标识 -// */ -// public static String putObject(String bucketName, String key, InputStream inputStream) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// try { -// PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key , inputStream); -// PutObjectResult example = hos.putObject(putObjectRequest); -// if (example.getResponse().isSuccessful()) { -// log.info("上传对象成功:" + bucketName + "--->" + key); -// return example.getETag(); -// } -// } catch (Exception e) { -// log.info("上传对象成功:" + bucketName); -// e.printStackTrace(); -// } -// return null; -// } -// -// -// /** -// * 查询对象 -// * @param bucketName 桶名称 -// * @param key 存储文件名 -// * @return -// */ -// public static HOSObject getObject(String bucketName, String key) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// try { -// HOSObject example = hos.getObject(bucketName, key); -// if (example.getResponse().isSuccessful()) { -// log.info("查询对象成功:" + bucketName + "--->" + key); -// return example; -// } -// } catch (Exception e) { -// log.info("查询对象失败:" + bucketName); -// e.printStackTrace(); -// } -// return null; -// } -// -// -// /** -// * 删除对象 -// * @param bucketName 桶名称 -// * @param key 存储文件名 -// * @return -// */ -// public static Boolean deleteObject(String bucketName, String key) { -// /** -// * endPoint:HOS的基础路径(公共前缀) -// * account:账户的ID -// * accessKey:向UAAS服务请求到的access_key -// * secretKey:向UAAS服务请求到的secret_key -// */ -// HOS hos = new HOSClientBuilder().build(qianYunTongConfig.getEndPoint(), qianYunTongConfig.getAccount(), qianYunTongConfig.getAccessKey(), qianYunTongConfig.getSecretKey()); -// try { -// VoidResult example = hos.deleteObject(bucketName, key); -// if (example.getResponse().isSuccessful()) { -// log.info("删除对象成功:" + bucketName + "--->" + key); -// return true; -// } -// } catch (Exception e) { -// log.info("删除对象失败:" + bucketName + "--->" + key); -// e.printStackTrace(); -// } -// return false; -// } -//} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/CallbackUtil.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/CallbackUtil.java new file mode 100644 index 0000000..5be24c1 --- /dev/null +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/CallbackUtil.java @@ -0,0 +1,47 @@ +package com.stylefeng.guns.modular.system.util.zhenglian; + +import com.stylefeng.guns.modular.system.util.SpringContextsUtil; +import com.stylefeng.guns.modular.system.util.zhenglian.model.MessageBody; +import com.zlpay.assist.encrypt.sm4.SM4Util; +import com.zlpay.assist.sign.sm2.SM2Util; +import lombok.extern.slf4j.Slf4j; + +/** + * @author zhibing.pu + * @Date 2025/7/28 14:25 + */ +@Slf4j +public class CallbackUtil { + + private static ZhengLianConfig zhengLianConfig = SpringContextsUtil.getBean(ZhengLianConfig.class).getZhengLianConfig(); + + + public static String callback(MessageBody messageBody) { + try { + String data = messageBody.getData(); + String sign = messageBody.getSign(); + String secret = messageBody.getSecret(); + //加密对称加密的秘钥 + // 获取公钥 + String publicKey = ZhengLianUtil.getPublicKey(); + // 验签 + boolean checkResult = SM2Util.verify(publicKey, zhengLianConfig.getEncrpNo(), sign, data); + System.out.println("验签结果:" + checkResult); + // 获取私钥 + String privateKey = ZhengLianUtil.getPrivateKey(); + // 解密对称秘钥 + String k = SM2Util.decrypt(privateKey, secret); + System.out.println("对称秘钥:" + k); + // 解密业务报文 + String backData = SM4Util.sm4EcbDecrypt(k, data); + System.out.println("业务报文:" + backData); + return backData; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + +} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/SM4Util.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/SM4Util.java deleted file mode 100644 index a577a70..0000000 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/SM4Util.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.stylefeng.guns.modular.system.util.zhenglian; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -import javax.crypto.Cipher; -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.security.Security; -import java.util.Base64; - -/** - * SM4国密工具类 - * @author zhibing.pu - * @Date 2025/7/24 15:29 - */ -public class SM4Util { - private static final String ALGORITHM_NAME = "SM4"; - - private static final String ALGORITHM_MODE = "SM4/ECB/PKCS5Padding"; - - - static { - Security.addProvider(new BouncyCastleProvider()); - } - - /** - * 生成 SM4 密钥 - * @return 密钥的 Base64 编码字符串 - * @throws Exception 异常 - */ - public static String generateKey() throws Exception { - KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, "BC"); - kg.init(128); - SecretKey secretKey = kg.generateKey(); - return Base64.getEncoder().encodeToString(secretKey.getEncoded()); - } - - /** - * SM4 加密 - * @param plainText 明文 - * @param key 密钥的 Base64 编码字符串 - * @return 密文的 Base64 编码字符串 - * @throws Exception 异常 - */ - public static String encrypt(String plainText, String key) throws Exception { - byte[] keyBytes = Base64.getDecoder().decode(key); - SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_NAME); - Cipher cipher = Cipher.getInstance(ALGORITHM_MODE, "BC"); - cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); - byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); - return Base64.getEncoder().encodeToString(encryptedBytes); - } - - /** - * SM4 解密 - * @param cipherText 密文的 Base64 编码字符串 - * @param key 密钥的 Base64 编码字符串 - * @return 明文 - * @throws Exception 异常 - */ - public static String decrypt(String cipherText, String key) throws Exception { - byte[] keyBytes = Base64.getDecoder().decode(key); - SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM_NAME); - Cipher cipher = Cipher.getInstance(ALGORITHM_MODE, "BC"); - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); - byte[] cipherBytes = Base64.getDecoder().decode(cipherText); - byte[] decryptedBytes = cipher.doFinal(cipherBytes); - return new String(decryptedBytes, StandardCharsets.UTF_8); - } - - public static void main(String[] args) { - try { - // 生成密钥 - String key = generateKey(); - System.out.println("生成的密钥: " + key); - - // 明文 - String plainText = "Hello, SM4!"; - System.out.println("明文: " + plainText); - - // 加密 - String cipherText = encrypt(plainText, key); - System.out.println("密文: " + cipherText); - - // 解密 - String decryptedText = decrypt(cipherText, key); - System.out.println("解密后的明文: " + decryptedText); - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/TokenUtil.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/TokenUtil.java index d0d4130..bbe6942 100644 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/TokenUtil.java +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/TokenUtil.java @@ -1,44 +1,89 @@ package com.stylefeng.guns.modular.system.util.zhenglian; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.stylefeng.guns.modular.system.util.SpringContextsUtil; import com.stylefeng.guns.modular.system.util.UUIDUtil; +import com.stylefeng.guns.modular.system.util.zhenglian.model.MessageBody; import com.stylefeng.guns.modular.system.util.zhenglian.model.TokenRequest; +import com.zlpay.assist.encrypt.sm4.SM4Util; +import com.zlpay.assist.sign.sm2.SM2Util; +import lombok.extern.slf4j.Slf4j; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; /** * @author zhibing.pu * @Date 2025/7/24 14:06 */ +@Slf4j public class TokenUtil { - + private static ZhengLianConfig zhengLianConfig = SpringContextsUtil.getBean(ZhengLianConfig.class).getZhengLianConfig(); - - - public static void getToken(TokenRequest request){ - request.setAppid(zhengLianConfig.getAppid()); - HttpRequest post = HttpUtil.createPost(zhengLianConfig.getUrl()); - String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); - post.header("msgId", UUIDUtil.getRandomCode()); - post.header("merchNo", zhengLianConfig.getMerchNo()); - post.header("txCode","ZLPAY.ACC.T0001"); - post.header("version","1.0.1"); - post.header("encrp","1"); - post.header("signa","1"); - post.header("encrpNo","123456"); - post.header("signNo","123456"); - post.header("timestamp", timestamp); - post.header("Content-Length", ""); - post.header("Content-Type", "application/json;charset=utf-8"); + + public static String getToken(TokenRequest tokenRequest) throws Exception { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + Map<String,String> headerMap = new HashMap<String,String>(); + MessageBody body = new MessageBody(); + headerMap.put("msgId", UUIDUtil.getRandomCode()); + headerMap.put("merchNo", "B00000871"); + headerMap.put("txCode", "ZLPAY.ACC.T0001"); + headerMap.put("version", "1.0.1"); + headerMap.put("signa", "1"); + headerMap.put("signNo", zhengLianConfig.getSignNo()); + headerMap.put("encrp", "1"); + headerMap.put("encrpNo", zhengLianConfig.getEncrpNo()); + headerMap.put("timestamp", sdf.format(new Date())); + tokenRequest.setAppId(zhengLianConfig.getAppid()); + tokenRequest.setType("04"); + String reqBO = JSON.toJSONString(tokenRequest); + // 生成对称加密秘钥 + String key = ZhengLianUtil.generateKey(16); + // 加密数据 + String jsonData = SM4Util.sm4EcbEncrypt(key, reqBO, "NoPadding"); + //加密对称加密的秘钥 + // 获取公钥 + String publicKey = ZhengLianUtil.getPublicKey(); + String secrtKey = SM2Util.encrypt(publicKey, key); - post.body("{}"); + // 将密文放入body + body.setData(jsonData); + body.setSign(ZhengLianUtil.sign(jsonData)); + body.setSecret(secrtKey); + String result = ZLHttpClientUtil.doPost(zhengLianConfig.getUrl(), headerMap, JSON.toJSONString(body)); - + System.out.println("应答内容:"+ result); + MessageBody respBody = JSON.parseObject(result,MessageBody.class); + // 验签 + boolean checkResult = SM2Util.verify(publicKey, zhengLianConfig.getEncrpNo(), respBody.getSign(), respBody.getData()); + System.out.println("验签结果:" + checkResult); + // 获取私钥 + String privateKey = ZhengLianUtil.getPrivateKey(); + // 解密对称秘钥 + String k = SM2Util.decrypt(privateKey, respBody.getSecret()); + System.out.println("对称秘钥:" + k); + // 解密业务报文 + String backData = SM4Util.sm4EcbDecrypt(k, respBody.getData()); + System.out.println("返回业务报文:" + backData); + JSONObject jsonObject = JSON.parseObject(backData); + String sysRtnCode = jsonObject.getString("sysRtnCode"); + if(!"000000".equals(sysRtnCode)){ + log.error("获取token失败!{}", jsonObject.getString("sysRtnMsg")); + throw new Exception(jsonObject.getString("sysRtnMsg")); + } + JSONObject bizData = jsonObject.getJSONObject("bizData"); + String resCode = bizData.getString("resCode"); + if(!"S010000".equals(resCode)){ + log.error("获取token失败!{}", bizData.getString("resMsg")); + throw new Exception(jsonObject.getString("resMsg")); + } + return bizData.getString("token"); } + } diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZLHttpClientUtil.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZLHttpClientUtil.java new file mode 100644 index 0000000..740a4be --- /dev/null +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZLHttpClientUtil.java @@ -0,0 +1,129 @@ +package com.stylefeng.guns.modular.system.util.zhenglian; + +import org.apache.http.client.config.AuthSchemes; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.util.EntityUtils; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * @author zhibing.pu + * @Date 2025/7/28 14:23 + */ +public class ZLHttpClientUtil { + + /** + * 连接超时时间 + */ + private final static int CONNECT_TIMEOUT = 30000; + /** + * 请求超时时间 + */ + private final static int REQUEST_TIMEOUT = 50000; + /** + * socket超时时间 + */ + private final static int SOCKET_TIMEOUT = 50000; + /** + * 请求格式 + */ + private final static String FORMAT = "application/json"; + /** + * 请求类型 + */ + private final static String POST_TYPE = "https://"; + + public static String doPost(String url, Map<String, String> headerMap, String jsonData) { + CloseableHttpClient httpClient = HttpClients.createDefault(); + if (url != null && url.startsWith(POST_TYPE)) { + httpClient = sslClient(); + } + HttpPost httpPost = new HttpPost(url); + RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT) + .setConnectionRequestTimeout(REQUEST_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).setRedirectsEnabled(true) + .build(); + httpPost.setConfig(requestConfig); + httpPost.setHeader("Content-Type", "application/json"); + if (headerMap != null) { + Set<String> keys = headerMap.keySet(); + for (Iterator<String> i = keys.iterator(); i.hasNext();) { + String key = (String) i.next(); + httpPost.addHeader(key, headerMap.get(key)); + } + } + try { + httpPost.setEntity(new StringEntity(jsonData, ContentType.create(FORMAT, "UTF-8"))); + CloseableHttpResponse execute = httpClient.execute(httpPost); + int statusCode = execute.getStatusLine().getStatusCode(); + if (statusCode == 200) { + return String.valueOf(EntityUtils.toString(execute.getEntity())); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + private static CloseableHttpClient sslClient() { + try { + X509TrustManager trustManager = new X509TrustManager() { + @Override public X509Certificate[] getAcceptedIssuers() { + return null; + } + @Override public void checkClientTrusted(X509Certificate[] xcs, String str) {} + @Override public void checkServerTrusted(X509Certificate[] xcs, String str) {} + }; + SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS); + ctx.init(null, new TrustManager[] { trustManager }, null); + SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE); + // 创建Registry + RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT) + .setExpectContinueEnabled(Boolean.TRUE).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM,AuthSchemes.DIGEST)) + .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build(); + Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() + .register("http", PlainConnectionSocketFactory.INSTANCE) + .register("https",socketFactory).build(); + // 创建ConnectionManager,添加Connection配置信息 + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connectionManager) + .setDefaultRequestConfig(requestConfig).build(); + return closeableHttpClient; + } catch (KeyManagementException ex) { + throw new RuntimeException(ex); + } catch (NoSuchAlgorithmException ex) { + throw new RuntimeException(ex); + } + } +} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianConfig.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianConfig.java index d5273b2..e78876c 100644 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianConfig.java +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianConfig.java @@ -34,6 +34,18 @@ * 签名证书序列号 */ private String signNo; + /** + * 证书 + */ + private String cer; + /** + * 证书 + */ + private String sm2; + /** + * + */ + private String password; /** * 获取不同环境的配置 @@ -44,15 +56,21 @@ this.url = "https://gatewaytest.zqpay.com"; this.appid = "F9BFEEA567196A92E053376010ACF004"; this.merchNo = "B00000871"; - this.encrpNo = "123456"; - this.signNo = "123456"; + this.encrpNo = "1055490595"; + this.signNo = "1066348524"; + this.cer = "C:\\Users\\39373\\Desktop\\UAT-demo-公用\\1055490595.cer"; + this.sm2 = "C:\\Users\\39373\\Desktop\\UAT-demo-公用\\871_111111.sm2"; + this.password = "111111"; } if("test".equals(activeProfile)){ this.url = "https://gatewaytest.zqpay.com"; this.appid = "F9BFEEA567196A92E053376010ACF004"; this.merchNo = "B00000871"; - this.encrpNo = "123456"; - this.signNo = "123456"; + this.encrpNo = "1055490595"; + this.signNo = "1066348524"; + this.cer = "C:\\Users\\39373\\Desktop\\UAT-demo-公用\\1055490595.cer"; + this.sm2 = "C:\\Users\\39373\\Desktop\\UAT-demo-公用\\871_111111.sm2"; + this.password = "111111"; } if("prod".equals(activeProfile)){ this.url = "https://gateway.zqpay.com"; @@ -60,6 +78,9 @@ this.merchNo = ""; this.encrpNo = ""; this.signNo = ""; + this.cer = ""; + this.sm2 = ""; + this.password = ""; } return this; } diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianUtil.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianUtil.java new file mode 100644 index 0000000..b6d723e --- /dev/null +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/ZhengLianUtil.java @@ -0,0 +1,108 @@ +package com.stylefeng.guns.modular.system.util.zhenglian; + +import com.stylefeng.guns.modular.system.util.SpringContextsUtil; +import com.zlpay.assist.sign.sm2.SM2Cert; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.RandomStringUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.Base64; + +/** + * @author zhibing.pu + * @Date 2025/7/28 14:22 + */ +@Slf4j +public class ZhengLianUtil { + + private static ZhengLianConfig zhengLianConfig = SpringContextsUtil.getBean(ZhengLianConfig.class).getZhengLianConfig(); + + /** + * @Description: 从公钥证书获取公钥串 + * @return + * @return String + * @throws + * @author: tsl + * @date: 2019年4月19日 下午9:07:56 + */ + public static String getPublicKey() { + String publicKey = ""; + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(new File(zhengLianConfig.getCer())); + X509Certificate publicCert = SM2Cert.getPublicCert(inputStream); + publicKey = Base64.getEncoder().encodeToString(publicCert.getEncoded()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return publicKey; + } + + /** + * @Description: 从私钥证书获取私钥传 + * @return + * @return String + * @throws + * @author: tsl + * @date: 2019年4月19日 下午9:08:00 + */ + public static String getPrivateKey() { + String privateKey = ""; + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(new File(zhengLianConfig.getSm2())); + byte[] priBytes = SM2Cert.getPrivateCert(inputStream); + privateKey = SM2Cert.getPrivateKey(zhengLianConfig.getPassword(), priBytes); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return privateKey; + } + /** + * @Description: 生成对称加密秘钥 + * @return String + * @throws + * @author: syuf + * @date: 2018年11月8日 下午5:50:05 + */ + public static String generateKey(int length) { + return RandomStringUtils.randomAlphanumeric(length); + } + /** + * @Description: 签名 + * @param data + * @return String + * @throws + * @author: syuf + * @date: 2018年11月15日 下午2:19:01 + */ + public static String sign(String data) { + try { + // 获取私钥 + String privateKey = getPrivateKey(); + return com.zlpay.assist.sign.sm2.SM2Util.sign(privateKey, zhengLianConfig.getSignNo(), data); + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } +} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/MessageBody.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/MessageBody.java new file mode 100644 index 0000000..fdbbc08 --- /dev/null +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/MessageBody.java @@ -0,0 +1,23 @@ +package com.stylefeng.guns.modular.system.util.zhenglian.model; + +import lombok.Data; + +/** + * @author zhibing.pu + * @Date 2025/7/28 14:19 + */ +@Data +public class MessageBody { + /** + * 业务数据 + */ + private String data; + /** + * 签名 + */ + private String sign; + /** + * 秘钥 + */ + private String secret; +} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/OpenAccountCallbackRequest.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/OpenAccountCallbackRequest.java new file mode 100644 index 0000000..ec14f8a --- /dev/null +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/OpenAccountCallbackRequest.java @@ -0,0 +1,11 @@ +package com.stylefeng.guns.modular.system.util.zhenglian.model; + +import lombok.Data; + +/** + * @author zhibing.pu + * @Date 2025/7/28 14:18 + */ +@Data +public class OpenAccountCallbackRequest { +} diff --git a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/TokenRequest.java b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/TokenRequest.java index 96364c1..671ca17 100644 --- a/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/TokenRequest.java +++ b/DriverQYTTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/zhenglian/model/TokenRequest.java @@ -11,7 +11,7 @@ /** * 应用appid */ - private String appid; + private String appId; /** * APP 端用户唯一标识 */ diff --git a/DriverQYTTravel/guns-admin/src/main/resources/application-dev.yml b/DriverQYTTravel/guns-admin/src/main/resources/application-dev.yml index dacdeaf..b19af59 100644 --- a/DriverQYTTravel/guns-admin/src/main/resources/application-dev.yml +++ b/DriverQYTTravel/guns-admin/src/main/resources/application-dev.yml @@ -113,3 +113,8 @@ #交通部推送数据功能开关 pushMinistryOfTransport: false +--- +rongyun: + app_key: 111 + app_secret: 111 + diff --git a/DriverQYTTravel/pom.xml b/DriverQYTTravel/pom.xml index 6f93755..fa97b22 100644 --- a/DriverQYTTravel/pom.xml +++ b/DriverQYTTravel/pom.xml @@ -41,7 +41,7 @@ <ehcache.core.version>2.6.11</ehcache.core.version> <mysql-connector-java.version>8.0.11</mysql-connector-java.version> <jwt.version>0.9.0</jwt.version> - <hutool.version>4.1.1</hutool.version> + <hutool.version>5.8.39</hutool.version> </properties> <dependencyManagement> diff --git a/UserQYTTravel/guns-admin/pom.xml b/UserQYTTravel/guns-admin/pom.xml index 33f1860..14973e1 100644 --- a/UserQYTTravel/guns-admin/pom.xml +++ b/UserQYTTravel/guns-admin/pom.xml @@ -226,6 +226,12 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> + + <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + <version>2.2.1</version> + </dependency> </dependencies> -- Gitblit v1.7.1