Explorar o código

feat(app):
1.拉卡拉支付集成相关demo代码
fix(app):
1.后台包场编辑逻辑bug修复
2.小程序订单回显详情数据补充

wzq hai 3 días
pai
achega
867fc32466
Modificáronse 44 ficheiros con 4474 adicións e 62 borrados
  1. 10 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/dto/AppOrderInfoDTO.java
  2. 22 7
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java
  3. 406 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/V3LabsApi.java
  4. 81 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/V3LosApi.java
  5. 103 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/controller/PayController.java
  6. 56 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayClient.java
  7. 79 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayConfig.java
  8. 125 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayKit.java
  9. 59 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayUrl.java
  10. 142 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/TkToken.java
  11. 11 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/LakalaRequest.java
  12. 11 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/ReqData.java
  13. 60 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/ReqLocationInfo.java
  14. 60 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/oauth/TokenRequest.java
  15. 74 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/LabsRequest.java
  16. 41 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/LosRequest.java
  17. 96 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/CloseRequest.java
  18. 259 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/MicropayRequest.java
  19. 262 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/PreorderRequest.java
  20. 163 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/RefundRequest.java
  21. 117 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/RevokedRequest.java
  22. 77 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/TradeQueryRequest.java
  23. 102 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/AliPayAccBusiFieldsRequest.java
  24. 89 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/AliPayExtendParamsRequest.java
  25. 150 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/AliPayGoodsDetailRequest.java
  26. 11 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/ReqAccBusiFields.java
  27. 131 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/WxPayAccBusiFieldsRequest.java
  28. 65 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/WxPayDetailRequest.java
  29. 99 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/WxPayGoodsDatailRequest.java
  30. 309 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/los/GenerateOrderRequest.java
  31. 100 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/los/OutSplitInfoRequest.java
  32. 67 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/los/QueryOrderRequest.java
  33. 74 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/service/PayService.java
  34. 398 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/service/impl/PayServiceImpl.java
  35. 305 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/util/HttpClientPool.java
  36. 54 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/util/HttpUtil.java
  37. 64 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/vo/NotifyVO.java
  38. 9 1
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/entity/InsureOrderInfo.java
  39. 44 48
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoureseServiceImpl.java
  40. 12 6
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppSitePlaceServiceImpl.java
  41. 28 0
      national-motion-module-system/national-motion-system-biz/src/main/resources/OP00000003_private_key.pem
  42. 20 0
      national-motion-module-system/national-motion-system-biz/src/main/resources/lakala-config.properties
  43. 25 0
      national-motion-module-system/national-motion-system-biz/src/main/resources/lkl-apigw-v2.cer
  44. 4 0
      pom.xml

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

@@ -10,6 +10,7 @@ import lombok.experimental.Accessors;
 import org.jeecg.modules.app.vo.AppGameScheduleVO;
 import org.jeecg.modules.system.app.entity.AppCourses;
 import org.jeecg.modules.system.app.entity.AppOrderProInfo;
+import org.jeecg.modules.system.app.entity.InsureOrderInfo;
 import org.jeecgframework.poi.excel.annotation.Excel;
 import org.springframework.format.annotation.DateTimeFormat;
 
