From 9a42cbae72259034a6cbe3a827d168a3a6f65154 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期五, 02 六月 2023 08:34:42 +0800
Subject: [PATCH] 新增加司机提现分账逻辑

---
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java          |   43 
 driver/guns-admin/src/main/resources/redis.properties                                                                  |   18 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DivisionRecordMapper.java               |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/XMLParse.java                   |   71 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverService.java                 |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveUser.java        |   27 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CashWithdrawal.java                   |    5 
 driver/guns-admin/src/main/resources/application.yml                                                                   |   26 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrder.java       |  293 +++++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DivisionRecordMapper.xml        |   19 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Category.java             |   18 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/QueryOrder.java         |   31 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICashWithdrawalService.java         |   19 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WeChatUtil.java                 |  415 +++++++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java     |    3 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveGood.java        |   48 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java                   |  100 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/MessageTemplate.java      |   36 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CashWithdrawalServiceImpl.java |  337 +++++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java        |    1 
 driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java                                   |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WxPKCS7Encoder.java             |   63 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplateKeywords.java  |   26 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CashWithdrawalMapper.xml        |    1 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RechargeRecordMapper.xml        |    1 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java         |  197 ++-
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXBizMsgCrypt.java              |  288 +++++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/KeywordEnum.java          |   17 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Receive.java            |  102 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Code2Session.java         |   33 
 /dev/null                                                                                                              |  120 --
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXCore.java                     |   52 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/RechargeRecord.java                   |    6 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Withdraw.java           |   96 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DivisionRecord.java                   |   73 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDivisionRecordService.java         |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AES.java                        |   72 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PamentOrderUser.java    |   46 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AesException.java               |   59 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/SHA1.java                       |   61 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java  |   14 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/ByteGroup.java                  |   26 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrderGood.java   |   48 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DivisionRecordServiceImpl.java |   15 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/PKCS7Encoder.java               |   67 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Complete.java           |   58 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplatetitles.java    |   26 
 47 files changed, 2,852 insertions(+), 269 deletions(-)

diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java
index aaee0c0..c33c28e 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java
@@ -1,5 +1,6 @@
 package com.supersavedriving.driver.modular.system.api;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.supersavedriving.driver.modular.system.model.Driver;
@@ -7,7 +8,9 @@
 import com.supersavedriving.driver.modular.system.model.Edition;
 import com.supersavedriving.driver.modular.system.model.JoiningRequirements;
 import com.supersavedriving.driver.modular.system.service.*;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.InterfaceResponse;
 import com.supersavedriving.driver.modular.system.util.MallBook.model.Register;
+import com.supersavedriving.driver.modular.system.util.MallBook.util.RSASignature;
 import com.supersavedriving.driver.modular.system.util.MallBook.util.TrhRequest;
 import com.supersavedriving.driver.modular.system.util.PayMoneyUtil;
 import com.supersavedriving.driver.modular.system.util.huawei.OBSUtil;
@@ -586,15 +589,16 @@
     @ResponseBody
     @PostMapping("/api/driver/withdrawCash")
 //    @ServiceLog(name = "司机提现操作", url = "/api/driver/withdrawCash")
-    @ApiOperation(value = "司机提现操作", tags = {"司机端-个人中心"}, notes = "")
+    @ApiOperation(value = "司机提现操作【1.1】", tags = {"司机端-个人中心"}, notes = "")
     @ApiImplicitParams({
             @ApiImplicitParam(value = "类型(1=余额提现,2=佣金提现)", name = "type", required = true, dataType = "int"),
+            @ApiImplicitParam(value = "银行卡id", name = "bankId", required = true, dataType = "int"),
             @ApiImplicitParam(value = "提现金额", name = "money", required = true, dataType = "double"),
             @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
     })