@@ -55,6 +56,9 @@ public class AppOrderInfoDTO implements Serializable {
     @Schema(description = "经营状态 0-营业 1-休息")
     private Integer runStatus;
 
+    @Schema(description = "经营类型0全天 1自定义")
+    private Integer runType;
+
     @Schema(description = "上课地址ID")
     private String addressSiteId;
 
@@ -64,6 +68,9 @@ public class AppOrderInfoDTO implements Serializable {
     @Schema(description = "学校地址")
     private String schoolAddress;
 
+    @Schema(description = "是否学校课程 0-否 1-是")
+    private Integer orSchoolCourse;
+
     @Schema(description = "日期")
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @DateTimeFormat(pattern = "yyyy-MM-dd")
@@ -120,6 +127,9 @@ public class AppOrderInfoDTO implements Serializable {
     @Schema(description = "赛事安排")
     private List<AppGameScheduleVO> appGameScheduleVOList;
 
+    @Schema(description = "保单信息")
+    private List<InsureOrderInfo> insureOrderInfoList;
+
     @Schema(description = "赛程数")
     private Integer gameScheduleNum;
 

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

@@ -443,18 +443,18 @@ public class OrderServiceImpl implements IOrderService {
                     //订单总价(商品的售价总和)
                     BigDecimal sumPrice = new BigDecimal(0);
 
-                    for (String id : list) {
-                        AppSitePriceRules priceRule = appSitePriceRulesMapper.selectById(list.get(0));
+                    for (int i = 0; i < list.size(); i++) {
+                        AppSitePriceRules priceRule = appSitePriceRulesMapper.selectById(list.get(i).split("\\|")[0]);
                         AppSitePlace appSitePlace = appSitePlaceMapper.selectById(priceRule.getSitePlaceId());
                         AppSite appSite = appSiteMapper.selectById(appSitePlace.getSiteId());
 
-                        String date = DateUtil.format(priceRule.getDateOfSale(), "yyyy-MM-dd");
+                        String date = list.get(i).split("\\|")[1];
                         String startTime = DateUtil.format(priceRule.getStartTime(), "HH:mm:ss");
                         String endTime = DateUtil.format(priceRule.getEndTime(), "HH:mm:ss");
                         String expireTime = date + " " + endTime;
 
                         AppOrderProInfo appOrderProInfo = new AppOrderProInfo();
-                        appOrderProInfo.setProductId(id);
+                        appOrderProInfo.setProductId(list.get(i).split("\\|")[0]);
                         appOrderProInfo.setProductName(date + " " + startTime + "-" + endTime + "|" + appSitePlace.getName());
                         appOrderProInfo.setExpireTime(expireTime);
                         appOrderProInfo.setAddress(appSite.getAddress());
@@ -709,6 +709,7 @@ public class OrderServiceImpl implements IOrderService {
 
                 //查询保单价格
                 InsurePrice insurePrice = insurePriceMapper.selectById(insureOrderInfoForm.getInsurePriceId());
+                FamilyMembers members = familyMembersMapper.selectById(id);
 
                 //创建保单
                 InsureOrderInfo insureOrderInfo = new InsureOrderInfo();
@@ -720,6 +721,7 @@ public class OrderServiceImpl implements IOrderService {
                         .setInsureId(appInsure.getId())
                         .setMoney(insurePrice.getInsurePrice())
                         .setFamilyMembersId(id)
+                        .setFamilyUserName(members.getFullName())
                         .setAssertStartTime(insureOrderInfoForm.getAssertStartTime())
                         .setAssertEndTime(insureOrderInfoForm.getAssertEndTime())
                         .setIsEnterSystem(CommonConstant.STATUS_0_INT)
@@ -880,7 +882,8 @@ public class OrderServiceImpl implements IOrderService {
             if (appOrder.getOrderType() == 1) {
                 //商品信息
                 String productIds = appOrder.getProductIds();
-                AppSitePriceRules appSitePriceRules = appSitePriceRulesMapper.selectById(productIds);
+                String[] split = productIds.split(",");
+                AppSitePriceRules appSitePriceRules = appSitePriceRulesMapper.selectById(split[0].split("\\|")[0]);
                 AppSitePlace appSitePlace = appSitePlaceMapper.selectById(appSitePriceRules.getSitePlaceId());
                 //使用须知
                 if (ObjectUtils.isNotEmpty(appSitePlace.getReminder())) {
@@ -916,8 +919,9 @@ public class OrderServiceImpl implements IOrderService {
                 appOrderInfoDTO.setSiteName(site.getName());
                 appOrderInfoDTO.setRunStatus(site.getRunStatus());
                 //预定信息
-                appOrderInfoDTO.setStartTime(appSitePriceRules.getStartTime());
-                appOrderInfoDTO.setEndTime(appSitePriceRules.getEndTime());
+                appOrderInfoDTO.setRunType(site.getRunType());
+                appOrderInfoDTO.setStartTime(site.getStartTime());
+                appOrderInfoDTO.setEndTime(site.getEndTime());
                 appOrderInfoDTO.setRefundType(appSitePlace.getRefundType());
                 //地址信息
                 appOrderInfoDTO.setSchoolAddress(site.getAddress());
@@ -970,6 +974,11 @@ public class OrderServiceImpl implements IOrderService {
             appOrderInfoDTO.setRunStatus(site.getRunStatus());
             //上课地点(经纬度)
             AppSite courseSite = appSiteMapper.selectById(appCourses.getAddressSiteId());
+            appOrderInfoDTO.setOrSchoolCourse(0);
+            //学校课程
+            if(courseSite.getType() == 0){
+                appOrderInfoDTO.setOrSchoolCourse(1);
+            }
             appOrderInfoDTO.setCourseSiteAddress(courseSite.getAddress());
             appOrderInfoDTO.setLatitude(courseSite.getLatitude());
             appOrderInfoDTO.setLongitude(courseSite.getLongitude());
@@ -977,6 +986,12 @@ public class OrderServiceImpl implements IOrderService {
             appOrderInfoDTO.setAddressSiteId(courseSite.getId());
         }
 
+        //保单信息
+        List<InsureOrderInfo> insureOrderInfoList = insureOrderInfoMapper.selectList(Wrappers.lambdaQuery(InsureOrderInfo.class).eq(InsureOrderInfo::getOrderId, orderId));
+        if (CollUtil.isNotEmpty(insureOrderInfoList)) {
+            appOrderInfoDTO.setInsureOrderInfoList(insureOrderInfoList);
+        }
+
         return appOrderInfoDTO;
     }
 

+ 406 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/V3LabsApi.java

@@ -0,0 +1,406 @@
+package org.jeecg.modules.pay;
+
+
+import org.jeecg.modules.pay.core.LakalaPayClient;
+import org.jeecg.modules.pay.core.LakalaPayUrl;
+import org.jeecg.modules.pay.request.ReqLocationInfo;
+import org.jeecg.modules.pay.request.v3.LabsRequest;
+import org.jeecg.modules.pay.request.v3.labs.*;
+import org.jeecg.modules.pay.request.v3.labs.accbusifields.*;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+/**
+ * 拉卡拉V3.0下支付类接口API
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class V3LabsApi {
+
+    /**
+     * 主扫交易接口
+     *
+     * @param preorderRequest 请求报文
+     * @return
+     */
+    public static String transPreorder(PreorderRequest preorderRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LABS_TRANS_PREORDER, new LabsRequest(preorderRequest));
+    }
+
+    /**
+     * 主扫支付-支付宝(41-NATIVE)场景下
+     *
+     * @param out_trade_no 商户交易流水号
+     * @param total_amount 金额
+     * @param request_ip   请求方IP地址
+     * @param subject      订单标题
+     * @param notify_url   商户通知地址
+     * @param goods_id     商品的编号
+     * @param goods_name   商品名称
+     * @param quantity     商品数量
+     * @return
+     * @throws IOException
+     */
+    public static String transPreorder_alipay_native(String out_trade_no, Integer total_amount, String request_ip, String subject, String notify_url, String goods_id, String goods_name, Integer quantity) throws IOException {
+        // 钱包类型
+        String account_type = "ALIPAY";
+        // 接入方式
+        String trans_type = "41";
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化主扫交易接口请求报文
+        PreorderRequest request = new PreorderRequest(out_trade_no, account_type, trans_type, Integer.toString(total_amount), location_info);
+        // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+        request.setSubject(subject);
+        // 商户通知地址
+        request.setNotify_url(notify_url);
+
+        // 账户端业务信息域
+        AliPayAccBusiFieldsRequest accBusiFieldsRequest = new AliPayAccBusiFieldsRequest();
+        // 商品价格 单位元
+        Double price = new BigDecimal(total_amount).divide(new BigDecimal(100)).doubleValue();
+        accBusiFieldsRequest.setGoods_detail(new AliPayGoodsDetailRequest(goods_id, goods_name, quantity, price));
+
+        request.setAcc_busi_fields(accBusiFieldsRequest);
+        return transPreorder(request);
+    }
+
+    /**
+     * 主扫支付-支付宝(51-JSAPI)场景下
+     *
+     * @param out_trade_no 商户交易流水号
+     * @param total_amount 金额
+     * @param request_ip   请求方IP地址
+     * @param subject      订单标题
+     * @param notify_url   商户通知地址
+     * @param user_id      买家在支付宝的用户id(支付宝的buyer_user_id)
+     * @param goods_id     商品的编号
+     * @param goods_name   商品名称
+     * @param quantity     商品数量
+     * @return
+     * @throws IOException
+     */
+    public static String transPreorder_alipay_jsapi(String out_trade_no, Integer total_amount, String request_ip, String subject, String notify_url, String user_id, String goods_id, String goods_name, Integer quantity) throws IOException {
+        // 钱包类型
+        String account_type = "ALIPAY";
+        // 接入方式
+        String trans_type = "51";
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化主扫交易接口请求报文
+        PreorderRequest request = new PreorderRequest(out_trade_no, account_type, trans_type, Integer.toString(total_amount), location_info);
+        // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+        request.setSubject(subject);
+        // 商户通知地址
+        request.setNotify_url(notify_url);
+
+        // 账户端业务信息域
+        AliPayAccBusiFieldsRequest accBusiFieldsRequest = new AliPayAccBusiFieldsRequest();
+        accBusiFieldsRequest.setUser_id(user_id);
+        // 商品价格 单位元
+        Double price = new BigDecimal(total_amount).divide(new BigDecimal(100)).doubleValue();
+        accBusiFieldsRequest.setGoods_detail(new AliPayGoodsDetailRequest(goods_id, goods_name, quantity, price));
+
+        request.setAcc_busi_fields(accBusiFieldsRequest);
+        return transPreorder(request);
+    }
+
+    /**
+     * 主扫支付-微信(71-小程序)场景下
+     *
+     * @param out_trade_no 商户交易流水号
+     * @param total_amount 金额
+     * @param request_ip   请求方IP地址
+     * @param subject      订单标题
+     * @param notify_url   商户通知地址
+     * @param sub_appid    子商户公众账号ID(微信分配的子商户公众账号ID,sub_appid)
+     * @param user_id      用户标识(用户在子商户sub_appid下的唯一标识,sub_openid)
+     * @param goods_id     商品编码
+     * @param goods_name   商品的实际名称
+     * @param quantity     用户购买的数量
+     * @return
+     * @throws IOException
+     */
+    public static String transPreorder_wxpay_applet(String out_trade_no, Integer total_amount, String request_ip, String subject, String notify_url, String sub_appid, String user_id, String goods_id, String goods_name, Integer quantity) throws IOException {
+        // 钱包类型
+        String account_type = "WECHAT";
+        // 接入方式
+        String trans_type = "71";
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化主扫交易接口请求报文
+        PreorderRequest request = new PreorderRequest(out_trade_no, account_type, trans_type, Integer.toString(total_amount), location_info);
+        // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+        request.setSubject(subject);
+        // 商户通知地址
+        request.setNotify_url(notify_url);
+
+        // 账户端业务信息域
+        WxPayAccBusiFieldsRequest accBusiFieldsRequest = new WxPayAccBusiFieldsRequest();
+        // 子商户公众账号ID
+        accBusiFieldsRequest.setSub_appid(sub_appid);
+        // 用户标识
+        accBusiFieldsRequest.setUser_id(user_id);
+        // 商品价格 单位元
+        Integer price = new BigDecimal(total_amount).divide(new BigDecimal(100)).intValue();
+        accBusiFieldsRequest.setDetail(new WxPayDetailRequest(new WxPayGoodsDatailRequest(goods_id, goods_name, quantity, price)));
+
+        request.setAcc_busi_fields(accBusiFieldsRequest);
+
+        return transPreorder(request);
+    }
+
+    /**
+     * 主扫支付-微信(51-JSAPI)场景下
+     *
+     * @param out_trade_no 商户交易流水号
+     * @param total_amount 金额
+     * @param request_ip   请求方IP地址
+     * @param subject      订单标题
+     * @param notify_url   商户通知地址
+     * @param sub_appid    子商户公众账号ID(微信分配的子商户公众账号ID,sub_appid)
+     * @param user_id      用户标识(用户在子商户sub_appid下的唯一标识,sub_openid)
+     * @param goods_id     商品编码
+     * @param goods_name   商品的实际名称
+     * @param quantity     用户购买的数量
+     * @return
+     * @throws IOException
+     */
+    public static String transPreorder_wxpay_jsapi(String out_trade_no, Integer total_amount, String request_ip, String subject, String notify_url, String sub_appid, String user_id, String goods_id, String goods_name, Integer quantity) throws IOException {
+        // 钱包类型
+        String account_type = "WECHAT";
+        // 接入方式
+        String trans_type = "51";
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化主扫交易接口请求报文
+        PreorderRequest request = new PreorderRequest(out_trade_no, account_type, trans_type, Integer.toString(total_amount), location_info);
+        // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+        request.setSubject(subject);
+        // 商户通知地址
+        request.setNotify_url(notify_url);
+
+        // 账户端业务信息域
+        WxPayAccBusiFieldsRequest accBusiFieldsRequest = new WxPayAccBusiFieldsRequest();
+        // 子商户公众账号ID
+        accBusiFieldsRequest.setSub_appid(sub_appid);
+        // 用户标识
+        accBusiFieldsRequest.setUser_id(user_id);
+        // 商品价格 单位元
+        Integer price = new BigDecimal(total_amount).divide(new BigDecimal(100)).intValue();
+        accBusiFieldsRequest.setDetail(new WxPayDetailRequest(new WxPayGoodsDatailRequest(goods_id, goods_name, quantity, price)));
+
+        request.setAcc_busi_fields(accBusiFieldsRequest);
+
+        return transPreorder(request);
+    }
+
+    /**
+     * 被扫交易
+     * <p>
+     * 说明:被扫支付场景,可能存在支付中需要用户输入密码的情况。该情况下一般交易会返回“BBS10000-支付中”状态。
+     * 在该场景下,建议发起方发起多次查询,查询频率推荐1分钟内按 5s+5s+5s+5s+10S+10S+20S方式联机查询,并保留手工发起查询的能力。
+     * <p>
+     * 场景说明: 如果用户支付密码用时比较长,商户多次查询完成时,用户还没有输密码完成,拉卡拉这边会按照一定的轮询策略
+     * (总时间范围大概在两个小时的多次查询)继续向账户端发起查询,查询成功后再按照接口中通知地址通知商户。
+     * 如果用户在拉卡拉的轮询查询都完成了还没有完成输入密码,此时交易还处于中间态,
+     * 只能依赖商户发起手工查询,触发拉卡拉再次向账户端发起交易结果查询
+     *
+     * @param micropayRequest 请求报文
+     * @return
+     */
+    public static String transMicropay(MicropayRequest micropayRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LABS_TRANS_MICROPAY, new LabsRequest(micropayRequest));
+    }
+
+    /**
+     * 被扫支付-支付宝支付
+     *
+     * @param out_trade_no 商户交易流水号
+     * @param auth_code    支付授权码
+     * @param total_amount 金额
+     * @param request_ip   请求方IP地址
+     * @param subject      订单标题
+     * @param notify_url   商户通知地址
+     * @param goods_id     商品的编号
+     * @param goods_name   商品名称
+     * @param quantity     商品数量
+     * @return
+     * @throws IOException
+     */
+    public static String transMicropay_alipay(String out_trade_no, String auth_code, String total_amount, String request_ip, String subject, String notify_url, String goods_id, String goods_name, Integer quantity) throws IOException {
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化被扫交易接口请求报文
+        MicropayRequest request = new MicropayRequest(out_trade_no, auth_code, total_amount, location_info);
+        // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+        request.setSubject(subject);
+        // 商户通知地址
+        request.setNotify_url(notify_url);
+        // 账户端业务信息域
+        AliPayAccBusiFieldsRequest accBusiFieldsRequest = new AliPayAccBusiFieldsRequest();
+        // 商品价格 单位元
+        Double price = new BigDecimal(total_amount).divide(new BigDecimal(100)).doubleValue();
+        accBusiFieldsRequest.setGoods_detail(new AliPayGoodsDetailRequest(goods_id, goods_name, quantity, price));
+        request.setAcc_busi_fields(accBusiFieldsRequest);
+
+        return transMicropay(request);
+    }
+
+    /**
+     * 被扫支付-微信支付
+     *
+     * @param out_trade_no 商户交易流水号
+     * @param auth_code    支付授权码
+     * @param total_amount 金额
+     * @param request_ip   请求方IP地址
+     * @param subject      订单标题
+     * @param notify_url   商户通知地址
+     * @param goods_id     商品的编号
+     * @param goods_name   商品名称
+     * @param quantity     商品数量
+     * @return
+     * @throws IOException
+     */
+    public static String transMicropay_wxpay(String out_trade_no, String auth_code, String total_amount, String request_ip, String subject, String notify_url, String goods_id, String goods_name, Integer quantity) throws IOException {
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化被扫交易接口请求报文
+        MicropayRequest request = new MicropayRequest(out_trade_no, auth_code, total_amount, location_info);
+        // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+        request.setSubject(subject);
+        // 商户通知地址
+        request.setNotify_url(notify_url);
+        // 账户端业务信息域
+        WxPayAccBusiFieldsRequest accBusiFieldsRequest = new WxPayAccBusiFieldsRequest();
+        // 商品价格 单位元
+        Integer price = new BigDecimal(total_amount).divide(new BigDecimal(100)).intValue();
+        accBusiFieldsRequest.setDetail(new WxPayDetailRequest(new WxPayGoodsDatailRequest(goods_id, goods_name, quantity, price)));
+        request.setAcc_busi_fields(accBusiFieldsRequest);
+
+        return transMicropay(request);
+    }
+
+
+    /**
+     * 退款交易
+     *
+     * @param refundRequest 请求报文
+     * @return
+     */
+    public static String relationRefund(RefundRequest refundRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LABS_RELATION_REFUND, new LabsRequest(refundRequest));
+    }
+
+    /**
+     * 退款交易-根据原商户交易流水号
+     *
+     * @param out_trade_no        商户交易流水号
+     * @param refund_amount       退款金额
+     * @param refund_reason       退款原因
+     * @param origin_out_trade_no 原商户交易流水号
+     * @param request_ip          请求方IP地址
+     * @return
+     * @throws IOException
+     */
+    public static String relationRefundByOriginOutTradeNo(String out_trade_no, String refund_amount, String refund_reason, String origin_out_trade_no, String request_ip) throws IOException {
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化主扫交易接口请求报文
+        RefundRequest request = new RefundRequest(out_trade_no, refund_amount, location_info);
+        // 退款原因
+        request.setRefund_reason(refund_reason);
+        // 原商户交易流水号(下单时的商户请求流水号(退款时origin_out_trade_no,origin_trade_no,origin_log_no必送其一))
+        request.setOrigin_out_trade_no(origin_out_trade_no);
+
+        return relationRefund(request);
+    }
+
+    /**
+     * 撤销交易
+     *
+     * @param revokedRequest 请求报文
+     * @return
+     */
+    public static String relationRevoked(RevokedRequest revokedRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LABS_RELATION_REVOKED, new LabsRequest(revokedRequest));
+    }
+
+
+    /**
+     * 撤销交易-根据原商户交易流水号
+     *
+     * @param out_trade_no        商户交易流水号
+     * @param origin_out_trade_no 原商户交易流水号
+     * @param request_ip          请求方IP地址
+     * @return
+     * @throws IOException
+     */
+    public static String relationRevokedByOriginOutTradeNo(String out_trade_no, String origin_out_trade_no, String request_ip) throws IOException {
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化撤销交易接口请求报文
+        RevokedRequest request = new RevokedRequest(out_trade_no, location_info);
+        request.setOrigin_out_trade_no(origin_out_trade_no);
+
+        return relationRevoked(request);
+    }
+
+    /**
+     * 关单交易
+     *
+     * @param closeRequest 请求报文
+     * @return
+     */
+    public static String relationClose(CloseRequest closeRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LABS_RELATION_CLOSE, new LabsRequest(closeRequest));
+    }
+
+    /**
+     * 关单交易-根据原商户交易流水号
+     *
+     * @param origin_out_trade_no 原商户交易流水号
+     * @param request_ip          请求方IP地址
+     * @return
+     * @throws IOException
+     */
+    public static String relationCloseByOriginOutTradeNo(String origin_out_trade_no, String request_ip) throws IOException {
+        // 地址位置信息(地址位置信息,风控要求必送)
+        ReqLocationInfo location_info = new ReqLocationInfo(request_ip);
+        // 初始化关单交易接口请求报文
+        CloseRequest request = new CloseRequest(location_info);
+        // 原商户交易流水号
+        request.setOrigin_out_trade_no(origin_out_trade_no);
+
+        return relationClose(request);
+    }
+
+    /**
+     * 查询交易
+     *
+     * @param tradeQueryRequest 请求报文
+     * @return
+     */
+    public static String queryTradeQuery(TradeQueryRequest tradeQueryRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LABS_QUERY_TRADEQUERY, new LabsRequest(tradeQueryRequest));
+    }
+
+    /**
+     * 查询交易-根据商户交易流水号
+     *
+     * @param out_trade_no 商户交易流水号
+     * @return
+     * @throws IOException
+     */
+    public static String queryTradeQueryByOutTradeNo(String out_trade_no) throws IOException {
+        // 初始化查询交易接口请求报文
+        TradeQueryRequest request = new TradeQueryRequest();
+        // 商户交易流水号
+        request.setOut_trade_no(out_trade_no);
+
+        return queryTradeQuery(request);
+    }
+}

+ 81 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/V3LosApi.java

@@ -0,0 +1,81 @@
+package org.jeecg.modules.pay;
+
+
+import org.jeecg.modules.pay.core.LakalaPayClient;
+import org.jeecg.modules.pay.core.LakalaPayUrl;
+import org.jeecg.modules.pay.request.v3.LabsRequest;
+import org.jeecg.modules.pay.request.v3.los.GenerateOrderRequest;
+import org.jeecg.modules.pay.request.v3.los.QueryOrderRequest;
+
+import java.io.IOException;
+
+/**
+ * 拉卡拉V3.0下订单类接口API
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class V3LosApi {
+
+    /**
+     * 收银台下单
+     *
+     * @param generateOrderRequest 请求报文
+     * @return
+     * @throws IOException
+     */
+    public static String generateOrder(GenerateOrderRequest generateOrderRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LOS_GENERATE_ORDER, new LabsRequest(generateOrderRequest));
+    }
+
+    /**
+     * 收银台下单-简单
+     *
+     * @param out_order_no 商户订单号
+     * @param total_amount 订单金额,单位:分
+     * @param order_info   订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
+     * @param notify_url   订单支付成功后商户接收订单通知的地址
+     * @param callback_url 客户端下单完成支付后返回的商户网页跳转地址
+     * @return
+     * @throws IOException
+     */
+    public static String generateOrder_simple(String out_order_no, Long total_amount, String order_info, String notify_url, String callback_url) throws IOException {
+        // 初始化收银台下单接口请求报文
+        GenerateOrderRequest request = new GenerateOrderRequest(out_order_no, total_amount, order_info);
+        // 订单支付成功后商户接收订单通知的地址
+        request.setNotify_url(notify_url);
+        // 客户端下单完成支付后返回的商户网页跳转地址。
+        request.setCallback_url(callback_url);
+
+        return generateOrder(request);
+    }
+
+    /**
+     * 订单交易信息查询
+     *
+     * @param queryOrderRequest 请求报文
+     * @return
+     * @throws IOException
+     */
+    public static String queryOrder(QueryOrderRequest queryOrderRequest) throws IOException {
+        return LakalaPayClient.execute(LakalaPayUrl.V3_LOS_QUERY_ORDER, new LabsRequest(queryOrderRequest));
+    }
+
+    /**
+     * 订单交易信息查询-根据商户订单号
+     *
+     * @param out_order_no 商户订单号
+     * @return
+     * @throws IOException
+     */
+    public static String queryOrderByOutOrderNo(String out_order_no) throws IOException {
+        // 初始化订单交易信息查询接口请求报文
+        QueryOrderRequest request = new QueryOrderRequest();
+        // 商户订单号
+        request.setOut_order_no(out_order_no);
+
+        return queryOrder(request);
+    }
+
+}

+ 103 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/controller/PayController.java

@@ -0,0 +1,103 @@
+package org.jeecg.modules.pay.controller;
+
+
+import io.swagger.v3.oas.annotations.Operation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.pay.service.PayService;
+import org.jeecg.modules.pay.vo.NotifyVO;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *     支付控制器
+ * </p>
+ *
+ * @author HY
+ * @date 2024-08-19 20:05
+ */
+@RestController
+@RequestMapping("/edu/pay")
+@Slf4j
+public class PayController {
+    @Resource
+    private PayService payService;
+    /**
+     * 支付回调
+     *
+     * @param notifyVO {@link NotifyVO}
+     * @return
+     */
+    @Operation(summary="支付回调")
+    @RequestMapping(value = "/notify")
+    public Result<String> notify(@RequestBody NotifyVO notifyVO) {
+        payService.notify(notifyVO);
+        return Result.OK("执行成功");
+
+
+    }
+
+    /**
+     * <p>
+     *    主扫-支付宝
+     * </p>
+     * @author HY
+     * @Date 2024-08-18
+     */
+//    @Operation(summary="主扫-支付宝")
+//    @GetMapping(value = "/transPreorderALi")
+//    public Result<String> transPreorderALi(@RequestParam("orderId") String orderId){
+//        return Result.OK(payService.transPreorderALi(orderId));
+//    }
+
+    /**
+     * <p>
+     *     被扫-聚合
+     * </p>
+     * @author HY
+     * @Date
+     */
+//    @Operation(summary="被扫-聚合")
+//    @PostMapping(value = "/transMicropay")
+//    public Result<Boolean> transMicropay(TransMicropayDTO transMicropayDTO){
+//        if(Optional.ofNullable(payService.transMicropay(transMicropayDTO)).isPresent()){
+//            return Result.OK(payService.transMicropay(transMicropayDTO));
+//        }else {
+//            return Result.OK();
+//        }
+//    }
+
+//    /**
+//     * <p>
+//     *      退款
+//     * </p>
+//     * @author HY
+//     * @param
+//     * @return
+//     * @Date
+//     */
+//    @ApiOperation(value="退款", notes="退款")
+//    @GetMapping(value = "/relationRefund")
+//    public Result<RefundVO> relationRefund(@RequestParam("orderId") String orderId){
+//        return Result.OK(payService.relationRefund(orderId));
+//    }
+
+    /**
+     * <p>
+     *    交易查询
+     * </p>
+     * @author HY
+     * @param
+     * @return
+     * @Date
+     */
+//    @Operation(summary="交易查询")
+//    @GetMapping(value = "/queryTradeQuery")
+//    public Result<QueryOrderVO> queryTradeQuery(@RequestParam("orderId") String orderId){
+//        return Result.OK(payService.queryTradeQuery(orderId, null));
+//    }
+}

+ 56 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayClient.java

@@ -0,0 +1,56 @@
+package org.jeecg.modules.pay.core;
+
+
+import com.google.gson.Gson;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.jeecg.modules.pay.request.LakalaRequest;
+import org.jeecg.modules.pay.util.HttpUtil;
+
+import java.io.IOException;
+
+/**
+ * 拉卡拉支付sdk客户端
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LakalaPayClient {
+
+    /**
+     * 拉卡拉支付客户端执行操作
+     *
+     * @param url           请求地址
+     * @param lakalaRequest 请求参数
+     * @return 响应报文
+     */
+    public static String execute(String url, LakalaRequest lakalaRequest) throws IOException {
+        String body = new Gson().toJson(lakalaRequest);
+        String authorization = LakalaPayKit.getAuthorization(body);
+        return execute(url, body, "LKLAPI-SHA256withRSA " + authorization);
+    }
+
+    public static String execute(String url, String body, String authorization) throws IOException {
+        HttpResponse response = HttpUtil.post(url, body, authorization);
+        if (response.getStatusLine().getStatusCode() != 200) {
+            return "";
+        }
+
+        String appid = HttpUtil.getHeadValue(response, "Lklapi-Appid");
+        String lklapiSerial = HttpUtil.getHeadValue(response, "Lklapi-Serial");
+        String timestamp = HttpUtil.getHeadValue(response, "Lklapi-Timestamp");
+        String nonce = HttpUtil.getHeadValue(response, "Lklapi-Nonce");
+        String signature = HttpUtil.getHeadValue(response, "Lklapi-Signature");
+
+        String resp = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+        String source = appid + "\n" + lklapiSerial + "\n" + timestamp + "\n" + nonce + "\n" + resp + "\n";
+        boolean verify = LakalaPayKit.verify(source.getBytes("UTF-8"), signature);
+        if (!verify) {
+            return "";
+        }
+        return resp;
+    }
+
+
+}

+ 79 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayConfig.java

@@ -0,0 +1,79 @@
+package org.jeecg.modules.pay.core;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * 拉卡拉支付配置参数
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LakalaPayConfig {
+
+    private static Properties properties;
+
+    private static String getValue(String key) {
+        if (properties == null) {
+            properties = new Properties();
+            try {
+                properties.load(LakalaPayConfig.class.getClassLoader().getResourceAsStream("lakala-config.properties"));
+            } catch (IOException e) {
+
+            }
+
+        }
+        return properties.getProperty(key);
+    }
+
+    /**
+     * 接入方唯一编号
+     */
+    public static final String APPID = getValue("appid");
+    /**
+     * 证书序列号
+     */
+    public static final String SERIAL_NO = getValue("serial_no");
+
+    /**
+     * 私钥证书文件名
+     */
+    public static final String SECRET_PRIVATE_KEY_NAME = getValue("secret_private_key_name");
+
+    /**
+     * 公钥证书文件名
+     */
+    public static final String SECRET_PUBLIC_KEY_NAME = getValue("secret_public_key_name");
+
+    /**
+     * 商户号
+     */
+    public static final String MERCHANT_NO = getValue("merchant_no");
+
+    /**
+     * 终端号
+     */
+    public static final String TERM_NO = getValue("term_no");
+
+    /**
+     * 签名生成随机字符串
+     */
+    public static final String STR = getValue("str");
+
+    /**
+     * 渠道号 (用于接收订单通知报文,拉卡拉开通)
+     */
+    public static final String CHANNEL_ID = getValue("channel_id");
+
+    /**
+     * 第三⽅客户端号(拓客SAAS)
+     */
+    public static final String TK_CLIENT_ID = getValue("tk_client_id");
+
+    /**
+     * 第三⽅客户端密码(拓客SAAS)
+     */
+    public static final String TK_CLIENT_SECRET = getValue("tk_client_secret");
+
+}

+ 125 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayKit.java

@@ -0,0 +1,125 @@
+package org.jeecg.modules.pay.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.*;
+import java.security.cert.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Base64;
+
+/**
+ * 拉卡拉支付签名工具类
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LakalaPayKit {
+    private static final String CHARSET_NAME = "UTF-8";
+
+    public static String getAuthorization(String body) throws UnsupportedEncodingException {
+        String nonceStr = generateNonceStr();
+        long timestamp = System.currentTimeMillis() / 1000;
+        String message = LakalaPayConfig.APPID + "\n" + LakalaPayConfig.SERIAL_NO + "\n" + timestamp + "\n" + nonceStr + "\n" + body  + "\n";
+        String signature = sign(message.getBytes(CHARSET_NAME), loadPrivateKey());
+        String authorization = "appid=\"" + LakalaPayConfig.APPID + "\"," + "serial_no=\"" + LakalaPayConfig.SERIAL_NO + "\",timestamp=\"" + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";
+        return authorization;
+    }
+
+    public static boolean verify(byte[] message, String signature) {
+        try {
+            X509Certificate certificate = loadCertificate();
+            Signature sign = Signature.getInstance("SHA256withRSA");
+            sign.initVerify(certificate);
+            sign.update(message);
+            byte[] signatureB = Base64.getDecoder().decode(signature);
+            return sign.verify(signatureB);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
+        } catch (SignatureException e) {
+            throw new RuntimeException("签名验证过程发生了错误", e);
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("无效的证书", e);
+        }
+    }
+
+    /**
+     * 公钥加载
+     * 目前指定加载 拉卡拉公钥证书
+     **/
+    private static X509Certificate loadCertificate() {
+        try (InputStream inputStream = LakalaPayKit.class.getClassLoader().getResourceAsStream(LakalaPayConfig.SECRET_PUBLIC_KEY_NAME)) {
+            CertificateFactory cf = CertificateFactory.getInstance("X509");
+            X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
+            cert.checkValidity();
+            return cert;
+        } catch (CertificateExpiredException e) {
+            throw new RuntimeException("证书已过期", e);
+        } catch (CertificateNotYetValidException e) {
+            throw new RuntimeException("证书尚未生效", e);
+        } catch (CertificateException e) {
+            throw new RuntimeException("无效的证书", e);
+        } catch (IOException e1) {
+            throw new RuntimeException(e1);
+        }
+    }
+
+    /**
+     * 密钥加载
+     * 目前指定加载 商户密钥证书
+     **/
+    private static PrivateKey loadPrivateKey() {
+        try (InputStream inputStream = LakalaPayKit.class.getClassLoader().getResourceAsStream(LakalaPayConfig.SECRET_PRIVATE_KEY_NAME)) {
+            ByteArrayOutputStream array = new ByteArrayOutputStream();
+            byte[] buffer = new byte[1024];
+            int length;
+            while ((length = inputStream.read(buffer)) != -1) {
+                array.write(buffer, 0, length);
+            }
+            String privateKey = array.toString("utf-8").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环境不支持RSA", e);
+        } catch (InvalidKeySpecException e) {
+            throw new RuntimeException("无效的密钥格式");
+        } catch (IOException e) {
+            throw new RuntimeException("无效的密钥");
+        }
+    }
+
+    /**
+     * 使用私钥进行签名
+     **/
+    private static String sign(byte[] message, PrivateKey privateKey) {
+        try {
+            Signature sign = Signature.getInstance("SHA256withRSA");
+            sign.initSign(privateKey);
+            sign.update(message);
+            return new String(Base64.getEncoder().encode(sign.sign()));
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
+        } catch (SignatureException e) {
+            throw new RuntimeException("签名计算失败", e);
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("无效的私钥", e);
+        }
+    }
+
+    /**
+     * 生成随机字符串
+     **/
+    private static String generateNonceStr() {
+        char[] nonceChars = new char[12];
+        for (int index = 0; index < nonceChars.length; ++index) {
+            nonceChars[index] = LakalaPayConfig.STR.charAt(new SecureRandom().nextInt(LakalaPayConfig.STR.length()));
+        }
+        return new String(nonceChars);
+    }
+
+
+}

+ 59 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/LakalaPayUrl.java

@@ -0,0 +1,59 @@
+package org.jeecg.modules.pay.core;
+
+/**
+ * 拉卡拉支付请求连接
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LakalaPayUrl {
+
+    /**
+     * 交易接口V3.0-订单类接口-收银台下单
+     */
+    public static final String V3_LOS_GENERATE_ORDER = "https://s2.lakala.com/api/v3/los/checkout_counter/generate_order";
+
+    /**
+     * 交易接口V3.0-订单类接口-订单交易信息查询
+     */
+    public static final String V3_LOS_QUERY_ORDER = "https://s2.lakala.com/api/v3/los/checkout_counter/query_order";
+
+    /**
+     * 交易接口V3.0-支付类接口-主扫交易接口
+     */
+//    public static final String V3_LABS_TRANS_PREORDER = "https://s2.lakala.com/api/v3/labs/trans/preorder";
+    public static final String V3_LABS_TRANS_PREORDER = "https://test.wsmsd.cn/sit/api/v3/labs/trans/preorder";
+
+    /**
+     * 交易接口V3.0-支付类接口-被扫交易接口
+     */
+    public static final String V3_LABS_TRANS_MICROPAY = "https://s2.lakala.com/api/v3/labs/trans/micropay";
+
+    /**
+     * 交易接口V3.0-支付类接口-退款交易接口
+     */
+//    public static final String V3_LABS_RELATION_REFUND = "https://s2.lakala.com/api/v3/labs/relation/refund";
+    public static final String V3_LABS_RELATION_REFUND = "https://test.wsmsd.cn/sit/api/v3/labs/relation/refund";
+
+    /**
+     * 交易接口V3.0-支付类接口-撤销交易接口
+     */
+    public static final String V3_LABS_RELATION_REVOKED = "https://s2.lakala.com/api/v3/labs/relation/revoked";
+
+    /**
+     * 交易接口V3.0-支付类接口-关闭交易接口
+     */
+    public static final String V3_LABS_RELATION_CLOSE = "https://s2.lakala.com/api/v3/labs/relation/close";
+
+    /**
+     * 交易接口V3.0-支付类接口-查询交易接口
+     */
+//    public static final String V3_LABS_QUERY_TRADEQUERY = "https://s2.lakala.com/api/v3/labs/query/tradequery";
+    public static final String V3_LABS_QUERY_TRADEQUERY = "https://test.wsmsd.cn/sit/api/v3/labs/query/tradequery";
+
+    /**
+     * 请求获取token
+     */
+    public static final String TK_OAUTH_TOKEN = "https://test.wsmsd.cn/sit/htkauth/oauth/token";
+}

+ 142 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/core/TkToken.java

@@ -0,0 +1,142 @@
+package org.jeecg.modules.pay.core;
+
+
+import com.google.gson.Gson;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.message.BasicNameValuePair;
+import org.jeecg.modules.pay.util.HttpUtil;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/**
+ * 拉卡拉拓客token对象
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class TkToken {
+
+    private static volatile TkToken token;
+
+    private TkToken() {
+    }
+
+    public static TkToken getInstance() throws IOException {
+        if (token == null) {
+            synchronized (TkToken.class) {
+                if (token == null) {
+                    token = getToken();
+                } else {
+                    if (!token.verify()) {
+                        token = getToken();
+                    }
+                }
+            }
+        } else {
+            if (!token.verify()) {
+                token = getToken();
+            }
+        }
+        return token;
+    }
+
+    private static TkToken getToken() throws IOException {
+        List<NameValuePair> list = new ArrayList<>();
+        list.add(new BasicNameValuePair("grant_type", "client_credentials"));
+        list.add(new BasicNameValuePair("client_id", LakalaPayConfig.TK_CLIENT_ID));
+        list.add(new BasicNameValuePair("client_secret", LakalaPayConfig.TK_CLIENT_SECRET));
+        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put("Authorization", getAuthorization());
+
+        HttpResponse response = HttpUtil.post(LakalaPayUrl.TK_OAUTH_TOKEN, entity, headerMap);
+        String res = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
+        token = new Gson().fromJson(res, TkToken.class);
+        token.setCreateTokenTime(System.currentTimeMillis());
+        return token;
+    }
+
+
+    private static String getAuthorization() throws UnsupportedEncodingException {
+        String src = String.format("%s:%s", LakalaPayConfig.TK_CLIENT_ID, LakalaPayConfig.TK_CLIENT_SECRET);
+        return "Basic " + Base64.getEncoder().encodeToString(src.getBytes("UTF-8"));
+    }
+
+
+    /**
+     * 访问token
+     */
+    private String access_token;
+
+    /**
+     * token类型
+     */
+    private String token_type;
+
+    /**
+     * 过期时间,
+     * 以当前时间为基准的秒数
+     */
+    private Long expires_in;
+
+    /**
+     * 有效范围
+     */
+    private String scope;
+
+    /**
+     * 获取token的时间
+     */
+    private Long createTokenTime;
+
+    public boolean verify() {
+        return System.currentTimeMillis() < createTokenTime + expires_in * 1000;
+    }
+
+
+    public String getAccess_token() {
+        return access_token;
+    }
+
+    public void setAccess_token(String access_token) {
+        this.access_token = access_token;
+    }
+
+    public String getToken_type() {
+        return token_type;
+    }
+
+    public void setToken_type(String token_type) {
+        this.token_type = token_type;
+    }
+
+    public Long getExpires_in() {
+        return expires_in;
+    }
+
+    public void setExpires_in(Long expires_in) {
+        this.expires_in = expires_in;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    public Long getCreateTokenTime() {
+        return createTokenTime;
+    }
+
+    public void setCreateTokenTime(Long createTokenTime) {
+        this.createTokenTime = createTokenTime;
+    }
+}

+ 11 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/LakalaRequest.java

@@ -0,0 +1,11 @@
+package org.jeecg.modules.pay.request;
+
+/**
+ * 拉卡拉请求参数基类
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LakalaRequest {
+}

+ 11 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/ReqData.java

@@ -0,0 +1,11 @@
+package org.jeecg.modules.pay.request;
+
+/**
+ * 拉卡拉请求业务参数基类(参见各个接口的请求参数格式)
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class ReqData {
+}

+ 60 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/ReqLocationInfo.java

@@ -0,0 +1,60 @@
+package org.jeecg.modules.pay.request;
+
+/**
+ * 地址位置信息,风控要求必送
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class ReqLocationInfo {
+
+    private ReqLocationInfo() {
+    }
+
+    public ReqLocationInfo(String request_ip) {
+        this.request_ip = request_ip;
+    }
+
+    /**
+     * 请求方IP地址
+     * 请求方的IP地址,存在必填,格式如36.45.36.95
+     */
+    private String request_ip;
+
+    /**
+     * 基站信息
+     * 客户端设备的基站信息(主扫时基站信息使用该字段)
+     */
+    private String base_station;
+
+    /**
+     * 纬度,经度
+     * 商户终端的地理位置,存在必填 格式:纬度,经度,+表示北纬、东经,-表示南纬、 西经,精度最长支持小数点后9位。举例:+37.123456789,-121.123456789
+     */
+    private String location;
+
+    public String getRequest_ip() {
+        return request_ip;
+    }
+
+    public void setRequest_ip(String request_ip) {
+        this.request_ip = request_ip;
+    }
+
+    public String getBase_station() {
+        return base_station;
+    }
+
+    public void setBase_station(String base_station) {
+        this.base_station = base_station;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public void setLocation(String location) {
+        this.location = location;
+    }
+}

+ 60 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/oauth/TokenRequest.java

@@ -0,0 +1,60 @@
+package org.jeecg.modules.pay.request.oauth;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.LakalaRequest;
+
+/**
+ * 拉卡拉拓客SAAS商户管理获取token请求
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class TokenRequest extends LakalaRequest {
+
+    public TokenRequest(){
+        this.grant_type = "client_credentials";
+        this.client_id = LakalaPayConfig.TK_CLIENT_ID;
+        this.client_secret = LakalaPayConfig.TK_CLIENT_SECRET;
+    }
+
+    /**
+     * 授权类型
+     */
+    private String grant_type;
+
+    /**
+     * 第三⽅client_id
+     */
+    private String client_id;
+
+    /**
+     * 第三⽅client_secret
+     */
+    private String client_secret;
+
+    public String getGrant_type() {
+        return grant_type;
+    }
+
+    public void setGrant_type(String grant_type) {
+        this.grant_type = grant_type;
+    }
+
+    public String getClient_id() {
+        return client_id;
+    }
+
+    public void setClient_id(String client_id) {
+        this.client_id = client_id;
+    }
+
+    public String getClient_secret() {
+        return client_secret;
+    }
+
+    public void setClient_secret(String client_secret) {
+        this.client_secret = client_secret;
+    }
+}

+ 74 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/LabsRequest.java

@@ -0,0 +1,74 @@
+package org.jeecg.modules.pay.request.v3;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.LakalaRequest;
+import org.jeecg.modules.pay.request.ReqData;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 拉卡拉V3.0下支付类接口请求参数
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LabsRequest extends LakalaRequest {
+
+    private LabsRequest() {
+    }
+
+    public LabsRequest(ReqData req_data) {
+        this.req_time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+        this.version = "3.0";
+        this.out_org_code = LakalaPayConfig.APPID;
+        this.req_data = req_data;
+    }
+
+    /**
+     * 请求时间
+     * 请求时间,格式yyyyMMddHHmmss
+     */
+    private String req_time;
+
+    /**
+     * 版本号
+     */
+    private String version;
+
+    /**
+     * 外部接入机构号(开放平台APPID)
+     */
+    private String out_org_code;
+
+    /**
+     * 请求参数
+     */
+    private ReqData req_data;
+
+    public String getReq_time() {
+        return req_time;
+    }
+
+    public void setReq_time(String req_time) {
+        this.req_time = req_time;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public ReqData getReq_data() {
+        return req_data;
+    }
+
+    public void setReq_data(ReqData req_data) {
+        this.req_data = req_data;
+    }
+}

+ 41 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/LosRequest.java

@@ -0,0 +1,41 @@
+package org.jeecg.modules.pay.request.v3;
+
+
+import org.jeecg.modules.pay.request.ReqData;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 拉卡拉V3.0下订单类接口请求参数
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class LosRequest {
+
+    private LosRequest(){}
+
+    public LosRequest(ReqData req_data){
+        this.req_time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+        this.version = "3.0";
+        this.req_data = req_data;
+    }
+
+    /**
+     * 请求时间
+     * 请求时间,格式yyyyMMddHHmmss
+     */
+    private String req_time;
+
+    /**
+     * 版本号
+     */
+    private String version;
+
+    /**
+     * 请求参数
+     */
+    private ReqData req_data;
+}

+ 96 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/CloseRequest.java

@@ -0,0 +1,96 @@
+package org.jeecg.modules.pay.request.v3.labs;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+import org.jeecg.modules.pay.request.ReqLocationInfo;
+
+/**
+ * 关单交易接口请求报文
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class CloseRequest extends ReqData {
+
+    private CloseRequest() {
+    }
+
+    /**
+     * 初始化关闭交易接口请求报文
+     *
+     * @param location_info
+     */
+    public CloseRequest(ReqLocationInfo location_info) {
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.term_no = LakalaPayConfig.TERM_NO;
+        this.location_info = location_info;
+    }
+
+    /**
+     * 商户号
+     */
+    private String merchant_no;
+    /**
+     * 终端号
+     */
+    private String term_no;
+    /**
+     * 原商户交易流水号
+     * 下单时商户请求流水号 origin_out_trade_no、origin_trade_no、origin_out_order_source+origin_out_order_no必有其一,
+     * 前两者为交易关单,后者为商户订单关单
+     */
+    private String origin_out_trade_no;
+    /**
+     * 原交易拉卡拉交易流水号
+     * 下单成功时,返回的SAAS生成的交易流水
+     */
+    private String origin_trade_no;
+    /**
+     * 地址位置信息
+     * 地址位置信息,风控要求必送
+     */
+    private ReqLocationInfo location_info;
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getOrigin_out_trade_no() {
+        return origin_out_trade_no;
+    }
+
+    public void setOrigin_out_trade_no(String origin_out_trade_no) {
+        this.origin_out_trade_no = origin_out_trade_no;
+    }
+
+    public String getOrigin_trade_no() {
+        return origin_trade_no;
+    }
+
+    public void setOrigin_trade_no(String origin_trade_no) {
+        this.origin_trade_no = origin_trade_no;
+    }
+
+    public ReqLocationInfo getLocation_info() {
+        return location_info;
+    }
+
+    public void setLocation_info(ReqLocationInfo location_info) {
+        this.location_info = location_info;
+    }
+}

+ 259 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/MicropayRequest.java