-    public ResponseWarpper withdrawCash(Integer type, Double money){
-        if(null == type){
-            return ResponseWarpper.success(ResultUtil.paranErr("type"));
+    public ResponseWarpper withdrawCash(Integer type, Integer bankId, Double money){
+        if(null == bankId){
+            return ResponseWarpper.success(ResultUtil.paranErr("bankId"));
         }
         if(null == money){
             return ResponseWarpper.success(ResultUtil.paranErr("money"));
@@ -604,7 +608,7 @@
             if(null == uid){
                 return ResponseWarpper.tokenErr();
             }
-            ResultUtil resultUtil = cashWithdrawalService.withdrawCash(uid, type, money);
+            ResultUtil resultUtil = cashWithdrawalService.withdrawCash(uid, type, bankId, money);
             return ResponseWarpper.success(resultUtil);
         }catch (Exception e){
             e.printStackTrace();
@@ -673,6 +677,39 @@
     }
 
 
+
+    @ResponseBody
+    @PostMapping("/base/driver/balanceRecharge1")
+//    @ServiceLog(name = "账户余额充值(跳小程序支付)", url = "/api/driver/balanceRecharge")
+    @ApiOperation(value = "账户余额充值(跳小程序支付)", tags = {"司机端-个人中心"}, notes = "")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "小程序code", name = "jscode", required = true, dataType = "string"),
+            @ApiImplicitParam(value = "司机id", name = "driverId", required = true, dataType = "int"),
+            @ApiImplicitParam(value = "充值金额", name = "amount", required = true, dataType = "double"),
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResponseWarpper balanceRecharge1(String jscode, Integer driverId, Double amount){
+        if(null == jscode){
+            return ResponseWarpper.success(ResultUtil.paranErr("jscode"));
+        }
+        if(null == driverId){
+            return ResponseWarpper.success(ResultUtil.paranErr("driverId"));
+        }
+        if(null == amount){
+            return ResponseWarpper.success(ResultUtil.paranErr("amount"));
+        }
+        try {
+            ResultUtil resultUtil = driverService.balanceRecharge1(driverId, jscode, amount);
+            return ResponseWarpper.success(resultUtil);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseWarpper(500, e.getMessage());
+        }
+    }
+
+
+
+
     /**
      * 账户余额充值支付回调
      * @param request
@@ -680,19 +717,26 @@
      */
     @ResponseBody
     @PostMapping("/base/driver/balanceRechargeCallback")
-    public void balanceRechargeCallback(HttpServletRequest request, HttpServletResponse response){
+    public void balanceRechargeCallback(@RequestBody InterfaceResponse interfaceResponse, HttpServletResponse response){
         try {
-            Map<String, String> map = payMoneyUtil.weixinpayCallback(request);
-            if(null != map){
-                String out_trade_no = map.get("out_trade_no");
-                String transaction_id = map.get("transaction_id");
-                String result = map.get("result");
-                String orderId = out_trade_no.substring(17);
-                driverService.balanceRechargeCallback(out_trade_no, transaction_id);
+            // 验签
+            boolean verify = RSASignature.validate(interfaceResponse.content(), interfaceResponse.getSign());
+            if (verify) {//验签成功业务处理逻辑
+                if(!"0000".equals(interfaceResponse.getCode())){
+                    System.err.println("充值回调异常:" + interfaceResponse.getMsg());
+                    return;
+                }
+                JSONObject jsonObject = JSON.parseObject(interfaceResponse.getResult());
+                String merOrderId = jsonObject.getString("merOrderId");
+                String out_trade_no = jsonObject.getString("parameter1");
+                driverService.balanceRechargeCallback(out_trade_no, merOrderId);
+                response.setStatus(200);
                 PrintWriter out = response.getWriter();
-                out.print(result);
+                out.print("OK");
                 out.flush();
                 out.close();
+            } else {//验签失败业务处理逻辑
+                System.err.println("支付回调验签失败");
             }
         }catch (Exception e){
             e.printStackTrace();
@@ -922,6 +966,10 @@
     }
 
 
+    /**
+     * 注册商户回调
+     * @param jsonObject
+     */
     @ResponseBody
     @PostMapping("/base/driver/microenterpriseCallback")
     public void microenterpriseCallback(@RequestBody JSONObject jsonObject){
@@ -944,7 +992,7 @@
                 return ResponseWarpper.tokenErr();
             }
             DriverBank driverId = driverBankService.selectOne(new EntityWrapper<DriverBank>().eq("driverId", uid));
-            return ResponseWarpper.success(driverId);
+            return ResponseWarpper.success(null == driverId ? new DriverBank() : driverId);
         }catch (Exception e){
             e.printStackTrace();
             return new ResponseWarpper(500, e.getMessage());
@@ -999,4 +1047,26 @@
             return new ResponseWarpper(500, e.getMessage());
         }
     }
+
+
+    /**
+     * 提现分账的回调
+     */
+    @ResponseBody
+    @PostMapping("/base/driver/withdrawCashFZCallback")
+    public void withdrawCashFZCallback(@RequestBody InterfaceResponse interfaceResponse){
+        cashWithdrawalService.withdrawCashFZCallback(interfaceResponse);
+    }
+
+
+
+
+    /**
+     * 提现确认收货后的结算回调
+     */
+    @ResponseBody
+    @PostMapping("/base/driver/withdrawCashCallback")
+    public void withdrawCashCallback(@RequestBody InterfaceResponse interfaceResponse){
+        cashWithdrawalService.withdrawCashCallback(interfaceResponse);
+    }
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DivisionRecordMapper.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DivisionRecordMapper.java
new file mode 100644
index 0000000..3acc2ac
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DivisionRecordMapper.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.driver.modular.system.dao;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.supersavedriving.driver.modular.system.model.DivisionRecord;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 16:41
+ */
+public interface DivisionRecordMapper extends BaseMapper<DivisionRecord> {
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CashWithdrawalMapper.xml b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CashWithdrawalMapper.xml
index 1be7f38..45fedd5 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CashWithdrawalMapper.xml
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CashWithdrawalMapper.xml
@@ -9,6 +9,7 @@
         <result column="userDriverId" property="userDriverId"/>
         <result column="code" property="code"/>
         <result column="businessType" property="businessType"/>
+        <result column="bankId" property="bankId"/>
         <result column="amount" property="amount"/>
         <result column="state" property="state"/>
         <result column="orderNumber" property="orderNumber"/>
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DivisionRecordMapper.xml b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DivisionRecordMapper.xml
new file mode 100644
index 0000000..177816f
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DivisionRecordMapper.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.supersavedriving.driver.modular.system.dao.DivisionRecordMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.supersavedriving.driver.modular.system.model.DivisionRecord">
+        <id column="id" property="id"/>
+        <result column="userType" property="userType"/>
+        <result column="userId" property="userId"/>
+        <result column="orderId" property="orderId"/>
+        <result column="merOrderId" property="merOrderId"/>
+        <result column="sourceType" property="sourceType"/>
+        <result column="amount" property="amount"/>
+        <result column="merchantNumber" property="merchantNumber"/>
+        <result column="state" property="state"/>
+        <result column="payTime" property="payTime"/>
+        <result column="createTime" property="createTime"/>
+    </resultMap>
+</mapper>
\ No newline at end of file
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RechargeRecordMapper.xml b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RechargeRecordMapper.xml
index eeb6b55..6dd9015 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RechargeRecordMapper.xml
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RechargeRecordMapper.xml
@@ -15,5 +15,6 @@
         <result column="orderNumber" property="orderNumber" />
         <result column="createTime" property="createTime" />
         <result column="agentId" property="agentId" />
+        <result column="surplusDividedAmount" property="surplusDividedAmount"/>
     </resultMap>
 </mapper>
\ No newline at end of file
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CashWithdrawal.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CashWithdrawal.java
index 257139a..e4a25b8 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CashWithdrawal.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CashWithdrawal.java
@@ -42,6 +42,11 @@
     @TableField("businessType")
     private Integer businessType;
     /**
+     * 银行卡id
+     */
+    @TableField("bankId")
+    private Integer bankId;
+    /**
      * 提现金额
      */
     @TableField("amount")
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DivisionRecord.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DivisionRecord.java
new file mode 100644
index 0000000..73608b5
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DivisionRecord.java
@@ -0,0 +1,73 @@
+package com.supersavedriving.driver.modular.system.model;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.annotations.TableId;
+import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.enums.IdType;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 15:54
+ */
+@Data
+@TableName("t_division_record")
+public class DivisionRecord {
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+    /**
+     * 用户类型(1=司机,2=代理商,3=平台)
+     */
+    @TableField("userType")
+    private Integer userType;
+    /**
+     * 用户id
+     */
+    @TableField("userId")
+    private Integer userId;
+    /**
+     * 分账业务订单id
+     */
+    @TableField("orderId")
+    private Long orderId;
+    /**
+     * 第三方分账业务订单id
+     */
+    @TableField("merOrderId")
+    private String merOrderId;
+    /**
+     * 业务来源(1=订单业务,2=平台充值)
+     */
+    @TableField("sourceType")
+    private Integer sourceType;
+    /**
+     * 分账金额
+     */
+    @TableField("amount")
+    private Double amount;
+    /**
+     * 收款商户号
+     */
+    @TableField("merchantNumber")
+    private String merchantNumber;
+    /**
+     * 分账状态(1=分账中,2=分账成功)
+     */
+    @TableField("state")
+    private Integer state;
+    /**
+     * 分账时间
+     */
+    @TableField("payTime")
+    private Date payTime;
+    /**
+     * 添加时间
+     */
+    @TableField("createTime")
+    private Date createTime;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/RechargeRecord.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/RechargeRecord.java
index 8ea082c..2330933 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/RechargeRecord.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/RechargeRecord.java
@@ -9,6 +9,7 @@
 import java.util.Date;
 
 /**
+ * 系统充值记录
  * @author zhibing.pu
  * @date 2023/3/21 23:08
  */
@@ -71,4 +72,9 @@
      */
     @TableField("agentId")
     private Integer agentId;
+    /**
+     * 剩余待分账金额
+     */
+    @TableField("surplusDividedAmount")
+    private Double surplusDividedAmount;
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICashWithdrawalService.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICashWithdrawalService.java
index 7b635bf..a066643 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICashWithdrawalService.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICashWithdrawalService.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.service.IService;
 import com.supersavedriving.driver.modular.system.model.CashWithdrawal;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.InterfaceResponse;
 import com.supersavedriving.driver.modular.system.util.ResultUtil;
 
 
@@ -14,10 +15,24 @@
 
     /**
      * 司机提现申请
-     * @param type
+     * @param bankId
      * @param money
      * @return
      * @throws Exception
      */
-    ResultUtil withdrawCash(Integer driverId, Integer type, Double money) throws Exception;
+    ResultUtil withdrawCash(Integer driverId, Integer type, Integer bankId, Double money) throws Exception;
+
+
+    /**
+     * 提现异步回调
+     * @param interfaceResponse
+     */
+    void withdrawCashFZCallback(InterfaceResponse interfaceResponse);
+
+
+    /**
+     * 提现确认收货后的结算回调
+     * @param interfaceResponse
+     */
+    void withdrawCashCallback(InterfaceResponse interfaceResponse);
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDivisionRecordService.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDivisionRecordService.java
new file mode 100644
index 0000000..db15a9e
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDivisionRecordService.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.driver.modular.system.service;
+
+import com.baomidou.mybatisplus.service.IService;
+import com.supersavedriving.driver.modular.system.model.DivisionRecord;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 16:42
+ */
+public interface IDivisionRecordService extends IService<DivisionRecord> {
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverService.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverService.java
index 511d160..d158e44 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverService.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverService.java
@@ -131,6 +131,17 @@
     ResultUtil balanceRecharge(Integer uid, Double amount) throws Exception;
 
 
+
+    /**
+     * 司机账户余额充值
+     * @param driverId
+     * @param amount
+     * @return
+     * @throws Exception
+     */
+    ResultUtil balanceRecharge1(Integer driverId, String jscode, Double amount) throws Exception;
+
+
     /**
      * 支付回调通知处理
      * @param out_trade_no
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CashWithdrawalServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CashWithdrawalServiceImpl.java
index 2c5b893..5d425b6 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CashWithdrawalServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CashWithdrawalServiceImpl.java
@@ -1,22 +1,24 @@
 package com.supersavedriving.driver.modular.system.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
 import com.supersavedriving.driver.core.util.ToolUtil;
 import com.supersavedriving.driver.modular.system.dao.CashWithdrawalMapper;
-import com.supersavedriving.driver.modular.system.model.AccountChangeDetail;
-import com.supersavedriving.driver.modular.system.model.CashWithdrawal;
-import com.supersavedriving.driver.modular.system.model.Driver;
-import com.supersavedriving.driver.modular.system.service.IAccountChangeDetailService;
-import com.supersavedriving.driver.modular.system.service.ICashWithdrawalService;
-import com.supersavedriving.driver.modular.system.service.IDriverService;
+import com.supersavedriving.driver.modular.system.model.*;
+import com.supersavedriving.driver.modular.system.service.*;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.*;
+import com.supersavedriving.driver.modular.system.util.MallBook.util.TrhRequest;
 import com.supersavedriving.driver.modular.system.util.PayMoneyUtil;
 import com.supersavedriving.driver.modular.system.util.ResultUtil;
 import com.supersavedriving.driver.modular.system.util.UUIDUtil;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.util.*;
 
 /**
  * @author zhibing.pu
@@ -34,6 +36,15 @@
     @Autowired
     private IAccountChangeDetailService accountChangeDetailService;
 
+    @Autowired
+    private IRechargeRecordService rechargeRecordService;
+
+    @Autowired
+    private IDivisionRecordService divisionRecordService;
+
+    @Value("${callbackPath}")
+    private String callbackPath;
+
 
 
 
@@ -42,26 +53,30 @@
     /**
      * 司机提现操作
      * @param driverId
-     * @param type
+     * @param bankId
      * @param money
      * @return
      * @throws Exception
      */
     @Override
-    public ResultUtil withdrawCash(Integer driverId, Integer type, Double money) throws Exception {
+    public ResultUtil withdrawCash(Integer driverId, Integer type, Integer bankId, Double money) throws Exception {
         Driver driver = driverService.selectById(driverId);
-        if(type == 1 && (null == driver.getBalance() || driver.getBalance() < money)){
-            return ResultUtil.error("账户余额不足");
+        if(type == 1 && null == driver.getBalance() || driver.getBalance() < money){
+            return ResultUtil.error("余额不足");
         }
-        if(type == 2 && (null == driver.getCommission() || driver.getCommission() < money)){
-            return ResultUtil.error("佣金余额不足");
+        if(type == 2 && null == driver.getCommission() || driver.getCommission() < money){
+            return ResultUtil.error("收入余额不足");
+        }
+        if(ToolUtil.isEmpty(driver.getMerchantNumber())){
+            return ResultUtil.error("请先注册商户号");
         }
 
         CashWithdrawal cashWithdrawal = new CashWithdrawal();
         cashWithdrawal.setType(2);
         cashWithdrawal.setUserDriverId(driverId);
         cashWithdrawal.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
-        cashWithdrawal.setBusinessType(type == 1 ? 12 : 11);
+        cashWithdrawal.setBusinessType(type == 2 ? 11 : 12);
+        cashWithdrawal.setBankId(bankId);
         cashWithdrawal.setAmount(money);
         cashWithdrawal.setState(1);
         cashWithdrawal.setCreateTime(new Date());
@@ -74,32 +89,294 @@
         accountChangeDetail.setUserId(driver.getId());
         accountChangeDetail.setType(1);
         accountChangeDetail.setChangeType(type == 1 ? 4 : 6);
+        accountChangeDetail.setOldData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
         if(type == 1){
-            accountChangeDetail.setOldData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
             driver.setBalance(driver.getBalance() - money);
-            accountChangeDetail.setNewData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
-            accountChangeDetail.setExplain("账户余额提现");
-        }
-        if(type == 2){
-            accountChangeDetail.setOldData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
+        }else{
             driver.setCommission(driver.getCommission() - money);
-            accountChangeDetail.setNewData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
-            accountChangeDetail.setExplain("佣金余额提现");
         }
+        accountChangeDetail.setNewData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
+        accountChangeDetail.setExplain(type == 1 ? "账户余额提现" : "佣金余额提现");
         driverService.updateById(driver);
         accountChangeDetailService.saveData(accountChangeDetail);
 
 
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
-        String outDetailNo = sdf.format(new Date()) + cashWithdrawal.getId();
-        String s = payMoneyUtil.weixinTransferMoney(outDetailNo, money, driver.getOpenid(), driver.getName(), "【超省新代驾】提现付款!");
-        if(ToolUtil.isEmpty(s)){
-            return ResultUtil.error("提现异常,请联系管理员");
+        if(type == 1){//余额提现,调用分账接口 -->确认收货--->提现
+            fenzhang(driver, money, cashWithdrawal, 1);
+        }else{//佣金提现,调用充值接口数据进行分账
+            fenzhang(driver, money, cashWithdrawal, 2);
         }
-        cashWithdrawal.setState(2);
-        cashWithdrawal.setOrderNumber(s);
-        this.updateById(cashWithdrawal);
+
+//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+//        String outDetailNo = sdf.format(new Date()) + cashWithdrawal.getId();
+//
+//        String s = payMoneyUtil.weixinTransferMoney(outDetailNo, money, driver.getOpenid(), driver.getName(), "【超省新代驾】提现付款!");
+//        if(ToolUtil.isEmpty(s)){
+//            return ResultUtil.error("提现异常,请联系管理员");
+//        }
+//        cashWithdrawal.setState(2);
+//        cashWithdrawal.setOrderNumber(s);
+//        this.updateById(cashWithdrawal);
         return ResultUtil.success();
     }
 
+
+    /**
+     * 司机提现,现将支付的订单进行分账
+     * @param driver
+     * @param amount
+     * @param cashWithdrawal
+     * @return
+     */
+    public ResultUtil fenzhang(Driver driver, Double amount, CashWithdrawal cashWithdrawal, Integer payType){
+        List<RechargeRecord> rechargeRecords = new ArrayList<>();
+        if(payType == 1){//司机充值
+            rechargeRecords = rechargeRecordService.selectList(new EntityWrapper<RechargeRecord>().eq("type", 2)
+                    .eq("userId", driver.getId()).eq("payType", 1).eq("payStatus", 2).gt("surplusDividedAmount", 0));
+        }
+        if(payType == 2){//平台充值(补贴金额)
+            rechargeRecords = rechargeRecordService.selectList(new EntityWrapper<RechargeRecord>()
+                   .eq("payType", 2).eq("payStatus", 2).gt("surplusDividedAmount", 0));
+        }
+        for (RechargeRecord rechargeRecord : rechargeRecords) {
+            Double surplusDividedAmount = rechargeRecord.getSurplusDividedAmount();
+            if(surplusDividedAmount.compareTo(amount) >= 0){//够分账
+                DivisionRecord divisionRecord = new DivisionRecord();
+                divisionRecord.setUserType(1);
+                divisionRecord.setUserId(driver.getId());
+                divisionRecord.setOrderId(rechargeRecord.getId().longValue());
+                divisionRecord.setSourceType(payType == 1 ? 3 : 2);
+                divisionRecord.setAmount(surplusDividedAmount);
+                divisionRecord.setMerchantNumber(driver.getMerchantNumber());
+                divisionRecord.setState(1);
+                divisionRecord.setCreateTime(new Date());
+                divisionRecordService.insert(divisionRecord);
+
+                Complete complete = new Complete();
+                complete.setOriginalMerOrderId(rechargeRecord.getOrderNumber());
+                complete.setNotifyUrl(callbackPath + "/base/driver/withdrawCashFZCallback");
+                complete.setParameter1(divisionRecord.getId().toString());
+                complete.setParameter2(rechargeRecord.getId() + "_" + cashWithdrawal.getId());
+                //分账方列表
+                List<PamentOrderUser> splitList = new ArrayList<>();
+                PamentOrderUser pamentOrderUser = new PamentOrderUser();
+                pamentOrderUser.setSplitUserId(driver.getMerchantNumber());
+                pamentOrderUser.setSplitAmount(amount.toString());
+                pamentOrderUser.setSplitType("1");
+                splitList.add(pamentOrderUser);
+                complete.setSplitList(splitList);
+                TrhRequest<Complete> request = new TrhRequest();
+                InterfaceResponse execute = request.execute(complete, Complete.SERVICE_CODE);//分账操作
+                if("0000".equals(execute.getCode())){
+                    JSONObject jsonObject = JSON.parseObject(execute.getResult());
+                    Integer status = jsonObject.getInteger("status");//0:待处理 1:成功 2:失败
+                    String merOrderId = jsonObject.getString("merOrderId");
+                    if(2 == status){
+                        System.err.println("司机提现分账失败:" + execute.getMsg());
+                        break;
+                    }
+                    if(1 == status){
+                        divisionRecord.setMerOrderId(merOrderId);
+                        divisionRecord.setPayTime(new Date());
+                        divisionRecord.setState(2);
+                        divisionRecordService.updateById(divisionRecord);
+                        //间隔10秒开始调用确认收货后开始提现
+
+                        new Timer().schedule(new TimerTask() {//确认收货和提现
+                            @Override
+                            public void run() {
+                                confirmReceipt(driver, rechargeRecord, divisionRecord, cashWithdrawal);
+                            }
+                        }, 15000);
+                    }
+                }else{
+                    System.err.println("司机提现分账异常:" + execute.getMsg());
+                }
+                break;
+            }else{//不够分账
+                DivisionRecord divisionRecord = new DivisionRecord();
+                divisionRecord.setUserType(1);
+                divisionRecord.setUserId(driver.getId());
+                divisionRecord.setOrderId(rechargeRecord.getId().longValue());
+                divisionRecord.setSourceType(payType == 1 ? 3 : 2);
+                divisionRecord.setAmount(surplusDividedAmount);
+                divisionRecord.setMerchantNumber(driver.getMerchantNumber());
+                divisionRecord.setState(1);
+                divisionRecord.setCreateTime(new Date());
+                divisionRecordService.insert(divisionRecord);
+
+                Complete complete = new Complete();
+                complete.setOriginalMerOrderId(rechargeRecord.getOrderNumber());
+                complete.setNotifyUrl(callbackPath + "/base/driver/withdrawCashFZCallback");
+                complete.setParameter1(divisionRecord.getId().toString());
+                //分账方列表
+                List<PamentOrderUser> splitList = new ArrayList<>();
+                PamentOrderUser pamentOrderUser = new PamentOrderUser();
+                pamentOrderUser.setSplitUserId(driver.getMerchantNumber());
+                pamentOrderUser.setSplitAmount(surplusDividedAmount.toString());
+                pamentOrderUser.setSplitType("1");
+                splitList.add(pamentOrderUser);
+                complete.setSplitList(splitList);
+                TrhRequest<Complete> request = new TrhRequest();
+                InterfaceResponse execute = request.execute(complete, Complete.SERVICE_CODE);//分账操作
+                if("0000".equals(execute.getCode())){
+                    JSONObject jsonObject = JSON.parseObject(execute.getResult());
+                    Integer status = jsonObject.getInteger("status");//0:待处理 1:成功 2:失败
+                    String merOrderId = jsonObject.getString("merOrderId");
+                    if(2 == status){
+                        System.err.println("司机提现分账失败:" + execute.getMsg());
+                        break;
+                    }
+                    if(1 == status){
+                        divisionRecord.setMerOrderId(merOrderId);
+                        divisionRecord.setPayTime(new Date());
+                        divisionRecord.setState(2);
+                        divisionRecordService.updateById(divisionRecord);
+
+                        //间隔10秒开始调用确认收货后开始提现
+                        new Timer().schedule(new TimerTask() {//确认收货和提现
+                            @Override
+                            public void run() {
+                                confirmReceipt(driver, rechargeRecord, divisionRecord, cashWithdrawal);
+                            }
+                        }, 15000);
+                    }
+                }else{
+                    System.err.println("司机提现分账异常:" + execute.getMsg());
+                    break;
+                }
+                amount -= surplusDividedAmount;
+            }
+        }
+        return ResultUtil.success();
+    }
+
+
+    /**
+     * 分账后的确认收货和提现操作
+     * @param driver
+     * @param rechargeRecord
+     * @param divisionRecord
+     * @param cashWithdrawal
+     */
+    public void confirmReceipt(Driver driver, RechargeRecord rechargeRecord, DivisionRecord divisionRecord, CashWithdrawal cashWithdrawal){
+        Receive receive = new Receive();
+        receive.setOriginalMerOrderId(rechargeRecord.getOrderNumber());
+        receive.setAsynMerOrderId(divisionRecord.getMerOrderId());
+        receive.setRcvAmount(divisionRecord.getAmount().toString());
+        List<ReceiveUser> splitList = new ArrayList<>();
+        ReceiveUser receiveUser = new ReceiveUser();
+        receiveUser.setSplitUserId(driver.getMerchantNumber());
+        receiveUser.setRcvSplitAmount(divisionRecord.getAmount().toString());
+        splitList.add(receiveUser);
+        receive.setSplitList(splitList);
+        TrhRequest<Receive> request = new TrhRequest();
+        InterfaceResponse execute1 = request.execute(receive, Receive.SERVICE_CODE);//确认收货
+        if("0000".equals(execute1.getCode())){
+            JSONObject jsonObject = JSON.parseObject(execute1.getResult());
+            String merOrderId = jsonObject.getString("merOrderId");
+            if(ToolUtil.isNotEmpty(merOrderId)){
+                Withdraw withdraw = new Withdraw();
+                withdraw.setUserId(driver.getMerchantNumber());
+                withdraw.setAmount(divisionRecord.getAmount().toString());
+                withdraw.setOrderName("账户余额提现");
+                withdraw.setRemark("账户余额提现");
+                withdraw.setNotifyUrl(callbackPath + "/base/driver/withdrawCashCallback");
+                withdraw.setParameter1(cashWithdrawal.getId().toString());
+                TrhRequest<Withdraw> request1 = new TrhRequest();
+                InterfaceResponse execute = request1.execute(withdraw, Withdraw.SERVICE_CODE);//结算(提现)
+                if("0000".equals(execute.getCode())){
+                    JSONObject jsonObject1 = JSON.parseObject(execute.getResult());
+                    String merOrderId1 = jsonObject1.getString("merOrderId");
+                    Integer status = jsonObject1.getInteger("status");//0:待处理;1:成功;2:失败
+                    if(1 == status){
+                        cashWithdrawal.setOrderNumber(merOrderId1);
+                        cashWithdrawal.setState(2);
+                        this.updateById(cashWithdrawal);
+                    }
+                    if(2 == status){
+                        System.err.println("结算接口异常【提现】:" + jsonObject1.getString("statusMsg"));
+                    }
+                }else{
+                    System.err.println("结算接口异常【提现】:" + execute.getMsg());
+                }
+            }
+        }else{
+            System.err.println("分账确认收货异常【提现】:" + execute1.getMsg());
+        }
+    }
+
+
+
+
+
+    /**
+     * 提现分账的异步回调
+     * @param interfaceResponse
+     */
+    @Override
+    public void withdrawCashFZCallback(InterfaceResponse interfaceResponse) {
+        if("0000".equals(interfaceResponse.getCode())){
+            JSONObject jsonObject = JSON.parseObject(interfaceResponse.getResult());
+            Integer status = jsonObject.getInteger("status");//0:待处理 1:成功 2:失败
+            String merOrderId = jsonObject.getString("merOrderId");
+            if(2 == status){
+                System.err.println("司机提现分账失败:" + interfaceResponse.getMsg());
+                return;
+            }
+            if(1 == status){
+                String parameter1 = jsonObject.getString("parameter1");
+                String parameter2 = jsonObject.getString("parameter2");
+                DivisionRecord divisionRecord = divisionRecordService.selectById(parameter1);
+                divisionRecord.setMerOrderId(merOrderId);
+                divisionRecord.setPayTime(new Date());
+                divisionRecord.setState(2);
+                divisionRecordService.updateById(divisionRecord);
+                Driver driver = driverService.selectById(divisionRecord.getUserId());
+                String[] s = parameter2.split("_");
+                RechargeRecord rechargeRecord = rechargeRecordService.selectById(s[0]);
+                CashWithdrawal cashWithdrawal = this.selectById(s[1]);
+
+                //间隔10秒开始调用确认收货后开始提现
+                new Timer().schedule(new TimerTask() {//确认收货和提现
+                    @Override
+                    public void run() {
+                        confirmReceipt(driver, rechargeRecord, divisionRecord, cashWithdrawal);
+                    }
+                }, 15000);
+            }
+        }else{
+            System.err.println("司机提现分账异常:" + interfaceResponse.getMsg());
+        }
+    }
+
+
+    /**
+     * 提现确认收货后的结算回调
+     * @param interfaceResponse
+     */
+    @Override
+    public void withdrawCashCallback(InterfaceResponse interfaceResponse) {
+        if("0000".equals(interfaceResponse.getCode())){
+            JSONObject jsonObject1 = JSON.parseObject(interfaceResponse.getResult());
+            String merOrderId1 = jsonObject1.getString("merOrderId");
+            Integer status = jsonObject1.getInteger("status");//0:待处理;1:成功;2:失败
+            if(1 == status){
+                String parameter1 = jsonObject1.getString("parameter1");
+                CashWithdrawal cashWithdrawal = this.selectById(parameter1);
+                cashWithdrawal.setOrderNumber(merOrderId1);
+                cashWithdrawal.setState(2);
+                this.updateById(cashWithdrawal);
+            }
+            if(2 == status){
+                System.err.println("结算接口异常【提现】:" + jsonObject1.getString("statusMsg"));
+            }
+        }else{
+            System.err.println("结算接口异常【提现】:" + interfaceResponse.getMsg());
+        }
+    }
+
+
+
+
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DivisionRecordServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DivisionRecordServiceImpl.java
new file mode 100644
index 0000000..c8de1f9
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DivisionRecordServiceImpl.java
@@ -0,0 +1,15 @@
+package com.supersavedriving.driver.modular.system.service.impl;
+
+import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import com.supersavedriving.driver.modular.system.dao.DivisionRecordMapper;
+import com.supersavedriving.driver.modular.system.model.DivisionRecord;
+import com.supersavedriving.driver.modular.system.service.IDivisionRecordService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 16:42
+ */
+@Service
+public class DivisionRecordServiceImpl extends ServiceImpl<DivisionRecordMapper, DivisionRecord> implements IDivisionRecordService {
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java
index 731626c..d0e7e06 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java
@@ -13,11 +13,12 @@
 import com.supersavedriving.driver.modular.system.service.*;
 import com.supersavedriving.driver.modular.system.dao.DriverMapper;
 import com.supersavedriving.driver.modular.system.util.*;
-import com.supersavedriving.driver.modular.system.util.MallBook.model.InterfaceResponse;
-import com.supersavedriving.driver.modular.system.util.MallBook.model.Register;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.*;
 import com.supersavedriving.driver.modular.system.util.MallBook.util.TrhRequest;
 import com.supersavedriving.driver.modular.system.util.mongodb.model.Location;
 import com.supersavedriving.driver.modular.system.util.rongyun.RongYunUtil;
+import com.supersavedriving.driver.modular.system.util.weChat.WeChatUtil;
+import com.supersavedriving.driver.modular.system.util.weChat.model.Code2Session;
 import com.supersavedriving.driver.modular.system.warpper.*;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.authc.UsernamePasswordToken;
@@ -40,6 +41,7 @@
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
@@ -101,8 +103,17 @@
     @Autowired
     private PushUtil pushUtil;
 
+    @Autowired
+    private WeChatUtil weChatUtil;
+
     @Value("${callbackPath}")
     private String callbackPath;
+
+    @Value("${wx.appletsAppid}")
+    private String appletsAppid;
+
+    @Value("${alipay.appid}")
+    private String appid;
 
 
 
@@ -678,84 +689,131 @@
         rechargeRecord.setAgentId(driver.getAgentId());
         rechargeRecordService.insert(rechargeRecord);
 
+        PaymentOrder paymentOrder = new PaymentOrder();
+        paymentOrder.setBizOrderId(out_trade_no);
+        paymentOrder.setAmount(String.valueOf(Double.valueOf(amount * 100).intValue()));
+        paymentOrder.setOrderName("账户充值");
+        paymentOrder.setPayType("WX_MINI");
+        paymentOrder.setTransferType("0");
+        paymentOrder.setAsynSplitFlag("1");
+        paymentOrder.setAppid(appletsAppid);
+        paymentOrder.setOpenid(driver.getOpenid());
+        paymentOrder.setTerminalIp(InetAddress.getLocalHost().getHostAddress());
+        List<PaymentOrderGood> goodsDetail = new ArrayList<>();
+        PaymentOrderGood paymentOrderGood = new PaymentOrderGood();
+        paymentOrderGood.setGoodsName("充值");
+        goodsDetail.add(paymentOrderGood);
+        paymentOrder.setGoodsDetail(goodsDetail);
+        paymentOrder.setFrontUrl("http://www.baidu.com");//前端回调地址
+        paymentOrder.setNotifyUrl(callbackPath + "/base/driver/balanceRechargeCallback");
+        paymentOrder.setParameter1(out_trade_no);
 
-        ResultUtil weixinpay = payMoneyUtil.weixinpay("余额充值", "", out_trade_no, amount.toString(), "/base/driver/balanceRechargeCallback", "APP");
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    int num = 1;
-                    int wait = 0;
-                    while (num <= 10){
-                        int min = 5000;
-                        wait += (min * num);
-                        RechargeRecord rechargeRecord1 = rechargeRecordService.selectOne(new EntityWrapper<RechargeRecord>().eq("code", out_trade_no));
-                        if(rechargeRecord1.getPayStatus() != 1){
-                            return;
-                        }
-
-                        /**
-                         * SUCCESS--支付成功
-                         * REFUND--转入退款
-                         * NOTPAY--未支付
-                         * CLOSED--已关闭
-                         * REVOKED--已撤销(刷卡支付)
-                         * USERPAYING--用户支付中
-                         * PAYERROR--支付失败(其他原因,如银行返回失败)
-                         * ACCEPT--已接收,等待扣款
-                         */
-                        ResultUtil<Map<String, String>> resultUtil = payMoneyUtil.queryWXOrder(out_trade_no, "");
-                        if(resultUtil.getCode() == 200){
-                            Map<String, String> map = resultUtil.getData();
-                            String trade_type = map.get("trade_type");
-                            String trade_state = map.get("trade_state");
-                            String transaction_id = map.get("transaction_id");
-                            if("REFUND".equals(trade_state) || "NOTPAY".equals(trade_state) || "CLOSED".equals(trade_state) || "REVOKED".equals(trade_state) || "PAYERROR".equals(trade_state)){
-                                rechargeRecordService.deleteById(rechargeRecord1.getId());
+        TrhRequest<PaymentOrder> request = new TrhRequest();
+        InterfaceResponse execute = request.execute(paymentOrder, PaymentOrder.SERVICE_CODE);
+        if(!"0000".equals(execute.getCode())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        String payCode = jsonObject.getString("payCode");
+        if(ToolUtil.isNotEmpty(payCode)){
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        int num = 1;
+                        int wait = 0;
+                        while (num <= 10){
+                            int min = 5000;
+                            wait += (min * num);
+                            RechargeRecord rechargeRecord1 = rechargeRecordService.selectOne(new EntityWrapper<RechargeRecord>().eq("code", out_trade_no));
+                            if(rechargeRecord1.getPayStatus() != 1){
                                 return;
                             }
-                            if("SUCCESS".equals(trade_state)){
-                                Driver driver1 = DriverServiceImpl.this.selectById(uid);
-                                AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
-                                accountChangeDetail.setUserType(2);
-                                accountChangeDetail.setUserId(uid);
-                                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
-                                accountChangeDetail.setChangeType(3);
-                                accountChangeDetail.setType(1);
-                                accountChangeDetail.setCreateTime(new Date());
-                                accountChangeDetail.setExplain("余额充值");
-                                accountChangeDetail.setOldData(driver1.getBalance() + driver1.getBackgroundBalance() + driver1.getCouponBalance() + driver1.getCommission());
-                                driver1.setBalance(driver1.getBalance() + amount);
-                                accountChangeDetail.setNewData(driver1.getBalance() + driver1.getBackgroundBalance() + driver1.getCouponBalance() + driver1.getCommission());
-                                DriverServiceImpl.this.updateById(driver1);
-                                accountChangeDetailService.saveData(accountChangeDetail);
+                            QueryOrder queryOrder = new QueryOrder();
+                            /**
+                             * 原请求订单号(必填)  字段长度最长:32位
+                             */
+                            queryOrder.setOriginalMerOrderId(out_trade_no);
+                            /**
+                             * 1:支付查询 2:退款查询 3:确认收货查询 4:结算查询 5:充值查询 6:转账查询 7:异步分账查询(必填)  字段长度最长:1位
+                             */
+                            queryOrder.setQueryType("1");
+                            TrhRequest<QueryOrder> request = new TrhRequest();
+                            InterfaceResponse execute1 = request.execute(queryOrder, QueryOrder.SERVICE_CODE);
+                            if("0000".equals(execute1.getCode())){
+                                JSONObject jsonObject1 = JSON.parseObject(execute1.getResult());
+                                String status1 = jsonObject1.getString("status");
+                                if("0".equals(status1)){//待处理
+                                    Thread.sleep(wait);
+                                    num++;
+                                }
+                                if("1".equals(status1)){//成功
+                                    String merOrderId = jsonObject1.getString("merOrderId");
+                                    Driver driver1 = DriverServiceImpl.this.selectById(rechargeRecord1.getUserId());
+                                    AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setUserType(2);
+                                    accountChangeDetail.setUserId(driver1.getId());
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
+                                    accountChangeDetail.setChangeType(3);
+                                    accountChangeDetail.setType(1);
+                                    accountChangeDetail.setCreateTime(new Date());
+                                    accountChangeDetail.setExplain("账户充值");
+                                    accountChangeDetail.setOldData(driver1.getBalance() + driver1.getBackgroundBalance() + driver1.getCouponBalance() + driver1.getCommission());
+                                    driver1.setBalance(driver1.getBalance() + rechargeRecord1.getAmount());
+                                    accountChangeDetail.setNewData(driver1.getBalance() + driver1.getBackgroundBalance() + driver1.getCouponBalance() + driver1.getCommission());
+                                    DriverServiceImpl.this.updateById(driver1);
+                                    accountChangeDetailService.saveData(accountChangeDetail);
 
-                                rechargeRecord1.setPayTime(new Date());
-                                rechargeRecord1.setPayStatus(2);
-                                rechargeRecord1.setOrderNumber(transaction_id);
-                                rechargeRecordService.updateById(rechargeRecord1);
-                                return;
-                            }
-                            if("USERPAYING".equals(trade_state) || "ACCEPT".equals(trade_state)){
+                                    rechargeRecord1.setPayTime(new Date());
+                                    rechargeRecord1.setPayStatus(2);
+                                    rechargeRecord1.setOrderNumber(merOrderId);
+                                    rechargeRecord1.setSurplusDividedAmount(rechargeRecord1.getAmount());
+                                    rechargeRecordService.updateById(rechargeRecord1);
+                                    break;
+                                }
+                                if("2".equals(status1) || 10 == num){//失败
+                                    rechargeRecordService.deleteById(rechargeRecord1.getId());
+                                    break;
+                                }
+                            }else{
                                 Thread.sleep(wait);
                                 num++;
                             }
-                        }else{
-                            Thread.sleep(wait);
-                            num++;
                         }
-                        if(10 == num){
-                            rechargeRecordService.deleteById(rechargeRecord1.getId());
-                        }
+                    }catch (Exception e){
+                        e.printStackTrace();
                     }
-                }catch (Exception e){
-                    e.printStackTrace();
                 }
-            }
-        }).start();
-        return weixinpay;
+            }).start();
+        }
+        return ResultUtil.success(payCode);
     }
 
+
+    /**
+     * 司机端跳小程序支付
+     * @param driverId
+     * @param jscode
+     * @param amount
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil balanceRecharge1(Integer driverId, String jscode, Double amount) throws Exception {
+        Code2Session code2Session = weChatUtil.code2Session(jscode);
+        if(null != code2Session.getErrcode() && code2Session.getErrcode() != 0){
+            return ResultUtil.error(code2Session.getErrmsg());
+        }
+        String openid = code2Session.getOpenid();
+        Driver driver = this.selectById(driverId);
+        driver.setOpenid(openid);
+        this.updateById(driver);
+        return balanceRecharge(driverId, amount);
+    }
 
     /**
      * 充值回调通知逻辑处理
@@ -776,7 +834,7 @@
         accountChangeDetail.setChangeType(3);
         accountChangeDetail.setType(1);
         accountChangeDetail.setCreateTime(new Date());
-        accountChangeDetail.setExplain("余额充值");
+        accountChangeDetail.setExplain("账户充值");
         accountChangeDetail.setOldData(driver1.getBalance() + driver1.getBackgroundBalance() + driver1.getCouponBalance() + driver1.getCommission());
         driver1.setBalance(driver1.getBalance() + rechargeRecord1.getAmount());
         accountChangeDetail.setNewData(driver1.getBalance() + driver1.getBackgroundBalance() + driver1.getCouponBalance() + driver1.getCommission());
@@ -786,6 +844,7 @@
         rechargeRecord1.setPayTime(new Date());
         rechargeRecord1.setPayStatus(2);
         rechargeRecord1.setOrderNumber(transaction_id);
+        rechargeRecord1.setSurplusDividedAmount(rechargeRecord1.getAmount());
         rechargeRecordService.updateById(rechargeRecord1);
     }
 
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java
index 8484b7d..c15dbd5 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java
@@ -53,6 +53,9 @@
     @Override
     public ResultUtil driverWork(Integer driverId) throws Exception {
         Driver driver = driverService.selectById(driverId);
+        if(ToolUtil.isEmpty(driver.getMerchantNumber())){
+            return ResultUtil.error("请先注册商户号");
+        }
         SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 6));
         Double num1 = JSON.parseObject(systemConfig.getContent()).getDouble("num1");
         if(driver.getBalance() == null || driver.getBalance().compareTo(num1) < 0){
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java
index 707e8a4..d3d7032 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java
@@ -48,6 +48,10 @@
     @Override
     public void saveOrderPosition(DriverPositionWarpper driverPositionWarpper) throws Exception {
         Integer orderId = driverPositionWarpper.getOrderId();
+        Order order = orderService.selectById(orderId);
+        if(order.getState() != 105){
+            return;
+        }
         Integer orderType = driverPositionWarpper.getOrderType();
         File file = new File(filePath + orderId + ".json");
         if(!file.exists()){
@@ -59,14 +63,14 @@
             OrderPositionWarpper orderPositionWarpper = orderPositionWarppers.get(orderPositionWarppers.size() - 1);
             saveOrderMileage(driverPositionWarpper, orderPositionWarpper);
         }
-        //大于50米才存储有效定位数据
+        //大于100米才存储有效定位数据
         if(orderPositionWarppers.size() > 0){
             OrderPositionWarpper orderPositionWarpper1 = orderPositionWarppers.get(orderPositionWarppers.size() - 1);
             String fromLonLat = driverPositionWarpper.getLon() + "," + driverPositionWarpper.getLat();
             String toLonLat = orderPositionWarpper1.getLon() + "," + orderPositionWarpper1.getLat();
             Map<String, Double> distance = GeodesyUtil.getDistance(fromLonLat, toLonLat);
             Double wgs84 = distance.get("WGS84");
-            if(wgs84 >= 50){
+            if(wgs84 >= 100){
                 OrderPositionWarpper orderPositionWarpper = new OrderPositionWarpper();
                 BeanUtils.copyProperties(driverPositionWarpper, orderPositionWarpper);
                 orderPositionWarpper.setInsertTime(new Date());
@@ -99,7 +103,7 @@
         Order order = orderService.selectById(driverPositionWarpper.getOrderId());
         Double wgs84 = distance.get("WGS84");
         Integer num = map.get(order.getId().toString());
-        if(50 < wgs84){
+        if(100 < wgs84){
             order.setActualMileage(order.getActualMileage() + wgs84.intValue());
             orderService.updateById(order);
             map.put(order.getId().toString(), 0);
@@ -115,7 +119,7 @@
                 }
             }
         }
-        if(50 >= wgs84 && 12 <= (null == num ? 0 : num)){//1分钟(5秒上传一次数据)
+        if(100 >= wgs84 && 12 <= (null == num ? 0 : num)){//1分钟(5秒上传一次数据)
             Integer integer = map.get(order.getId().toString());
             map.put(order.getId().toString(), null == integer ? 0 : integer++);
             //进入等待状态
@@ -128,7 +132,7 @@
                 e.printStackTrace();
             }
         }
-        if(50 >= wgs84 && 12 > (null == num ? 0 : num)){
+        if(100 >= wgs84 && 12 > (null == num ? 0 : num)){
             Integer integer = map.get(order.getId().toString());
             map.put(order.getId().toString(), null == integer ? 0 : integer++);
         }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
index 583abd5..47b1267 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
@@ -1158,6 +1158,8 @@
                 order.setCouponId(coupon.getId());
                 order.setDiscountAmount(coupon.getCouponPreferentialAmount());
                 order.setPayMoney(order.getOrderMoney() - coupon.getCouponPreferentialAmount());
+            }else{
+                order.setPayMoney(order.getOrderMoney());
             }
         }
 
@@ -1169,9 +1171,6 @@
                     userToCoupon.setValidCount(userToCoupon.getValidCount() - 1);
                     userToCouponService.updateById(userToCoupon);
                     Coupon coupon = couponService.selectById(userToCoupon.getCouponId());
-                    order.setPayMoney(order.getPayMoney() - coupon.getCouponPreferentialAmount());
-                    order.setCouponId(coupon.getId());
-                    order.setDiscountedPrice(coupon.getCouponPreferentialAmount());
 
                     Driver driver = driverService.selectById(order.getDriverId());
                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
@@ -1193,7 +1192,7 @@
         }
         this.updateById(order);
 
-        if(state == 108){//计算抽成
+        if(payType == 2 && state == 108){//计算抽成
             saveRevenue(order);
         }
 
@@ -1628,6 +1627,40 @@
      */
     @Override
     public void completeCollection() {
-        this.baseMapper.completeCollection();
+        List<Order> orders = this.selectList(new EntityWrapper<Order>().eq("state", 107).eq("status", 1).eq("payType", 3));
+        for (Order order : orders) {
+            order.setPayTime(new Date());
+            if(null != order.getCouponId()){
+                UserToCoupon userToCoupon = userToCouponService.selectById(order.getCouponId());
+                if(userToCoupon.getValidCount() > 0){
+                    userToCoupon.setValidCount(userToCoupon.getValidCount() - 1);
+                    userToCouponService.updateById(userToCoupon);
+                    Coupon coupon = couponService.selectById(userToCoupon.getCouponId());
+
+                    Driver driver = driverService.selectById(order.getDriverId());
+                    AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
+                    accountChangeDetail.setUserType(2);
+                    accountChangeDetail.setUserId(order.getDriverId());
+                    accountChangeDetail.setCreateTime(new Date());
+                    accountChangeDetail.setOldData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
+                    accountChangeDetail.setType(1);
+                    accountChangeDetail.setChangeType(7);
+                    accountChangeDetail.setOrderId(order.getId());
+                    accountChangeDetail.setExplain("优惠券收入");
+                    driver.setCouponBalance(driver.getCouponBalance() + coupon.getCouponPreferentialAmount());
+                    accountChangeDetail.setNewData(driver.getBalance() + driver.getBackgroundBalance() + driver.getCouponBalance() + driver.getCommission());
+                    driverService.updateById(driver);
+                    accountChangeDetailService.insert(accountChangeDetail);
+                }
+            }
+            this.updateById(order);
+
+            try {
+                saveRevenue(order);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
     }
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java
index 591cfc2..0bca408 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java
@@ -66,6 +66,7 @@
             CommissionListWarpper commissionListWarpper = new CommissionListWarpper();
             commissionListWarpper.setCreateTime(revenue.getCreateTime().getTime());
             commissionListWarpper.setAmount(revenue.getAmount());
+            commissionListWarpper.setUserType(2);
             Order order = orderService.selectById(revenue.getOrderId());
             if(null != order.getUserId()){
                 AppUser appUser = appUserService.selectById(order.getUserId());
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Complete.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Complete.java
new file mode 100644
index 0000000..ec88592
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Complete.java
@@ -0,0 +1,58 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+import java.util.List;
+
+public class Complete {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "complete";
+    //原支付请求订单号
+    private String originalMerOrderId;
+    //分账方列表
+    private List<PamentOrderUser> splitList;
+    //后台回调地址
+    private String notifyUrl;
+    //自定义参数1
+    private String parameter1;
+    //自定义参数2
+    private String parameter2;
+
+    public String getOriginalMerOrderId() {
+        return originalMerOrderId;
+    }
+
+    public void setOriginalMerOrderId(String originalMerOrderId) {
+        this.originalMerOrderId = originalMerOrderId;
+    }
+
+    public List<PamentOrderUser> getSplitList() {
+        return splitList;
+    }
+
+    public void setSplitList(List<PamentOrderUser> splitList) {
+        this.splitList = splitList;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+
+    public String getParameter1() {
+        return parameter1;
+    }
+
+    public void setParameter1(String parameter1) {
+        this.parameter1 = parameter1;
+    }
+
+    public String getParameter2() {
+        return parameter2;
+    }
+
+    public void setParameter2(String parameter2) {
+        this.parameter2 = parameter2;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PamentOrderUser.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PamentOrderUser.java
new file mode 100644
index 0000000..5ead594
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PamentOrderUser.java
@@ -0,0 +1,46 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class PamentOrderUser {
+
+    /**
+     * 分账方会员ID(必填)
+     */
+    private  String splitUserId;
+
+    /**
+     * 分账金额(必填)
+     */
+    private String splitAmount;
+
+    /**
+     * 分账类型(必填)
+     * 0:收单金额(收款人)
+     * 1:分账金额
+     * 2:佣金
+     */
+    private String splitType;
+
+    public String getSplitUserId() {
+        return splitUserId;
+    }
+
+    public void setSplitUserId(String splitUserId) {
+        this.splitUserId = splitUserId;
+    }
+
+    public String getSplitAmount() {
+        return splitAmount;
+    }
+
+    public void setSplitAmount(String splitAmount) {
+        this.splitAmount = splitAmount;
+    }
+
+    public String getSplitType() {
+        return splitType;
+    }
+
+    public void setSplitType(String splitType) {
+        this.splitType = splitType;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrder.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrder.java
new file mode 100644
index 0000000..e792331
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrder.java
@@ -0,0 +1,293 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+import java.util.List;
+
+public class PaymentOrder {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "paymentOrder";
+    /**
+     * 业务订单号(必填)
+     */
+    private String bizOrderId;
+
+    /**
+     * 交易金额(必填)
+     */
+    private String amount;
+
+    /**
+     * 付款人
+     */
+    private String payerUserName;
+
+    /**
+     * 收款人会员ID(必填)
+     */
+    private String payeeUserId;
+
+    /**
+     * 订单名称(必填)
+     */
+    private String orderName;
+
+    /**
+     * 支付类型(必填)
+     */
+    private String payType;
+
+    /**
+     * 交易类型(必填)
+     */
+    private String transferType;
+
+    /**
+     * 订单过期时间
+     */
+    private String expire;
+
+    /**
+     * 微信或支付宝的appid
+     */
+    private String appid;
+
+    /**
+     * 微信或支付宝用户id
+     */
+    private String openid;
+
+    /**
+     * 终端IP(必填)
+     */
+    private String terminalIp;
+
+    /**
+     * 分账方列表(必填)
+     */
+    private List<PamentOrderUser> splitList;
+
+    /**
+     * 商品列表(必填)
+     */
+    private List<PaymentOrderGood> goodsDetail;
+
+    /**
+     * 前台回调地址(必填)
+     */
+    private String frontUrl;
+
+    /**
+     * 后台回调地址(必填)
+     */
+    private String notifyUrl;
+
+    /**
+     * 自定义参数1
+     */
+    private String parameter1;
+
+    /**
+     * 自定义参数2
+     */
+    private String parameter2;
+    /*
+     * 是否异步分账
+     */
+    private String asynSplitFlag;
+
+    /**
+     * 付款方子商户编号
+     */
+    private String payerUserId;
+
+    /**
+     * 银行编码
+     */
+    private String bankCode;
+
+    /**
+     * 银行卡类型
+     */
+    private String cardType;
+
+    /**
+     * 快捷卡唯一标识
+     */
+    private String tokenNo;
+
+
+    public String getPayerUserId() {
+        return payerUserId;
+    }
+
+    public void setPayerUserId(String payerUserId) {
+        this.payerUserId = payerUserId;
+    }
+
+    public String getBankCode() {
+        return bankCode;
+    }
+
+    public void setBankCode(String bankCode) {
+        this.bankCode = bankCode;
+    }
+
+    public String getCardType() {
+        return cardType;
+    }
+
+    public void setCardType(String cardType) {
+        this.cardType = cardType;
+    }
+
+    public String getTokenNo() {
+        return tokenNo;
+    }
+
+    public void setTokenNo(String tokenNo) {
+        this.tokenNo = tokenNo;
+    }
+
+    public String getAsynSplitFlag() {
+        return asynSplitFlag;
+    }
+
+    public void setAsynSplitFlag(String asynSplitFlag) {
+        this.asynSplitFlag = asynSplitFlag;
+    }
+
+    public String getBizOrderId() {
+        return bizOrderId;
+    }
+
+    public void setBizOrderId(String bizOrderId) {
+        this.bizOrderId = bizOrderId;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getPayerUserName() {
+        return payerUserName;
+    }
+
+    public void setPayerUserName(String payerUserName) {
+        this.payerUserName = payerUserName;
+    }
+
+    public String getPayeeUserId() {
+        return payeeUserId;
+    }
+
+    public void setPayeeUserId(String payeeUserId) {
+        this.payeeUserId = payeeUserId;
+    }
+
+    public String getOrderName() {
+        return orderName;
+    }
+
+    public void setOrderName(String orderName) {
+        this.orderName = orderName;
+    }
+
+    public String getPayType() {
+        return payType;
+    }
+
+    public void setPayType(String payType) {
+        this.payType = payType;
+    }
+
+    public String getTransferType() {
+        return transferType;
+    }
+
+    public void setTransferType(String transferType) {
+        this.transferType = transferType;
+    }
+
+    public String getExpire() {
+        return expire;
+    }
+
+    public void setExpire(String expire) {
+        this.expire = expire;
+    }
+
+    public String getAppid() {
+        return appid;
+    }
+
+    public void setAppid(String appid) {
+        this.appid = appid;
+    }
+
+    public String getOpenid() {
+        return openid;
+    }
+
+    public void setOpenid(String openid) {
+        this.openid = openid;
+    }
+
+    public String getTerminalIp() {
+        return terminalIp;
+    }
+
+    public void setTerminalIp(String terminalIp) {
+        this.terminalIp = terminalIp;
+    }
+
+    public List<PamentOrderUser> getSplitList() {
+        return splitList;
+    }
+
+    public void setSplitList(List<PamentOrderUser> splitList) {
+        this.splitList = splitList;
+    }
+
+    public List<PaymentOrderGood> getGoodsDetail() {
+        return goodsDetail;
+    }
+
+    public void setGoodsDetail(List<PaymentOrderGood> goodsDetail) {
+        this.goodsDetail = goodsDetail;
+    }
+
+    public String getFrontUrl() {
+        return frontUrl;
+    }
+
+    public void setFrontUrl(String frontUrl) {
+        this.frontUrl = frontUrl;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+
+    public String getParameter1() {
+        return parameter1;
+    }
+
+    public void setParameter1(String parameter1) {
+        this.parameter1 = parameter1;
+    }
+
+    public String getParameter2() {
+        return parameter2;
+    }
+
+    public void setParameter2(String parameter2) {
+        this.parameter2 = parameter2;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrderGood.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrderGood.java
new file mode 100644
index 0000000..fc26ad3
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/PaymentOrderGood.java
@@ -0,0 +1,48 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class PaymentOrderGood {
+
+    /** 商品编号 */
+    private String goodsId;
+
+    /** 商品名称,必填 */
+    private String goodsName;
+
+    /** 商品数量 */
+    private String quantity;
+
+    /** 商品价格 */
+    private String price;
+
+    public String getGoodsId() {
+        return goodsId;
+    }
+
+    public void setGoodsId(String goodsId) {
+        this.goodsId = goodsId;
+    }
+
+    public String getGoodsName() {
+        return goodsName;
+    }
+
+    public void setGoodsName(String goodsName) {
+        this.goodsName = goodsName;
+    }
+
+    public String getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(String quantity) {
+        this.quantity = quantity;
+    }
+
+    public String getPrice() {
+        return price;
+    }
+
+    public void setPrice(String price) {
+        this.price = price;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/QueryOrder.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/QueryOrder.java
new file mode 100644
index 0000000..dbace2b
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/QueryOrder.java
@@ -0,0 +1,31 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class QueryOrder {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "queryOrder";
+    /**
+     * 原请求订单号
+     */
+    private String originalMerOrderId;
+
+    /**
+     * 查询类型
+     */
+    private String queryType;
+
+    public String getOriginalMerOrderId() {
+        return originalMerOrderId;
+    }
+
+    public void setOriginalMerOrderId(String originalMerOrderId) {
+        this.originalMerOrderId = originalMerOrderId;
+    }
+
+    public String getQueryType() {
+        return queryType;
+    }
+
+    public void setQueryType(String queryType) {
+        this.queryType = queryType;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Receive.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Receive.java
new file mode 100644
index 0000000..068a10a
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Receive.java
@@ -0,0 +1,102 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+import java.util.List;
+
+/**
+ * 确认收货信息参数
+ */
+public class Receive {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "receive";
+    /**
+     * 原支付请求订单号(必填)
+     */
+    private String originalMerOrderId;
+    /**
+     * 异步分账订单号(多次异步确认订单进行确认收货时必传)
+     */
+    private String asynMerOrderId;
+
+    /**
+     * 确认收货总额(必填)
+     * 必须大于0
+     * 确认收货总额=总确认分账金额
+     */
+    private String rcvAmount;
+
+    /**
+     * 分账方列表(必填)
+     */
+    private List<ReceiveUser> splitList;
+
+    /**
+     * 商品列表
+     */
+    private List<ReceiveGood> goodsDetail;
+    /**
+     * 自定义参数1
+     */
+    private String parameter1;
+
+    /**
+     * 自定义参数2
+     */
+    private String parameter2;
+
+    public String getOriginalMerOrderId() {
+        return originalMerOrderId;
+    }
+
+    public void setOriginalMerOrderId(String originalMerOrderId) {
+        this.originalMerOrderId = originalMerOrderId;
+    }
+
+    public String getAsynMerOrderId() {
+        return asynMerOrderId;
+    }
+
+    public void setAsynMerOrderId(String asynMerOrderId) {
+        this.asynMerOrderId = asynMerOrderId;
+    }
+
+    public String getRcvAmount() {
+        return rcvAmount;
+    }
+
+    public void setRcvAmount(String rcvAmount) {
+        this.rcvAmount = rcvAmount;
+    }
+
+    public List<ReceiveUser> getSplitList() {
+        return splitList;
+    }
+
+    public void setSplitList(List<ReceiveUser> splitList) {
+        this.splitList = splitList;
+    }
+
+    public List<ReceiveGood> getGoodsDetail() {
+        return goodsDetail;
+    }
+
+    public void setGoodsDetail(List<ReceiveGood> goodsDetail) {
+        this.goodsDetail = goodsDetail;
+    }
+
+    public String getParameter1() {
+        return parameter1;
+    }
+
+    public void setParameter1(String parameter1) {
+        this.parameter1 = parameter1;
+    }
+
+    public String getParameter2() {
+        return parameter2;
+    }
+
+    public void setParameter2(String parameter2) {
+        this.parameter2 = parameter2;
+    }
+
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveGood.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveGood.java
new file mode 100644
index 0000000..ced3f30
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveGood.java
@@ -0,0 +1,48 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class ReceiveGood {
+
+    /** 商品编号 */
+    private String goodsId;
+
+    /** 商品名称,必填 */
+    private String goodsName;
+
+    /** 商品数量 */
+    private String quantity;
+
+    /** 商品价格 */
+    private String price;
+
+    public String getGoodsId() {
+        return goodsId;
+    }
+
+    public void setGoodsId(String goodsId) {
+        this.goodsId = goodsId;
+    }
+
+    public String getGoodsName() {
+        return goodsName;
+    }
+
+    public void setGoodsName(String goodsName) {
+        this.goodsName = goodsName;
+    }
+
+    public String getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(String quantity) {
+        this.quantity = quantity;
+    }
+
+    public String getPrice() {
+        return price;
+    }
+
+    public void setPrice(String price) {
+        this.price = price;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveUser.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveUser.java
new file mode 100644
index 0000000..69f64e3
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/ReceiveUser.java
@@ -0,0 +1,27 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+
+public class ReceiveUser {
+
+    /** 分账方会员ID,必填 */
+    private String splitUserId;
+
+    /** 确认分账金额,必填 */
+    private String rcvSplitAmount;
+
+    public String getSplitUserId() {
+        return splitUserId;
+    }
+
+    public void setSplitUserId(String splitUserId) {
+        this.splitUserId = splitUserId;
+    }
+
+    public String getRcvSplitAmount() {
+        return rcvSplitAmount;
+    }
+
+    public void setRcvSplitAmount(String rcvSplitAmount) {
+        this.rcvSplitAmount = rcvSplitAmount;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Withdraw.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Withdraw.java
new file mode 100644
index 0000000..4716e17
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Withdraw.java
@@ -0,0 +1,96 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class Withdraw {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "withdraw";
+    /**
+     * 子商户编号(必填)
+     */
+    private String userId;
+
+    /**
+     * 结算金额(必填)
+     */
+    private String amount;
+
+    /**
+     * 订单名称
+     */
+    private String orderName;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 后台回调地址(必填)
+     */
+    private String notifyUrl;
+
+    /**
+     * 自定义参数1
+     */
+    private String parameter1;
+
+    /**
+     * 自定义参数2
+     */
+    private String parameter2;
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getOrderName() {
+        return orderName;
+    }
+
+    public void setOrderName(String orderName) {
+        this.orderName = orderName;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+
+    public String getParameter1() {
+        return parameter1;
+    }
+
+    public void setParameter1(String parameter1) {
+        this.parameter1 = parameter1;
+    }
+
+    public String getParameter2() {
+        return parameter2;
+    }
+
+    public void setParameter2(String parameter2) {
+        this.parameter2 = parameter2;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/WeChatUtil.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/WeChatUtil.java
deleted file mode 100644
index a190365..0000000
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/WeChatUtil.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.supersavedriving.driver.modular.system.util;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 微信工具类
- */
-@Component
-public class WeChatUtil {
-
-    @Value("${wx.appletsAppid}")
-    private String wxAppletsAppid;
-
-    @Value("${wx.appletsAppSecret}")
-    private String wxAppletsAppSecret;
-
-    @Autowired
-    private RestTemplate restTemplate;
-
-
-    /**
-     * 小程序使用jscode获取openid
-     * @param jscode
-     * @return
-     */
-    public Map<String, String> code2Session(String jscode){
-        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret
-                + "&js_code=" + jscode + "&grant_type=authorization_code";
-        String forObject = restTemplate.getForObject(url, String.class);
-        JSONObject jsonObject = JSON.parseObject(forObject);
-        int errcode = jsonObject.getIntValue("errcode");
-        Map<String, String> map = new HashMap<>();
-        if(errcode == 0){//成功
-            map.put("openid", jsonObject.getString("openid"));
-            map.put("sessionKey", jsonObject.getString("session_key"));
-            map.put("unionid", jsonObject.getString("unionid"));
-            return map;
-        }
-        if(errcode == -1){//系统繁忙,此时请开发者稍候再试
-            map.put("msg", jsonObject.getString("errmsg"));
-            return map;
-        }
-        if(errcode == 40029){//code 无效
-            map.put("msg", jsonObject.getString("errmsg"));
-            return map;
-        }
-        if(errcode == 45011){//频率限制,每个用户每分钟100次
-            map.put("msg", jsonObject.getString("errmsg"));
-            return map;
-        }
-        return null;
-    }
-
-
-    /**
-     * 通过config接口注入权限验证配置(公众号)
-     * 附录1-JS-SDK使用权限签名算法,
-     * @return
-     */
-    public Map<String,Object> getSignatureConfig(String url){
-        //获取token
-        try {
-            url = URLDecoder.decode(url, "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-        }
-        String ticket = getJSApiTicket();
-        String noncestr = UUIDUtil.getRandomCode();
-        Long timestamp = System.currentTimeMillis();
-        String content = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
-        String signature = DigestUtils.sha1Hex(content);
-        Map<String,Object> map=new HashMap<>();
-        map.put("appId", "wx0e72f86394831b34");
-        map.put("timestamp", timestamp);
-        map.put("nonceStr", noncestr);
-        map.put("signature", signature);
-        return  map;
-    }
-
-
-
-    /***
-     * 获取jsapiTicket(公众号)
-     * 来源 www.vxzsk.com
-     * @return
-     */
-    public String getJSApiTicket(){
-        //获取token
-        String acess_token= this.getAccessToken();
-        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acess_token + "&type=jsapi";
-        String backData = restTemplate.getForObject(urlStr, String.class);
-        System.out.println(backData);
-        String ticket = JSONObject.parseObject(backData).getString("ticket");
-        return  ticket;
-    }
-
-
-    /***
-     * 获取acess_token (公众号)
-     * 来源www.vxzsk.com
-     * @return
-     */
-    public String getAccessToken(){
-        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx0e72f86394831b34&secret=930f857abc74f7bb5cbd89e1544c5669";
-        String backData = restTemplate.getForObject(url, String.class);
-        String accessToken = JSONObject.parseObject(backData).getString("access_token");
-        return accessToken;
-    }
-}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AES.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AES.java
new file mode 100644
index 0000000..b87a2a1
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AES.java
@@ -0,0 +1,72 @@
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.*;
+
+/**
+* AES加密
+* @author pzb
+* @Date 2021/12/3 15:43
+*/
+public class AES {
+
+    public static boolean initialized = false;
+
+    /**
+     * AES解密
+     *
+     * @param content
+     *            密文
+     * @return
+     * @throws InvalidAlgorithmParameterException
+     * @throws NoSuchProviderException
+     */
+    public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
+        initialize();
+        try {
+            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
+            Key sKeySpec = new SecretKeySpec(keyByte, "AES");
+            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
+            byte[] result = cipher.doFinal(content);
+            return result;
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+        } catch (InvalidKeyException e) {
+            e.printStackTrace();
+        } catch (IllegalBlockSizeException e) {
+            e.printStackTrace();
+        } catch (BadPaddingException e) {
+            e.printStackTrace();
+        } catch (NoSuchProviderException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static void initialize() {
+        if (initialized)
+            return;
+        Security.addProvider(new BouncyCastleProvider());
+        initialized = true;
+    }
+
+    // 生成iv
+    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
+        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
+        params.init(new IvParameterSpec(iv));
+        return params;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AesException.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AesException.java
new file mode 100644
index 0000000..46cd33d
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/AesException.java
@@ -0,0 +1,59 @@
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+@SuppressWarnings("serial")
+public class AesException extends Exception {
+
+	public final static int OK = 0;
+	public final static int ValidateSignatureError = -40001;
+	public final static int ParseXmlError = -40002;
+	public final static int ComputeSignatureError = -40003;
+	public final static int IllegalAesKey = -40004;
+	public final static int ValidateAppidError = -40005;
+	public final static int EncryptAESError = -40006;
+	public final static int DecryptAESError = -40007;
+	public final static int IllegalBuffer = -40008;
+	//public final static int EncodeBase64Error = -40009;
+	//public final static int DecodeBase64Error = -40010;
+	//public final static int GenReturnXmlError = -40011;
+
+	private int code;
+
+	private static String getMessage(int code) {
+		switch (code) {
+		case ValidateSignatureError:
+			return "签名验证错误";
+		case ParseXmlError:
+			return "xml解析失败";
+		case ComputeSignatureError:
+			return "sha加密生成签名失败";
+		case IllegalAesKey:
+			return "SymmetricKey非法";
+		case ValidateAppidError:
+			return "appid校验失败";
+		case EncryptAESError:
+			return "aes加密失败";
+		case DecryptAESError:
+			return "aes解密失败";
+		case IllegalBuffer:
+			return "解密后得到的buffer非法";
+//		case EncodeBase64Error:
+//			return "base64加密错误";
+//		case DecodeBase64Error:
+//			return "base64解密错误";
+//		case GenReturnXmlError:
+//			return "xml生成失败";
+		default:
+			return null; // cannot be
+		}
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	AesException(int code) {
+		super(getMessage(code));
+		this.code = code;
+	}
+
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/ByteGroup.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/ByteGroup.java
new file mode 100644
index 0000000..875f95b
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/ByteGroup.java
@@ -0,0 +1,26 @@
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import java.util.ArrayList;
+
+class ByteGroup {
+	ArrayList<Byte> byteContainer = new ArrayList<Byte>();
+
+	public byte[] toBytes() {
+		byte[] bytes = new byte[byteContainer.size()];
+		for (int i = 0; i < byteContainer.size(); i++) {
+			bytes[i] = byteContainer.get(i);
+		}
+		return bytes;
+	}
+
+	public ByteGroup addBytes(byte[] bytes) {
+		for (byte b : bytes) {
+			byteContainer.add(b);
+		}
+		return this;
+	}
+
+	public int size() {
+		return byteContainer.size();
+	}
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/PKCS7Encoder.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/PKCS7Encoder.java
new file mode 100644
index 0000000..a118028
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/PKCS7Encoder.java
@@ -0,0 +1,67 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+/**
+ * 提供基于PKCS7算法的加解密接口.
+ */
+class PKCS7Encoder {
+	static Charset CHARSET = Charset.forName("utf-8");
+	static int BLOCK_SIZE = 32;
+
+	/**
+	 * 获得对明文进行补位填充的字节.
+	 * 
+	 * @param count 需要进行填充补位操作的明文字节个数
+	 * @return 补齐用的字节数组
+	 */
+	static byte[] encode(int count) {
+		// 计算需要填充的位数
+		int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
+		if (amountToPad == 0) {
+			amountToPad = BLOCK_SIZE;
+		}
+		// 获得补位所用的字符
+		char padChr = chr(amountToPad);
+		String tmp = new String();
+		for (int index = 0; index < amountToPad; index++) {
+			tmp += padChr;
+		}
+		return tmp.getBytes(CHARSET);
+	}
+
+	/**
+	 * 删除解密后明文的补位字符
+	 * 
+	 * @param decrypted 解密后的明文
+	 * @return 删除补位字符后的明文
+	 */
+	static byte[] decode(byte[] decrypted) {
+		int pad = (int) decrypted[decrypted.length - 1];
+		if (pad < 1 || pad > 32) {
+			pad = 0;
+		}
+		return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
+	}
+
+	/**
+	 * 将数字转化成ASCII码对应的字符,用于对明文进行补码
+	 * 
+	 * @param a 需要转化的数字
+	 * @return 转化得到的字符
+	 */
+	static char chr(int a) {
+		byte target = (byte) (a & 0xFF);
+		return (char) target;
+	}
+
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/SHA1.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/SHA1.java
new file mode 100644
index 0000000..4d957c6
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/SHA1.java
@@ -0,0 +1,61 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+/**
+ * SHA1 class
+ *
+ * 计算公众平台的消息签名接口.
+ */
+public class SHA1 {
+
+	/**
+	 * 用SHA1算法生成安全签名
+	 * @param token 票据
+	 * @param timestamp 时间戳
+	 * @param nonce 随机字符串
+	 * @param encrypt 密文
+	 * @return 安全签名
+	 * @throws AesException 
+	 */
+	public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException
+			  {
+		try {
+			String[] array = new String[] { token, timestamp, nonce, encrypt };
+			StringBuffer sb = new StringBuffer();
+			// 字符串排序
+			Arrays.sort(array);
+			for (int i = 0; i < 4; i++) {
+				sb.append(array[i]);
+			}
+			String str = sb.toString();
+			// SHA1签名生成
+			MessageDigest md = MessageDigest.getInstance("SHA-1");
+			md.update(str.getBytes());
+			byte[] digest = md.digest();
+
+			StringBuffer hexstr = new StringBuffer();
+			String shaHex = "";
+			for (int i = 0; i < digest.length; i++) {
+				shaHex = Integer.toHexString(digest[i] & 0xFF);
+				if (shaHex.length() < 2) {
+					hexstr.append(0);
+				}
+				hexstr.append(shaHex);
+			}
+			return hexstr.toString();
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.ComputeSignatureError);
+		}
+	}
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXBizMsgCrypt.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXBizMsgCrypt.java
new file mode 100644
index 0000000..c9be83c
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXBizMsgCrypt.java
@@ -0,0 +1,288 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * 针对org.apache.commons.codec.binary.Base64,
+ * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
+ * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
+ */
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
+ * <ol>
+ * 	<li>第三方回复加密消息给公众平台</li>
+ * 	<li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
+ * </ol>
+ * 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
+ * <ol>
+ * 	<li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
+ *      http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
+ * 	<li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
+ * 	<li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
+ * 	<li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
+ * </ol>
+ */
+public class WXBizMsgCrypt {
+	static Charset CHARSET = Charset.forName("utf-8");
+	Base64 base64 = new Base64();
+	byte[] aesKey;
+	String token;
+	String appId;
+
+	/**
+	 * 构造函数
+	 * @param token 公众平台上,开发者设置的token
+	 * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
+	 * @param appId 公众平台appid
+	 * 
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public WXBizMsgCrypt(String token, String encodingAesKey, String appId) throws AesException {
+		if (encodingAesKey.length() != 43) {
+			throw new AesException(AesException.IllegalAesKey);
+		}
+
+		this.token = token;
+		this.appId = appId;
+		aesKey = Base64.decodeBase64(encodingAesKey + "=");
+	}
+
+	// 生成4个字节的网络字节序
+	byte[] getNetworkBytesOrder(int sourceNumber) {
+		byte[] orderBytes = new byte[4];
+		orderBytes[3] = (byte) (sourceNumber & 0xFF);
+		orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
+		orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
+		orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);
+		return orderBytes;
+	}
+
+	// 还原4个字节的网络字节序
+	int recoverNetworkBytesOrder(byte[] orderBytes) {
+		int sourceNumber = 0;
+		for (int i = 0; i < 4; i++) {
+			sourceNumber <<= 8;
+			sourceNumber |= orderBytes[i] & 0xff;
+		}
+		return sourceNumber;
+	}
+
+	// 随机生成16位字符串
+	String getRandomStr() {
+		String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+		Random random = new Random();
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < 16; i++) {
+			int number = random.nextInt(base.length());
+			sb.append(base.charAt(number));
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * 对明文进行加密.
+	 * 
+	 * @param text 需要加密的明文
+	 * @return 加密后base64编码的字符串
+	 * @throws AesException aes加密失败
+	 */
+	String encrypt(String randomStr, String text) throws AesException {
+		ByteGroup byteCollector = new ByteGroup();
+		byte[] randomStrBytes = randomStr.getBytes(CHARSET);
+		byte[] textBytes = text.getBytes(CHARSET);
+		byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length);
+		byte[] appidBytes = appId.getBytes(CHARSET);
+
+		// randomStr + networkBytesOrder + text + appid
+		byteCollector.addBytes(randomStrBytes);
+		byteCollector.addBytes(networkBytesOrder);
+		byteCollector.addBytes(textBytes);
+		byteCollector.addBytes(appidBytes);
+
+		// ... + pad: 使用自定义的填充方式对明文进行补位填充
+		byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
+		byteCollector.addBytes(padBytes);
+
+		// 获得最终的字节流, 未加密
+		byte[] unencrypted = byteCollector.toBytes();
+
+		try {
+			// 设置加密模式为AES的CBC模式
+			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+			SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
+			IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
+			cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
+
+			// 加密
+			byte[] encrypted = cipher.doFinal(unencrypted);
+
+			// 使用BASE64对加密后的字符串进行编码
+			String base64Encrypted = base64.encodeToString(encrypted);
+
+			return base64Encrypted;
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.EncryptAESError);
+		}
+	}
+
+	/**
+	 * 对密文进行解密.
+	 * 
+	 * @param text 需要解密的密文
+	 * @return 解密得到的明文
+	 * @throws AesException aes解密失败
+	 */
+	String decrypt(String text) throws AesException {
+		byte[] original;
+		try {
+			// 设置解密模式为AES的CBC模式
+			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+			SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
+			IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
+			cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
+
+			// 使用BASE64对密文进行解码
+			byte[] encrypted = Base64.decodeBase64(text);
+
+			// 解密
+			original = cipher.doFinal(encrypted);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.DecryptAESError);
+		}
+
+		String xmlContent, from_appid;
+		try {
+			// 去除补位字符
+			byte[] bytes = PKCS7Encoder.decode(original);
+
+			// 分离16位随机字符串,网络字节序和AppId
+			byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
+
+			int xmlLength = recoverNetworkBytesOrder(networkOrder);
+
+			xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
+			from_appid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
+					CHARSET);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.IllegalBuffer);
+		}
+
+		// appid不相同的情况
+		if (!from_appid.equals(appId)) {
+			throw new AesException(AesException.ValidateAppidError);
+		}
+		return xmlContent;
+
+	}
+
+	/**
+	 * 将公众平台回复用户的消息加密打包.
+	 * <ol>
+	 * 	<li>对要发送的消息进行AES-CBC加密</li>
+	 * 	<li>生成安全签名</li>
+	 * 	<li>将消息密文和安全签名打包成xml格式</li>
+	 * </ol>
+	 * 
+	 * @param replyMsg 公众平台待回复用户的消息,xml格式的字符串
+	 * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
+	 * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce
+	 * 
+	 * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public String encryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {
+		// 加密
+		String encrypt = encrypt(getRandomStr(), replyMsg);
+
+		// 生成安全签名
+		if (timeStamp == "") {
+			timeStamp = Long.toString(System.currentTimeMillis());
+		}
+
+		String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt);
+
+		// System.out.println("发送给平台的签名是: " + signature[1].toString());
+		// 生成发送的xml
+		String result = XMLParse.generate(encrypt, signature, timeStamp, nonce);
+		return result;
+	}
+
+	/**
+	 * 检验消息的真实性,并且获取解密后的明文.
+	 * <ol>
+	 * 	<li>利用收到的密文生成安全签名,进行签名验证</li>
+	 * 	<li>若验证通过,则提取xml中的加密消息</li>
+	 * 	<li>对消息进行解密</li>
+	 * </ol>
+	 * 
+	 * @param msgSignature 签名串,对应URL参数的msg_signature
+	 * @param timeStamp 时间戳,对应URL参数的timestamp
+	 * @param nonce 随机串,对应URL参数的nonce
+	 * @param postData 密文,对应POST请求的数据
+	 * 
+	 * @return 解密后的原文
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData)
+			throws AesException {
+
+		// 密钥,公众账号的app secret
+		// 提取密文
+		Object[] encrypt = XMLParse.extract(postData);
+
+		// 验证安全签名
+		String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString());
+
+		// 和URL中的签名比较是否相等
+		// System.out.println("第三方收到URL中的签名:" + msg_sign);
+		// System.out.println("第三方校验签名:" + signature);
+		if (!signature.equals(msgSignature)) {
+			throw new AesException(AesException.ValidateSignatureError);
+		}
+
+		// 解密
+		String result = decrypt(encrypt[1].toString());
+		return result;
+	}
+
+	/**
+	 * 验证URL
+	 * @param msgSignature 签名串,对应URL参数的msg_signature
+	 * @param timeStamp 时间戳,对应URL参数的timestamp
+	 * @param nonce 随机串,对应URL参数的nonce
+	 * @param echoStr 随机串,对应URL参数的echostr
+	 * 
+	 * @return 解密之后的echostr
+	 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
+	 */
+	public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr)
+			throws AesException {
+		String signature = SHA1.getSHA1(token, timeStamp, nonce, "");
+
+		if (!signature.equals(msgSignature)) {
+			throw new AesException(AesException.ValidateSignatureError);
+		}
+
+		String result = decrypt(echoStr);
+		return result;
+	}
+
+}
\ No newline at end of file
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXCore.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXCore.java
new file mode 100644
index 0000000..3947b93
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WXCore.java
@@ -0,0 +1,52 @@
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+
+public class WXCore {
+
+    private static Logger logger = LoggerFactory.getLogger(WXCore.class);
+
+    private static final String WATERMARK = "watermark";
+
+    @Value("${wx.appletsAppid}")
+    private static String appid ;
+
+
+
+    /**
+     * 解密数据
+     * @return
+     * @throws Exception
+     */
+    public static String decrypt(String encryptedData, String sessionKey, String iv){
+        String result = "";
+        try {
+            AES aes = new AES();
+            byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
+            if(null != resultByte && resultByte.length > 0){
+                result = new String(WxPKCS7Encoder.decode(resultByte), "UTF-8");
+//                JSONObject jsonObject = JSON.parseObject(result);
+//                String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString("appid");
+//                if(!appid.equals(decryptAppid)){
+//                    result = "";
+//                }
+            }
+        } catch (Exception e) {
+            result = "";
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+
+    public static void main(String[] args) throws Exception{
+        String appId = "wx4f4bc4dec97d474b";
+        String encryptedData = "ajhisfk0EhWCBcoxt/5QJA3bKPTygQXANbCSev92MyqIqGxRhzZFS1SlQrIWAo3tx8YfsB+VlScZNOlRyfnXKqPUl9h+PDeKsTkTst9V4pq4mUbI+r3AautXBffVk/rpyjMfanVsWeOlxkupdv2U9U4BrueR/Rak+TCmHTWUUf8eDLoi6nioL/Pft/rYaO3JD54hgpcY0Ef/k7Boyap4E0/uKVowY1ANO7KVydSXE6S7OKzXuzmDTbV38v+7ryMHtglUzoKzF1gL8y9OZRwkaesfHN1kfItjpsAibjSgkIiiW6ZEHLT2n1UDkJtfUqg63je2cJAH7gzeUm9TCDDftdhLU+NuPk3j/LXyFQ05pJ8B19+kIXF3dcmHOH7lFvi7yGmVuAD/9AnetGWgId3TZDS/OjbiVUM30RogeziAw98VpAyAAq1r2ULFwi8e928m";
+        String sessionKey = "CdxFGwXIluQFZ+qD+NSFKQ==";
+        String iv = "3FD8r1Spwlf7LG8YEq41+Q==";
+        logger.debug(decrypt(encryptedData, sessionKey, iv));
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WeChatUtil.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WeChatUtil.java
new file mode 100644
index 0000000..04bf0a5
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WeChatUtil.java
@@ -0,0 +1,415 @@
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.supersavedriving.driver.core.util.ToolUtil;
+import com.supersavedriving.driver.modular.system.util.RedisUtil;
+import com.supersavedriving.driver.modular.system.util.UUIDUtil;
+import com.supersavedriving.driver.modular.system.util.httpClinet.HttpClientUtil;
+import com.supersavedriving.driver.modular.system.util.httpClinet.HttpResult;
+import com.supersavedriving.driver.modular.system.util.weChat.model.Code2Session;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * 微信工具类
+ */
+@Component
+public class WeChatUtil {
+
+    private static Logger logger = LoggerFactory.getLogger(WeChatUtil.class);
+
+    @Value("${wx.appletsAppid}")
+    private String wxAppletsAppid;
+
+    @Value("${wx.appletsAppSecret}")
+    private String wxAppletsAppSecret;
+
+    @Value("${wx.officialAccountAppid}")
+    private String officialAccountAppid;
+
+    @Value("{wx.officialAccountAppSecret}")
+    private String officialAccountAppSecret;
+
+    @Value("${wx.appid}")
+    private String webAppId;
+
+    @Value("${wx.appSecret}")
+    private String webAppSecret;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+
+
+    {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    Thread.sleep(30000);
+                    new Timer().schedule(new TimerTask() {
+                        @Override
+                        public void run() {
+                            try {
+                                String wxAppletsAccessToken = getWxAppletsAccessToken();
+                                if(ToolUtil.isEmpty(wxAppletsAccessToken)){
+                                    System.err.println("获取微信小程序access_token失败");
+                                    return;
+                                }
+                                redisUtil.setStrValue("wxAppletsAccessToken", wxAppletsAccessToken, 7000);
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }, 0, 7000000);
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            }
+        }).start();
+
+    }
+
+
+    /**
+     * 小程序使用jscode获取openid
+     * @param jscode
+     * @return
+     */
+    public Code2Session code2Session(String jscode) throws Exception{
+        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret
+                + "&js_code=" + jscode + "&grant_type=authorization_code";
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "form");
+        if(null == httpResult || httpResult.getCode() != 200){
+            return null;
+        }
+        Code2Session code2Session = JSON.parseObject(httpResult.getData(), Code2Session.class);
+        return code2Session;
+    }
+
+
+    /**
+     * 获取微信小程序token
+     * @return
+     */
+    public String getWxAppletsAccessToken() throws Exception{
+        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret;
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return "";
+        }
+        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
+        return jsonObject.getString("access_token");
+    }
+
+
+    /***
+     * 获取jsapiTicket(小程序)
+     * 来源 www.vxzsk.com
+     * @return
+     */
+    public String getWxAppletsJSApiTicket() throws Exception{
+        String wxAppletsAccessToken = redisUtil.getValue("wxAppletsAccessToken");
+        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + wxAppletsAccessToken + "&type=jsapi";
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", urlStr, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        logger.debug(httpResult.getData());
+        String ticket = JSONObject.parseObject(httpResult.getData()).getString("ticket");
+        return  ticket;
+    }
+
+    /**
+     * 通过config接口注入权限验证配置(小程序)
+     * 附录1-JS-SDK使用权限签名算法,
+     * @return
+     */
+    public Map<String,Object> getWxAppletsSignatureConfig(String url) throws Exception{
+        //获取token
+        try {
+            url = URLDecoder.decode(url, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        String ticket = getWxAppletsJSApiTicket();
+        String noncestr = UUIDUtil.getRandomCode();
+        Long timestamp = System.currentTimeMillis();
+        String content = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
+        String signature = DigestUtils.sha1Hex(content);
+        Map<String,Object> map=new HashMap<>();
+        map.put("appId", wxAppletsAppid);
+        map.put("timestamp", timestamp);
+        map.put("nonceStr", noncestr);
+        map.put("signature", signature);
+        return  map;
+    }
+
+
+
+    /**
+     * 网站应用登录
+     * @param code
+     * @return
+     */
+    public Map<String, String> webAccessToken(String code) throws Exception{
+        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + webAppId + "&secret=" + webAppSecret + "&code=" + code + "&grant_type=authorization_code";
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
+        int errcode = jsonObject.getIntValue("errcode");
+        Map<String, String> map = new HashMap<>();
+        if(errcode == 0){//成功
+            map.put("access_token", jsonObject.getString("access_token"));
+            map.put("openid", jsonObject.getString("openid"));
+            map.put("refresh_token", jsonObject.getString("refresh_token"));
+            map.put("unionid", jsonObject.getString("unionid"));
+            return map;
+        }
+        if(errcode == -1){//系统繁忙,此时请开发者稍候再试
+            map.put("msg", jsonObject.getString("errmsg"));
+            return map;
+        }
+        if(errcode == 40029){//code 无效
+            map.put("msg", jsonObject.getString("errmsg"));
+            return map;
+        }
+        if(errcode == 45011){//频率限制,每个用户每分钟100次
+            map.put("msg", jsonObject.getString("errmsg"));
+            return map;
+        }
+        return map;
+    }
+
+
+    /**
+     * 获取微信个人信息
+     * @param access_token
+     * @param openid
+     * @return
+     */
+    public Map<String, Object> getUserInfo(String access_token, String openid) throws Exception{
+        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid;
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
+        int errcode = jsonObject.getIntValue("errcode");
+        Map<String, Object> map = new HashMap<>();
+        if(errcode == 0){//成功
+            map.put("nickname", jsonObject.getString("nickname"));
+            map.put("openid", jsonObject.getString("openid"));
+            map.put("sex", jsonObject.getString("sex"));
+            map.put("headimgurl", jsonObject.getString("headimgurl"));
+            return map;
+        }
+        if(errcode == -1){//系统繁忙,此时请开发者稍候再试
+            map.put("msg", jsonObject.getString("errmsg"));
+            return map;
+        }
+        if(errcode == 40029){//code 无效
+            map.put("msg", jsonObject.getString("errmsg"));
+            return map;
+        }
+        if(errcode == 45011){//频率限制,每个用户每分钟100次
+            map.put("msg", jsonObject.getString("errmsg"));
+            return map;
+        }
+        return map;
+    }
+
+
+    /**
+     * 公众号获取openid
+     * @param code
+     * @return
+     */
+    public Map<String,Object> getOpenId(String code) throws Exception{
+        if (code == null || code.length() == 0) {
+            return null;
+        }
+        String grantType = "authorization_code";
+        String params = "appid=" + officialAccountAppid + "&secret=" + officialAccountAppSecret + "&code=" + code + "&grant_type=" + grantType;
+        logger.debug("sssss"+params);
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", "https://api.weixin.qq.com/sns/oauth2/access_token?" + params, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        JSONObject json = JSON.parseObject(httpResult.getData());
+        logger.debug(json.toJSONString());
+        String openId = json.get("openid").toString();
+        String accessToken = json.get("access_token").toString();
+        Integer expiresIn = json.getInteger("expires_in");
+        String refresh_token = json.getString("refresh_token");
+        String unionid = json.getString("unionid");
+        Map<String,Object> map=new HashMap<>();
+        map.put("openId",openId);
+        map.put("accessToken",accessToken);
+        map.put("expiresIn", expiresIn);
+        map.put("refreshToken", refresh_token);
+        map.put("unionid", unionid);
+        return map;
+    }
+
+
+    /***
+     * 获取acess_token (公众号)
+     * 来源www.vxzsk.com
+     * @return
+     */
+    public String getAccessToken() throws Exception{
+        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + officialAccountAppid
+                + "&secret=" + officialAccountAppSecret;
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        String accessToken = JSONObject.parseObject(httpResult.getData()).getString("access_token");
+        return accessToken;
+    }
+
+    /***
+     * 获取jsapiTicket(公众号)
+     * 来源 www.vxzsk.com
+     * @return
+     */
+    public String getJSApiTicket() throws Exception{
+        //获取token
+        String acess_token = redisUtil.getValue("acess_token");
+        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acess_token + "&type=jsapi";
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", urlStr, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        logger.debug(httpResult.getData());
+        String ticket = JSONObject.parseObject(httpResult.getData()).getString("ticket");
+        return  ticket;
+    }
+
+    /**
+     * 通过config接口注入权限验证配置(公众号)
+     * 附录1-JS-SDK使用权限签名算法,
+     * @return
+     */
+    public Map<String,Object> getSignatureConfig(String url) throws Exception{
+        //获取token
+        try {
+            url = URLDecoder.decode(url, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        String ticket = getJSApiTicket();
+        String noncestr = UUIDUtil.getRandomCode();
+        Long timestamp = System.currentTimeMillis();
+        String content = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
+        String signature = DigestUtils.sha1Hex(content);
+        Map<String,Object> map=new HashMap<>();
+        map.put("appId", officialAccountAppid);
+        map.put("timestamp", timestamp);
+        map.put("nonceStr", noncestr);
+        map.put("signature", signature);
+        return  map;
+    }
+
+
+    /**
+     * 公众号获取用户个人信息
+     * @param access_token
+     * @param openid
+     * @return
+     */
+    public Map<String, Object> queryUserInfo(String access_token, String openid) throws Exception{
+        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN";
+        HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "form");
+        if(httpResult.getCode() != 200){
+            return null;
+        }
+        logger.debug(httpResult.getData());
+        JSONObject j = JSON.parseObject(httpResult.getData());
+        Map<String, Object> map = new HashMap<>();
+        map.put("nickname", j.getString("nickname"));
+        map.put("sex", j.getInteger("sex"));
+        map.put("headimgurl", j.getString("headimgurl"));
+        map.put("unionid", j.getString("unionid"));
+        return map;
+    }
+
+
+    /**
+     * 获取小程序二维码
+     * @param page      跳转页 例如 pages/index/index
+     * @param scene     参数 a=1&b=2
+     */
+    public InputStream getwxacodeunlimit(String page, String scene, String envVersion) throws Exception{
+        try {
+            String wxAppletsAccessToken = redisUtil.getValue("wxAppletsAccessToken");
+            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + wxAppletsAccessToken;
+            Map<String, Object> param = new HashMap<>();
+            param.put("scene", scene);
+            param.put("page", page);
+            param.put("env_version", envVersion);
+            HttpHeaders httpHeaders = new HttpHeaders();
+            MediaType type=MediaType.parseMediaType("application/json;charset=UTF-8");
+            httpHeaders.setContentType(type);
+            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, httpHeaders);
+            ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class, new Object[0]);
+            String body1 = exchange.getBody();
+//            System.err.println(body1);
+            ResponseEntity<byte[]> entity  = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
+            byte[] body = entity.getBody();
+//            System.err.println(Base64.encodeBase64String(body));
+            return new ByteArrayInputStream(body);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    /**
+     * 获取小程序urlscheme码
+     * @return
+     */
+    public String getUrlscheme(String path) throws Exception{
+        String wxAppletsAccessToken = redisUtil.getValue("wxAppletsAccessToken");
+        String url = "https://api.weixin.qq.com/wxa/generatescheme?access_token=" + wxAppletsAccessToken;
+        Map<String, Object> param = new HashMap<>();
+        param.put("is_expire", true);
+        param.put("expire_type", 1);
+        param.put("expire_interval", 180);
+        Map<String, Object> map1 = new HashMap<>();
+        map1.put("path", path);
+        map1.put("query", "");
+        map1.put("env_version", "release");
+        param.put("jump_wxa", map1);
+        HttpHeaders httpHeaders = new HttpHeaders();
+        MediaType type=MediaType.parseMediaType("application/json;charset=UTF-8");
+        httpHeaders.setContentType(type);
+        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, httpHeaders);
+        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
+        String body1 = exchange.getBody();
+        return body1;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WxPKCS7Encoder.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WxPKCS7Encoder.java
new file mode 100644
index 0000000..8c8b5eb
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/WxPKCS7Encoder.java
@@ -0,0 +1,63 @@
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+/**
+* 微信小程序加解密
+* @author pzb
+* @Date 2021/12/3 15:43
+*/
+public class WxPKCS7Encoder {
+    private static final Charset CHARSET = Charset.forName("utf-8");
+    private static final int BLOCK_SIZE = 32;
+
+    /**
+     * 获得对明文进行补位填充的字节.
+     *
+     * @param count
+     *            需要进行填充补位操作的明文字节个数
+     * @return 补齐用的字节数组
+     */
+    public static byte[] encode(int count) {
+        // 计算需要填充的位数
+        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
+        if (amountToPad == 0) {
+            amountToPad = BLOCK_SIZE;
+        }
+        // 获得补位所用的字符
+        char padChr = chr(amountToPad);
+        String tmp = new String();
+        for (int index = 0; index < amountToPad; index++) {
+            tmp += padChr;
+        }
+        return tmp.getBytes(CHARSET);
+    }
+
+    /**
+     * 删除解密后明文的补位字符
+     *
+     * @param decrypted
+     *            解密后的明文
+     * @return 删除补位字符后的明文
+     */
+    public static byte[] decode(byte[] decrypted) {
+        int pad = decrypted[decrypted.length - 1];
+        if (pad < 1 || pad > 32) {
+            pad = 0;
+        }
+        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
+    }
+
+    /**
+     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
+     *
+     * @param a
+     *            需要转化的数字
+     * @return 转化得到的字符
+     */
+    public static char chr(int a) {
+        byte target = (byte) (a & 0xFF);
+        return (char) target;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/XMLParse.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/XMLParse.java
new file mode 100644
index 0000000..8ff2d39
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/XMLParse.java
@@ -0,0 +1,71 @@
+/**
+ * 对公众平台发送给公众账号的消息加解密示例代码.
+ * 
+ * @copyright Copyright (c) 1998-2014 Tencent Inc.
+ */
+
+// ------------------------------------------------------------------------
+
+package com.supersavedriving.driver.modular.system.util.weChat;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.StringReader;
+
+/**
+ * XMLParse class
+ *
+ * 提供提取消息格式中的密文及生成回复消息格式的接口.
+ */
+class XMLParse {
+
+	/**
+	 * 提取出xml数据包中的加密消息
+	 * @param xmltext 待提取的xml字符串
+	 * @return 提取出的加密消息字符串
+	 * @throws AesException 
+	 */
+	public static Object[] extract(String xmltext) throws AesException     {
+		Object[] result = new Object[3];
+		try {
+			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+			DocumentBuilder db = dbf.newDocumentBuilder();
+			StringReader sr = new StringReader(xmltext);
+			InputSource is = new InputSource(sr);
+			Document document = db.parse(is);
+
+			Element root = document.getDocumentElement();
+			NodeList nodelist1 = root.getElementsByTagName("Encrypt");
+			NodeList nodelist2 = root.getElementsByTagName("ToUserName");
+			result[0] = 0;
+			result[1] = nodelist1.item(0).getTextContent();
+			result[2] = nodelist2.item(0).getTextContent();
+			return result;
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new AesException(AesException.ParseXmlError);
+		}
+	}
+
+	/**
+	 * 生成xml消息
+	 * @param encrypt 加密后的消息密文
+	 * @param signature 安全签名
+	 * @param timestamp 时间戳
+	 * @param nonce 随机字符串
+	 * @return 生成的xml字符串
+	 */
+	public static String generate(String encrypt, String signature, String timestamp, String nonce) {
+
+		String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+				+ "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+				+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "</xml>";
+		return String.format(format, encrypt, signature, timestamp, nonce);
+
+	}
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Category.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Category.java
new file mode 100644
index 0000000..41ae2b0
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Category.java
@@ -0,0 +1,18 @@
+package com.supersavedriving.driver.modular.system.util.weChat.model;
+
+import lombok.Data;
+
+/**
+ * 订阅消息类目
+ */
+@Data
+public class Category {
+    /**
+     * 类目id
+     */
+    private String id;
+    /**
+     * 类目名称
+     */
+    private String name;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Code2Session.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Code2Session.java
new file mode 100644
index 0000000..2064e04
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/Code2Session.java
@@ -0,0 +1,33 @@
+package com.supersavedriving.driver.modular.system.util.weChat.model;
+
+import lombok.Data;
+
+/**
+ * TODO
+ *
+ * @author 39373
+ * @date 2023/2/26 19:42
+ */
+@Data
+public class Code2Session {
+    /**
+     * 状态码(-1=系统繁忙,0=成功,40029=code无效,45011=频率限制,每个用户每分钟100次,40226=高风险等级用户,小程序登录拦截 )
+     */
+    private Integer errcode;
+    /**
+     * 状态说明
+     */
+    private String errmsg;
+    /**
+     * openid
+     */
+    private String openid;
+    /**
+     * sessionKey
+     */
+    private String session_key;
+    /**
+     * unionid
+     */
+    private String unionid;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/KeywordEnum.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/KeywordEnum.java
new file mode 100644
index 0000000..413c11a
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/KeywordEnum.java
@@ -0,0 +1,17 @@
+package com.supersavedriving.driver.modular.system.util.weChat.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class KeywordEnum {
+    /**
+     * 枚举参数的 key
+     */
+    private String keywordCode;
+    /**
+     * 枚举参数值范围列表
+     */
+    private List<String> enumValueList;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/MessageTemplate.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/MessageTemplate.java
new file mode 100644
index 0000000..98869c0
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/MessageTemplate.java
@@ -0,0 +1,36 @@
+package com.supersavedriving.driver.modular.system.util.weChat.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 消息模板
+ */
+@Data
+public class MessageTemplate {
+    /**
+     * 添加至帐号下的模板 id,发送小程序订阅消息时所需
+     */
+    private String priTmplId;
+    /**
+     * 模版标题
+     */
+    private String title;
+    /**
+     * 模版内容
+     */
+    private String content;
+    /**
+     * 模板内容示例
+     */
+    private String example;
+    /**
+     * 模版类型,2 为一次性订阅,3 为长期订阅
+     */
+    private Integer type;
+    /**
+     * 枚举参数值范围
+     */
+    private List<KeywordEnum> keywordEnumValueList;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplateKeywords.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplateKeywords.java
new file mode 100644
index 0000000..38bfaa3
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplateKeywords.java
@@ -0,0 +1,26 @@
+package com.supersavedriving.driver.modular.system.util.weChat.model;
+
+import lombok.Data;
+
+/**
+ * 公共消息模板关键字
+ */
+@Data
+public class PubTemplateKeywords {
+    /**
+     * 关键词 id,选用模板时需要
+     */
+    private Integer kid;
+    /**
+     * 关键词内容
+     */
+    private String name;
+    /**
+     * 关键词内容对应的示例
+     */
+    private String example;
+    /**
+     * 参数类型
+     */
+    private String rule;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplatetitles.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplatetitles.java
new file mode 100644
index 0000000..c6c8d4d
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/weChat/model/PubTemplatetitles.java
@@ -0,0 +1,26 @@
+package com.supersavedriving.driver.modular.system.util.weChat.model;
+
+import lombok.Data;
+
+/**
+ * 功能模板
+ */
+@Data
+public class PubTemplatetitles {
+    /**
+     * 模版标题 id
+     */
+    private Integer tid;
+    /**
+     * 模版标题
+     */
+    private String title;
+    /**
+     * 模版类型,2 为一次性订阅,3 为长期订阅
+     */
+    private Integer type;
+    /**
+     * 模版所属类目 id
+     */
+    private Integer categoryId;
+}
diff --git a/driver/guns-admin/src/main/resources/application.yml b/driver/guns-admin/src/main/resources/application.yml
index 0f01794..0c5d6a9 100644
--- a/driver/guns-admin/src/main/resources/application.yml
+++ b/driver/guns-admin/src/main/resources/application.yml
@@ -79,8 +79,12 @@
   grantType: authorization_code #填authorization_code
   appid: wx8a9af3889395d0e1 #应用唯一标识,在微信开放平台提交应用审核通过后获得
   appSecret: 95a34f114973298cce4297a20bb59bc3 #应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
-  appletsAppid: 1 #小程序APPid
-  appletsAppSecret: 1 #
+  appletsAppid: wx8ae6c610563f2fe6 #小程序APPid
+  appletsAppSecret: 8b2c93b0be4f017350050f1e660680fe #
+  officialAccountAppid: 11111
+  officialAccountAppSecret: 1111
+  webAppId: 111
+  webAppSecret: 11
   mchId: 1636941942 #微信支付分配的商户号
   key: Eri2GR2SB3b6iIhaoD7k3KQ8X0wf1Ybh #key为商户平台设置的密钥key:
   apiv3: AKJ51Z4nhSqYBxmOXgUyCKA1vLP0J5Aj #key为商户平台设置的密钥key:
@@ -88,10 +92,10 @@
 ---
 
 alipay:
-  appid: 2021001161600393  #应用程序唯一标识
-  appPrivateKey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCEbTcG2wz+kaYDo2YxflpHE59MvKc3rbl6RlBgO6i5GzgphzeRTv5kRWUpSVkKCsbxFvAYLcgFPmm5nY2fz5hCTKiRcYfpUjH/OougUbzYU3ilUc9JqMbmvy7KN+Kv7+kQYCGLvMqlyYPiJ7LrmJLpE/FUcNLDwo6xUmwJSxaF7M4TbD3ZQZdddki1iJp9GihlqehZCMWOBeotEXvPKDEzSEkYlnvHPQaaspVgeesGmlHDuOiZUokENutxpjo7klWe97NA49hXEtI+xlczNGJKdBr0keBX/kSMsnx8kMxYDjh4QTySBaR6zlO4RYPFekWv9QZ2CrfiKCS7AHUpZYZ5AgMBAAECggEAXjCoUPIBHhhOcowIJe/vGlr0lUohzdJ8+GGGzcvhSDf6DF+mwG3lN0C8oU8QS7o6okRkZW46tLAd1u4fS6oGbDHGPBz6RJQ4B4eGxHMe1OcaCsxTmdq4DmuxRhfV3rnPldwqQA/6O01HxtXhxvzwkWOj5SGSZ7a8c5diTIHh9ULd6neUI/rIFC97mH1TeW0uDIxAtyvswz0pIfDhAR+lsOyTg/8qzsIXjpBFG4gAVxhUeUqQA5HzbsFglC08V7ViDk1OEoWi3yIj1CmNdtntJI4cxqLgTK7MNB9udhbN2I9YasuIpZvlAcvPi5R9cYT8vvFBCFGM+i22wtcsQmxdAQKBgQDaD9y6WNmsp+IaAUG3FqbJC8SqwreGIiEflWwVjrd+LuN6yhyr45CobOmhbTz0de8gRJEZKgJZEJcywL1ScrPIC4n1JaG688lk5aR+0Lik5fy1+L6G/CydJoJqlh6KKdwPJmDGpVu/geLJcLkWcYOwL56IL7GK2JI1p607R0x6iQKBgQCbd0n4xG9GkpvW4LDAJiMEhwPu9QcCKIT0mXVXCgMFdWel9bY3+8RSZoziWutaofm9tRHFAqwjbRyOZ+EdckkNsWVkkTnkKGtAhYKgM0GaOwdMFxmvME5WYJ74a5t1jiezDmR3obUBtS2nyQ8CFPUnlimoTR9F6APrth3h8uvwcQKBgFWaCn1AqdrEYNbyjViRVNHxg7fBDohiV3xtjOt9hfzL7VLjipPTlpL3hlNvbZFNxpx1LjyhqCBMif5LeUanbnnmRbbtmeqpDvNDzupVh1Z8TlMlHa4hymW6m1G6MqzsN83es/jnKvgnxd5sGMx9rUN5vhMaHekykVrswu1VVOl5AoGAMDljh7gfMEv/7TqLeT8bM6dR8AivoNrCy0Di5hnj8AiIGzHJ0TnWnxzSbNB5GwcNeew109/NV7vb1MyiRskRoh657eUiiQSEqGIBsAHWQqo2zEKKJA6e7ipQhYyTj3aGGAPJ5FYT2LDDtb0nW6T2ms34pA0wOzYKKU63nEQHLfECgYEAgbbpZJRtPxWB1M/Dg7loguT5O/VUsKefS0JrSD+tJIqYkumH5mejvYW5YEeDdelkvBhAEFUW9JOkzL+1w1g3wz2QQ2aPV/r55cJE3EfOzbwgw6GsO+8UuyiavbFhS3pFZNI0pR5M3u1+SIcLqQCnYLbO11vnEXglB6wjw9/oxPE= #开发者应用私钥
-  alipayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhG03BtsM/pGmA6NmMX5aRxOfTLynN625ekZQYDuouRs4KYc3kU7+ZEVlKUlZCgrG8RbwGC3IBT5puZ2Nn8+YQkyokXGH6VIx/zqLoFG82FN4pVHPSajG5r8uyjfir+/pEGAhi7zKpcmD4iey65iS6RPxVHDSw8KOsVJsCUsWhezOE2w92UGXXXZItYiafRooZanoWQjFjgXqLRF7zygxM0hJGJZ7xz0GmrKVYHnrBppRw7jomVKJBDbrcaY6O5JVnvezQOPYVxLSPsZXMzRiSnQa9JHgV/5EjLJ8fJDMWA44eEE8kgWkes5TuEWDxXpFr/UGdgq34igkuwB1KWWGeQIDAQAB #应用公钥
-  alipay_public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzmDrvcNvhexu3KkxVS9bemdSn6pyQUFmpyOGMDOirGR+RbmldpH2N9bPegzZynb5+bmRHii4ib31XeoXc7M7r6UsPhmPeLoSBNwpC+Uig0VxPa0hmvHjAl6StArhB3eMib6Zo40nM6eCYZLLZ1kKpI5Ad/APov9uLrbSnoeZsgeRibQix07arvTEsZq6pJavNlA+UBjp65o6Bv0+kfQ65pMTpbu+jRtTzkTj1hoW9PjwlWrY21F1FvN67zDWkTB2LjGFsqan0Qoe4/X8nK3VsDvkjIm/ZQsnQr8ZzfcuTzQPrcZpo3h9DPZoHeiToEfXtyk7E0bQHEmYVpmrvk/IJwIDAQAB #支付宝公钥
+  appid: 111  #应用程序唯一标识
+  appPrivateKey: 111 #开发者应用私钥
+  alipayPublicKey: 111 #应用公钥
+  alipay_public_key: 111 #支付宝公钥
 
 ---
 
@@ -129,17 +133,15 @@
 #  mallbook 调起接口参数配置
 mallbook:
   # pay_url:mallbook接口地址    测试环境: https://uat.mallbook.cn/api   生产环境:https://cloudpay.mallbook.cn/api
-  pay_url: https://uat.mallbook.cn/api
+  pay_url: https://cloudpay.mallbook.cn/api
   # merchant_no 业务系统商户平台编号,需替换为mallbook工作人员提供的商户编号
-  merchant_no: HF2023041901
+  merchant_no: MBH23056
   # version 接口版本号
   version: 1.0.0
   # channel_type 渠道类型 HF:汇付
   channel_type: HF
   # merchant_private_key 商户平台私钥,需要替换成商户平台自己生成的私钥
-  merchant_private_key: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIDGadl1oxP7EJg+/o32vpAMa8cwFevD6xu3FjIh04TOuVTpC9hbAwiyX/9OKQi3nHEISyrtnF6Y49tkmb7X8nDwOahvsyOjgNYp+NtSLAdgPAbd6lv2DPC1lVYYu5IkMz7PRifntROFH6OvE5fpj6GinaFY3TYBjyDcC2VVbq/LAgMBAAECgYATdmlvDWF9Vpe2eubcK+u3N7leXH0jqfOxt6UqJISkcN3/4E0DARZfTR5HJtf60k1ZpAhAT7MvdOoTMYwvFNI2WEFRwND5wBl+OdEN/lyWeISjjg1EnnTLj/azGLgE8Z2q/FodGikqrGrc2tSNIy75afeW2gUTF3DHiwcG76SYeQJBAPOyIzpT3yMfM7iVhjaPfmyxvDXq0cLwiAF0eUbrebPO0EevI+PKYhmN2oRMis6wSJbv+sbkElOXQzDefjw0ieUCQQCHRuFlX9JQYUOoyyirKxpu30uys+ygZqmo4PiKgIaaJJPm2p2o7vzZJANGmkmdwFf2LLzij70InKGvqGTEnvfvAkEAnJOMRuG0sOBPXv3TaiLwW+4mu43QkKvy9txbP9H0NC9ha22AZc+XEEwwZmi3lu109mXifv/zNnot1axe91facQJALExcwQqo32OKeXrVvX+m70m2CzX6NeiIhGHvYcOG0HFL8ZwDZu+j4yN04yjhFISJCXdK/1Icj/ZiyBf3r59zBwJACl7Sya9BcqRo5XJ/A7+T2E3VQT2nIopy0hPRLKWFaOzrCIsn3gcC58KSACXl2QMiG5kp1192QOC26b3o57ZecA==
+  merchant_private_key: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALHmyTrxPYcAwABnX+3VW9vxUftm57zBpnbfOT4vizMnKdpfCkIgtdbfdnSCtt637yWM2fxnZfItnhTeQA2lL8f4SXgZt/bVXfmAWi4IxQ+HJy0Qs8nNy2nnjICPBPcpWzHwUxQ/THHqU0a7b9B91J5DFcbQb25BHeRpHwkBw6A/AgMBAAECgYAmcWq2s/7Jt53F+JDAQkTRaHqAyyH0phwkv+QMzhVUfngK2lLLK2pf/nYIg16lDjY9dQx+AJIFHVp1w/kveayzOz3BIqPoznyIVYPolRGZCWPo+2vdp0CIdBh7zahST5g5Gem4cU47wO5hPYs1kXKPG4mUPtaIAMHFxhyLvIagAQJBAOS63AIZrRrldeNCVVNXbpAT52JuWLCgravM9coOh6scmG6UQwxxcott8hneHr9fazk2LHbHMxlG8F+dQPA0+D8CQQDHHJN7Dnske8oJ+1sq4uhQP3HMsmNIgth+ZcaZpiPcxnNKYVGhzAwTVV2ruFJle5ajebo6zfWuqJhtZGRNh1gBAkA/lRoXk1+lfGfa9tOVSVa4wm+t0xLgdqoQefdRZdyc2mQdSSWiTd8Tl0qXmkFd3X6G9uJBWnp/6lJjoektXOwtAkBsZTQsw99qJzIAaSRinpDWTxPG2j6OlR0DAqkxsG7JnAfbsEteh9TzGYAbIgdJVBTX/kbSCJn9ca85rnOkeVABAkAUbDfU3Z702z20NtwAxc1IkrtQ1lKuqSpj9/LuR1/6KRkYQsUWnUiOO9hu5YDWIcflFrnCenF8j8OnvGghltxT
   # mall_book_public_key mallbook测试环境公钥 不需要替换
-  mall_book_public_key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0L2DaHOO8ekhktB6RoHxIcki/0v7OUeOn9tX9VBE+jv6PRjqlZRWL3Qezxz5ADtHEyLv+RFFaceXSep6rWyoQ6DRlvLv5CySUAxAM42LLVe4DI3l/0ccEAIuU5NCpwAAj1zkm2X01DwUCZwymLjlqbDlBvQhpq+1fddtTtA/QLQIDAQAB
-  # mall_book_public_key mallbook生产环境公钥  不需要替换
-  # mall_book_public_key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq6OLZKgUHH5wOk9xSBgN7yC17r3PQwMlY9/IorqrOlaIqrU0eAVZ5+dWrJD/3bdu7Ctq8n8trTm/IUYs7wtMg5SKwyX4/N+KQc2N7LL4yCq4vNl41q9sYgrtA0QnZoucIZcq1mwyu7RTDC8Wp7LGddnlkJsmL8masgMxA6cc9NwIDAQAB
+  mall_book_public_key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq6OLZKgUHH5wOk9xSBgN7yC17r3PQwMlY9/IorqrOlaIqrU0eAVZ5+dWrJD/3bdu7Ctq8n8trTm/IUYs7wtMg5SKwyX4/N+KQc2N7LL4yCq4vNl41q9sYgrtA0QnZoucIZcq1mwyu7RTDC8Wp7LGddnlkJsmL8masgMxA6cc9NwIDAQAB
 
diff --git a/driver/guns-admin/src/main/resources/redis.properties b/driver/guns-admin/src/main/resources/redis.properties
index 726be87..524fa7c 100644
--- a/driver/guns-admin/src/main/resources/redis.properties
+++ b/driver/guns-admin/src/main/resources/redis.properties
@@ -3,18 +3,18 @@
 spring.redis.database=0
 
 # Redis��������ַ
-spring.redis.host=127.0.0.1
-# Redis���������Ӷ˿�
-spring.redis.port=16379
-# Redis�������������루Ĭ��Ϊ�գ�
-spring.redis.password=cKsEeyffDXG5PzNg8CIbrWxFluXrCprZ
-
-## Redis��������ַ
 #spring.redis.host=127.0.0.1
 ## Redis���������Ӷ˿�
-#spring.redis.port=6379
+#spring.redis.port=16379
 ## Redis�������������루Ĭ��Ϊ�գ�
-#spring.redis.password=123456
+#spring.redis.password=cKsEeyffDXG5PzNg8CIbrWxFluXrCprZ
+
+## Redis��������ַ
+spring.redis.host=127.0.0.1
+# Redis���������Ӷ˿�
+spring.redis.port=6379
+# Redis�������������루Ĭ��Ϊ�գ�
+spring.redis.password=123456
 
 # ���ӳ������������ʹ�ø�ֵ��ʾû�����ƣ�
 spring.redis.jedis.pool.max-active=1024
diff --git a/driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java b/driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java
index f46a29c..5cd2811 100644
--- a/driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java
+++ b/driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java
@@ -42,8 +42,15 @@
 //        System.err.println(JSON.toJSONString(driverId));
 
 
-        ResultUtil resultUtil = driverBankService.addDriverBank(1, "蒲芝兵", "15828353127"
-                , "510823198911154858", "6212264402094114687");
+//        ResultUtil resultUtil = driverBankService.addDriverBank(1, "蒲芝兵", "15828353127"
+//                , "510823198911154858", "6212264402094114687");
+//        System.err.println(JSON.toJSONString(resultUtil));
+
+
+//        ResultUtil resultUtil1 = driverBankService.delDriverBank(1, 1);
+//        System.err.println(JSON.toJSONString(resultUtil1));
+
+        ResultUtil resultUtil = driverService.balanceRecharge(1, 1D);
         System.err.println(JSON.toJSONString(resultUtil));
     }
 }

--
Gitblit v1.7.1