@@ -0,0 +1,259 @@
+package org.jeecg.modules.pay.request.v3.labs;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+import org.jeecg.modules.pay.request.ReqLocationInfo;
+import org.jeecg.modules.pay.request.v3.labs.accbusifields.ReqAccBusiFields;
+
+/**
+ * 被扫交易接口请求报文
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class MicropayRequest extends ReqData {
+
+    private MicropayRequest() {
+    }
+
+    /**
+     * 初始化被扫交易接口请求报文
+     *
+     * @param out_trade_no  商户交易流水号
+     * @param auth_code     支付授权码
+     * @param total_amount  金额
+     * @param location_info 地址位置信息
+     */
+    public MicropayRequest(String out_trade_no, String auth_code, String total_amount, ReqLocationInfo location_info) {
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.term_no = LakalaPayConfig.TERM_NO;
+        this.out_trade_no = out_trade_no;
+        this.auth_code = auth_code;
+        this.total_amount = total_amount;
+        this.location_info = location_info;
+    }
+
+    /**
+     * 商户号
+     * 拉卡拉分配的商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 终端号
+     * 拉卡拉分配的业务终端号
+     */
+    private String term_no;
+
+    /**
+     * 商户交易流水号
+     * 商户系统唯一,不可重复
+     */
+    private String out_trade_no;
+
+    /**
+     * 支付授权码
+     * 扫码支付授权码,设备读取用户APP中的条码或者二维码信息,用户付款码条形码规则见说明
+     */
+    private String auth_code;
+
+    /**
+     * 金额
+     * 单位分,整数型字符
+     */
+    private String total_amount;
+
+    /**
+     * 地址位置信息
+     * 地址位置信息,风控要求必送
+     */
+    private ReqLocationInfo location_info;
+
+    /**
+     * 业务模式
+     * 业务模式: ACQ-收单 不填,默认为“ACQ-收单”
+     */
+    private String busi_mode;
+
+    /**
+     * 订单标题
+     * 标题,用于简单描述订单或商品(账户端控制,实际最多42个字符),微信支付必送。
+     */
+    private String subject;
+
+    /**
+     * 拉卡拉支付业务订单号
+     * 拉卡拉订单系统订单号,以拉卡拉支付业务订单号为驱动的支付行为,需上传该字段。
+     * 订单交易下单,交易时上送订单系统订单号,交易流程中会校验有效性、判重
+     */
+    private String pay_order_no;
+
+    /**
+     * 商户通知地址
+     */
+    private String notify_url;
+
+    /**
+     * 结算类型
+     * “0”或者空,常规结算方式;
+     */
+    private String settle_type;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 扫码类型
+     * 0或不填:扫码支付 1:刷脸支付
+     */
+    private String scan_type;
+
+    /**
+     * 身份信息
+     */
+    private String identity_info;
+
+    /**
+     * 营销信息
+     * 拉卡拉优惠相关信息,JSON格式。暂不支持
+     */
+    private String promo_info;
+
+    /**
+     * 账户端业务信息域
+     */
+    private ReqAccBusiFields acc_busi_fields;
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getAuth_code() {
+        return auth_code;
+    }
+
+    public void setAuth_code(String auth_code) {
+        this.auth_code = auth_code;
+    }
+
+    public String getTotal_amount() {
+        return total_amount;
+    }
+
+    public void setTotal_amount(String total_amount) {
+        this.total_amount = total_amount;
+    }
+
+    public ReqLocationInfo getLocation_info() {
+        return location_info;
+    }
+
+    public void setLocation_info(ReqLocationInfo location_info) {
+        this.location_info = location_info;
+    }
+
+    public String getBusi_mode() {
+        return busi_mode;
+    }
+
+    public void setBusi_mode(String busi_mode) {
+        this.busi_mode = busi_mode;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getPay_order_no() {
+        return pay_order_no;
+    }
+
+    public void setPay_order_no(String pay_order_no) {
+        this.pay_order_no = pay_order_no;
+    }
+
+    public String getNotify_url() {
+        return notify_url;
+    }
+
+    public void setNotify_url(String notify_url) {
+        this.notify_url = notify_url;
+    }
+
+    public String getSettle_type() {
+        return settle_type;
+    }
+
+    public void setSettle_type(String settle_type) {
+        this.settle_type = settle_type;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getScan_type() {
+        return scan_type;
+    }
+
+    public void setScan_type(String scan_type) {
+        this.scan_type = scan_type;
+    }
+
+    public String getIdentity_info() {
+        return identity_info;
+    }
+
+    public void setIdentity_info(String identity_info) {
+        this.identity_info = identity_info;
+    }
+
+    public String getPromo_info() {
+        return promo_info;
+    }
+
+    public void setPromo_info(String promo_info) {
+        this.promo_info = promo_info;
+    }
+
+    public ReqAccBusiFields getAcc_busi_fields() {
+        return acc_busi_fields;
+    }
+
+    public void setAcc_busi_fields(ReqAccBusiFields acc_busi_fields) {
+        this.acc_busi_fields = acc_busi_fields;
+    }
+}

+ 262 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/PreorderRequest.java

@@ -0,0 +1,262 @@
+package org.jeecg.modules.pay.request.v3.labs;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+import org.jeecg.modules.pay.request.ReqLocationInfo;
+import org.jeecg.modules.pay.request.v3.labs.accbusifields.ReqAccBusiFields;
+
+/**
+ * 主扫交易接口请求报文
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class PreorderRequest extends ReqData {
+
+    private PreorderRequest() {
+    }
+
+    /**
+     * 初始化主扫交易接口请求报文
+     *
+     * @param out_trade_no  商户交易流水号
+     * @param account_type  钱包类型
+     * @param trans_type    接入方式
+     * @param total_amount  金额
+     * @param location_info 地址位置信息
+     */
+    public PreorderRequest(String out_trade_no, String account_type, String trans_type, String total_amount, ReqLocationInfo location_info) {
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.term_no = LakalaPayConfig.TERM_NO;
+        this.out_trade_no = out_trade_no;
+        this.account_type = account_type;
+        this.trans_type = trans_type;
+        this.total_amount = total_amount;
+        this.location_info = location_info;
+    }
+
+    /**
+     * 商户号
+     * 拉卡拉分配的商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 终端号
+     * 拉卡拉分配的业务终端号
+     */
+    private String term_no;
+
+    /**
+     * 商户交易流水号
+     * 商户系统唯一,对应数据库表中外部请求流水号。
+     */
+    private String out_trade_no;
+
+    /**
+     * 钱包类型
+     * 微信:WECHAT 支付宝:ALIPAY 银联:UQRCODEPAY 翼支付: BESTPAY
+     * 苏宁易付宝: SUNING 拉卡拉支付账户:LKLACC 网联小钱包:NUCSPAY
+     */
+    private String account_type;
+
+    /**
+     * 接入方式
+     * 41:NATIVE((ALIPAY,云闪付支持)
+     * 51:JSAPI(微信公众号支付,支付宝服务窗支付,银联JS支付,翼支付JS支付、拉卡拉钱包支付)
+     * 71:微信小程序支付
+     */
+    private String trans_type;
+
+    /**
+     * 金额
+     * 单位分,整数型字符
+     */
+    private String total_amount;
+
+    /**
+     * 地址位置信息,风控要求必送
+     */
+    private ReqLocationInfo location_info;
+
+    /**
+     * 业务模式: ACQ-收单 不填,默认为“ACQ-收单”
+     */
+    private String busi_mode;
+
+    /**
+     * 订单标题
+     * 标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),
+     * 微信支付必送。
+     */
+    private String subject;
+
+    /**
+     * 支付业务订单号
+     * 拉卡拉订单系统订单号,以拉卡拉支付业务订单号为驱动的支付行为,需上传该字段。
+     */
+    private String pay_order_no;
+
+    /**
+     * 商户通知地址
+     */
+    private String notify_url;
+
+    /**
+     * 结算类型
+     * “0”或者空,常规结算方式,如需接拉卡拉分账需传“1”;
+     */
+    private String settle_type;
+
+    /**
+     * 备注(非必填)
+     */
+    private String remark;
+
+    /**
+     * 身份信息(非必填)
+     * 实名支付信息,json字符串,如{“identityNo”:”32000000000000000X”,”name”:”张三”} ,
+     * 然后国密sm2加密
+     */
+    private String identity_info;
+    /**
+     * 优惠信息(非必填)
+     */
+    private String promo_info;
+
+    /**
+     * 账户端业务信息域
+     */
+    private ReqAccBusiFields acc_busi_fields;
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getAccount_type() {
+        return account_type;
+    }
+
+    public void setAccount_type(String account_type) {
+        this.account_type = account_type;
+    }
+
+    public String getTrans_type() {
+        return trans_type;
+    }
+
+    public void setTrans_type(String trans_type) {
+        this.trans_type = trans_type;
+    }
+
+    public String getTotal_amount() {
+        return total_amount;
+    }
+
+    public void setTotal_amount(String total_amount) {
+        this.total_amount = total_amount;
+    }
+
+    public ReqLocationInfo getLocation_info() {
+        return location_info;
+    }
+
+    public void setLocation_info(ReqLocationInfo location_info) {
+        this.location_info = location_info;
+    }
+
+    public String getBusi_mode() {
+        return busi_mode;
+    }
+
+    public void setBusi_mode(String busi_mode) {
+        this.busi_mode = busi_mode;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getPay_order_no() {
+        return pay_order_no;
+    }
+
+    public void setPay_order_no(String pay_order_no) {
+        this.pay_order_no = pay_order_no;
+    }
+
+    public String getNotify_url() {
+        return notify_url;
+    }
+
+    public void setNotify_url(String notify_url) {
+        this.notify_url = notify_url;
+    }
+
+    public String getSettle_type() {
+        return settle_type;
+    }
+
+    public void setSettle_type(String settle_type) {
+        this.settle_type = settle_type;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getIdentity_info() {
+        return identity_info;
+    }
+
+    public void setIdentity_info(String identity_info) {
+        this.identity_info = identity_info;
+    }
+
+    public String getPromo_info() {
+        return promo_info;
+    }
+
+    public void setPromo_info(String promo_info) {
+        this.promo_info = promo_info;
+    }
+
+    public ReqAccBusiFields getAcc_busi_fields() {
+        return acc_busi_fields;
+    }
+
+    public void setAcc_busi_fields(ReqAccBusiFields acc_busi_fields) {
+        this.acc_busi_fields = acc_busi_fields;
+    }
+}

+ 163 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/RefundRequest.java

@@ -0,0 +1,163 @@
+package org.jeecg.modules.pay.request.v3.labs;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+import org.jeecg.modules.pay.request.ReqLocationInfo;
+
+/**
+ * 退款交易接口请求报文
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class RefundRequest extends ReqData {
+
+    private RefundRequest() {
+    }
+
+    /**
+     * 初始化退款交易接口请求报文
+     *
+     * @param out_trade_no  商户交易流水号
+     * @param refund_amount 退款金额
+     * @param location_info 地址位置信息
+     */
+    public RefundRequest(String out_trade_no, String refund_amount, ReqLocationInfo location_info) {
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.term_no = LakalaPayConfig.TERM_NO;
+        this.out_trade_no = out_trade_no;
+        this.refund_amount = refund_amount;
+        this.location_info = location_info;
+    }
+
+    /**
+     * 商户号
+     * 拉卡拉分配的商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 终端号
+     * 拉卡拉分配的商户号
+     */
+    private String term_no;
+
+    /**
+     * 商户交易流水号
+     * 商户系统唯一
+     */
+    private String out_trade_no;
+
+    /**
+     * 退款金额
+     * 单位分,整数数字型字符
+     */
+    private String refund_amount;
+
+    /**
+     * 退款原因
+     */
+    private String refund_reason;
+
+    /**
+     * 原商户交易流水号
+     * 下单时的商户请求流水号
+     * (退款时origin_out_trade_no,origin_trade_no,origin_log_no必送其一)
+     */
+    private String origin_out_trade_no;
+
+    /**
+     * 原拉卡拉交易流水号
+     * 下单成功时,返回的拉卡拉交易流水。 origin_out_trade_no、origin_log_no、origin_trade_no至少一个必填
+     * (调用收银台下单接口拉起交易后发起退款时至少要传两个),同时存在时优先级顺序如下: origin_trade_no、origin_log_no、origin_out_trade_no。
+     */
+    private String origin_trade_no;
+
+    /**
+     * 原对账单流水号
+     * 对账单中的交易流水。 origin_out_trade_no、origin_log_no、origin_trade_no至少一个必填
+     * (调用收银台下单接口拉起交易后发起退款时至少要传两个,同时存在时优先级顺序如下: origin_trade_no、origin_log_no、origin_out_trade_no。
+     */
+    private String origin_log_no;
+
+    /**
+     * 地址位置信息
+     * 地址位置信息,风控要求必送
+     */
+    private ReqLocationInfo location_info;
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getRefund_amount() {
+        return refund_amount;
+    }
+
+    public void setRefund_amount(String refund_amount) {
+        this.refund_amount = refund_amount;
+    }
+
+    public String getRefund_reason() {
+        return refund_reason;
+    }
+
+    public void setRefund_reason(String refund_reason) {
+        this.refund_reason = refund_reason;
+    }
+
+    public String getOrigin_out_trade_no() {
+        return origin_out_trade_no;
+    }
+
+    public void setOrigin_out_trade_no(String origin_out_trade_no) {
+        this.origin_out_trade_no = origin_out_trade_no;
+    }
+
+    public String getOrigin_trade_no() {
+        return origin_trade_no;
+    }
+
+    public void setOrigin_trade_no(String origin_trade_no) {
+        this.origin_trade_no = origin_trade_no;
+    }
+
+    public String getOrigin_log_no() {
+        return origin_log_no;
+    }
+
+    public void setOrigin_log_no(String origin_log_no) {
+        this.origin_log_no = origin_log_no;
+    }
+
+    public ReqLocationInfo getLocation_info() {
+        return location_info;
+    }
+
+    public void setLocation_info(ReqLocationInfo location_info) {
+        this.location_info = location_info;
+    }
+}

+ 117 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/RevokedRequest.java

@@ -0,0 +1,117 @@
+package org.jeecg.modules.pay.request.v3.labs;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+import org.jeecg.modules.pay.request.ReqLocationInfo;
+
+/**
+ * 撤销交易接口请求报文
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class RevokedRequest extends ReqData {
+
+    private RevokedRequest() {
+    }
+
+    /**
+     * 初始化撤销交易接口请求报文
+     *
+     * @param out_trade_no  商户交易流水号
+     * @param location_info 地址位置信息
+     */
+    public RevokedRequest(String out_trade_no, ReqLocationInfo location_info) {
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.term_no = LakalaPayConfig.TERM_NO;
+        this.out_trade_no = out_trade_no;
+        this.location_info = location_info;
+    }
+
+    /**
+     * 商户号
+     * 拉卡拉分配的商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 终端号
+     * 拉卡拉分配的商户号
+     */
+    private String term_no;
+
+    /**
+     * 商户交易流水号
+     * 商户系统唯一
+     */
+    private String out_trade_no;
+
+    /**
+     * 原商户交易流水号
+     * 下单时的商户请求流水号(撤销时origin_out_trade_no,origin_trade_no必送其一)
+     */
+    private String origin_out_trade_no;
+
+    /**
+     * 原拉卡拉交易流水号
+     * 下单成功时,返回的拉卡拉交易流水。
+     */
+    private String origin_trade_no;
+
+    /**
+     * 地址位置信息
+     * 地址位置信息,风控要求必送
+     */
+    private ReqLocationInfo location_info;
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getOrigin_out_trade_no() {
+        return origin_out_trade_no;
+    }
+
+    public void setOrigin_out_trade_no(String origin_out_trade_no) {
+        this.origin_out_trade_no = origin_out_trade_no;
+    }
+
+    public String getOrigin_trade_no() {
+        return origin_trade_no;
+    }
+
+    public void setOrigin_trade_no(String origin_trade_no) {
+        this.origin_trade_no = origin_trade_no;
+    }
+
+    public ReqLocationInfo getLocation_info() {
+        return location_info;
+    }
+
+    public void setLocation_info(ReqLocationInfo location_info) {
+        this.location_info = location_info;
+    }
+}

+ 77 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/TradeQueryRequest.java

@@ -0,0 +1,77 @@
+package org.jeecg.modules.pay.request.v3.labs;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+
+/**
+ * 查询交易接口请求报文
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class TradeQueryRequest extends ReqData {
+
+    public TradeQueryRequest() {
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.term_no = LakalaPayConfig.TERM_NO;
+    }
+
+    /**
+     * 商户号
+     * 拉卡拉分配的商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 终端号
+     * 拉卡拉分配的业务终端号
+     */
+    private String term_no;
+
+    /**
+     * 商户交易流水号
+     * 下单时的商户请求流水号 说明:out_trade_no、trade_no、必有其一。
+     * 如果存在多个字段上送,优先级顺序如下: trade_no、 out_trade_no
+     */
+    private String out_trade_no;
+
+    /**
+     * 拉卡拉交易流水号
+     */
+    private String trade_no;
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getOut_trade_no() {
+        return out_trade_no;
+    }
+
+    public void setOut_trade_no(String out_trade_no) {
+        this.out_trade_no = out_trade_no;
+    }
+
+    public String getTrade_no() {
+        return trade_no;
+    }
+
+    public void setTrade_no(String trade_no) {
+        this.trade_no = trade_no;
+    }
+}

+ 102 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/AliPayAccBusiFieldsRequest.java

@@ -0,0 +1,102 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+import com.google.gson.Gson;
+
+/**
+ * 支付宝支付
+ * 账户端业务信息域
+ * 交易接口请求
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class AliPayAccBusiFieldsRequest extends ReqAccBusiFields {
+
+    /**
+     * 买家在支付宝的用户id
+     * 支付宝的buyer_user_id ,trans_type为41-NATIVE情况下不需要传
+     * 为51情况下必须传入
+     */
+    private String user_id;
+
+    /**
+     * 预下单有效时间
+     * 预下单的订单的有效时间,以分钟为单位。
+     * 如果在有效时间内没有完成付款,则在账户端该订单失效。
+     * 如果不上送,以账户端订单失效时间为准。
+     * 建议不超过15分钟。不传值则默认5分钟。
+     */
+    private String timeout_express;
+
+    /**
+     * 业务扩展参数
+     */
+    private AliPayExtendParamsRequest extend_params;
+
+    /**
+     * 商品详情
+     * 订单包含的商品列表信息,Json格式。
+     */
+    private AliPayGoodsDetailRequest goods_detail;
+
+    /**
+     * 用户付款中途退出返回商户网站的地址
+     * transType=81时(即支付宝H5支付),此参数必传
+     */
+    private String quit_url;
+
+    /**
+     * 支付宝的店铺编号
+     */
+    private String alipay_store_id;
+
+    public String getUser_id() {
+        return user_id;
+    }
+
+    public void setUser_id(String user_id) {
+        this.user_id = user_id;
+    }
+
+    public String getTimeout_express() {
+        return timeout_express;
+    }
+
+    public void setTimeout_express(String timeout_express) {
+        this.timeout_express = timeout_express;
+    }
+
+    public AliPayExtendParamsRequest getExtend_params() {
+        return extend_params;
+    }
+
+    public void setExtend_params(AliPayExtendParamsRequest extend_params) {
+        this.extend_params = extend_params;
+    }
+
+    public String getGoods_detail() {
+        return new Gson().toJson(goods_detail);
+    }
+
+    public void setGoods_detail(AliPayGoodsDetailRequest goods_detail) {
+        this.goods_detail = goods_detail;
+    }
+
+    public String getQuit_url() {
+        return quit_url;
+    }
+
+    public void setQuit_url(String quit_url) {
+        this.quit_url = quit_url;
+    }
+
+    public String getAlipay_store_id() {
+        return alipay_store_id;
+    }
+
+    public void setAlipay_store_id(String alipay_store_id) {
+        this.alipay_store_id = alipay_store_id;
+    }
+}

+ 89 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/AliPayExtendParamsRequest.java

@@ -0,0 +1,89 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+/**
+ * 业务扩展参数
+ * 支付宝支付
+ * 账户端业务信息域
+ * 交易接口请求
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class AliPayExtendParamsRequest {
+
+    private AliPayExtendParamsRequest() {
+    }
+
+    /**
+     * 初始化业务扩展参数
+     *
+     * @param hb_fq_num            花呗分期期数
+     * @param hb_fq_seller_percent 卖家承担手续费比例
+     */
+    public AliPayExtendParamsRequest(String hb_fq_num, String hb_fq_seller_percent) {
+        this.hb_fq_num = hb_fq_num;
+        this.hb_fq_seller_percent = hb_fq_seller_percent;
+    }
+
+    /**
+     * 服务商的PID
+     * 系统商编号,该参数作为系统商返佣数据提取的依据,请填写系统商签约协议的 PID
+     */
+    private String sys_service_provider_id;
+
+    /**
+     * 花呗分期期数
+     * 支付宝花呗分期必送字段: 花呗分期数 3:3期 6:6期 12:12期
+     */
+    private String hb_fq_num;
+
+    /**
+     * 卖家承担手续费比例
+     * 支付宝花呗分期必送字段: 卖家承担收费比例,
+     * 商家承担手续费传入100,用户承担手续费传入0,
+     * 仅支持传入100、0两种,其他比例暂不支持
+     * 100:代表商家贴息 0:代表用户承担手续费
+     */
+    private String hb_fq_seller_percent;
+
+    /**
+     * 点餐场景类型
+     * 点餐场景类型:qr_order(店内扫码点餐),pre_order(预点到店自提),
+     * home_delivery (外送到家),direct_payment(直接付款),other(其它)
+     */
+    private String food_order_type;
+
+    public String getSys_service_provider_id() {
+        return sys_service_provider_id;
+    }
+
+    public void setSys_service_provider_id(String sys_service_provider_id) {
+        this.sys_service_provider_id = sys_service_provider_id;
+    }
+
+    public String getHb_fq_num() {
+        return hb_fq_num;
+    }
+
+    public void setHb_fq_num(String hb_fq_num) {
+        this.hb_fq_num = hb_fq_num;
+    }
+
+    public String getHb_fq_seller_percent() {
+        return hb_fq_seller_percent;
+    }
+
+    public void setHb_fq_seller_percent(String hb_fq_seller_percent) {
+        this.hb_fq_seller_percent = hb_fq_seller_percent;
+    }
+
+    public String getFood_order_type() {
+        return food_order_type;
+    }
+
+    public void setFood_order_type(String food_order_type) {
+        this.food_order_type = food_order_type;
+    }
+}

+ 150 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/AliPayGoodsDetailRequest.java

@@ -0,0 +1,150 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+/**
+ * 商品详情
+ * 支付宝支付
+ * 账户端业务信息域
+ * 交易接口请求
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class AliPayGoodsDetailRequest {
+
+    private AliPayGoodsDetailRequest() {
+    }
+
+    /**
+     * 初始化商品详情
+     *
+     * @param goods_id   商品的编号(String(32))
+     * @param goods_name 商品名称(String(256))
+     * @param quantity   商品数量
+     * @param price      商品价格 单位元
+     */
+    public AliPayGoodsDetailRequest(String goods_id, String goods_name, Integer quantity, Double price) {
+        this.goods_id = goods_id;
+        this.goods_name = goods_name;
+        this.quantity = quantity;
+        this.price = price;
+    }
+
+    /**
+     * 商品的编号
+     */
+    private String goods_id;
+
+    /**
+     * 支付宝定义的统一商品编号
+     */
+    private String alipay_goods_id;
+
+    /**
+     * 商品名称
+     */
+    private String goods_name;
+
+    /**
+     * 商品数量
+     */
+    private Integer quantity;
+
+    /**
+     * 商品价格 单位元
+     */
+    private Double price;
+
+    /**
+     * 商品类目
+     */
+    private String goods_category;
+
+    /**
+     * 商品类目树,从商品类目根节点到叶子节点的类目 id 组成,类目 id 值使用|分割
+     */
+    private String categories_tree;
+
+    /**
+     * 商品描述信息
+     */
+    private String body;
+
+    /**
+     * 商品的展示地址
+     */
+    private String show_url;
+
+    public String getGoods_id() {
+        return goods_id;
+    }
+
+    public void setGoods_id(String goods_id) {
+        this.goods_id = goods_id;
+    }
+
+    public String getAlipay_goods_id() {
+        return alipay_goods_id;
+    }
+
+    public void setAlipay_goods_id(String alipay_goods_id) {
+        this.alipay_goods_id = alipay_goods_id;
+    }
+
+    public String getGoods_name() {
+        return goods_name;
+    }
+
+    public void setGoods_name(String goods_name) {
+        this.goods_name = goods_name;
+    }
+
+    public Integer getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(Integer quantity) {
+        this.quantity = quantity;
+    }
+
+    public Double getPrice() {
+        return price;
+    }
+
+    public void setPrice(Double price) {
+        this.price = price;
+    }
+
+    public String getGoods_category() {
+        return goods_category;
+    }
+
+    public void setGoods_category(String goods_category) {
+        this.goods_category = goods_category;
+    }
+
+    public String getCategories_tree() {
+        return categories_tree;
+    }
+
+    public void setCategories_tree(String categories_tree) {
+        this.categories_tree = categories_tree;
+    }
+
+    public String getBody() {
+        return body;
+    }
+
+    public void setBody(String body) {
+        this.body = body;
+    }
+
+    public String getShow_url() {
+        return show_url;
+    }
+
+    public void setShow_url(String show_url) {
+        this.show_url = show_url;
+    }
+}

+ 11 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/ReqAccBusiFields.java

@@ -0,0 +1,11 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+/**
+ * 账户端业务信息域
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class ReqAccBusiFields {
+}

+ 131 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/WxPayAccBusiFieldsRequest.java

@@ -0,0 +1,131 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+/**
+ * 微信支付
+ * 账户端业务信息域
+ * 交易接口请求
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class WxPayAccBusiFieldsRequest extends ReqAccBusiFields {
+
+    /**
+     * 预下单有效时间
+     * 预下单的订单的有效时间,以分钟为单位。建议不超过15分钟。不传值则默认5分钟。
+     * (微信主扫下单上送的失效时间,是控制prepay_id调起支付的有效时间。微信后台不会根据失效时间发起关单。 如需关单,调用关单接口。)
+     */
+    private String timeout_express;
+
+    /**
+     * 子商户公众账号ID
+     * 微信分配的子商户公众账号ID,sub_appid
+     * (即微信小程序支付-71、公众号支付-51),此参数必传,只对微信支付有效
+     * 工行数字钱包情况下,该字段上送工行的openId 拉卡拉钱包情况下,该字段上送LAKALA的userId
+     */
+    private String sub_appid;
+
+    /**
+     * 用户标识
+     * 用户在子商户sub_appid下的唯一标识,sub_openid,
+     * (即微信小程序支付-71、众号支付-51),此参数必传,只对微信支付有效
+     */
+    private String user_id;
+
+    /**
+     * 商品详情
+     */
+    private WxPayDetailRequest detail;
+
+    /**
+     * 订单优惠标记
+     * 订单优惠标记,微信平台配置的商品标记,用于优惠券或者满减使用,
+     * accountType为WECHAT时,可选填此字段
+     */
+    private String goods_tag;
+
+    /**
+     * 附加域
+     * 该字段主要用于商户携带订单的自定义数据。商户定制字段,直接送到账户端。
+     */
+    private String attach;
+
+    /**
+     * 设备号
+     * 终端设备号(门店号或收银设备ID),
+     * 注意:PC网页或JSAPI支付请传”WEB”
+     */
+    private String device_info;
+
+    /**
+     * 指定支付方式
+     * no_credit–指定不能使用信用卡支付
+     */
+    private String limit_pay;
+
+    public String getTimeout_express() {
+        return timeout_express;
+    }
+
+    public void setTimeout_express(String timeout_express) {
+        this.timeout_express = timeout_express;
+    }
+
+    public String getSub_appid() {
+        return sub_appid;
+    }
+
+    public void setSub_appid(String sub_appid) {
+        this.sub_appid = sub_appid;
+    }
+
+    public String getUser_id() {
+        return user_id;
+    }
+
+    public void setUser_id(String user_id) {
+        this.user_id = user_id;
+    }
+
+    public WxPayDetailRequest getDetail() {
+        return detail;
+    }
+
+    public void setDetail(WxPayDetailRequest detail) {
+        this.detail = detail;
+    }
+
+    public String getGoods_tag() {
+        return goods_tag;
+    }
+
+    public void setGoods_tag(String goods_tag) {
+        this.goods_tag = goods_tag;
+    }
+
+    public String getAttach() {
+        return attach;
+    }
+
+    public void setAttach(String attach) {
+        this.attach = attach;
+    }
+
+    public String getDevice_info() {
+        return device_info;
+    }
+
+    public void setDevice_info(String device_info) {
+        this.device_info = device_info;
+    }
+
+    public String getLimit_pay() {
+        return limit_pay;
+    }
+
+    public void setLimit_pay(String limit_pay) {
+        this.limit_pay = limit_pay;
+    }
+}

+ 65 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/WxPayDetailRequest.java

@@ -0,0 +1,65 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+import com.google.gson.Gson;
+
+/**
+ * 商品详情
+ * 微信支付
+ * 账户端业务信息域
+ * 交易接口请求
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class WxPayDetailRequest {
+
+    private WxPayDetailRequest() {
+    }
+
+    public WxPayDetailRequest(WxPayGoodsDatailRequest goods_detail) {
+        this.goods_detail = goods_detail;
+    }
+
+    /**
+     * 1.商户侧一张小票订单可能被分多次支付,订单原价用于记录整张小票的交易金额。
+     * 2.当订单原价与支付金额不相等,则不享受优惠。
+     * 3.该字段主要用于防止同一张小票分多次支付,以 享受多次优惠的情况,正常支付订单不必上传此参 数。 如:608800
+     */
+    private String cost_price;
+
+    /**
+     * 商家小票 ID
+     */
+    private String receipt_id;
+
+    /**
+     * 单品信息,使用Json数组格式提交
+     */
+    private WxPayGoodsDatailRequest goods_detail;
+
+    public String getCost_price() {
+        return cost_price;
+    }
+
+    public void setCost_price(String cost_price) {
+        this.cost_price = cost_price;
+    }
+
+    public String getReceipt_id() {
+        return receipt_id;
+    }
+
+    public void setReceipt_id(String receipt_id) {
+        this.receipt_id = receipt_id;
+    }
+
+    public String getGoods_detail() {
+        return new Gson().toJson(goods_detail);
+    }
+
+    public void setGoods_detail(WxPayGoodsDatailRequest goods_detail) {
+        this.goods_detail = goods_detail;
+    }
+}

+ 99 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/labs/accbusifields/WxPayGoodsDatailRequest.java

@@ -0,0 +1,99 @@
+package org.jeecg.modules.pay.request.v3.labs.accbusifields;
+
+/**
+ * 单品信息,使用Json数组格式提交
+ * 商品详情
+ * 微信支付
+ * 账户端业务信息域
+ * 交易接口请求
+ * 交易接口V3.0下支付类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class WxPayGoodsDatailRequest {
+
+    private WxPayGoodsDatailRequest() {
+    }
+
+    /**
+     * 初始化单品信息
+     *
+     * @param goods_id   商品编码
+     * @param goods_name 商品的实际名称
+     * @param quantity   用户购买的数量
+     * @param price      单位为:分。如果商户有优惠,需传输商户优惠后的单价
+     */
+    public WxPayGoodsDatailRequest(String goods_id, String goods_name, Integer quantity, Integer price) {
+        this.goods_id = goods_id;
+        this.goods_name = goods_name;
+        this.quantity = quantity;
+        this.price = price;
+    }
+
+    /**
+     * 由半角的大小写字母、数字、中划线、下划线中的一种或几种组成。如“商品编码”
+     */
+    private String goods_id;
+
+    /**
+     * 微信支付定义的统一商品编号
+     */
+    private String wxpay_goods_id;
+
+    /**
+     * 商品的实际名称
+     */
+    private String goods_name;
+
+    /**
+     * 用户购买的数量
+     */
+    private Integer quantity;
+
+    /**
+     * 单位为:分。如果商户有优惠,需传输商户优惠后的单价
+     */
+    private Integer price;
+
+    public String getGoods_id() {
+        return goods_id;
+    }
+
+    public void setGoods_id(String goods_id) {
+        this.goods_id = goods_id;
+    }
+
+    public String getWxpay_goods_id() {
+        return wxpay_goods_id;
+    }
+
+    public void setWxpay_goods_id(String wxpay_goods_id) {
+        this.wxpay_goods_id = wxpay_goods_id;
+    }
+
+    public String getGoods_name() {
+        return goods_name;
+    }
+
+    public void setGoods_name(String goods_name) {
+        this.goods_name = goods_name;
+    }
+
+    public Integer getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(Integer quantity) {
+        this.quantity = quantity;
+    }
+
+    public Integer getPrice() {
+        return price;
+    }
+
+    public void setPrice(Integer price) {
+        this.price = price;
+    }
+}

+ 309 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/los/GenerateOrderRequest.java

@@ -0,0 +1,309 @@
+package org.jeecg.modules.pay.request.v3.los;
+
+
+import org.jeecg.modules.pay.core.LakalaPayConfig;
+import org.jeecg.modules.pay.request.ReqData;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.List;
+
+/**
+ * 收银台下单请求报文
+ * 交易接口V3.0下订单类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class GenerateOrderRequest extends ReqData {
+
+    private GenerateOrderRequest() {
+    }
+
+    /**
+     * 初始化收银台下单接口请求报文
+     *
+     * @param out_order_no 商户订单号
+     * @param total_amount 订单金额,单位:分
+     * @param order_info   订单标题,在使用收银台扫码支付时必输入
+     */
+    public GenerateOrderRequest(String out_order_no, Long total_amount, String order_info) {
+        this.out_order_no = out_order_no;
+        this.merchant_no = LakalaPayConfig.MERCHANT_NO;
+        this.channel_id = LakalaPayConfig.CHANNEL_ID;
+        this.total_amount = total_amount;
+        this.order_efficient_time = orderEfficientTime(10);
+        this.order_info = order_info;
+    }
+
+    /**
+     * 商户订单号
+     */
+    private String out_order_no;
+
+    /**
+     * 商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 交易设备标识(非合单场景必输该字段),进件返回接口中的termId字段,非API接口进件请联系业务员
+     */
+    private String vpos_id;
+
+    /**
+     * 渠道号 (用于接收订单通知报文,拉卡拉开通)
+     */
+    private String channel_id;
+
+    /**
+     * 业务模式: ACQ-收单 不填,默认为“ACQ-收单”
+     */
+    private String busi_mode;
+
+    /**
+     * 订单金额,单位:分
+     */
+    private Long total_amount;
+
+    /**
+     * 订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
+     */
+    private String order_efficient_time;
+
+    /**
+     * 订单支付成功后商户接收订单通知的地址
+     */
+    private String notify_url;
+
+    /**
+     * 是否支持撤销 默认 0 不支持
+     * busi_mode为“PAY-付款”不支持 撤销
+     */
+    private Integer support_cancel;
+
+    /**
+     * 是否支持退款 默认0 不支持
+     */
+    private Integer support_refund;
+
+    /**
+     * 是否支持“多次发起支付” 默认0 不支持
+     */
+    private Integer support_repeat_pay;
+
+    /**
+     * 	业务类型控制参数,jsonStr格式
+     */
+    private String busi_type_param;
+
+    /**
+     * 发起订单方的userId,归属于channelId下的userId
+     */
+    private String out_user_id;
+
+    /**
+     * 客户端下单完成支付后返回的商户网页跳转地址。
+     */
+    private String callback_url;
+
+    /**
+     * 订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
+     */
+    private String order_info;
+
+    /**
+     * 	结算终端号,合单场景必输该字段
+     */
+    private String term_no;
+
+    /**
+     * 	合单标识,“1”为合单,不填默认是为非合单
+     */
+    private String split_mark;
+
+    /**
+     * 	拆单信息
+     * 合单标识为“1”时必传该字段。,详细字段见out_split_info字段说明
+     */
+    private List<OutSplitInfoRequest> out_split_info;
+
+    /**
+     * 收银台样式(STD-标准收银台、FSWY - 福斯网银、FSZZ - 福斯转账、B2B-B2B收银台
+     */
+    private String page_style;
+
+    /**
+     * 结算类型(非合单) (“0”或者空,常规结算方式) 注意:该字段会影响结算方式,慎用。
+     */
+    private String settle_type;
+
+    public String getOut_order_no() {
+        return out_order_no;
+    }
+
+    public void setOut_order_no(String out_order_no) {
+        this.out_order_no = out_order_no;
+    }
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getVpos_id() {
+        return vpos_id;
+    }
+
+    public void setVpos_id(String vpos_id) {
+        this.vpos_id = vpos_id;
+    }
+
+    public String getChannel_id() {
+        return channel_id;
+    }
+
+    public void setChannel_id(String channel_id) {
+        this.channel_id = channel_id;
+    }
+
+    public String getBusi_mode() {
+        return busi_mode;
+    }
+
+    public void setBusi_mode(String busi_mode) {
+        this.busi_mode = busi_mode;
+    }
+
+    public Long getTotal_amount() {
+        return total_amount;
+    }
+
+    public void setTotal_amount(Long total_amount) {
+        this.total_amount = total_amount;
+    }
+
+    public String getOrder_efficient_time() {
+        return order_efficient_time;
+    }
+
+    public void setOrder_efficient_time(String order_efficient_time) {
+        this.order_efficient_time = order_efficient_time;
+    }
+
+    public String getNotify_url() {
+        return notify_url;
+    }
+
+    public void setNotify_url(String notify_url) {
+        this.notify_url = notify_url;
+    }
+
+    public Integer getSupport_cancel() {
+        return support_cancel;
+    }
+
+    public void setSupport_cancel(Integer support_cancel) {
+        this.support_cancel = support_cancel;
+    }
+
+    public Integer getSupport_refund() {
+        return support_refund;
+    }
+
+    public void setSupport_refund(Integer support_refund) {
+        this.support_refund = support_refund;
+    }
+
+    public Integer getSupport_repeat_pay() {
+        return support_repeat_pay;
+    }
+
+    public void setSupport_repeat_pay(Integer support_repeat_pay) {
+        this.support_repeat_pay = support_repeat_pay;
+    }
+
+    public String getBusi_type_param() {
+        return busi_type_param;
+    }
+
+    public void setBusi_type_param(String busi_type_param) {
+        this.busi_type_param = busi_type_param;
+    }
+
+    public String getOut_user_id() {
+        return out_user_id;
+    }
+
+    public void setOut_user_id(String out_user_id) {
+        this.out_user_id = out_user_id;
+    }
+
+    public String getCallback_url() {
+        return callback_url;
+    }
+
+    public void setCallback_url(String callback_url) {
+        this.callback_url = callback_url;
+    }
+
+    public String getOrder_info() {
+        return order_info;
+    }
+
+    public void setOrder_info(String order_info) {
+        this.order_info = order_info;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getSplit_mark() {
+        return split_mark;
+    }
+
+    public void setSplit_mark(String split_mark) {
+        this.split_mark = split_mark;
+    }
+
+    public List<OutSplitInfoRequest> getOut_split_info() {
+        return out_split_info;
+    }
+
+    public void setOut_split_info(List<OutSplitInfoRequest> out_split_info) {
+        this.out_split_info = out_split_info;
+    }
+
+    public String getPage_style() {
+        return page_style;
+    }
+
+    public void setPage_style(String page_style) {
+        this.page_style = page_style;
+    }
+
+    public String getSettle_type() {
+        return settle_type;
+    }
+
+    public void setSettle_type(String settle_type) {
+        this.settle_type = settle_type;
+    }
+
+    private String orderEfficientTime(int minutes) {
+        LocalDateTime date = LocalDateTime.now();
+        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        LocalDateTime nextWeek = date.minus(-minutes, ChronoUnit.MINUTES);//20分钟后
+        return nextWeek.format(format1);
+    }
+}

+ 100 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/los/OutSplitInfoRequest.java

@@ -0,0 +1,100 @@
+package org.jeecg.modules.pay.request.v3.los;
+
+/**
+ * 拆单信息
+ * 收银台下单请求报文
+ * 交易接口V3.0下订单类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class OutSplitInfoRequest {
+
+    private OutSplitInfoRequest() {
+    }
+
+    /**
+     * 初始化拆单信息
+     *
+     * @param out_sub_order_no 外部子订单号
+     * @param merchant_no      商户号
+     * @param term_no          终端号
+     * @param amount           金额
+     */
+    public OutSplitInfoRequest(String out_sub_order_no, String merchant_no, String term_no, String amount) {
+        this.out_sub_order_no = out_sub_order_no;
+        this.merchant_no = merchant_no;
+        this.term_no = term_no;
+        this.amount = amount;
+    }
+
+    /**
+     * 外部子订单号
+     */
+    private String out_sub_order_no;
+
+    /**
+     * 商户号
+     * 拉卡拉分配的商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 终端号
+     * 拉卡拉分配的业务终端号
+     */
+    private String term_no;
+
+    /**
+     * 金额
+     * 单位分,整数型字符
+     */
+    private String amount;
+
+    /**
+     * 结算类型(合单)
+     * “0”或者空,常规结算方式
+     */
+    private String settle_type;
+
+    public String getOut_sub_order_no() {
+        return out_sub_order_no;
+    }
+
+    public void setOut_sub_order_no(String out_sub_order_no) {
+        this.out_sub_order_no = out_sub_order_no;
+    }
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getTerm_no() {
+        return term_no;
+    }
+
+    public void setTerm_no(String term_no) {
+        this.term_no = term_no;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getSettle_type() {
+        return settle_type;
+    }
+
+    public void setSettle_type(String settle_type) {
+        this.settle_type = settle_type;
+    }
+}

+ 67 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/request/v3/los/QueryOrderRequest.java

@@ -0,0 +1,67 @@
+package org.jeecg.modules.pay.request.v3.los;
+
+
+import org.jeecg.modules.pay.request.ReqData;
+
+/**
+ * 订单交易信息查询请求报文
+ * 交易接口V3.0下订单类接口
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class QueryOrderRequest extends ReqData {
+
+    /**
+     * 商户订单号
+     */
+    private String out_order_no;
+
+    /**
+     * 商户号
+     */
+    private String merchant_no;
+
+    /**
+     * 支付订单号
+     */
+    private String pay_order_no;
+
+    /**
+     * 渠道号
+     */
+    private String channel_id;
+
+    public String getOut_order_no() {
+        return out_order_no;
+    }
+
+    public void setOut_order_no(String out_order_no) {
+        this.out_order_no = out_order_no;
+    }
+
+    public String getMerchant_no() {
+        return merchant_no;
+    }
+
+    public void setMerchant_no(String merchant_no) {
+        this.merchant_no = merchant_no;
+    }
+
+    public String getPay_order_no() {
+        return pay_order_no;
+    }
+
+    public void setPay_order_no(String pay_order_no) {
+        this.pay_order_no = pay_order_no;
+    }
+
+    public String getChannel_id() {
+        return channel_id;
+    }
+
+    public void setChannel_id(String channel_id) {
+        this.channel_id = channel_id;
+    }
+}

+ 74 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/service/PayService.java

@@ -0,0 +1,74 @@
+package org.jeecg.modules.pay.service;
+
+import org.jeecg.modules.pay.vo.NotifyVO;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author HY
+ * @date 2024-08-19 20:07
+ */
+public interface PayService {
+/**
+ * <p>
+ *    支付回调
+ * </p>
+ * @author HY
+ * @param notifyVO {@link NotifyVO}
+ * @Date 2024-08-18
+ */
+void notify(NotifyVO notifyVO);
+
+/**
+ * <p>
+ *    主扫-支付宝
+ * </p>
+ * @author HY
+ * @Date 2024-08-18
+ */
+//String transPreorderALi(String orderId);
+
+/**
+ * <p>
+ *    主扫-微信
+ * </p>
+ * @author HY
+ * @Date 2024-08-18
+ */
+//Map<String, Object> transPreorderWx(String orderId, String openid);
+
+/**
+ * <p>
+ *     被扫-聚合
+ * </p>
+ * @author HY
+ * @Date
+ */
+//boolean transMicropay(TransMicropayDTO transMicropayDTO);
+
+/**
+ * <p>
+ *      退款
+ * </p>
+ * @author HY
+ * @param
+ * @return
+ * @Date
+ */
+//boolean relationRefund(String orderId);
+
+/**
+ * <p>
+ *    交易查询
+ * </p>
+ * @author HY
+ * @param
+ * @return
+ * @Date
+ */
+//String queryTradeQuery(String orderId, String orderNumber);
+
+//boolean prePaymentInquiry(String orederId);
+}

+ 398 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/service/impl/PayServiceImpl.java

@@ -0,0 +1,398 @@
+package org.jeecg.modules.pay.service.impl;
+
+import org.jeecg.modules.pay.service.PayService;
+import org.jeecg.modules.pay.vo.NotifyVO;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author HY
+ * @date 2024-08-19 20:09
+ */
+@Service
+public class PayServiceImpl implements PayService {
+
+
+
+    /**
+     * <p>
+     * 支付回调
+     * </p>
+     *
+     * @param notifyVO {@link NotifyVO}
+     * @return boolean
+     * @author HY
+     * @Date 2024-08-18
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void notify(NotifyVO notifyVO) {
+        System.out.println("支付回调:  " + notifyVO);
+
+//        if(null == eduOrder.getCallbackFlag()){
+//            queryTradeQuery(eduOrder.getId(),null);
+//        }
+//        if (Optional.ofNullable(eduOrder).isPresent()) {
+//            try {
+//                String trade_no = "H9995935";
+//                if(eduOrder.getPaymentType() == 1){
+//                    trade_no = "J9442025";
+//                }
+//                String string = V3LabsApi.queryTradeQuery(new TradeQueryRequest().setTerm_no(trade_no).setTrade_no(notifyVO.getTrade_no()).setOut_trade_no(notifyVO.getOut_trade_no()).setMerchant_no(notifyVO.getMerchant_no()));
+//                PayDataVO queryOrderVO = new Gson().fromJson(string, PayDataVO.class);
+//                Map<String, Object> respData = (Map<String, Object>) queryOrderVO.getResp_data();
+//                if (respData.get("trade_state").equals("SUCCESS") && respData.get("total_amount").equals(getMoney(eduOrder.getPayment()))) {
+//                    switch (respData.get("account_type").toString()){
+//                        case "WECHAT":
+//                            eduOrder.setPaymentType(1);
+//                            break;
+//                        case "ALIPAY":
+//                            eduOrder.setPaymentType(2);
+//                            break;
+//                        case "UQRCODEPAY":
+//                            eduOrder.setPaymentType(3);
+//                            break;
+//                        case "BESTPAY":
+//                            eduOrder.setPaymentType(4);
+//                            break;
+//                        case "DCPAY":
+//                            eduOrder.setPaymentType(5);
+//                            break;
+//                    }
+//                    eduOrder.setPayStatus(1);
+//                    eduOrderMapper.updateById(eduOrder);
+//                }
+//            } catch (Exception e) {
+//                log.print("订单:" + notifyVO.getAcc_trade_no() + "查询失败");
+//            }
+//        }
+
+    }
+
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public String transPreorderALi(String orderId) {
+//        EduOrder eduOrder = eduOrderMapper.selectOne(Wrappers.<EduOrder>lambdaQuery().eq(EduOrder::getId, orderId).ne(EduOrder::getPayStatus, 5));
+//        eduOrder.setPayStatus(2);
+//        eduOrderMapper.updateById(eduOrder);
+//        String orderNumber = generateAnOrderNumber();
+//        eduOrderNumberMapper.insert(new EduOrderNumber().setOrderNumber(orderNumber).setOrderId(orderId).setPayType(1));
+//        String transPreorderALi = null;
+//        if(Optional.ofNullable(eduOrder).isPresent() && eduOrder.getPayStatus() != 1){
+//            try {
+//                // 初始化主扫交易接口请求报文
+//                PreorderRequest request = new PreorderRequest(orderNumber, "ALIPAY",
+//                        "41", getMoney(eduOrder.getPayment()), new ReqLocationInfo(InetAddress.getLocalHost().getHostAddress()));
+//                // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+//                request.setSubject(eduOrder.getTitle() + "-" + eduStudentMapper.selectById(eduOrder.getUserId()).getName());
+//                // 商户通知地址
+//                request.setNotify_url(LakalaPayConfig.NOTIFY_URL);
+//                String res = V3LabsApi.transPreorder(request);
+//                PayDataVO payDataVO = new Gson().fromJson(res, PayDataVO.class);
+//                if(payDataVO.getCode().equals("BBS00000") && payDataVO.getMsg().equals("成功")){
+//                    Map<String, Object> respData = (Map<String, Object>) payDataVO.getResp_data();
+//                    Map<String, Object> acc_resp_fields = (Map<String, Object>) respData.get("acc_resp_fields");
+//                    if(Optional.ofNullable(acc_resp_fields.get("code")).isPresent()){
+//                        transPreorderALi = (String) acc_resp_fields.get("code");
+//                        eduOrder.setPayStatus(2);
+//                    }
+//                }
+//            }catch (Exception e){
+//                throw new JeecgBootException("支付失败");
+//            }
+//            updateChildOrder(eduOrder.getId());
+//            eduOrder.setPaymentTime(new Date())
+//                    .setOrderId(orderNumber).setPaymentType(2);
+//            if(eduOrderMapper.updateById(eduOrder) == 0) throw new JeecgBootException("支付失败");
+//        }else if(eduOrder.getPayStatus() == 1){
+//            throw new JeecgBootException("已支付");
+//        }
+//        return transPreorderALi;
+//    }
+//
+//@Override
+//public Map<String, Object> transPreorderWx(String orderId,String openid) {
+//    if(!Optional.ofNullable(openid).isPresent()) throw new JeecgBootException("支付失败! 请重新尝试!");
+//    EduOrder eduOrder = eduOrderMapper.selectOne(Wrappers.<EduOrder>lambdaQuery().eq(EduOrder::getId, orderId).ne(EduOrder::getPayStatus, 5));
+//    eduOrder.setPayStatus(2);
+//    eduOrderMapper.updateById(eduOrder);
+//    String orderNumber = generateAnOrderNumber();
+//    eduOrderNumberMapper.insert(new EduOrderNumber().setOrderNumber(orderNumber).setOrderId(orderId).setPayType(1));
+//    Map<String, Object> acc_resp_fields = null;
+//    if(Optional.ofNullable(eduOrder).isPresent() && eduOrder.getPayStatus() != 1){
+//        try {
+//            // 初始化主扫交易接口请求报文
+//            PreorderRequest request = new PreorderRequest(orderNumber, "WECHAT",
+//                    "51", getMoney(eduOrder.getPayment()), new ReqLocationInfo(InetAddress.getLocalHost().getHostAddress()));
+//            // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+//            request.setSubject(eduOrder.getTitle() + "-" + eduStudentMapper.selectById(eduOrder.getUserId()).getName());
+//            // 商户通知地址
+//            request.setNotify_url(LakalaPayConfig.NOTIFY_URL);
+//            // 账户端业务信息域
+//            WxPayAccBusiFieldsRequest accBusiFieldsRequest = new WxPayAccBusiFieldsRequest();
+//            // 子商户公众账号ID
+//            accBusiFieldsRequest.setSub_appid("wxe3e575a4a2142f5b");
+////            accBusiFieldsRequest.setSub_appid("678959622");
+//            // 用户标识
+//            accBusiFieldsRequest.setUser_id(openid);
+//            // 商品价格 单位元
+//            Integer price = new BigDecimal(getMoney(eduOrder.getPayment())).divide(new BigDecimal(100)).intValue();
+////            accBusiFieldsRequest.setDetail(new WxPayDetailRequest(new WxPayGoodsDatailRequest(orderNumber, eduOrder.getTitle(), 1, price)));
+//            request.setAcc_busi_fields(accBusiFieldsRequest);
+//            String res = V3LabsApi.transPreorder(request);
+//            System.out.println(res);
+//            PayDataVO payDataVO = new Gson().fromJson(res, PayDataVO.class);
+//            if(payDataVO.getCode().equals("BBS00000") && payDataVO.getMsg().equals("成功")){
+//                Map<String, Object> respData = (Map<String, Object>) payDataVO.getResp_data();
+//                acc_resp_fields = (Map<String, Object>) respData.get("acc_resp_fields");
+//                if(Optional.ofNullable(acc_resp_fields).isPresent() && Optional.ofNullable(acc_resp_fields.get("prepay_id")).isPresent()){
+//                    eduOrder.setPayStatus(2);
+//                }
+//            }
+//        }catch (Exception e){
+//            throw new JeecgBootException("支付失败");
+//        }
+//        updateChildOrder(eduOrder.getId());
+//        eduOrder.setPaymentTime(new Date()).setOrderId(orderNumber).setPaymentType(1);
+//        if(eduOrderMapper.updateById(eduOrder) == 0) throw new JeecgBootException("支付失败");
+//    }else if(eduOrder.getPayStatus() == 1){
+//        throw new JeecgBootException("已支付");
+//    }else {
+//        throw new JeecgBootException("支付失败");
+//    }
+//    return acc_resp_fields;
+//}
+//
+//@Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public boolean transMicropay(TransMicropayDTO transMicropayDTO) {
+//        PayDataVO payDataVO = null;
+//        EduOrder eduOrder = eduOrderMapper.selectOne(Wrappers.<EduOrder>lambdaQuery().eq(EduOrder::getId, transMicropayDTO.getOrederId()).ne(EduOrder::getPayStatus, 5));
+//        eduOrder.setPayStatus(2);
+//        eduOrderMapper.updateById(eduOrder);
+//        String orderNumber = generateAnOrderNumber();
+//      eduOrderNumberMapper.insert(new EduOrderNumber().setOrderNumber(orderNumber).setOrderId(eduOrder.getId()).setPayType(1));
+//        if(Optional.ofNullable(eduOrder).isPresent() && eduOrder.getPayStatus() != 1){
+//            eduOrder.setPaymentType(getPayType(transMicropayDTO.getAuthCode()));
+//            try {
+//                // 初始化被扫交易接口请求报文
+//                MicropayRequest request = new MicropayRequest(orderNumber, transMicropayDTO.getAuthCode(),
+//                        getMoney(eduOrder.getPayment()),new ReqLocationInfo(InetAddress.getLocalHost().getHostAddress()));
+//                // 订单标题,用于简单描述订单或商品主题,会传递给账户端 (账户端控制,实际最多42个字符),微信支付必送。
+//                request.setSubject(eduOrder.getTitle() + "-" + eduStudentMapper.selectById(eduOrder.getUserId()).getName());
+//                // 商户通知地址
+//                request.setNotify_url(LakalaPayConfig.NOTIFY_URL);
+//                // 账户端业务信息域
+//                AliPayAccBusiFieldsRequest accBusiFieldsRequest = new AliPayAccBusiFieldsRequest();
+//                accBusiFieldsRequest.setGoods_detail(new AliPayGoodsDetailRequest(orderNumber, eduOrder.getTitle(),
+//                        1, eduOrder.getPayment().doubleValue()));
+//                request.setAcc_busi_fields(accBusiFieldsRequest);
+//                String res = V3LabsApi.transMicropay(request);
+//                payDataVO = new Gson().fromJson(res, PayDataVO.class);
+//                if(payDataVO.getCode().equals("BBS10000")){
+//                    Map<String, Object> respData = (Map<String, Object>) payDataVO.getResp_data();
+////                微信:WECHAT 支付宝:ALIPAY 银联:UQRCODEPAY 翼支付: BESTPAY 数字货币:DCPAY
+//                    switch (respData.get("account_type").toString()){
+//                        case "WECHAT":
+//                            eduOrder.setPaymentType(1);
+//                            break;
+//                        case "ALIPAY":
+//                            eduOrder.setPaymentType(2);
+//                            break;
+//                        case "UQRCODEPAY":
+//                            eduOrder.setPaymentType(3);
+//                            break;
+//                        case "BESTPAY":
+//                            eduOrder.setPaymentType(4);
+//                            break;
+//                        case "DCPAY":
+//                            eduOrder.setPaymentType(5);
+//                            break;
+//                    }
+//                    if(Objects.equals(respData.get("need_query").toString(), "1")){
+//                        eduOrder.setPayStatus(2);
+//                    }else {
+//                        eduOrder.setPayStatus(1);
+//                    }
+//                }
+//            }catch (Exception e){
+//                throw new JeecgBootException(payDataVO.getMsg());
+//            }
+//            updateChildOrder(eduOrder.getId());
+//            eduOrder.setPaymentTime(new Date()).setOrderId(orderNumber);
+//            if(eduOrderMapper.updateById(eduOrder) == 0) throw new JeecgBootException("支付失败");
+//        }else if(eduOrder.getPayStatus() == 1){
+//            throw new JeecgBootException("已支付");
+//        }
+//        return true;
+//    }
+//
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public boolean relationRefund(String orderId) {
+//        try {
+//            EduOrder eduOrder = eduOrderMapper.selectOne(Wrappers.<EduOrder>lambdaQuery().eq(EduOrder::getId, orderId).eq(EduOrder::getPayStatus, 1));
+//            if(!Optional.ofNullable(eduOrder).isPresent()) throw new JeecgBootException("账单未支付!");
+//            String orderNumber = generateAnOrderNumber();
+//            eduOrderNumberMapper.insert(new EduOrderNumber().setOrderNumber(orderNumber).setOrderId(eduOrder.getId()).setPayType(1).setPayType(2));
+//            updateChildOrder(eduOrder.getId());
+//            ReqLocationInfo location_info = new ReqLocationInfo(InetAddress.getLocalHost().getHostAddress());
+//            RefundRequest request = new RefundRequest(orderNumber, getMoney(eduOrder.getPayment()), location_info);
+//            request.setOrigin_out_trade_no(eduOrder.getOrderId());
+//            request.setOut_trade_no(orderNumber);
+//            String res = V3LabsApi.relationRefund(request);
+//            PayDataVO payDataVO = new Gson().fromJson(res, PayDataVO.class);
+//            if(payDataVO.getMsg().equals("成功")){
+//                eduOrder.setPayStatus(5).setOrderId(orderNumber);
+//                eduOrderMapper.updateById(eduOrder);
+//                return true;
+//            }else {
+//                throw new JeecgBootException("退款失败");
+//            }
+//        }catch (Exception e){
+//            throw new JeecgBootException("退款失败");
+//        }
+//    }
+//
+//    @Override
+//    public String queryTradeQuery(String orderId, String orderNumber) {
+//        String res = null;
+//        EduOrder eduOrder = null;
+//            // 初始化查询交易接口请求报文
+//            TradeQueryRequest request = new TradeQueryRequest();
+//            eduOrder = eduOrderMapper.selectById(orderId);
+//        if(null != orderNumber){
+//            request.setOut_trade_no(orderNumber);
+//        }else {
+//            request.setOut_trade_no(eduOrder.getOrderId());
+//        }
+//        res = V3LabsApi.queryTradeQuery(request);
+//        PayDataVO payDataVO = new Gson().fromJson(res, PayDataVO.class);
+//        Map<String, Object> respData = (Map<String, Object>) payDataVO.getResp_data();
+//        if(!Optional.ofNullable(respData).isPresent()) return "订单: " + orderId + " 未成功支付";
+//        if (respData.get("trade_state").equals("SUCCESS") && respData.get("total_amount").equals(getMoney(eduOrder.getPayment()))){
+//            switch (respData.get("account_type").toString()){
+//                case "WECHAT":
+//                    eduOrder.setPaymentType(1);
+//                    break;
+//                case "ALIPAY":
+//                    eduOrder.setPaymentType(2);
+//                    break;
+//                case "UQRCODEPAY":
+//                    eduOrder.setPaymentType(3);
+//                    break;
+//                case "BESTPAY":
+//                    eduOrder.setPaymentType(4);
+//                    break;
+//                case "DCPAY":
+//                    eduOrder.setPaymentType(5);
+//                    break;
+//            }
+//            eduOrder.setPayStatus(1).setCallbackFlag(1);
+//            if(null != orderNumber) eduOrder.setOrderId(orderNumber);
+//            eduOrderMapper.updateById(eduOrder);
+//            System.out.println(respData.get("trade_state_desc") + "  订单:  " + eduOrder.getId());
+//            return "SUCCESS";
+//        }else {
+//            return (String) respData.get("trade_state_desc");
+//        }
+//
+//    }
+//
+//    String generateAnOrderNumber(){
+//        int randomFourDigit = (int) (Math.random() * 9000) + 1000;
+//        return "8" + randomFourDigit + System.currentTimeMillis();
+//    }
+//
+//    int getPayType(String authCode){
+//        int payType = 0;
+//        if (Optional.ofNullable(authCode).isPresent() && authCode.length() > 2) {
+//            String substring = authCode.substring(0, 2);
+//            switch (substring) {
+//                case "10":
+//                case "11":
+//                case "12":
+//                case "13":
+//                case "14":
+//                case "15":
+//                    payType = 1;
+//                    break;
+//                case "25":
+//                case "26":
+//                case "27":
+//                case "28":
+//                case "29":
+//                case "30":
+//                    payType = 2;
+//                    break;
+//                case "62":
+//                    payType = 3;
+//                    break;
+//                case "01":
+//                    payType = 4;
+//                    break;
+//                case "51":
+//                    payType = 5;
+//                    break;
+//            }
+//        } else {
+//            payType = -1;
+//        }
+//        return payType;
+//    }
+//
+//    void updateChildOrder(String orderId){
+//        List<EduOrderChild> eduOrderChildren = eduOrderChildMapper.selectList(Wrappers.<EduOrderChild>lambdaQuery().eq(EduOrderChild::getOrderId, orderId));
+//        eduOrderChildren.forEach(a->{
+//            a.setSerialNumber(orderId);
+//        });
+//    }
+//
+//    String getMoney(BigDecimal payment){
+//        return String.valueOf(payment.multiply(new BigDecimal("100")).intValue());
+//    }
+//
+//    public WeiXinUserInfoVO getAccessToken(String code) {
+//        String url = StrFormatter.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={}&secret={}&code={}&grant_type=authorization_code", "wxe3e575a4a2142f5b", "0db278065bc326c8c808048126994c5e", code);
+//        //请求返回的内容,一个json对象
+//        String body = HttpUtil.get(url);
+//        System.out.println(body);
+//        if(!Optional.ofNullable(body).isPresent()) throw new JeecgBootException("请求异常请联系管理员!");
+//        //将接收的json对象转换为对象
+//        AccessTokenInfoVO accessTokenInfo = JSONUtil.toBean(body, AccessTokenInfoVO.class);
+//        System.out.println(accessTokenInfo.toString());
+//        //获取用户信息
+//        url = StrFormatter.format("https://api.weixin.qq.com/sns/userinfo?access_token={}&openid={}&lang=zh_CN",accessTokenInfo.getAccess_token(),accessTokenInfo.getOpenid());
+//        //请求返回的内容,一个json对象
+//        body = HttpUtil.get(url);
+//        WeiXinUserInfoVO weiXinUserInfo = JSONUtil.toBean(body, WeiXinUserInfoVO.class);
+//        System.out.println(weiXinUserInfo.toString());
+//        return weiXinUserInfo;
+//    }
+//
+//    public boolean prePaymentInquiry(String orderId){
+//        String res = null;
+//        try {
+//            // 初始化查询交易接口请求报文
+//            TradeQueryRequest request = new TradeQueryRequest();
+//            EduOrder eduOrder = eduOrderMapper.selectOne(Wrappers.<EduOrder>lambdaQuery().eq(EduOrder::getId, orderId));
+//            // 商户交易流水号
+//            request.setOut_trade_no(eduOrder.getOrderId());
+//            res = V3LabsApi.queryTradeQuery(request);
+//        } catch (Exception e) {
+//            return false;
+//        }
+//        PayDataVO payDataVO = new Gson().fromJson(res, PayDataVO.class);
+//        Map<String, Object> respData = (Map<String, Object>) payDataVO.getResp_data();
+//        if(!Optional.ofNullable(respData).isPresent()) return false;
+//        if (respData.get("trade_state").equals("SUCCESS")){
+//            return true;
+//        }
+//        return false;
+//    }
+}

+ 305 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/util/HttpClientPool.java

@@ -0,0 +1,305 @@
+package org.jeecg.modules.pay.util;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.*;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 高并发连接池的配制及使用
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class HttpClientPool {
+
+    private final static String HTTP_DEFAULT_CONTENT_TYPE = "application/json";
+    private static final String APIGW_HTTP_EXCEPTION_HEAD = "APIGW_HTTP_EXCEPTION_HEAD_";
+    //根据业务使用场景及对端服务器的基本情况,建立支持高并发和高性能的http连接
+    private final static int DEFAULT_REQ_TIMEOUT = 200;       //从池中请求数据时间  0.2秒
+    private final static int DEFAULT_CON_TIMEOUT = 3 * 1000;  //socket连接超时时间 3秒   未通,最多重连3次
+    private final static int DEFAULT_SOCKET_TIMEOUT = 10 * 1000; //页面返回的时间必须在30秒内,否则判定服务不可用
+
+    // 通过枚举来实现单例
+    private static enum Singleton {
+        Client;
+        //线程安全Client
+        private final CloseableHttpClient threadSafeClient;
+        //池监控
+        private final IdleConnectionMonitor monitor;
+        //KeepAlive策略 1分钟  一个建链最多保持1分钟
+        ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
+            public long getKeepAliveDuration(HttpResponse response,
+                                             HttpContext context) {
+                return 1 * 60 * 1000;                              //如果没有约定,则默认定义时长为120s
+            }
+        };
+
+        //实例
+        private Singleton() {
+            Registry<ConnectionSocketFactory> socketFactoryRegistry = null;
+            try {
+                SSLContextBuilder sslBuilder = new SSLContextBuilder();
+                sslBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
+                SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
+                sslContext.init(null, null, null);
+                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
+                // SSLContext sslContext = SSLContext.getInstance("TLS");
+                /* 配置同时支持 HTTP 和 HTPPS */
+                socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+                        .register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf)
+                        .build();
+            } catch (Exception e) {
+                System.out.println("创建SSLContextBuilder异常," + e);
+            }
+            PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+            cm.setMaxTotal(300);
+            cm.setDefaultMaxPerRoute(300); //每个系统保持一个连接
+            //保持默认的2秒,不要修改,因这个参数与对方有关系
+            //cm.setValidateAfterInactivity(10 * 1000);//10秒就验证连接
+            //重试策略
+            HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
+                public boolean retryRequest(IOException exp, int retryTimes, HttpContext ctx) {
+                    if (retryTimes > 3) {
+                        return false;
+                    }
+                    if (exp instanceof UnknownHostException || exp instanceof ConnectTimeoutException) {
+                        //return true;
+                        return false; //不进行重连
+                    }
+                    return false;
+                }
+            };
+            //创建一个Buider
+            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(DEFAULT_REQ_TIMEOUT)
+                    .setConnectTimeout(DEFAULT_CON_TIMEOUT).setSocketTimeout(DEFAULT_SOCKET_TIMEOUT)
+                    .setCookieSpec(CookieSpecs.STANDARD).build();
+            HttpClientBuilder builder = HttpClients.custom().setConnectionManager(cm).setKeepAliveStrategy(myStrategy)
+                    .setDefaultRequestConfig(requestConfig).setRetryHandler(retryHandler);
+            threadSafeClient = builder.build();
+            //排除过期的和空闲的
+            monitor = new IdleConnectionMonitor(cm);
+            Thread monitorThread = new Thread(monitor);
+            monitorThread.setDaemon(true);
+            monitorThread.start();
+        }
+
+        /**
+         * @return
+         * @Description 得到一个线程安全的client
+         */
+        public CloseableHttpClient get() {
+            return threadSafeClient;
+        }
+
+    }
+
+    /**
+     * @return
+     * @Description 得到一个线程安全的client
+     */
+    public static CloseableHttpClient getClient() {
+        return Singleton.Client.get();
+    }
+
+    /**
+     * @throws InterruptedException
+     * @throws IOException
+     * @Description 关闭池
+     */
+    public static void shutdown() throws InterruptedException, IOException {
+        Singleton.Client.monitor.shutdown();
+    }
+
+    //池监控线程
+    private static class IdleConnectionMonitor implements Runnable {
+        private final PoolingHttpClientConnectionManager cm;
+        //使用BlockingQueue来处理停服务事件
+        private final BlockingQueue<Stop> stopSignal = new ArrayBlockingQueue<Stop>(1);
+
+        IdleConnectionMonitor(PoolingHttpClientConnectionManager cm) {
+            this.cm = cm;
+        }
+
+        public void run() {
+            try {
+                Stop stopRequest;
+                //每3秒check
+                while ((stopRequest = stopSignal.poll(3, TimeUnit.SECONDS)) == null) {
+                    cm.closeExpiredConnections();//关闭过期的
+                    cm.closeIdleConnections(10, TimeUnit.SECONDS);//10秒还一直空闲 就关闭连接
+                }
+                stopRequest.stopped();
+            } catch (InterruptedException ex) {
+                System.out.println("中断异常," + ex);
+            }
+        }
+
+        //判断池是否关闭
+        private static class Stop {
+            private final BlockingQueue<Stop> stop = new ArrayBlockingQueue<Stop>(1);
+
+            //通知池关闭
+            public void stopped() {
+                stop.add(this);
+            }
+
+            //取到Stop
+            public void waitForStopped() throws InterruptedException {
+                stop.take();
+            }
+        }
+
+        /**
+         * @throws InterruptedException
+         * @throws IOException
+         * @Description 通知池进行关闭
+         */
+        public void shutdown() throws InterruptedException, IOException {
+            Stop stop = new Stop();
+            stopSignal.add(stop);
+            stop.waitForStopped();
+            HttpClientPool.getClient().close();
+            cm.close();
+        }
+    }
+
+    /**
+     * @param url
+     * @param postData
+     * @param header
+     * @param encoding
+     * @return
+     * @throws Exception
+     * @Description POST 请求
+     */
+    public static String doJsonRequest(String url, String postData, Map<String, String> header, String encoding)
+            throws Exception {
+        //HTTP
+        HttpPost postRequest = new HttpPost(url.trim());
+        //BODY
+        StringEntity stringEntity = new StringEntity(postData, encoding);
+        stringEntity.setContentType(HTTP_DEFAULT_CONTENT_TYPE);
+        postRequest.setEntity(stringEntity);
+        return getHttpResultMsg(url, header, postRequest, encoding);
+    }
+
+    /**
+     * @param url
+     * @param header
+     * @param encoding
+     * @return
+     * @throws Exception
+     * @Description GET请求
+     */
+    public static String doGetRequest(String url, Map<String, String> header, String encoding) throws Exception {
+        HttpGet getRequest = new HttpGet(url.trim());
+        return getHttpResultMsg(url, header, getRequest, encoding);
+    }
+
+    /**
+     * @param url
+     * @param postData
+     * @param header
+     * @param encoding
+     * @return
+     * @throws Exception
+     * @Description PUT 请求
+     */
+    public static String doPutRequest(String url, String postData, Map<String, String> header, String encoding)
+            throws Exception {
+        HttpPut putRequest = new HttpPut(url.trim());
+        //BODY
+        StringEntity stringEntity = new StringEntity(postData, encoding);
+        stringEntity.setContentType(HTTP_DEFAULT_CONTENT_TYPE);
+        putRequest.setEntity(stringEntity);
+        return getHttpResultMsg(url, header, putRequest, encoding);
+    }
+
+    /**
+     * @param header
+     * @param encoding
+     * @return
+     * @throws Exception
+     */
+    public static String doDeleteRequest(String url, Map<String, String> header, String encoding) throws Exception {
+        //HTTP
+        HttpDelete delRequest = new HttpDelete(url.trim());
+        return getHttpResultMsg(url, header, delRequest, encoding);
+
+    }
+
+    /**
+     * @param url
+     * @param header
+     * @param reqData
+     * @param encoding
+     * @return
+     * @throws Exception
+     */
+    private static String getHttpResultMsg(final String url, Map<String, String> header, HttpRequestBase reqData,
+                                           final String encoding)
+            throws Exception {
+        //HEADER
+        if (header != null) {
+            Set<Entry<String, String>> entrySet = header.entrySet();
+            for (Iterator<Entry<String, String>> itor = entrySet.iterator(); itor.hasNext(); ) {
+                Entry<String, String> entry = (Entry<String, String>) itor.next();
+                reqData.setHeader(entry.getKey(), entry.getValue());
+            }
+        }
+        //REQ&ANS
+        //使用hander直接让其得到InputStream并关闭流及释放连接操作,应用层不用关心
+        //具体看源码 CloseableHttpClient类  216行代码
+        String responseString = getClient().execute(reqData, new ResponseHandler<String>() {
+            public String handleResponse(HttpResponse response) {
+                String result;
+                HttpEntity entity = response.getEntity();
+                int statueCode = response.getStatusLine().getStatusCode();
+                try {
+                    result = EntityUtils.toString(entity, encoding);
+                    if (statueCode != 200) {
+                        System.out.println("http返回异常:" + result);
+                        return APIGW_HTTP_EXCEPTION_HEAD + statueCode;
+                    }
+                } catch (Exception e) {
+                    System.out.println("得到应答数据异常url=" + e);
+                    return APIGW_HTTP_EXCEPTION_HEAD + statueCode;
+                }
+                return result;
+            }
+        });
+        return responseString;
+    }
+}

+ 54 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/util/HttpUtil.java

@@ -0,0 +1,54 @@
+package org.jeecg.modules.pay.util;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * http请求工具类
+ *
+ * @author Mr丶xie
+ * @version 1.0.0
+ * @mail xielinke@lklink.cn
+ */
+public class HttpUtil {
+
+    /**
+     * 请求工具
+     **/
+    public static HttpResponse post(String url, String message, String authorization) throws IOException, ClientProtocolException {
+        StringEntity entity = new StringEntity(message, "UTF-8");
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put("Authorization", authorization);
+        headerMap.put("Accept", "application/json");
+        headerMap.put("Content-Type", "application/json");
+        return post(url, entity, headerMap);
+    }
+
+    /**
+     * 请求工具
+     **/
+    public static HttpResponse post(String url, HttpEntity entity, Map<String, String> headerMap) throws IOException, ClientProtocolException {
+        HttpClient http = HttpClientPool.getClient();
+        HttpPost post = new HttpPost(url);
+        post.setEntity(entity);
+        for (String key : headerMap.keySet()) {
+            post.setHeader(key, headerMap.get(key));
+        }
+        return http.execute(post);
+    }
+
+    /**
+     * 读取响应header 数据 工具
+     **/
+    public static String getHeadValue(HttpResponse response, String key) {
+        return (response.containsHeader(key)) ? response.getFirstHeader(key).getValue() : "";
+    }
+}

+ 64 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/vo/NotifyVO.java

@@ -0,0 +1,64 @@
+package org.jeecg.modules.pay.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 回调函数
+ * </p>
+ *
+ * @author HY
+ * @date 2024-08-18 19:52
+ */
+@Data
+@Accessors(chain = true)
+@Schema(description = "")
+public class NotifyVO {
+    //	商户号
+    public String merchant_no;
+    //商户交易流水号
+    public String out_trade_no;
+    //	拉卡拉交易流水号
+    public String trade_no;
+    //拉卡拉对账单流水号
+    public String log_no;
+    //账户端交易订单号
+    public String acc_trade_no;
+    //钱包类型
+    public String account_type;
+    //结算商户号
+    public String settle_merchant_no;
+    //结算终端号
+    public String settle_term_no;
+    //交易状态
+    public String trade_status;
+    //	订单金额
+    public String total_amount;
+    //付款人实付金额
+    public String payer_amount;
+    //账户端结算金额
+    public String acc_settle_amount;
+    //商户侧优惠金额(账户端)
+    public String acc_mdiscount_amount;
+    //账户端优惠金额
+    public String acc_discount_amount;
+    //账户端其它优惠金额
+    public String acc_other_discount_amount;
+    //交易完成时间
+    public String trade_time;
+    //用户标识1
+    public String user_id1;
+    //用户标识2
+    public String user_id2;
+    //活动 ID
+    public String acc_activity_id;
+    //付款银行
+    public String bank_type;
+    //银行卡类型
+    public String card_type;
+    //	备注
+    public String remark;
+
+}

+ 9 - 1
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/entity/InsureOrderInfo.java

@@ -61,7 +61,15 @@ public class InsureOrderInfo implements Serializable {
 	@Excel(name = "用户编号", width = 15)
     @Schema(description = "用户编号")
     private String familyMembersId;
-	/**生效开始时间*/
+    /**
+     * 用户名称
+     */
+    @Excel(name = "用户名称", width = 15)
+    @Schema(description = "用户名称")
+    private String familyUserName;
+    /**
+     * 生效开始时间
+     */
 	@Excel(name = "生效开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
 	@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
     @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")

+ 44 - 48
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppCoureseServiceImpl.java

@@ -193,7 +193,7 @@ public class AppCoureseServiceImpl extends ServiceImpl<AppCoursesMapper, AppCour
         LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
 //        checkPermission(sysUser,dbCourse);
         List<AppCoursesPriceRules> priceRulesList =
-                priceRulesMapper.selectList(Wrappers.<AppCoursesPriceRules>lambdaQuery().eq(AppCoursesPriceRules::getCoursesId, id));
+                priceRulesMapper.selectList(Wrappers.<AppCoursesPriceRules>lambdaQuery().eq(AppCoursesPriceRules::getCoursesId, id).eq(AppCoursesPriceRules::getCoursesType,0));
         AppCoursesCuDTO coursesCuDTO = new AppCoursesCuDTO();
         BeanUtils.copyProperties(dbCourse, coursesCuDTO);
         List<AppCoursesRuleDTO> priceRules = new ArrayList<>();
@@ -233,7 +233,7 @@ public class AppCoureseServiceImpl extends ServiceImpl<AppCoursesMapper, AppCour
             String[] split = r.getCategoryId().split(",");
             List<String> ids = Arrays.stream(split).collect(Collectors.toList());
 
-            Long count = priceRulesMapper.selectCount(Wrappers.<AppCoursesPriceRules>lambdaQuery().eq(AppCoursesPriceRules::getCoursesId, r.getId()));
+            Long count = priceRulesMapper.selectCount(Wrappers.<AppCoursesPriceRules>lambdaQuery().eq(AppCoursesPriceRules::getCoursesId, r.getId()).eq(AppCoursesPriceRules::getCoursesType,0));
 
             r.setTotalNum(Math.toIntExact(count));
 
@@ -267,52 +267,48 @@ public class AppCoureseServiceImpl extends ServiceImpl<AppCoursesMapper, AppCour
 
         List<AppCoursesPriceRules> priceRulesList = priceRulesMapper.selectList(Wrappers.lambdaQuery(AppCoursesPriceRules.class).eq(AppCoursesPriceRules::getCoursesId, courseId));
 
-        Map<Integer, List<AppCoursesPriceRules>> map = priceRulesList.stream().collect(Collectors.groupingBy(AppCoursesPriceRules::getCoursesType));
-
-        map.keySet().forEach(key -> {
-            map.get(key).forEach(priceRules -> {
-                CoursesPriceRulesVO coursesPriceRulesVO = new CoursesPriceRulesVO();
-                coursesPriceRulesVO.setId(priceRules.getId());
-                coursesPriceRulesVO.setCoursesId(priceRules.getCoursesId());
-                coursesPriceRulesVO.setName(priceRules.getName());
-                coursesPriceRulesVO.setStartTime(priceRules.getStartTime());
-                coursesPriceRulesVO.setEndTime(priceRules.getEndTime());
-                coursesPriceRulesVO.setCoursesType(priceRules.getCoursesType());
-
-                List<AppCoursesVerificationRecord> verificationRecordList = appCoursesVerificationRecordMapper
-                        .selectList(Wrappers.<AppCoursesVerificationRecord>lambdaQuery().eq(AppCoursesVerificationRecord::getCoursesPriceRuleId, priceRules.getId()));
-                //共计
-                coursesPriceRulesVO.setTotalNum(verificationRecordList.size());
-                //延期
-                long postponeNum = verificationRecordList.stream().filter(e -> e.getOrPostpone() == 1).count();
-                coursesPriceRulesVO.setPostponeNum((int) postponeNum);
-                //已核验
-                long writtenOffNum = verificationRecordList.stream().filter(e -> e.getVerifyStatus() == 1).count();
-                coursesPriceRulesVO.setWrittenOffNum((int) writtenOffNum);
-                //未核验
-                long unwrittenOffNum = verificationRecordList.stream().filter(e -> e.getVerifyStatus() == 0 && e.getOrPostpone() == 0).count();
-                coursesPriceRulesVO.setUnwrittenOffNum((int) unwrittenOffNum);
-
-                //判断是否为当日数据
-                LocalDate today = LocalDate.now();
-                LocalDate localDate = priceRules.getStartTime().toInstant()
-                        .atZone(ZoneId.systemDefault())
-                        .toLocalDate();
-                if (coursesPriceRulesVO.getEndTime().after(new Date())) {
-                    coursesPriceRulesVO.setOrDone(false);
-                }else {
-                    coursesPriceRulesVO.setOrDone(true);
-                }
-                if (today.isAfter(localDate)) {
-                    coursesPriceRulesVO.setOrToday(false);
-                } else {
-                    coursesPriceRulesVO.setOrToday(true);
-                }
-                coursesPriceRulesVO.setCourseType(key);
-                verifyCourseInfoDTOList.add(coursesPriceRulesVO);
-            });
-
-        });
+//        Map<Integer, List<AppCoursesPriceRules>> map = priceRulesList.stream().collect(Collectors.groupingBy(AppCoursesPriceRules::getCoursesType));
+
+        for (AppCoursesPriceRules priceRules : priceRulesList) {
+            CoursesPriceRulesVO coursesPriceRulesVO = new CoursesPriceRulesVO();
+            coursesPriceRulesVO.setId(priceRules.getId());
+            coursesPriceRulesVO.setCoursesId(priceRules.getCoursesId());
+            coursesPriceRulesVO.setName(priceRules.getName());
+            coursesPriceRulesVO.setStartTime(priceRules.getStartTime());
+            coursesPriceRulesVO.setEndTime(priceRules.getEndTime());
+            coursesPriceRulesVO.setCoursesType(priceRules.getCoursesType());
+
+            List<AppCoursesVerificationRecord> verificationRecordList = appCoursesVerificationRecordMapper
+                    .selectList(Wrappers.<AppCoursesVerificationRecord>lambdaQuery().eq(AppCoursesVerificationRecord::getCoursesPriceRuleId, priceRules.getId()));
+            //共计
+            coursesPriceRulesVO.setTotalNum(verificationRecordList.size());
+            //延期
+            long postponeNum = verificationRecordList.stream().filter(e -> e.getOrPostpone() == 1).count();
+            coursesPriceRulesVO.setPostponeNum((int) postponeNum);
+            //已核验
+            long writtenOffNum = verificationRecordList.stream().filter(e -> e.getVerifyStatus() == 1).count();
+            coursesPriceRulesVO.setWrittenOffNum((int) writtenOffNum);
+            //未核验
+            long unwrittenOffNum = verificationRecordList.stream().filter(e -> e.getVerifyStatus() == 0 && e.getOrPostpone() == 0).count();
+            coursesPriceRulesVO.setUnwrittenOffNum((int) unwrittenOffNum);
+
+            //判断是否为当日数据
+            LocalDate today = LocalDate.now();
+            LocalDate localDate = priceRules.getStartTime().toInstant()
+                    .atZone(ZoneId.systemDefault())
+                    .toLocalDate();
+            if (coursesPriceRulesVO.getEndTime().after(new Date())) {
+                coursesPriceRulesVO.setOrDone(false);
+            }else {
+                coursesPriceRulesVO.setOrDone(true);
+            }
+            if (!localDate.isEqual(today)) {
+                coursesPriceRulesVO.setOrToday(false);
+            } else {
+                coursesPriceRulesVO.setOrToday(true);
+            }
+            verifyCourseInfoDTOList.add(coursesPriceRulesVO);
+        }
 
         return verifyCourseInfoDTOList;
     }

+ 12 - 6
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/system/app/service/impl/AppSitePlaceServiceImpl.java

@@ -602,10 +602,10 @@ public class AppSitePlaceServiceImpl extends ServiceImpl<AppSitePlaceMapper, App
             if (sitePlaceNum < count) {
                 if (sitePlaceNum > 0) {
                     // 增加场地 数量
-                    for (int i = 1; i < count - sitePlaceNum; i++) {
+                    for (int i = 1; i <= count - sitePlaceNum; i++) {
                         AppSitePlace appSitePlace = new AppSitePlace();
                         BeanUtils.copyProperties(placeCuDTO, appSitePlace);
-                        appSitePlace.setSiteId(site.getId()).setCategoryId(categoryId).setName(category.getName() + (count + i)).setType(SitePlaceTypeEnum.PACKAGE.getCode()).setOrgCode(site.getOrgCode()).setTenantId(site.getTenantId());
+                        appSitePlace.setSiteId(site.getId()).setCategoryId(categoryId).setName(category.getName() + (sitePlaceNum + i)).setType(SitePlaceTypeEnum.PACKAGE.getCode()).setOrgCode(site.getOrgCode()).setTenantId(site.getTenantId());
                         baseMapper.insert(appSitePlace);
                         List<AppSitePriceRules> appSitePriceRulesList = new ArrayList<>();
                         appSiteCategoryRuleDTO.getAppSiteRuleTimeFormDTOList().forEach(formDTO -> {
@@ -624,11 +624,17 @@ public class AppSitePlaceServiceImpl extends ServiceImpl<AppSitePlaceMapper, App
             // 数据库场地数量    大于   表单场地数量  -----删除多余场地数量
             if (sitePlaceNum > count) {
                 // 减少场地 数量
-                for (int i = 1; i < sitePlaceNum - count; i++) {
+                for (int i = 0; i < sitePlaceNum - count; i++) {
                     // 名称匹配
-                    AppSitePlace appSitePlace = baseMapper.selectOne(Wrappers.<AppSitePlace>lambdaQuery().eq(AppSitePlace::getSiteId, site.getId()).eq(AppSitePlace::getCategoryId, categoryId).eq(AppSitePlace::getName, category.getName() + (sitePlaceNum - i)));
-                    appSitePriceRulesMapper.delete(Wrappers.<AppSitePriceRules>lambdaQuery().eq(AppSitePriceRules::getSitePlaceId, appSitePlace.getId()));
-                    baseMapper.deleteById(appSitePlace);
+                    AppSitePlace appSitePlace = baseMapper.selectOne(Wrappers.<AppSitePlace>lambdaQuery()
+                            .eq(AppSitePlace::getSiteId, site.getId())
+                            .eq(AppSitePlace::getCategoryId, categoryId)
+                            .eq(AppSitePlace::getName, category.getName() + (sitePlaceNum - i)));
+                    log.debug(appSitePlace.getName());
+                    if (ObjectUtil.isNotEmpty(appSitePlace)) {
+                        appSitePriceRulesMapper.delete(Wrappers.<AppSitePriceRules>lambdaQuery().eq(AppSitePriceRules::getSitePlaceId, appSitePlace.getId()));
+                        baseMapper.deleteById(appSitePlace);
+                    }
                 }
             }
         }

+ 28 - 0
national-motion-module-system/national-motion-system-biz/src/main/resources/OP00000003_private_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx
+rIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M
+8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD
+ZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW
+dhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN
+rpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1
+5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4
+mE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7
+qCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK
+NXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X
+3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK
+TPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk
+9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH
+STTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0
+Zr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv
+AtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI
+RgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke
+MzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4
+8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP
+scd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi
+bEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn
+Ll2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz
+NzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j
+Aylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq
+CHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6
+QsFLQgFyXgvDnzr/o+hQJelW
+-----END PRIVATE KEY-----

+ 20 - 0
national-motion-module-system/national-motion-system-biz/src/main/resources/lakala-config.properties

@@ -0,0 +1,20 @@
+#???????
+appid = OP00000003
+#?????
+serial_no = 00dfba8194c41b84cf
+#???
+merchant_no = 822290059430BF9
+#???
+term_no = D9261076
+#?????????
+str = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+#???????
+secret_private_key_name = OP00000003_private_key.pem
+#???????
+secret_public_key_name = lkl-apigw-v2.cer
+#??? ??????V3LosApi???
+channel_id = 25
+#???????(??SAAS)
+tk_client_id = temiao
+#????????(??SAAS)
+tk_client_secret= CwxFxYdz2k7dVEgB

+ 25 - 0
national-motion-module-system/national-motion-system-biz/src/main/resources/lkl-apigw-v2.cer

@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIGAXRTgcMnMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYT
+AkNOMRAwDgYDVQQIDAdCZWlKaW5nMRAwDgYDVQQHDAdCZWlKaW5nMRcwFQYDVQQK
+DA5MYWthbGEgQ28uLEx0ZDEqMCgGA1UEAwwhTGFrYWxhIE9yZ2FuaXphdGlvbiBW
+YWxpZGF0aW9uIENBMB4XDTIwMTAxMDA1MjQxNFoXDTMwMTAwODA1MjQxNFowZTEL
+MAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaUppbmcxEDAOBgNVBAcMB0JlaUppbmcx
+FzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMRkwFwYDVQQDDBBBUElHVy5MQUtBTEEu
+Q09NMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1zHL54HiI8d2sLJ
+lwoQji3/ln0nsvfZ/XVpOjuB+1YR6/0LdxEDMC/hxI6iH2Rm5MjwWz3dmN/6BZeI
+gwGeTOWJUZFARo8UduKrlhC6gWMRpAiiGC8wA8stikc5gYB+UeFVZi/aJ0WN0cpP
+JYCvPBhxhMvhVDnd4hNohnR1L7k0ypuWg0YwGjC25FaNAEFBYP9EYUyCJjE//9Z7
+sMzHR9SJYCqqo6r9bOH9G6sWKuEp+osuAh+kJIxJMHfipw7w3tEcWG0hce9u/el4
+cYJtg8/PPMVoccKmeCzMvarr7jdKP4lenJbtwlgyfs+JgNu60KMUJH8RS72wC9NY
+uFz09wIDAQABo4HVMIHSMIGSBgNVHSMEgYowgYeAFCnH4DkZPR6CZxRn/kIqVsMo
+dJHpoWekZTBjMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpSmluZzEQMA4GA1UE
+BwwHQmVpSmluZzEXMBUGA1UECgwOTGFrYWxhIENvLixMdGQxFzAVBgNVBAMMDkxh
+a2FsYSBSb290IENBggYBaiUALIowHQYDVR0OBBYEFJ2Kx9YZfmWpkKFnC33C0r5D
+K3rFMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUA
+A4IBAQBZoeU0XyH9O0LGF9R+JyGwfU/O5amoB97VeM+5n9v2z8OCiIJ8eXVGKN9L
+tl9QkpTEanYwK30KkpHcJP1xfVkhPi/cCMgfTWQ5eKYC7Zm16zk7n4CP6IIgZIqm
+TVGsIGKk8RzWseyWPB3lfqMDR52V1tdA1S8lJ7a2Xnpt5M2jkDXoArl3SVSwCb4D
+AmThYhak48M++fUJNYII9JBGRdRGbfJ2GSFdPXgesUL2CwlReQwbW4GZkYGOg9LK
+CNPK6XShlNdvgPv0CCR08KCYRwC3HZ0y1F0NjaKzYdGNPrvOq9lA495ONZCvzYDo
+gmsu/kd6eqxTs/JwdaIYr4sCMg8Z
+-----END CERTIFICATE-----

+ 4 - 0
pom.xml

@@ -72,6 +72,9 @@
 		<!-- Log4j2爆雷漏洞 -->
 		<log4j2.version>2.17.0</log4j2.version>
 		<logback.version>1.2.13</logback.version>
+
+		<httpclient.version>4.5.13</httpclient.version>
+		<gson.version>2.10</gson.version>
 	</properties>
 	<modules>
         <module>national-motion-base-core</module>
@@ -435,6 +438,7 @@
 					<source>${java.version}</source>
 					<target>${java.version}</target>
 					<encoding>UTF-8</encoding>
+
 				</configuration>
 			</plugin>
 			<!-- 打包跳过测试 -->