From 1798c91f6b0782d1970a8a4fdcaf4a174e68cb61 Mon Sep 17 00:00:00 2001
From: xuhy <3313886187@qq.com>
Date: 星期二, 16 五月 2023 10:45:58 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java               |   34 
 driver/guns-admin/src/main/resources/redis.properties                                                                       |   18 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/OCRUtil.java                           |  269 +++
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceRequest.java            |  176 +
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/AgentMapper.java                                 |   11 
 driver/guns-admin/src/main/resources/application.yml                                                                        |   33 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/PlatformRechargeRecordMapper.java                |   11 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PamentOrderUser.java             |   46 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/TrhRequest.java               |   31 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/RechargeRecord.java                            |    5 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSASignature.java                 |  118 +
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/DivisionRecord.java                            |   73 
 management/pom.xml                                                                                                          |    1 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DriverMapper.xml                         |    4 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Receive.java                     |  102 +
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSAEncryptGeneration.java         |   65 
 management/guns-admin/src/main/java/com/stylefeng/guns/config/RedisConfig.java                                              |   46 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OrderServiceImpl.java                   |  392 +++
 user/guns-admin/src/main/resources/application.yml                                                                          |   31 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/StringUtil.java               |   23 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java                        |  110 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/BranchOfficeServiceImpl.java        |   48 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverBankServiceImpl.java          |  108 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml                     |    4 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DivisionRecordMapper.xml                 |   19 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceResponse.java           |  121 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/config/ChannelConfig.java          |   60 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/BindAccount.java             |  107 +
 driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java                                        |   14 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DivisionRecordMapper.java                        |   11 
 management/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java                                   |  265 ++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DriverBank.java                            |   46 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java              |   49 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/UnbindAccount.java           |   19 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveUser.java                 |   27 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/PlatformRechargeRecordMapper.xml         |   16 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/StringUtil.java                   |   23 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/config/ChannelConfig.java              |   60 
 user/guns-admin/src/main/resources/redis.properties                                                                         |   22 
 driver/guns-admin/pom.xml                                                                                                   |   27 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IAgentService.java                           |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/CacheUtils.java               |   39 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Register.java                |  193 ++
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrder.java                |  293 +++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java                    |    2 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Base64.java                       |  288 +++
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IBranchOfficeService.java                |    8 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSAEncryptGeneration.java     |   65 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDivisionRecordService.java                  |   11 
 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/dao/mapping/OrderMapper.xml                      |    3 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DivisionRecordServiceImpl.java          |   15 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Agent.java                                     |  105 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DriverBankMapper.java                        |   11 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/YouTuiDriver.java                              |    2 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AgentServiceImpl.java                   |   15 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/PlatformRechargeRecordServiceImpl.java  |   15 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IPlatformRechargeRecordService.java          |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java          |    2 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/CacheUtils.java                   |   39 
 management/guns-admin/src/main/resources/redis.properties                                                                   |   29 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java                                |   20 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveGood.java                 |   48 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AccountChangeDetailServiceImpl.java |   28 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Complete.java                    |   58 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverBankMapper.xml                 |   14 
 user/guns-admin/pom.xml                                                                                                     |    6 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/TrhRequest.java                   |   31 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/Base64.java                   |  288 +++
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Driver.java                                    |   20 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/AgentMapper.xml                          |   21 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/OrderMapper.xml                          |    2 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java                 |   52 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/PlatformRechargeRecord.java                    |   58 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IAgentService.java                       |   11 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AgentServiceImpl.java               |   55 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrderGood.java            |   48 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceRequest.java        |  176 +
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverBankService.java                  |   33 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSASignature.java             |  118 +
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Transfer.java                     |   76 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/OrderController.java                                    |  144 +
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Order.java                                     |    5 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/DriverInfoWarpper.java                   |    8 
 user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java                                  |   47 
 driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceResponse.java       |  121 +
 86 files changed, 4,998 insertions(+), 303 deletions(-)

diff --git a/driver/guns-admin/pom.xml b/driver/guns-admin/pom.xml
index a2cdae4..ec03fc5 100644
--- a/driver/guns-admin/pom.xml
+++ b/driver/guns-admin/pom.xml
@@ -68,17 +68,17 @@
             <version>2.11.3</version>
         </dependency>
 
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-tomcat</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>javax.servlet-api</artifactId>
-            <version>3.1.0</version>
-            <scope>provided</scope>
-        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
+            <!--<scope>provided</scope>-->
+        <!--</dependency>-->
+        <!--<dependency>-->
+            <!--<groupId>javax.servlet</groupId>-->
+            <!--<artifactId>javax.servlet-api</artifactId>-->
+            <!--<version>3.1.0</version>-->
+            <!--<scope>provided</scope>-->
+        <!--</dependency>-->
 
 
         <!--shiro依赖-->
@@ -194,6 +194,11 @@
             <artifactId>wechatpay-java-shangmi</artifactId>
             <version>0.2.1</version>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.7.7</version>
+        </dependency>
     </dependencies>
 
 
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 271b146..ba6a17e 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,9 +1,12 @@
 package com.supersavedriving.driver.modular.system.api;
 
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.supersavedriving.driver.modular.system.model.DriverBank;
 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.Register;
+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;
 import com.supersavedriving.driver.modular.system.util.huawei.SMSUtil;
@@ -80,6 +83,12 @@
     @Autowired
     private IEditionService editionService;
 
+    @Autowired
+    private IDriverBankService driverBankService;
+
+    @Autowired
+    private IAgentService agentService;
+
 
 
 
@@ -92,7 +101,7 @@
     })
     public ResponseWarpper<List<OpenCityWarpper>> queryCityList(){
         try {
-            List<OpenCityWarpper> list = branchOfficeService.queryOpenCity();
+            List<OpenCityWarpper> list = agentService.queryOpenCity();
             return ResponseWarpper.success(list);
         }catch (Exception e){
             e.printStackTrace();
@@ -870,4 +879,103 @@
             return new ResponseWarpper(500, e.getMessage());
         }
     }
+
+
+
+    @ResponseBody
+    @PostMapping("/api/driver/microenterprise")
+//    @ServiceLog(name = "绑定商户", url = "/api/driver/microenterprise")
+    @ApiOperation(value = "绑定商户", tags = {"司机端-个人中心"}, notes = "")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "姓名", name = "name", required = true, dataType = "String"),
+            @ApiImplicitParam(value = "身份证号码", name = "IDCode", required = true, dataType = "String"),
+            @ApiImplicitParam(value = "手机号", name = "phone", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResponseWarpper microenterprise(String name, String IDCode, String phone){
+        try {
+            Integer uid = driverService.getUserByRequest();
+            if(null == uid){
+                return ResponseWarpper.tokenErr();
+            }
+            ResultUtil resultUtil = driverService.microenterprise(uid, name, IDCode, phone);
+            return ResponseWarpper.success(resultUtil);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseWarpper(500, e.getMessage());
+        }
+    }
+
+
+
+
+    @ResponseBody
+    @PostMapping("/api/driver/queryBank")
+//    @ServiceLog(name = "获取绑定的银行卡", url = "/api/driver/queryBank")
+    @ApiOperation(value = "获取绑定的银行卡", tags = {"司机端-个人中心"}, notes = "")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResponseWarpper<DriverBank> queryBank(){
+        try {
+            Integer uid = driverService.getUserByRequest();
+            if(null == uid){
+                return ResponseWarpper.tokenErr();
+            }
+            DriverBank driverId = driverBankService.selectOne(new EntityWrapper<DriverBank>().eq("driverId", uid));
+            return ResponseWarpper.success(driverId);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseWarpper(500, e.getMessage());
+        }
+    }
+
+
+    @ResponseBody
+    @PostMapping("/api/driver/addDriverBank")
+//    @ServiceLog(name = "绑定银行卡", url = "/api/driver/addDriverBank")
+    @ApiOperation(value = "绑定银行卡", tags = {"司机端-个人中心"}, notes = "")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "姓名", name = "name", required = true, dataType = "String"),
+            @ApiImplicitParam(value = "身份证号码", name = "IDCode", required = true, dataType = "String"),
+            @ApiImplicitParam(value = "手机号", name = "phone", required = true, dataType = "String"),
+            @ApiImplicitParam(value = "银行卡号", name = "bankNumber", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResponseWarpper addDriverBank(String name, String phone, String IDCode, String bankNumber){
+        try {
+            Integer uid = driverService.getUserByRequest();
+            if(null == uid){
+                return ResponseWarpper.tokenErr();
+            }
+            ResultUtil resultUtil = driverBankService.addDriverBank(uid, name, phone, IDCode, bankNumber);
+            return ResponseWarpper.success(resultUtil);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseWarpper(500, e.getMessage());
+        }
+    }
+
+
+    @ResponseBody
+    @PostMapping("/api/driver/delDriverBank")
+//    @ServiceLog(name = "解绑银行卡", url = "/api/driver/delDriverBank")
+    @ApiOperation(value = "解绑银行卡", tags = {"司机端-个人中心"}, notes = "")
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "银行卡id", name = "id", required = true, dataType = "int"),
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResponseWarpper delDriverBank(Integer id){
+        try {
+            Integer uid = driverService.getUserByRequest();
+            if(null == uid){
+                return ResponseWarpper.tokenErr();
+            }
+            ResultUtil resultUtil = driverBankService.delDriverBank(uid, id);
+            return ResponseWarpper.success(resultUtil);
+        }catch (Exception e){
+            e.printStackTrace();
+            return new ResponseWarpper(500, e.getMessage());
+        }
+    }
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DriverBankMapper.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DriverBankMapper.java
new file mode 100644
index 0000000..d3b7127
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DriverBankMapper.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.DriverBank;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/4/23 17:40
+ */
+public interface DriverBankMapper extends BaseMapper<DriverBank> {
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverBankMapper.xml b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverBankMapper.xml
new file mode 100644
index 0000000..34a4c75
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverBankMapper.xml
@@ -0,0 +1,14 @@
+<?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.DriverBankMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.supersavedriving.driver.modular.system.model.DriverBank">
+        <id column="id" property="id"/>
+        <result column="driverId" property="driverId"/>
+        <result column="name" property="name"/>
+        <result column="phone" property="phone"/>
+        <result column="IDCode" property="IDCode"/>
+        <result column="bankNumber" property="bankNumber"/>
+    </resultMap>
+</mapper>
\ No newline at end of file
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml
index 5369833..90f1c46 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml
@@ -49,5 +49,9 @@
         <result column="zfbCollectionCode" property="zfbCollectionCode"/>
         <result column="openid" property="openid"/>
         <result column="openOrderQRCode" property="openOrderQRCode"/>
+        <result column="merchantNumber" property="merchantNumber"/>
+        <result column="merchantName" property="merchantName"/>
+        <result column="merchantPhone" property="merchantPhone"/>
+        <result column="merchantIDCode" property="merchantIDCode"/>
     </resultMap>
 </mapper>
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml
index c54cda9..e05ff23 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml
@@ -85,7 +85,7 @@
         a.startPrice
         from t_order a
         left join t_app_user b on (a.userId = b.id)
-        where a.`status` = 1 and a.hallOrder = 1 and a.state = 101 order by a.createTime desc
+        where a.`status` = 1 and a.hallOrder = 1 and a.state in (101, 201) order by a.createTime desc
     </select>
 
 
@@ -93,6 +93,7 @@
     <select id="queryOrderInfo" resultType="com.supersavedriving.driver.modular.system.warpper.OrderInfoWarpper">
         select
         a.id,
+        b.id as userId,
         b.avatar,
         a.userName,
         a.userPhone,
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java
index 1296169..63b141a 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java
@@ -237,4 +237,24 @@
      */
     @TableField("openOrderQRCode")
     private Integer openOrderQRCode;
+    /**
+     * 商户号
+     */
+    @TableField("merchantNumber")
+    private String merchantNumber;
+    /**
+     * 商户姓名
+     */
+    @TableField("merchantName")
+    private String merchantName;
+    /**
+     * 商户电话
+     */
+    @TableField("merchantPhone")
+    private String merchantPhone;
+    /**
+     * 商户身份证号码
+     */
+    @TableField("merchantIDCode")
+    private String merchantIDCode;
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DriverBank.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DriverBank.java
new file mode 100644
index 0000000..bbe2916
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DriverBank.java
@@ -0,0 +1,46 @@
+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;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/4/23 17:38
+ */
+@Data
+@TableName("t_driver_bank")
+public class DriverBank {
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+    /**
+     * 司机id
+     */
+    @TableField("driverId")
+    private Integer driverId;
+    /**
+     * 姓名
+     */
+    @TableField("name")
+    private String name;
+    /**
+     * 手机号
+     */
+    @TableField("phone")
+    private String phone;
+    /**
+     * 身份证号码
+     */
+    @TableField("IDCode")
+    private String IDCode;
+    /**
+     * 银行卡号
+     */
+    @TableField("bankNumber")
+    private String bankNumber;
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IAgentService.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IAgentService.java
index cc35f85..7f3990b 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IAgentService.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IAgentService.java
@@ -2,10 +2,21 @@
 
 import com.baomidou.mybatisplus.service.IService;
 import com.supersavedriving.driver.modular.system.model.Agent;
+import com.supersavedriving.driver.modular.system.warpper.OpenCityWarpper;
+
+import java.util.List;
 
 /**
  * @author zhibing.pu
  * @Date 2023/3/22 22:52
  */
 public interface IAgentService extends IService<Agent> {
+
+    /**
+     * 获取开通省市数据
+     * @return
+     * @throws Exception
+     */
+    List<OpenCityWarpper> queryOpenCity() throws Exception;
+
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IBranchOfficeService.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IBranchOfficeService.java
index 4b3854d..7592288 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IBranchOfficeService.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IBranchOfficeService.java
@@ -15,14 +15,6 @@
 
 
     /**
-     * 获取开通省市数据
-     * @return
-     * @throws Exception
-     */
-    List<OpenCityWarpper> queryOpenCity() throws Exception;
-
-
-    /**
      * 根据城市code获取开通区域
      * @param cityCode  城市code
      * @return
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverBankService.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverBankService.java
new file mode 100644
index 0000000..441b6f8
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverBankService.java
@@ -0,0 +1,33 @@
+package com.supersavedriving.driver.modular.system.service;
+
+import com.baomidou.mybatisplus.service.IService;
+import com.supersavedriving.driver.modular.system.model.DriverBank;
+import com.supersavedriving.driver.modular.system.util.ResultUtil;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/4/23 17:42
+ */
+public interface IDriverBankService extends IService<DriverBank> {
+
+
+    /**
+     * 添加银行卡
+     * @param name
+     * @param phone
+     * @param IDCode
+     * @param bankNumber
+     * @return
+     * @throws Exception
+     */
+    ResultUtil addDriverBank(Integer uid, String name, String phone, String IDCode, String bankNumber) throws Exception;
+
+
+    /**
+     * 删除银行卡
+     * @param id
+     * @return
+     * @throws Exception
+     */
+    ResultUtil delDriverBank(Integer uid, Integer id) throws Exception;
+}
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 306bab2..0cdd764 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
@@ -175,4 +175,15 @@
      * @throws Exception
      */
     ResultUtil closeOrderQRCode(Integer uid) throws Exception;
+
+
+    /**
+     * 开通小微商户
+     * @param name
+     * @param number
+     * @param phone
+     * @return
+     * @throws Exception
+     */
+    ResultUtil microenterprise(Integer uid, String name, String number, String phone) throws Exception;
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AccountChangeDetailServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AccountChangeDetailServiceImpl.java
index 0b1b322..ad5147d 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AccountChangeDetailServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AccountChangeDetailServiceImpl.java
@@ -129,7 +129,7 @@
             }
 
             double d = num1.doubleValue();
-            if(backgroundBalance < d){
+            if(backgroundBalance > 0 && backgroundBalance < d){
                 AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                 accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                 accountChangeDetail.setUserType(2);
@@ -143,7 +143,8 @@
                 this.insert(accountChangeDetail);
                 d -= backgroundBalance;
                 driver.setBackgroundBalance(0D);
-            }else{
+            }
+            if(backgroundBalance > 0 && backgroundBalance >= d){
                 AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                 accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                 accountChangeDetail.setUserType(2);
@@ -151,16 +152,16 @@
                 accountChangeDetail.setType(1);
                 accountChangeDetail.setChangeType(8);
                 accountChangeDetail.setOldData(driver.getBackgroundBalance());
-                d = 0;
                 driver.setBackgroundBalance(driver.getBackgroundBalance() - d);
                 accountChangeDetail.setNewData(driver.getBackgroundBalance());
                 accountChangeDetail.setExplain("收取保险费");
                 accountChangeDetail.setCreateTime(new Date());
                 this.insert(accountChangeDetail);
+                d = 0;
             }
 
             if(d > 0){
-                if(couponBalance < d){
+                if(couponBalance > 0 && couponBalance < d){
                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                     accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                     accountChangeDetail.setUserType(2);
@@ -174,7 +175,8 @@
                     this.insert(accountChangeDetail);
                     d -= couponBalance;
                     driver.setCouponBalance(0D);
-                }else{
+                }
+                if(couponBalance > 0 && couponBalance >= d){
                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                     accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                     accountChangeDetail.setUserType(2);
@@ -182,16 +184,16 @@
                     accountChangeDetail.setType(1);
                     accountChangeDetail.setChangeType(8);
                     accountChangeDetail.setOldData(driver.getCouponBalance());
-                    d = 0;
                     driver.setCouponBalance(driver.getCouponBalance() - d);
                     accountChangeDetail.setNewData(driver.getCouponBalance());
                     accountChangeDetail.setExplain("收取保险费");
                     accountChangeDetail.setCreateTime(new Date());
                     this.insert(accountChangeDetail);
+                    d = 0;
                 }
             }
             if(d > 0){
-                if(commission < d){
+                if(commission > 0 && commission < d){
                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                     accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                     accountChangeDetail.setUserType(2);
@@ -205,7 +207,8 @@
                     this.insert(accountChangeDetail);
                     d -= commission;
                     driver.setCommission(0D);
-                }else{
+                }
+                if(commission > 0 && commission >= d){
                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                     accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                     accountChangeDetail.setUserType(2);
@@ -213,18 +216,19 @@
                     accountChangeDetail.setType(1);
                     accountChangeDetail.setChangeType(8);
                     accountChangeDetail.setOldData(driver.getCommission());
-                    d = 0;
                     driver.setCommission(driver.getCommission() - d);
                     accountChangeDetail.setNewData(driver.getCommission());
                     accountChangeDetail.setExplain("收取保险费");
                     accountChangeDetail.setCreateTime(new Date());
                     this.insert(accountChangeDetail);
+                    d = 0;
                 }
             }
             if(d > 0){
-                if(balance < d){
+                if(balance > 0 && balance < d){
                     continue;
-                }else{
+                }
+                if(balance > 0 && balance >= d){
                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
                     accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                     accountChangeDetail.setUserType(2);
@@ -232,12 +236,12 @@
                     accountChangeDetail.setType(1);
                     accountChangeDetail.setChangeType(8);
                     accountChangeDetail.setOldData(driver.getBalance());
-                    d = 0;
                     driver.setBalance(driver.getBalance() - d);
                     accountChangeDetail.setNewData(driver.getBalance());
                     accountChangeDetail.setExplain("收取保险费");
                     accountChangeDetail.setCreateTime(new Date());
                     this.insert(accountChangeDetail);
+                    d = 0;
                 }
             }
 
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AgentServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AgentServiceImpl.java
index ce2526b..2acf8e6 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AgentServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AgentServiceImpl.java
@@ -1,10 +1,15 @@
 package com.supersavedriving.driver.modular.system.service.impl;
 
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.service.impl.ServiceImpl;
 import com.supersavedriving.driver.modular.system.dao.AgentMapper;
 import com.supersavedriving.driver.modular.system.model.Agent;
 import com.supersavedriving.driver.modular.system.service.IAgentService;
+import com.supersavedriving.driver.modular.system.warpper.OpenCityWarpper;
 import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @author zhibing.pu
@@ -12,4 +17,54 @@
  */
 @Service
 public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements IAgentService {
+
+
+    /**
+     * 获取开通省市数据
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<OpenCityWarpper> queryOpenCity() throws Exception {
+        List<Agent> branchOffices = this.selectList(new EntityWrapper<Agent>().eq("status", 1));
+        List<OpenCityWarpper> province = new ArrayList<>();
+
+        //遍历处理省级数据
+        List<String> provinceCodes = new ArrayList<>();
+        for (Agent branchOffice : branchOffices) {
+            String provinceCode = branchOffice.getProvinceCode();
+            if(!provinceCodes.contains(provinceCode)){
+                provinceCodes.add(provinceCode);
+
+                OpenCityWarpper openCityWarpper = new OpenCityWarpper();
+                openCityWarpper.setCode(provinceCode);
+                openCityWarpper.setName(branchOffice.getProvinceName());
+                province.add(openCityWarpper);
+            }
+        }
+
+        //遍历处理省级对应的市级数据
+        for (OpenCityWarpper openCityWarpper : province) {
+            String code = openCityWarpper.getCode();
+
+            List<OpenCityWarpper> city = new ArrayList<>();
+            List<String> cityCodes = new ArrayList<>();
+            for (Agent branchOffice : branchOffices) {
+                String provinceCode1 = branchOffice.getProvinceCode();
+                String cityCode = branchOffice.getCityCode();
+
+                if(code.equals(provinceCode1) && !cityCodes.contains(cityCode)){
+                    cityCodes.add(cityCode);
+
+                    OpenCityWarpper openCityWarpper1 = new OpenCityWarpper();
+                    openCityWarpper1.setCode(cityCode);
+                    openCityWarpper1.setName(branchOffice.getCityName());
+                    city.add(openCityWarpper1);
+                }
+            }
+            openCityWarpper.setSublevel(city);
+        }
+        return province;
+    }
+
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/BranchOfficeServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/BranchOfficeServiceImpl.java
index 742c1d9..14a3d92 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/BranchOfficeServiceImpl.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/BranchOfficeServiceImpl.java
@@ -21,54 +21,6 @@
 public class BranchOfficeServiceImpl extends ServiceImpl<BranchOfficeMapper, BranchOffice> implements IBranchOfficeService {
 
 
-    /**
-     * 获取开通省市数据
-     * @return
-     * @throws Exception
-     */
-    @Override
-    public List<OpenCityWarpper> queryOpenCity() throws Exception {
-        List<BranchOffice> branchOffices = this.selectList(new EntityWrapper<BranchOffice>().eq("status", 1));
-        List<OpenCityWarpper> province = new ArrayList<>();
-
-        //遍历处理省级数据
-        List<String> provinceCodes = new ArrayList<>();
-        for (BranchOffice branchOffice : branchOffices) {
-            String provinceCode = branchOffice.getProvinceCode();
-            if(!provinceCodes.contains(provinceCode)){
-                provinceCodes.add(provinceCode);
-
-                OpenCityWarpper openCityWarpper = new OpenCityWarpper();
-                openCityWarpper.setCode(provinceCode);
-                openCityWarpper.setName(branchOffice.getProvinceName());
-                province.add(openCityWarpper);
-            }
-        }
-
-        //遍历处理省级对应的市级数据
-        for (OpenCityWarpper openCityWarpper : province) {
-            String code = openCityWarpper.getCode();
-
-            List<OpenCityWarpper> city = new ArrayList<>();
-            List<String> cityCodes = new ArrayList<>();
-            for (BranchOffice branchOffice : branchOffices) {
-                String provinceCode1 = branchOffice.getProvinceCode();
-                String cityCode = branchOffice.getCityCode();
-
-                if(code.equals(provinceCode1) && !cityCodes.contains(cityCode)){
-                    cityCodes.add(cityCode);
-
-                    OpenCityWarpper openCityWarpper1 = new OpenCityWarpper();
-                    openCityWarpper1.setCode(cityCode);
-                    openCityWarpper1.setName(branchOffice.getCityName());
-                    city.add(openCityWarpper1);
-                }
-            }
-            openCityWarpper.setSublevel(city);
-        }
-        return province;
-    }
-
 
     /**
      * 根据城市code获取开通区域
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverBankServiceImpl.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverBankServiceImpl.java
new file mode 100644
index 0000000..5dc4692
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverBankServiceImpl.java
@@ -0,0 +1,108 @@
+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.DriverBankMapper;
+import com.supersavedriving.driver.modular.system.model.Driver;
+import com.supersavedriving.driver.modular.system.model.DriverBank;
+import com.supersavedriving.driver.modular.system.service.IDriverBankService;
+import com.supersavedriving.driver.modular.system.service.IDriverService;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.BindAccount;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.InterfaceResponse;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.UnbindAccount;
+import com.supersavedriving.driver.modular.system.util.MallBook.util.TrhRequest;
+import com.supersavedriving.driver.modular.system.util.ResultUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/4/23 17:42
+ */
+@Service
+public class DriverBankServiceImpl extends ServiceImpl<DriverBankMapper, DriverBank> implements IDriverBankService {
+
+    @Autowired
+    private IDriverService driverService;
+
+
+    /**
+     * 添加银行卡
+     * @param name
+     * @param phone
+     * @param IDCode
+     * @param bankNumber
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil addDriverBank(Integer uid, String name, String phone, String IDCode, String bankNumber) throws Exception {
+        Driver driver = driverService.selectById(uid);
+        if(ToolUtil.isEmpty(driver.getMerchantNumber())){
+            return ResultUtil.error("请先注册商户");
+        }
+        int count = this.selectCount(new EntityWrapper<DriverBank>().eq("driverId", uid));
+        if(count != 0){
+            return ResultUtil.error("您已经有结算账户了");
+        }
+        DriverBank driverBank = new DriverBank();
+        driverBank.setDriverId(uid);
+        driverBank.setBankNumber(bankNumber);
+        driverBank.setIDCode(IDCode);
+        driverBank.setName(name);
+        driverBank.setPhone(phone);
+
+        BindAccount bindAccount = new BindAccount();
+        bindAccount.setUserId(driver.getMerchantNumber());
+        bindAccount.setCertId(IDCode);
+        bindAccount.setCardName(name);
+        bindAccount.setCardNo(bankNumber);
+        bindAccount.setBankAcctType("2");
+        bindAccount.setPhone(phone);
+        TrhRequest<BindAccount> request = new TrhRequest();
+        InterfaceResponse execute = request.execute(bindAccount, BindAccount.SERVICE_CODE);
+        if(!"0000".equals(execute.getResult())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        if("0".equals(status)){
+            return ResultUtil.error("处理中");
+        }
+        this.insert(driverBank);
+        return ResultUtil.success();
+    }
+
+
+    @Override
+    public ResultUtil delDriverBank(Integer uid, Integer id) throws Exception {
+        Driver driver = driverService.selectById(uid);
+        if(ToolUtil.isEmpty(driver.getMerchantNumber())){
+            return ResultUtil.error("请先注册商户");
+        }
+        UnbindAccount unbindAccount = new UnbindAccount();
+        unbindAccount.setUserId(driver.getMerchantNumber());
+
+        TrhRequest<UnbindAccount> request = new TrhRequest<>();
+        InterfaceResponse execute = request.execute(unbindAccount, UnbindAccount.SERVICE_CODE);
+        if(!"0000".equals(execute.getResult())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        if("0".equals(status)){
+            return ResultUtil.error("处理中");
+        }
+        this.deleteById(id);
+        return ResultUtil.success();
+    }
+}
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 966a7ee..506c1d4 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,6 +13,9 @@
 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.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.warpper.*;
@@ -315,6 +318,7 @@
                 key = token.substring(token.length() - 16);
             }
             redisUtil.setStrValue(key, driver.getId().toString(), 7 * 24 * 60 * 60);//7天
+            redisUtil.setStrValue("DRIVER_" + phone, key, 7 * 24 * 60 * 60);//7天
             return token;
         }
         return "";
@@ -548,9 +552,9 @@
             driverInfo.setYouTuiEnd(youTuiDriver.getType() == 1 ? youTuiDriver.getFailureTime().getTime() : youTuiDriver.getEndTime().getTime());
         }
         List<Integer> state = Arrays.asList(107, 108, 109);
-        int count = orderService.selectCount(new EntityWrapper<Order>().eq("driverId", uid).eq("status", 1).in("state", state).last(" and DATE_FORMAT('%Y-%m-%d', createTime) = DATE_FORMAT('%Y-%m-%d', now())"));
+        int count = orderService.selectCount(new EntityWrapper<Order>().eq("driverId", uid).eq("status", 1).in("state", state).last(" and DATE_FORMAT(createTime, '%Y-%m-%d') = DATE_FORMAT(now(), '%Y-%m-%d')"));
         driverInfo.setTodayNum(count);
-        count = orderService.selectCount(new EntityWrapper<Order>().eq("driverId", uid).eq("status", 1).in("state", state).last(" and DATE_FORMAT('%Y-%m', createTime) = DATE_FORMAT('%Y-%m', now())"));
+        count = orderService.selectCount(new EntityWrapper<Order>().eq("driverId", uid).eq("status", 1).in("state", state).last(" and DATE_FORMAT(createTime, '%Y-%m') = DATE_FORMAT(now(), '%Y-%m')"));
         driverInfo.setMonthNum(count);
         DriverWork driverWork = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", uid).eq("status", 1));
         driverInfo.setWork(null == driverWork ? 0 : 1);
@@ -841,4 +845,45 @@
         this.updateById(driver);
         return ResultUtil.success();
     }
+
+
+    /**
+     * 开通小微商户
+     * @param name
+     * @param number
+     * @param phone
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public ResultUtil microenterprise(Integer uid, String name, String number, String phone) throws Exception {
+        Driver driver = this.selectById(uid);
+        Register registerVO = new Register();
+        registerVO.setMerUserId("driver_" + uid);
+        registerVO.setPhone(phone);
+        registerVO.setUserType("0");
+        registerVO.setUserName(name);
+        registerVO.setCertId(number);
+        registerVO.setNotifyUrl("");
+        TrhRequest<Register> request = new TrhRequest();
+        InterfaceResponse execute = request.execute(registerVO, Register.SERVICE_CODE);
+        if(!"0000".equals(execute.getResult())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        if("0".equals(status)){
+            return ResultUtil.error("处理中");
+        }
+        String userId = jsonObject.getString("userId");
+        driver.setMerchantNumber(userId);
+        driver.setMerchantIDCode(number);
+        driver.setMerchantName(name);
+        driver.setMerchantPhone(phone);
+        this.updateById(driver);
+        return ResultUtil.success();
+    }
 }
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 e5ac4a8..69279ab 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
@@ -70,7 +70,7 @@
             }
         }
 
-        DriverWork driverWork = this.selectOne(new EntityWrapper<DriverWork>().eq("driverId", 1).eq("status", 1));
+        DriverWork driverWork = this.selectOne(new EntityWrapper<DriverWork>().eq("driverId", driverId).eq("status", 1));
         if(null != driverWork){
             return ResultUtil.error("您正在上班中");
         }
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 4416d6b..0b943a8 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
@@ -190,7 +190,13 @@
             pushUtil.pushOrderStatus(uid, 2, order.getId(), order.getStatus());
         }else{
             //开始推单
-            pushOrder(order);
+            Order finalOrder = order;
+            new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    pushOrder(finalOrder);
+                }
+            }).start();
         }
         return ResultUtil.success(order.getState() == 102 ? order.getId() : null);
     }
@@ -535,6 +541,9 @@
         String value = redisUtil.getValue("DRIVER" + uid);
         List<HallOrderList> hallOrderLists = this.baseMapper.queryOrderHall(pageNum, pageSize);
         hallOrderLists.forEach(hallOrderList -> {
+            if(ToolUtil.isEmpty(hallOrderList.getAvatar())){
+                hallOrderList.setAvatar("https://csxdj.obs.cn-south-1.myhuaweicloud.com:443/66cc269703a84e4da87fb21e2c21ab1f.png");
+            }
             hallOrderList.setCurrentDistance(0D);
             if(ToolUtil.isNotEmpty(value)){
                 Map<String, Double> distance = GeodesyUtil.getDistance(hallOrderList.getStartLng() + "," + hallOrderList.getStartLat(), value);
@@ -714,9 +723,12 @@
         if(orderInfoWarpper.getTravelTime() == null){
             orderInfoWarpper.setTravelTime(0);
         }
-        AppUser appUser = appUserService.selectById(uid);
-        orderInfoWarpper.setBalance(appUser.getAccountBalance());
+        AppUser appUser = appUserService.selectById(orderInfoWarpper.getUserId());
+        orderInfoWarpper.setBalance(null == appUser ? 0D : appUser.getAccountBalance());
         orderInfoWarpper.setCurrentDistance(0D);
+        if(ToolUtil.isEmpty(orderInfoWarpper.getAvatar())){
+            orderInfoWarpper.setAvatar("https://csxdj.obs.cn-south-1.myhuaweicloud.com:443/66cc269703a84e4da87fb21e2c21ab1f.png");
+        }
         String value = redisUtil.getValue("DRIVER" + uid);
         orderInfoWarpper.setPickUpTime(0);
         if(ToolUtil.isNotEmpty(value)){
@@ -956,7 +968,13 @@
         orderTransferService.insert(orderTransfer);
 
         //开始派单
-        pushOrder(order);
+        Order finalOrder = order;
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                pushOrder(finalOrder);
+            }
+        }).start();
         return ResultUtil.success();
     }
 
@@ -1165,6 +1183,7 @@
                         if(num1 > 0){
                             Driver driver1 = driverService.selectById(appUser.getInviterId());
                             AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                            accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                             accountChangeDetail.setUserType(2);
                             accountChangeDetail.setUserId(driver1.getId());
                             accountChangeDetail.setType(1);
@@ -1211,6 +1230,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver1.getId());
                                     accountChangeDetail.setType(1);
@@ -1236,6 +1256,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver2.getId());
                                     accountChangeDetail.setType(1);
@@ -1261,6 +1282,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver3.getId());
                                     accountChangeDetail.setType(1);
@@ -1289,6 +1311,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver1.getId());
                                     accountChangeDetail.setType(1);
@@ -1314,6 +1337,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver2.getId());
                                     accountChangeDetail.setType(1);
@@ -1342,6 +1366,7 @@
                                 revenueService.insert(revenue);
 
                                 AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                 accountChangeDetail.setUserType(2);
                                 accountChangeDetail.setUserId(driver1.getId());
                                 accountChangeDetail.setType(1);
@@ -1374,6 +1399,7 @@
         //司机余额扣减抽佣金额
         if(n > 0){
             AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+            accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
             accountChangeDetail.setUserType(2);
             accountChangeDetail.setUserId(driver.getId());
             accountChangeDetail.setType(1);
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/config/ChannelConfig.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/config/ChannelConfig.java
new file mode 100644
index 0000000..1a5697a
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/config/ChannelConfig.java
@@ -0,0 +1,60 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.config;
+
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.core.io.ClassPathResource;
+
+import java.util.Properties;
+
+/**
+ * @Author xiaogc
+ * @Date 2022/2/10 10:03
+ */
+public class ChannelConfig {
+    /**
+     * mallbook 测试环境地址
+     */
+    public static String payUrl;
+
+    /**
+     * 业务系统商户平台编号
+     */
+    public static String merchantNo;
+    /**
+     * 接口版本号,不同版本号触发不同接口业务
+     */
+    public static String version;
+    /*
+     * 渠道类型 HF:汇付
+     */
+    public static String channelType;
+
+    /**
+     * 商户平台私钥路径
+     */
+    public static String merchantPrivateKey;
+    /**
+     * mallbook公钥路径
+     */
+    public static String mallBookPublicKey;
+
+    static {
+        YamlPropertiesFactoryBean yamlProFb = new YamlPropertiesFactoryBean();
+        yamlProFb.setResources(new ClassPathResource("application.yaml"));
+        Properties properties = yamlProFb.getObject();
+        System.out.println("mallbook 参数配置初始化");
+        System.out.println("--------------------------------");
+        System.out.println("环境地址:" + properties.get("mallbook.pay_url"));
+        System.out.println("商户平台编号:" + properties.get("mallbook.merchant_no"));
+        System.out.println("接口版本号:" + properties.get("mallbook.version"));
+        System.out.println("渠道类型:" + properties.get("mallbook.channel_type"));
+        System.out.println("商户平台私钥:" + properties.get("mallbook.merchant_private_key"));
+        System.out.println("mallbook 公钥:" + properties.get("mallbook.mall_book_public_key"));
+        System.out.println("--------------------------------");
+        payUrl = properties.get("mallbook.pay_url").toString();
+        merchantNo = properties.get("mallbook.merchant_no").toString();
+        version = properties.get("mallbook.version").toString();
+        channelType = properties.get("mallbook.channel_type").toString();
+        merchantPrivateKey = properties.get("mallbook.merchant_private_key").toString();
+        mallBookPublicKey = properties.get("mallbook.mall_book_public_key").toString();
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/BindAccount.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/BindAccount.java
new file mode 100644
index 0000000..42f2532
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/BindAccount.java
@@ -0,0 +1,107 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class BindAccount<T> {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "bindAccount";
+    //子商户编号
+    private String userId;
+    //身份证号
+    private String certId;
+    //结算账户名
+    private String cardName;
+    //结算账户号
+    private String cardNo;
+    //银行账户类型
+    private String bankAcctType;
+    //手机号
+    private String phone;
+    //开户银行名称
+    private String bankName;
+    //银行编码
+    private String bankCode;
+    //省份编码
+    private String provCode;
+    //地区编码
+    private String areaCode;
+
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getCertId() {
+        return certId;
+    }
+
+    public void setCertId(String certId) {
+        this.certId = certId;
+    }
+
+    public String getCardName() {
+        return cardName;
+    }
+
+    public void setCardName(String cardName) {
+        this.cardName = cardName;
+    }
+
+    public String getCardNo() {
+        return cardNo;
+    }
+
+    public void setCardNo(String cardNo) {
+        this.cardNo = cardNo;
+    }
+
+    public String getBankAcctType() {
+        return bankAcctType;
+    }
+
+    public void setBankAcctType(String bankAcctType) {
+        this.bankAcctType = bankAcctType;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getBankName() {
+        return bankName;
+    }
+
+    public void setBankName(String bankName) {
+        this.bankName = bankName;
+    }
+
+    public String getBankCode() {
+        return bankCode;
+    }
+
+    public void setBankCode(String bankCode) {
+        this.bankCode = bankCode;
+    }
+
+    public String getProvCode() {
+        return provCode;
+    }
+
+    public void setProvCode(String provCode) {
+        this.provCode = provCode;
+    }
+
+    public String getAreaCode() {
+        return areaCode;
+    }
+
+    public void setAreaCode(String areaCode) {
+        this.areaCode = areaCode;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceRequest.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceRequest.java
new file mode 100644
index 0000000..05ebaf3
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceRequest.java
@@ -0,0 +1,176 @@
+/**
+ *
+ */
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.supersavedriving.driver.modular.system.util.MallBook.config.ChannelConfig;
+import com.supersavedriving.driver.modular.system.util.MallBook.util.RSASignature;
+import com.supersavedriving.driver.modular.system.util.MallBook.util.StringUtil;
+
+import java.io.Serializable;
+
+/**
+ * 接口请求包
+ *
+ */
+public class InterfaceRequest<T> implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8130938432046696213L;
+
+
+    /**
+     * 商户平台编号
+     */
+    private String merchantNo = ChannelConfig.merchantNo;
+
+    /**
+     * 接口版本号,不同版本号触发不同接口业务
+     */
+    private String version = ChannelConfig.version;
+    /*
+     * 渠道类型  HF:汇付
+     */
+    private String channelType = ChannelConfig.channelType;
+
+
+    /**
+     * 业务系统订单ID
+     */
+    private String merOrderId;
+
+    /**
+     * 签名
+     */
+    private String sign;
+
+    /**
+     * 业务类型编号
+     */
+    private String serverCode;
+
+    /**
+     * 业务参数,json格式
+     */
+    private String params;
+
+    /**
+     * 时间戳
+     */
+    private String date;
+
+
+    public String getChannelType() {
+        return channelType;
+    }
+
+    public void setChannelType(String channelType) {
+        this.channelType = channelType;
+    }
+
+    public String getMerOrderId() {
+        return merOrderId;
+    }
+
+    public void setMerOrderId(String merOrderId) {
+        this.merOrderId = merOrderId;
+    }
+
+    public String getMerchantNo() {
+        return merchantNo;
+    }
+
+    public void setMerchantNo(String merchantNo) {
+        this.merchantNo = merchantNo;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getServerCode() {
+        return serverCode;
+    }
+
+    public void setServerCode(String serverCode) {
+        this.serverCode = serverCode;
+    }
+
+    public String getParams() {
+        return params;
+    }
+
+    public void setParams(String params) {
+        this.params = params;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+
+    /**
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     *  订单号 + 商户号 + 渠道类型 +  时间戳 + 业务参数json
+     * @return 待签名字符串
+     */
+    public String content() {
+        return StrUtil.builder()
+                .append(StringUtil.convertNull(merOrderId))
+                .append(StringUtil.convertNull(merchantNo))
+                .append(StringUtil.convertNull(channelType))
+                .append(StringUtil.convertNull(date))
+                .append(StringUtil.convertNull(params))
+                .toString();
+    }
+
+    public InterfaceRequest() {
+    }
+
+    public InterfaceRequest(T obj, String serverCode) {
+        this.merOrderId = IdUtil.fastSimpleUUID();
+        this.serverCode = serverCode;
+        this.date = System.currentTimeMillis() + "";
+        this.params = JSONUtil.toJsonStr(obj);
+        // todo 使用商户平台私钥生成sign,需要修改证书对应路径
+        this.sign = RSASignature.sign(content());
+    }
+
+
+    @Override
+    public String toString() {
+        return "InterfaceRequest{" +
+                "merOrderId='" + merOrderId + '\'' +
+                ", merchantNo='" + merchantNo + '\'' +
+                ", sign='" + sign + '\'' +
+                ", serverCode='" + serverCode + '\'' +
+                ", params='" + params + '\'' +
+                ", date='" + date + '\'' +
+                ", version='" + version + '\'' +
+                ", channelType='" + channelType + '\'' +
+                '}';
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceResponse.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceResponse.java
new file mode 100644
index 0000000..fe88795
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceResponse.java
@@ -0,0 +1,121 @@
+/**
+ *
+ */
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+
+import cn.hutool.core.util.StrUtil;
+import com.supersavedriving.driver.modular.system.util.MallBook.util.StringUtil;
+
+import java.io.Serializable;
+
+
+public class InterfaceResponse implements Serializable {
+
+
+    /**
+     * 结果字符串,json格式
+     */
+    private String result;
+
+    /**
+     * 签名,由code+msg+date+result根据私钥生成, 如果有参数为null,签名串中应当做空字符串("")来处理
+     */
+    private String sign;
+
+    /**
+     * 结果代码
+     */
+    private String code;
+
+    /**
+     * 结果信息
+     */
+    private String msg;
+
+    /**
+     * 时间戳
+     */
+    private String date;
+
+    /**
+     * 接口版本号
+     */
+    private String version;
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    @Override
+    public String toString() {
+        return "InterfaceResponse{" +
+                "result='" + result + '\'' +
+                ", sign='" + sign + '\'' +
+                ", code='" + code + '\'' +
+                ", msg='" + msg + '\'' +
+                ", date='" + date + '\'' +
+                ", version='" + version + '\'' +
+                '}';
+    }
+
+    /**
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     *  结果代码 + 结果信息 + 渠道类型 +  时间戳 + 结果字符串json
+     * @return 待签名字符串
+     */
+    public String content() {
+        return StrUtil.builder()
+                .append(StringUtil.convertNull(code))
+                .append(StringUtil.convertNull(msg))
+                .append(StringUtil.convertNull(date))
+                .append(StringUtil.convertNull(result))
+                .toString();
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Register.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Register.java
new file mode 100644
index 0000000..b68a119
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Register.java
@@ -0,0 +1,193 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+/**
+ * @author huangh
+ * @version 1.0
+ * @description
+ * @date 2021/12/10 16:45
+ */
+
+public class Register {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "register";
+    //业务系统会员id
+    private String merUserId;
+    //手机号
+    private String phone;
+    //子商户类型
+    private String userType;
+    //子商户名称
+    private String userName;
+    //身份证号码
+    private String certId;
+    //法人身份证有效期
+    private String certIdExpires;
+    //经营范围
+    private String businessScope;
+    //统一社会信用码
+    private String socialCreditCode;
+    //统一社会信用证有效期
+    private String socialCreditCodeExpires;
+    //法人手机号
+    private String legalPhone;
+    //法人姓名
+    private String legalPerson;
+    //企业地址
+    private String address;
+    //省份编码
+    private String provCode;
+    //地区编码
+    private String areaCode;
+    //附件编号
+    private String fileNo;
+    //后台回调地址
+    private String notifyUrl;
+    //自定义参数1
+    private String parameter1;
+    //自定义参数2
+    private String parameter2;
+
+    public String getMerUserId() {
+        return merUserId;
+    }
+
+    public void setMerUserId(String merUserId) {
+        this.merUserId = merUserId;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getUserType() {
+        return userType;
+    }
+
+    public void setUserType(String userType) {
+        this.userType = userType;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getCertId() {
+        return certId;
+    }
+
+    public void setCertId(String certId) {
+        this.certId = certId;
+    }
+
+    public String getCertIdExpires() {
+        return certIdExpires;
+    }
+
+    public void setCertIdExpires(String certIdExpires) {
+        this.certIdExpires = certIdExpires;
+    }
+
+    public String getBusinessScope() {
+        return businessScope;
+    }
+
+    public void setBusinessScope(String businessScope) {
+        this.businessScope = businessScope;
+    }
+
+    public String getSocialCreditCode() {
+        return socialCreditCode;
+    }
+
+    public void setSocialCreditCode(String socialCreditCode) {
+        this.socialCreditCode = socialCreditCode;
+    }
+
+    public String getSocialCreditCodeExpires() {
+        return socialCreditCodeExpires;
+    }
+
+    public void setSocialCreditCodeExpires(String socialCreditCodeExpires) {
+        this.socialCreditCodeExpires = socialCreditCodeExpires;
+    }
+
+    public String getLegalPhone() {
+        return legalPhone;
+    }
+
+    public void setLegalPhone(String legalPhone) {
+        this.legalPhone = legalPhone;
+    }
+
+    public String getLegalPerson() {
+        return legalPerson;
+    }
+
+    public void setLegalPerson(String legalPerson) {
+        this.legalPerson = legalPerson;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getProvCode() {
+        return provCode;
+    }
+
+    public void setProvCode(String provCode) {
+        this.provCode = provCode;
+    }
+
+    public String getAreaCode() {
+        return areaCode;
+    }
+
+    public void setAreaCode(String areaCode) {
+        this.areaCode = areaCode;
+    }
+
+    public String getFileNo() {
+        return fileNo;
+    }
+
+    public void setFileNo(String fileNo) {
+        this.fileNo = fileNo;
+    }
+
+    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/UnbindAccount.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/UnbindAccount.java
new file mode 100644
index 0000000..03099a5
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/UnbindAccount.java
@@ -0,0 +1,19 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.model;
+
+public class UnbindAccount {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "unbindAccount";
+
+    /**
+     * 子商户编号
+     */
+    private String userId;
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/Base64.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/Base64.java
new file mode 100644
index 0000000..b02617f
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/Base64.java
@@ -0,0 +1,288 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.util;
+
+/**
+ * @Author xiaogc
+ * @Date 2021/12/21 14:23
+ */
+public class Base64 {
+    static private final int BASELENGTH = 128;
+    static private final int LOOKUPLENGTH = 64;
+    static private final int TWENTYFOURBITGROUP = 24;
+    static private final int EIGHTBIT = 8;
+    static private final int SIXTEENBIT = 16;
+    static private final int FOURBYTE = 4;
+    static private final int SIGN = -128;
+    static private final char PAD = '=';
+    static private final boolean fDebug = false;
+    static final private byte[] base64Alphabet = new byte[BASELENGTH];
+    static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+        }
+
+        for (int i = 26, j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+        }
+
+        for (int i = 52, j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        }
+        lookUpBase64Alphabet[62] = (char) '+';
+        lookUpBase64Alphabet[63] = (char) '/';
+
+    }
+
+    private static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    private static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+
+    private static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData
+     *            Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+
+        if (binaryData == null) {
+            return null;
+        }
+
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
+                : numberTriplets;
+        char encodedData[] = null;
+
+        encodedData = new char[numberQuartet * 4];
+
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets);
+        }
+
+        for (int i = 0; i < numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+
+            if (fDebug) {
+                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+            }
+
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                    : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
+                    : (byte) ((b3) >> 6 ^ 0xfc);
+
+            if (fDebug) {
+                System.out.println("val2 = " + val2);
+                System.out.println("k4   = " + (k << 4));
+                System.out.println("vak  = " + (val2 | (k << 4)));
+            }
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1 >> 2));
+            }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                    : (byte) ((b2) >> 4 ^ 0xf0);
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded
+     *            string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+
+        if (encoded == null) {
+            return null;
+        }
+
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+
+        if (len % FOURBYTE != 0) {
+            return null;// should be divisible by four
+        }
+
+        int numberQuadruple = (len / FOURBYTE);
+
+        if (numberQuadruple == 0) {
+            return new byte[0];
+        }
+
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        decodedData = new byte[(numberQuadruple) * 3];
+
+        for (; i < numberQuadruple - 1; i++) {
+
+            if (!isData((d1 = base64Data[dataIndex++]))
+                    || !isData((d2 = base64Data[dataIndex++]))
+                    || !isData((d3 = base64Data[dataIndex++]))
+                    || !isData((d4 = base64Data[dataIndex++]))) {
+                return null;
+            }// if found "no data" just return null
+
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+
+        if (!isData((d1 = base64Data[dataIndex++]))
+                || !isData((d2 = base64Data[dataIndex++]))) {
+            return null;// if found "no data" just return null
+        }
+
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {
+                if ((b2 & 0xf) != 0)// last 4 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 1];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+                return tmp;
+            } else if (!isPad(d3) && isPad(d4)) {
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0)// last 2 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 2];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+                return tmp;
+            } else {
+                return null;
+            }
+        } else { // No PAD e.g 3cQl
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+
+        }
+
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     *
+     * @param data
+     *            the byte array of base64 data (with WS)
+     * @return the new length
+     */
+    private static int removeWhiteSpace(char[] data) {
+        if (data == null) {
+            return 0;
+        }
+
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i])) {
+                data[newSize++] = data[i];
+            }
+        }
+        return newSize;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/CacheUtils.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/CacheUtils.java
new file mode 100644
index 0000000..910de06
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/CacheUtils.java
@@ -0,0 +1,39 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.util;
+
+import cn.hutool.cache.CacheUtil;
+import cn.hutool.cache.impl.TimedCache;
+
+/**
+ * @author linqy
+ * 缓存工具类,生产建议使用其他缓存中间件
+ */
+public class CacheUtils {
+    private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000);
+
+    static {
+        /** 每1s检查一次过期 */
+        TIMED_CACHE.schedulePrune(1000);
+    }
+
+    /**
+     * 存入键值对,提供消逝时间
+     *
+     * @param key
+     * @param value
+     * @param timeout
+     */
+    public static void put(String key, String value, Long timeout) {
+        /** 设置消逝时间 */
+        TIMED_CACHE.put(key, value, timeout);
+    }
+
+    /**
+     * 每次重新get一次缓存,均会重新刷新消逝时间
+     * @param key
+     * @return
+     */
+    public static String get(String key) {
+        return TIMED_CACHE.get(key);
+    }
+
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSAEncryptGeneration.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSAEncryptGeneration.java
new file mode 100644
index 0000000..eca7346
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSAEncryptGeneration.java
@@ -0,0 +1,65 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.util;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * 公私钥代码生成
+ * @Author xiaogc
+ * @Date 2021/12/21 14:22
+ */
+public class RSAEncryptGeneration {
+
+    public static void main(String[] args) {
+        // 生成一对公私钥到指定路径下  .pfx私钥 .cer公钥
+        RSAEncryptGeneration.genKeyPair("D:\\tools");
+    }
+    /**
+     * 随机生成密钥对
+     */
+    public static void genKeyPair(String filePath) {
+        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
+        KeyPairGenerator keyPairGen = null;
+        try {
+            keyPairGen = KeyPairGenerator.getInstance("RSA");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        // 初始化密钥对生成器,密钥大小为96-1024位
+        keyPairGen.initialize(1024, new SecureRandom());
+        // 生成一个密钥对,保存在keyPair中
+        KeyPair keyPair = keyPairGen.generateKeyPair();
+        // 得到私钥
+        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
+        // 得到公钥
+        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+        try {
+            // 得到公钥字符串
+            String publicKeyString = Base64.encode(publicKey.getEncoded());
+            System.out.println("公钥字符串:"+publicKeyString);
+            // 得到私钥字符串
+            String privateKeyString = Base64.encode(privateKey.getEncoded());
+            System.out.println("私钥字符串:"+privateKeyString);
+            // 将密钥对写入到文件  .pfx私钥 .cer公钥
+            FileWriter pubfw = new FileWriter(filePath + "/merchant_no.cer");
+            FileWriter prifw = new FileWriter(filePath + "/merchant_no.pfx");
+            BufferedWriter pubbw = new BufferedWriter(pubfw);
+            BufferedWriter pribw = new BufferedWriter(prifw);
+            pubbw.write(publicKeyString);
+            pribw.write(privateKeyString);
+            pubbw.flush();
+            pubbw.close();
+            pubfw.close();
+            pribw.flush();
+            pribw.close();
+            prifw.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSASignature.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSASignature.java
new file mode 100644
index 0000000..96df15f
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSASignature.java
@@ -0,0 +1,118 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.util;
+
+
+import com.supersavedriving.driver.modular.system.util.MallBook.config.ChannelConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * @author RSA签名验签类
+ */
+public class RSASignature {
+
+    public static Logger logger = LoggerFactory.getLogger(RSASignature.class);
+
+    /**
+     * 签名算法
+     */
+    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
+
+
+    /**
+     * 商户平台私钥签名
+     *
+     * @param content
+     * @return
+     */
+    public static String sign(String content) {
+        try {
+            String privateKey = ChannelConfig.merchantPrivateKey;
+            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
+            KeyFactory keyf = KeyFactory.getInstance("RSA");
+            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+            signature.initSign(priKey);
+            signature.update(content.getBytes());
+            byte[] signed = signature.sign();
+            return Base64.encode(signed);
+        } catch (Exception e) {
+            logger.error("签名失败{}", e);
+        }
+        return null;
+    }
+
+
+    /**
+     * 读取证书
+     *
+     * @param filePath 证书文件路径
+     */
+    public static String loadKey(String filePath) throws Exception {
+        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
+            String readLine;
+            StringBuilder sb = new StringBuilder();
+            while ((readLine = br.readLine()) != null) {
+                sb.append(readLine);
+            }
+            return sb.toString();
+        } catch (IOException e) {
+            throw new Exception("私钥数据读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("私钥输入流为空");
+        }
+    }
+
+
+    /**
+     * mallbook公钥验签
+     *
+     * @param content 待签名数据
+     * @param sign    签名值
+     * @return false 验签失败 true 成功
+     */
+    public static boolean validate(String content, String sign) {
+        boolean verify = false;
+        try {
+            String publicKey = ChannelConfig.mallBookPublicKey;
+            verify = RSASignature.doCheck(content, sign, publicKey, "utf-8");
+        } catch (Exception e) {
+            logger.error("验签失败:{}", e);
+        }
+        return verify;
+    }
+
+
+    /**
+     * RSA验签
+     *
+     * @param content   待签名数据
+     * @param sign      签名值
+     * @param publicKey 分配给开发商公钥
+     * @param encode    字符集编码
+     * @return 布尔值
+     */
+    public static boolean doCheck(String content, String sign, String publicKey, String encode) {
+        try {
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            byte[] encodedKey = Base64.decode(publicKey);
+            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+            signature.initVerify(pubKey);
+            signature.update(content.getBytes(encode));
+            return signature.verify(Base64.decode(sign));
+        } catch (Exception e) {
+            logger.error("验签失败{}", e);
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/StringUtil.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/StringUtil.java
new file mode 100644
index 0000000..169f2d0
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/StringUtil.java
@@ -0,0 +1,23 @@
+
+package com.supersavedriving.driver.modular.system.util.MallBook.util;
+
+import cn.hutool.core.util.StrUtil;
+
+
+public class StringUtil extends StrUtil {
+
+    /**
+     * null转为空字符串
+     *
+     * @param str
+     * @return
+     */
+    public static String convertNull(String str) {
+        if (str == null) {
+            return "";
+        }
+        return str;
+    }
+
+
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/TrhRequest.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/TrhRequest.java
new file mode 100644
index 0000000..bd61eeb
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/TrhRequest.java
@@ -0,0 +1,31 @@
+package com.supersavedriving.driver.modular.system.util.MallBook.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.exceptions.ValidateException;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import com.supersavedriving.driver.modular.system.util.MallBook.config.ChannelConfig;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.InterfaceRequest;
+import com.supersavedriving.driver.modular.system.util.MallBook.model.InterfaceResponse;
+
+/**
+ * @Author xiaogc
+ * @Date 2022/1/24 13:45
+ */
+public class TrhRequest<T> {
+
+    public InterfaceResponse execute(T t, String serverCode) {
+        InterfaceRequest<T> request = new InterfaceRequest(t, serverCode);
+        System.out.println("mallbook请求参数:" + JSONUtil.toJsonStr(request));
+        String result = HttpUtil.post(ChannelConfig.payUrl, BeanUtil.beanToMap(request));
+        System.out.println("mallbook响应参数:" + result);
+        InterfaceResponse response = JSONUtil.toBean(result, InterfaceResponse.class);
+        boolean verify = RSASignature.validate(response.content(), response.getSign());
+        if (!verify) {
+            throw new ValidateException("签名验证失败");
+        } else {
+            System.out.printf("签名验证通过");
+        }
+        return response;
+    }
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/OCRUtil.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/OCRUtil.java
new file mode 100644
index 0000000..21ddeb0
--- /dev/null
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/OCRUtil.java
@@ -0,0 +1,269 @@
+package com.supersavedriving.driver.modular.system.util.juhe;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.supersavedriving.driver.modular.system.util.httpClinet.HttpClientUtil;
+import com.supersavedriving.driver.modular.system.util.httpClinet.HttpResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/4/10 15:35
+ */
+public class OCRUtil {
+
+    static Logger logger = LoggerFactory.getLogger("ServiceLog");
+
+    private final static String key = "5cc9622f299335639dbc046f3812c52a";
+
+    private static HttpClientUtil httpClientUtil = new HttpClientUtil();
+
+
+    /**
+     * OCR证件识别
+     * @param cardType
+     *          "1": "一代身份证",
+     *         "2": "二代身份证正面",
+     *         "3": "二代身份证证背面",
+     *         "4": "临时身份证",
+     *         "5": "驾照",
+     *         "6": "行驶证",
+     *         "7": "军官证1998版",
+     *         "9": "中华人民共和国往来港澳通行证2005版",
+     *         "10": "台湾居民往来大陆通行证1992版-照片页",
+     *         "11": "大陆居民往来台湾通行证1992版-照片页",
+     *         "12": "签证(护照幅面)",
+     *         "13": "护照(护照幅面)",
+     *         "14": "港澳居民来往内地通行证-照片页",
+     *         "15": "港澳居民来往内地通行证-机读码页",
+     *         "16": "户口本",
+     *         "17": "银行卡",
+     *         "22": "往来港澳通行证2014版-照片页(卡式港澳通行证)",
+     *         "25": "台湾居民来往大陆通行证2015版-照片页",
+     *         "26": "台湾居民往来大陆通行证2015版-机读码页",
+     *         "28": "中国驾驶证副页",
+     *         "29": "往来台湾通行证2017版-照片页",
+     *         "30": "行驶证副页",
+     *         "31": "港澳台居民居住证正面",
+     *         "32": "港澳台居民居住证反面",
+     *         "33": "外国人永久居留身份证",
+     *         "101": "二代身份证正面背面自动分类",
+     *         "102": "驾驶证正副页自动分类",
+     *         "103": "行驶证正副页自动分类",
+     *         "104": "身份证、驾驶证、行驶证自动分类",
+     *         "1000": "居住证",
+     *         "1001": "香港永久性居民身份证",
+     *         "1002": "登机牌(拍照设备目前不支持登机牌的识别)",
+     *         "1003": "边民证(A)(照片页)",
+     *         "2008":"营业执照"
+     * @param file  图片文件
+     * @return
+     */
+    public static JSONObject certificate(Integer cardType, MultipartFile file){
+        String url = "http://v.juhe.cn/certificates/query";
+        HttpResult httpResult = null;
+        try {
+            Map<String, Object> params = new HashMap<>();
+            params.put("key", key);
+            params.put("cardType", cardType.toString());
+            params.put("pic", file);
+            httpResult = httpClientUtil.pushHttpRequset("POST", url, params, null, "form");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if(httpResult.getCode() != 200){
+            logger.debug("查询证件失败:" + httpResult.getData());
+            return null;
+        }
+        String data = httpResult.getData();
+        JSONObject jsonObject = JSON.parseObject(data);
+        Integer error_code = jsonObject.getInteger("error_code");
+        if(0 != error_code){
+            logger.debug("查询证件失败:" + jsonObject.getString("reason"));
+            return null;
+        }
+        JSONObject result = jsonObject.getJSONObject("result");
+        return result;
+    }
+
+
+    ////身份证识别返回示例
+    //{
+    //    "error_code": 0,
+    //    "reason": "操作成功",
+    //    "result": {
+    //        "住址": "武汉市江岸区永清路****",
+    //        "保留": "",
+    //        "公民身份号码": "42010619510609****",
+    //        "出生": "1951-06-09",
+    //        "头像": "",/*Base64字符串*/
+    //        "姓名": "彭*",
+    //        "性别": "男",
+    //        "民族": "汉",
+    //        "orderid":"JH1531180126114835937669",
+    //        "userid":"1234567"
+    //    }
+    //}
+    //
+    ////车牌识别返回示例
+    //{
+    //  "reason": "操作成功",
+    //  "result": {
+    //    "车牌号": "粤N0***81",
+    //    "车牌颜色": "1",
+    //    "车牌类型": "1",
+    //    "整牌可信度": "86",
+    //    "亮度评价": "215",
+    //    "车牌运动方向": "0",
+    //    "车牌位置(left_top_right_bottom)": "30_118_498_222",
+    //        "orderid":"JH1531180126114835937669",
+    //        "userid":"1234567"
+    //  },
+    //  "error_code": 0
+    //}
+    ////港澳台居民居住证正面
+    //{
+    //   "reason": "操作成功",
+    //   "result":{
+    //     "保留" : "",
+    //     "姓名" : "",
+    //     "性别" : "",
+    //     "民族" : "",
+    //     "住址" : "",
+    //     "出生" : "",
+    //     "公民身份号码" : "",
+    //     "复印件判别" : "",
+    //     "头像" : ""
+    //   }
+    //}
+    ////港澳台居民居住证反面
+    //{
+    //   "reason": "操作成功",
+    //   "result":{
+    //     "保留" : "",
+    //     "签发机关" : "",
+    //     "有效期限" : "",
+    //     "签发日期" : "",
+    //     "有效期至" : "",
+    //     "通行证号码" : ""
+    //   }
+    //}
+    ////港澳居民来往内地通行证-照片页
+    //{
+    //   "reason": "操作成功",
+    //   "result":{
+    //     "保留" : "",
+    //     "证件号码" : "",
+    //     "中文姓名" : "",
+    //     "英文姓名" : "",
+    //     "性别" : "",
+    //     "出生日期" : "",
+    //     "本证有效期至" : "",
+    //     "英文姓" : "",
+    //     "英文名" : "",
+    //    "港澳证件号码" : "",
+    //    "签发日期" : "",
+    //    "有效期限" : "",
+    //    "签发机关" : "",
+    //    "换证次数" : "",
+    //    "其他姓名" : "",
+    //    "归属地" : "",
+    //    "头像" : "",
+    //   }
+    //}
+    ////中国台湾居民来往内地通行证照片页
+    //{
+    //   "reason": "操作成功",
+    //   "result":{
+    //     "保留" : "",
+    //     "中文姓名" : "",
+    //     "英文姓名" : "",
+    //     "出生日期" : "",
+    //     "性别" : "",
+    //     "有效期限" : "",
+    //     "签发地点" : "",
+    //     "证件号码" : "",
+    //     "签发次数" : "",
+    //     "签发机关" : "",
+    //     "头像" : "",
+    //   }
+    //}
+    ////针对车牌的信息:
+    //1.车牌颜色类型:
+    //	 0 //未知车牌
+    //	 1 //蓝牌
+    //	 2 //黑牌
+    //	 3 //单排黄牌
+    //	 4 //双排黄牌(大车尾牌,农用车)
+    //	 5 //警车车牌
+    //	 6 //武警车牌
+    //	 7 //个性化车牌
+    //	 8 //单排军车
+    //	 9 //双排军车
+    //	 10 //使馆牌
+    //	 11 //香港牌
+    //	 12 //拖拉机
+    //	 13 //澳门牌
+    //	 14 //厂内牌
+    //	 15 //民航牌
+    //	 16 //领事馆车牌
+    //	 17 //新能源车牌-小型车
+    //	 18 //新能源车牌-大型车
+    //
+    //2.车牌可信度:
+    //    当前识别结果的分数,分数越高识别对的可能越大
+    //3.车牌位置:
+    //    是指车牌在图像中的坐标值
+    //4.车牌运动方向:
+    //    0 unknown, 1 left, 2 right, 3 up , 4 down
+    //
+    ////行驶证查询返回:
+    //{
+    //    "保留": "",
+    //    "号牌号码": "粤A4****",
+    //    "车辆类型": "小型轿车",
+    //    "所有人": "黄**",
+    //    "住址": "广东省从化市城郊街东风***********",
+    //    "品牌型号": "别克1B*******71801S",
+    //    "车辆识别代号": "LSGJ********44832",
+    //    "发动机号码": "T18S********C",
+    //    "注册日期": "2000-06-13",
+    //    "发证日期": "2020-07-11",
+    //    "使用性质": "非营运",
+    //        "orderid":"JH1531180126114835937669",
+    //        "userid":"1234567"
+    //}
+    ////VIN识别
+    //{
+    //    "vin": "WBAFR7103BC727722",
+    //    "orderid": "JH1531180524123006771818"
+    //}
+    ////营业执照
+    //{
+    //"reason": "操作成功",
+    //"result":{
+    //"统一社会信用代码": "91110105MA01AMC6Q",
+    //"组织机构代码": "",
+    //"税务登记证号": "",
+    //"社保登记号": "",
+    //"统计证证号": "",
+    //"名称": "北京数字传奇网络科技有限公司",
+    //"类型": "有限责任公司(自然人投资或控股)",
+    //"住所": "北京市朝阳区将台乡驼房营路8号新华科技大厦21层2106室",
+    //"法定代表人": "吴发强",
+    //"组成形式": "",
+    //"注册资本": "100万元",
+    //"成立日期": "2018年03月21日",
+    //"营业期限": "2018年03月21日至长期",
+    //"经营范围": "技术开发、技术推广、技术咨询、技术服务。(企业依法自主\n选择经营项目,开展经营活班依法须经批准的顼目,经相关\n部门批准后依批准的内容开展经营活班不得从事本市产业政\n策禁止和限制类顼目的经营活动。)",
+    //"登记机关": "",
+    //"登记日期": "",
+    //"二维码": "http://qyxy.baic.gov.cn/wap/wap/creditWapAction!qr.dhtml?id=ff8080816242f1250162463d9d3168f3",
+    //"副本": ""
+    //},
+}
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/DriverInfoWarpper.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/DriverInfoWarpper.java
index 34c37a4..c0285b6 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/DriverInfoWarpper.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/DriverInfoWarpper.java
@@ -47,4 +47,12 @@
     private Integer wechatAuthorization;
     @ApiModelProperty("客服电话")
     private String serviceCalls;
+    @ApiModelProperty("商户号")
+    private String merchantNumber;
+    @ApiModelProperty("商户姓名")
+    private String merchantName;
+    @ApiModelProperty("商户电话")
+    private String merchantPhone;
+    @ApiModelProperty("商户身份证号码")
+    private String merchantIDCode;
 }
diff --git a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java
index 216bb49..5cf71df 100644
--- a/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java
+++ b/driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java
@@ -9,6 +9,8 @@
 public class OrderInfoWarpper {
     @ApiModelProperty("订单id")
     private Long id;
+    @ApiModelProperty("用户id")
+    private Integer userId;
     @ApiModelProperty("用户头像")
     private String avatar;
     @ApiModelProperty("用户名称")
diff --git a/driver/guns-admin/src/main/resources/application.yml b/driver/guns-admin/src/main/resources/application.yml
index db49129..d4439eb 100644
--- a/driver/guns-admin/src/main/resources/application.yml
+++ b/driver/guns-admin/src/main/resources/application.yml
@@ -13,8 +13,8 @@
   application:
     name: driver-server
   profiles:
-#    active: dev
-    active: produce
+    active: dev
+#    active: produce
   mvc:
     static-path-pattern: /static/**
     view:
@@ -55,8 +55,8 @@
   datasource:
     url: jdbc:mysql://127.0.0.1:3306/super_save_driving?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
-    password: f4OfRjqoN3jSiNGiUoiNsQdOBtCOKYRj
-#    password: 123456
+#    password: f4OfRjqoN3jSiNGiUoiNsQdOBtCOKYRj
+    password: 123456
     db-name: guns #用来搜集数据库的所有表
     filters: wall,mergeStat
 
@@ -116,11 +116,30 @@
 spring:
   data:
     mongodb:
-      uri: mongodb://root:CEtyLdKjPk0yeHNo@127.0.0.1:27017/admin
-#      uri: mongodb://127.0.0.1:27017/admin
+#      uri: mongodb://root:CEtyLdKjPk0yeHNo@127.0.0.1:27017/admin
+      uri: mongodb://127.0.0.1:27017/admin
 
 ---
 
 rongyun:
   app_key: k51hidwqkx92b
-  app_secret: t0jxbPrHHar
\ No newline at end of file
+  app_secret: t0jxbPrHHar
+
+
+#  mallbook 调起接口参数配置
+mallbook:
+  # pay_url:mallbook接口地址    测试环境: http://ld.mallbook.cn:12000/api   生产环境:https://cloudpay.mallbook.cn/api
+  pay_url: http://ld.mallbook.cn:12000/api
+  # merchant_no 业务系统商户平台编号,需替换为mallbook工作人员提供的商户编号
+  merchant_no:  需要替换内容
+  # version 接口版本号
+  version: 1.0.0
+  # channel_type 渠道类型 HF:汇付
+  channel_type: HF
+  # merchant_private_key 商户平台私钥,需要替换成商户平台自己生成的私钥
+  merchant_private_key: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIoGARvX6k6rVwuUW6HjAPkzXVntCtDI8q/niGZbeILc5T/noer+UNDECSy9f8T6ENw7tEKWaHOFcicrqgRv+wXeo2hPiJI2iYsUNs6I8ckd8i4uy/PBEDMW78GlnQLAatk0NC44HKjn8cuIHaETKNG2Vk3rwGBzNgDZ/God1L6JAgMBAAECgYBhCsOwzehBk5pJ2+9pLO+8Rm72EQGvtflb0BBI1zst1x2gBr4DOPedMJe6yymQVrmP/rJItvONdV/DRqHtKMZ2Wa4ul/U1mDnAtS/FkpRYBA5FaXV2hNEW11xBLhL5iGk35P23Bzaa0MJw9Vsd0vjeykridIw/PweDyTdeRBwC2QJBANS+iOaKRuf6BRwCKDmBSHOiZmc/kKnpx2f5BD3h+LWEX3JsNxObMbW1SxQIf2/qwqzIoEm/WbWaOyuwtRZkXQ8CQQCmFjTm5l+Ws2LoQgM+5+eLmPyMyRFOu4G8yqsUkhKuANHK/qrsS1GTbv6SN341NijjNYl05e0h6Jq1T9UZmtrnAkEAwTfzmn7H+3RmI5QJ+IBkzzEWFHv05X0/8DyID7QmcKWzEncaZqIzObdYYu983qa2/LqSaahyz68uQnYRYi7xHQJATr3SgPIRuaH8r360iTtrRHzYp2qgYQJ25On1KECEyKgszp/kqzieSVbjLLFQjavKwMXeEGT+AwiDaJibwJLxWwJAXZApORsqGqdxc9FTxt5iiqG2ZP5DTXxc6E+ihmlmoVl9KncgTf9ez0Q0Qz/4KUTPTHNVgzt1nyBxiLtnyzFavA==
+  # 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
+
diff --git a/driver/guns-admin/src/main/resources/redis.properties b/driver/guns-admin/src/main/resources/redis.properties
index 726be87..c3f1494 100644
--- a/driver/guns-admin/src/main/resources/redis.properties
+++ b/driver/guns-admin/src/main/resources/redis.properties
@@ -2,19 +2,19 @@
 # Redis���ݿ�������Ĭ��Ϊ0��
 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 5d8d3d6..639e49a 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
@@ -1,6 +1,7 @@
 //package com.supersavedriving.driver;
 //
 //import com.supersavedriving.driver.modular.system.model.WeatherCity;
+//import com.supersavedriving.driver.modular.system.service.IAccountChangeDetailService;
 //import com.supersavedriving.driver.modular.system.service.IWeatherCityService;
 //import com.supersavedriving.driver.modular.system.util.juhe.WeatherCityInfo;
 //import com.supersavedriving.driver.modular.system.util.juhe.WeatherUtil;
@@ -11,26 +12,17 @@
 //import org.springframework.boot.test.context.SpringBootTest;
 //import org.springframework.test.context.junit4.SpringRunner;
 //
-//import java.util.ArrayList;
-//import java.util.List;
 //
 //@RunWith(SpringRunner.class)
 //@SpringBootTest
 //public class GunsApplicationTest {
 //
 //    @Autowired
-//    private IWeatherCityService weatherCityService;
+//    private IAccountChangeDetailService accountChangeDetailService;
 //
 //
 //    @Test
 //    public void test(){
-//        List<WeatherCityInfo> weatherCities = WeatherUtil.queryCityList();
-//        List<WeatherCity> list = new ArrayList<>();
-//        for (WeatherCityInfo weatherCityInfo : weatherCities) {
-//            WeatherCity weatherCity1 = new WeatherCity();
-//            BeanUtils.copyProperties(weatherCityInfo, weatherCity1);
-//            list.add(weatherCity1);
-//        }
-//        weatherCityService.insertBatch(list);
+//        accountChangeDetailService.deductionInsurance();
 //    }
 //}
diff --git a/management/guns-admin/src/main/java/com/stylefeng/guns/config/RedisConfig.java b/management/guns-admin/src/main/java/com/stylefeng/guns/config/RedisConfig.java
new file mode 100644
index 0000000..d459612
--- /dev/null
+++ b/management/guns-admin/src/main/java/com/stylefeng/guns/config/RedisConfig.java
@@ -0,0 +1,46 @@
+package com.stylefeng.guns.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+@Configuration
+@PropertySource("classpath:redis.properties")
+public class RedisConfig {
+    @Value("${spring.redis.host}")
+    private String host;
+
+    @Value("${spring.redis.port}")
+    private int port;
+
+    @Value("${spring.redis.timeout}")
+    private int timeout;
+
+    @Value("${spring.redis.jedis.pool.max-idle}")
+    private int maxIdle;
+
+    @Value("${spring.redis.jedis.pool.max-wait}")
+    private long maxWaitMillis;
+
+    @Value("${spring.redis.password}")
+    private String password;
+
+    @Value("${spring.redis.block-when-exhausted}")
+    private boolean  blockWhenExhausted;
+
+    @Bean
+    public JedisPool redisPoolFactory()  throws Exception{
+        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
+        jedisPoolConfig.setMaxIdle(maxIdle);
+        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
+        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
+        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
+        // 是否启用pool的jmx管理功能, 默认true
+        jedisPoolConfig.setJmxEnabled(true);
+        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
+        return jedisPool;
+    }
+}
diff --git a/management/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java b/management/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java
index ce51f7f..589657b 100644
--- a/management/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java
+++ b/management/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java
@@ -1,21 +1,15 @@
 package com.stylefeng.guns.modular.system.util;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.stylefeng.guns.core.util.ToolUtil;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
 import org.springframework.stereotype.Component;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
+import org.springframework.util.StringUtils;
 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.Pipeline;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.io.IOException;
+import java.util.*;
 
 
 /**
@@ -24,6 +18,10 @@
 @Component
 public class RedisUtil {
 
+    @Autowired
+    private JedisPool jedisPool;
+
+    private Timer timer;
 
 
     /**
@@ -32,18 +30,11 @@
      * @param value
      */
     public void setStrValue(String key, String value){
-        if(ToolUtil.isNotEmpty(key)){
-            //将请求头部和参数合成一个请求
-            Map<String,String> map = new HashMap<>();
-            map.put("key", key);
-            map.put("value", value);
-            String s = HttpRequestUtil.postRequest(PushURL.zull_user_url + "/redis/setValue_", map);
-            JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
-            if(jsonObject.getIntValue("code") != 200){
-                System.err.println("调用redis出错了");
-            }
+        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(value)){
+            Jedis resource = jedisPool.getResource();
+            String set = resource.set(key, value);
+            closeJedis(resource);
         }
-
     }
 
 
@@ -54,16 +45,10 @@
      * @param time 秒
      */
     public void setStrValue(String key, String value, int time){
-        if(ToolUtil.isNotEmpty(key)){
-            Map<String,String> map = new HashMap<>();
-            map.put("key", key);
-            map.put("value", value);
-            map.put("time", String.valueOf(time));
-            String s = HttpRequestUtil.postRequest(PushURL.zull_user_url + "/redis/setValue", map);
-            JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
-            if(jsonObject.getIntValue("code") != 200){
-                System.err.println("调用redis出错了");
-            }
+        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(value)){
+            Jedis resource = jedisPool.getResource();
+            String setex = resource.setex(key, time, value);
+            closeJedis(resource);
         }
     }
 
@@ -75,35 +60,43 @@
      */
     public String getValue(String key){
         if(ToolUtil.isNotEmpty(key)){
-            Map<String,String> map = new HashMap<>();
-            map.put("key", key);
-            String s = HttpRequestUtil.postRequest(PushURL.zull_user_url + "/redis/getValue", map);
-            JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
-            if(jsonObject.getIntValue("code") != 200){
-                System.err.println("调用redis出错了");
-            }
-            return jsonObject.getString("data");
+            Jedis resource = jedisPool.getResource();
+            String data = resource.get(key);
+            closeJedis(resource);
+            return data;
         }
         return null;
     }
 
 
-
     /**
-     * 从redis中获取值
-     * @param key
+     * 批量获取
+     * @param kes
      * @return
      */
-    public String getValues(String key){
-        if(ToolUtil.isNotEmpty(key)){
-            Map<String,String> map = new HashMap<>();
-            map.put("keys", key);
-            String s = HttpRequestUtil.postRequest(PushURL.zull_user_url + "/redis/getValues", map);
-            JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
-            if(jsonObject.getIntValue("code") != 200){
-                System.err.println("调用redis出错了");
+    public List<Object> getValues(List<String> kes){
+        if(null != kes){
+            Jedis resource = jedisPool.getResource();
+            Pipeline pipelined = resource.pipelined();
+            for(String key : kes){
+                pipelined.get(key);
             }
-            return jsonObject.getString("data");
+            List<Object> list = pipelined.syncAndReturnAll();
+
+            closeJedis(resource);
+            pipelined.clear();
+            try {
+                pipelined.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            List<Object> data = new ArrayList<>();
+            for(Object o : list){
+                if(null != o){
+                    data.add(o);
+                }
+            }
+            return data;
         }
         return null;
     }
@@ -113,17 +106,167 @@
      * 删除key
      * @param key
      */
-    public String remove(String key){
+    public void remove(String key){
         if(ToolUtil.isNotEmpty(key)){
-            Map<String,String> map = new HashMap<>();
-            map.put("key", key);
-            String s = HttpRequestUtil.postRequest(PushURL.zull_user_url + "/redis/getValue", map);
-            JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
-            if(jsonObject.getIntValue("code") != 200){
-                System.err.println("调用redis出错了");
-            }
-            return jsonObject.getString("data");
+            Jedis resource = jedisPool.getResource();
+            Long del = resource.del(key);
+            closeJedis(resource);
         }
-        return null;
+    }
+
+
+    /**
+     * 向集合key添加数据
+     * @param key
+     * @param members
+     */
+    public void addSetValue(String key, String...members){
+        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(members)){
+            Jedis resource = jedisPool.getResource();
+            Long sadd = resource.sadd(key, members);
+            resource.close();
+        }
+    }
+
+
+    /**
+     * 返回Set集合数据
+     * @param key
+     * @return
+     */
+    public Set<String> getSetAllValue(String key){
+        Set<String> smembers = new HashSet<>();
+        if(ToolUtil.isNotEmpty(key)){
+            Jedis resource = jedisPool.getResource();
+            smembers = resource.smembers(key);
+            resource.close();
+        }
+        return smembers;
+    }
+
+
+    /**
+     * 删除Set集合中的值
+     * @param key
+     * @param members
+     */
+    public void delSetValue(String key, String...members){
+        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(members)){
+            Jedis resource = jedisPool.getResource();
+            Long sadd = resource.srem(key, members);
+            resource.close();
+        }
+    }
+
+
+    /**
+     * 删除资源
+     * @param jedis
+     */
+    public void closeJedis(Jedis jedis){
+        if(null != jedis){
+            jedis.close();
+        }
+    }
+
+
+    /**
+     * redis加锁
+     * @param key
+     * @param value
+     * @param time
+     * @return
+     */
+    public boolean lock(String key, String value, int time){
+        if(!StringUtils.isEmpty(key)){
+            key += "_lock";
+            Jedis resource = jedisPool.getResource();
+            String set = resource.set(key, value, "nx", "ex", time);
+            if("OK".equals(set)){
+                String finalKey = key;
+                timer = new Timer();
+                timer.schedule(new TimerTask() {
+                    @Override
+                    public void run() {
+                        System.err.println("定时任务启动");
+                        Jedis resource = jedisPool.getResource();
+                        resource.setex(finalKey, time, value);
+                        resource.close();
+                    }
+                }, 1000, 500);
+            }
+            resource.close();
+            return "OK".equals(set) ? true : false;
+        }
+        return false;
+    }
+
+    /**
+     * 获取redis锁
+     * @return
+     */
+    public boolean lock(){
+        try {
+            boolean b = lock(5);
+            if(!b){
+                int num1 = 1;
+                while (num1 <= 10){
+                    try {
+                        Thread.sleep(3000);//等待3秒
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    b = lock(5);
+                    if(b){
+                        return true;
+                    }else{
+                        num1++;
+                    }
+                }
+                return false;
+            }
+            return b;
+        }catch (Exception e){
+            e.printStackTrace();
+            unlock();
+        }
+        return false;
+    }
+
+
+    /**
+     * 获取redis锁
+     * @param time
+     * @return
+     */
+    public boolean lock(int time){
+        String uuid = UUID.randomUUID().toString();
+        return lock("redis", uuid, time);
+    }
+
+
+    /**
+     * redis释放锁
+     * @param key
+     * @return
+     */
+    public boolean unlock(String key){
+        if(!StringUtils.isEmpty(key)){
+            key += "_lock";
+            Jedis resource = jedisPool.getResource();
+            timer.cancel();//取消定时任务
+            Long del = resource.del(key);
+            resource.close();
+            return del != 0 ? true : false;
+        }
+        return false;
+    }
+
+    /**
+     * 删除锁
+     * @return
+     */
+    public boolean unlock(){
+        return unlock("redis");
     }
 }
diff --git a/management/guns-admin/src/main/resources/redis.properties b/management/guns-admin/src/main/resources/redis.properties
new file mode 100644
index 0000000..8e63a9f
--- /dev/null
+++ b/management/guns-admin/src/main/resources/redis.properties
@@ -0,0 +1,29 @@
+#redis���ÿ�ʼ
+# Redis���ݿ�������Ĭ��Ϊ0��
+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
+# Redis�������������루Ĭ��Ϊ�գ�
+spring.redis.password=123456
+
+# ���ӳ������������ʹ�ø�ֵ��ʾû�����ƣ�
+spring.redis.jedis.pool.max-active=1024
+# ���ӳ���������ȴ�ʱ�䣨ʹ�ø�ֵ��ʾû�����ƣ�
+spring.redis.jedis.pool.max-wait=10000
+# ���ӳ��е�����������
+spring.redis.jedis.pool.max-idle=200
+# ���ӳ��е���С��������
+spring.redis.jedis.pool.min-idle=0
+# ���ӳ�ʱʱ�䣨���룩
+spring.redis.timeout=10000
+#redis���ý���
+spring.redis.block-when-exhausted=true
\ No newline at end of file
diff --git a/management/pom.xml b/management/pom.xml
index bbae030..121e0c3 100644
--- a/management/pom.xml
+++ b/management/pom.xml
@@ -11,7 +11,6 @@
     <modules>
         <module>guns-admin</module>
         <module>guns-core</module>
-        <module>guns-rest</module>
         <module>guns-generator</module>
     </modules>
 
diff --git a/user/guns-admin/pom.xml b/user/guns-admin/pom.xml
index 9127482..4d63379 100644
--- a/user/guns-admin/pom.xml
+++ b/user/guns-admin/pom.xml
@@ -198,6 +198,12 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-mongodb</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.7.7</version>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java
index facf287..3fcf80f 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java
@@ -8,6 +8,8 @@
 import com.supersavedriving.user.modular.system.model.AppUser;
 import com.supersavedriving.user.modular.system.model.SystemConfig;
 import com.supersavedriving.user.modular.system.service.*;
+import com.supersavedriving.user.modular.system.util.MallBook.model.InterfaceResponse;
+import com.supersavedriving.user.modular.system.util.MallBook.util.RSASignature;
 import com.supersavedriving.user.modular.system.util.PayMoneyUtil;
 import com.supersavedriving.user.modular.system.util.RedisUtil;
 import com.supersavedriving.user.modular.system.util.ResultUtil;
@@ -314,18 +316,47 @@
 //    @ServiceLog(name = "余额充值回调", url = "/base/appUser/rechargeBalanceCallback")
     public void rechargeBalanceCallback(HttpServletRequest request, 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);
-                appUserService.rechargeBalanceCallback(out_trade_no, transaction_id);
+            String code = request.getParameter("code");
+            String version = request.getParameter("version");
+            String msg = request.getParameter("msg");
+            String date = request.getParameter("date");
+            String result = request.getParameter("result");
+            String sign = request.getParameter("sign");
+            InterfaceResponse interfaceResponse = new InterfaceResponse();
+            interfaceResponse.setCode(code);
+            interfaceResponse.setVersion(version);
+            interfaceResponse.setMsg(msg);
+            interfaceResponse.setDate(date);
+            interfaceResponse.setResult(result);
+            interfaceResponse.setSign(sign);
+            // 验签
+            boolean verify = RSASignature.validate(interfaceResponse.content(), interfaceResponse.getSign());
+            if (verify) {//验签成功业务处理逻辑
+                JSONObject jsonObject = JSON.parseObject(result);
+                String merOrderId = jsonObject.getString("merOrderId");
+                String orderId = jsonObject.getString("parameter1");
+                appUserService.rechargeBalanceCallback(orderId, merOrderId);
+                response.setStatus(200);
                 PrintWriter out = response.getWriter();
-                out.print(result);
+                out.print("OK");
                 out.flush();
                 out.close();
+            } else {//验签失败业务处理逻辑
+                System.err.println("支付回调验签失败");
             }
+
+//            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);
+//                appUserService.rechargeBalanceCallback(out_trade_no, transaction_id);
+//                PrintWriter out = response.getWriter();
+//                out.print(result);
+//                out.flush();
+//                out.close();
+//            }
         }catch (Exception e){
             e.printStackTrace();
         }
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/OrderController.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/OrderController.java
index 53d9271..5b37b5e 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/OrderController.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/OrderController.java
@@ -1,13 +1,20 @@
 package com.supersavedriving.user.modular.api;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.supersavedriving.user.core.common.annotion.ServiceLog;
 import com.supersavedriving.user.core.util.ToolUtil;
 import com.supersavedriving.user.modular.system.model.AppUser;
+import com.supersavedriving.user.modular.system.model.Driver;
 import com.supersavedriving.user.modular.system.model.Order;
-import com.supersavedriving.user.modular.system.service.IAppUserService;
-import com.supersavedriving.user.modular.system.service.IBillService;
-import com.supersavedriving.user.modular.system.service.IOrderService;
+import com.supersavedriving.user.modular.system.model.Revenue;
+import com.supersavedriving.user.modular.system.service.*;
+import com.supersavedriving.user.modular.system.util.MallBook.model.InterfaceResponse;
+import com.supersavedriving.user.modular.system.util.MallBook.model.Receive;
+import com.supersavedriving.user.modular.system.util.MallBook.model.ReceiveUser;
+import com.supersavedriving.user.modular.system.util.MallBook.util.RSASignature;
+import com.supersavedriving.user.modular.system.util.MallBook.util.TrhRequest;
 import com.supersavedriving.user.modular.system.util.PayMoneyUtil;
 import com.supersavedriving.user.modular.system.util.ResultUtil;
 import com.supersavedriving.user.modular.system.warpper.*;
@@ -23,9 +30,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -48,6 +53,12 @@
 
     @Autowired
     private IBillService billService;
+
+    @Autowired
+    private IRevenueService revenueService;
+
+    @Autowired
+    private IDriverService driverService;
 
 
 
@@ -345,19 +356,124 @@
     @PostMapping("/base/order/orderPayCallback")
     public void orderPayCallback(HttpServletRequest request, 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);
-                ResultUtil resultUtil = orderService.orderPayCallback(orderId, transaction_id);
+            String code = request.getParameter("code");
+            String version = request.getParameter("version");
+            String msg = request.getParameter("msg");
+            String date = request.getParameter("date");
+            String result = request.getParameter("result");
+            String sign = request.getParameter("sign");
+            InterfaceResponse interfaceResponse = new InterfaceResponse();
+            interfaceResponse.setCode(code);
+            interfaceResponse.setVersion(version);
+            interfaceResponse.setMsg(msg);
+            interfaceResponse.setDate(date);
+            interfaceResponse.setResult(result);
+            interfaceResponse.setSign(sign);
+            // 验签
+            boolean verify = RSASignature.validate(interfaceResponse.content(), interfaceResponse.getSign());
+            if (verify) {//验签成功业务处理逻辑
+                JSONObject jsonObject = JSON.parseObject(result);
+                String merOrderId = jsonObject.getString("merOrderId");
+                String orderId = jsonObject.getString("parameter1");
+                ResultUtil resultUtil = orderService.orderPayCallback(orderId, merOrderId);
                 if(resultUtil.getCode() == 10000){
+                    response.setStatus(200);
                     PrintWriter out = response.getWriter();
-                    out.print(result);
+                    out.print("OK");
                     out.flush();
                     out.close();
                 }
+            } else {//验签失败业务处理逻辑
+                System.err.println("支付回调验签失败");
+            }
+
+
+//            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);
+//                ResultUtil resultUtil = orderService.orderPayCallback(orderId, transaction_id);
+//                if(resultUtil.getCode() == 10000){
+//                    PrintWriter out = response.getWriter();
+//                    out.print(result);
+//                    out.flush();
+//                    out.close();
+//                }
+//            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * 异步分账回调
+     */
+    @ResponseBody
+    @PostMapping("/base/order/ledgerCallback")
+    public void ledgerCallback(HttpServletRequest request, HttpServletResponse response){
+        try{
+            String code = request.getParameter("code");
+            String version = request.getParameter("version");
+            String msg = request.getParameter("msg");
+            String date = request.getParameter("date");
+            String result = request.getParameter("result");
+            String sign = request.getParameter("sign");
+            InterfaceResponse interfaceResponse = new InterfaceResponse();
+            interfaceResponse.setCode(code);
+            interfaceResponse.setVersion(version);
+            interfaceResponse.setMsg(msg);
+            interfaceResponse.setDate(date);
+            interfaceResponse.setResult(result);
+            interfaceResponse.setSign(sign);
+            // 验签
+            boolean verify = RSASignature.validate(interfaceResponse.content(), interfaceResponse.getSign());
+            if (verify) {//验签成功业务处理逻辑
+                JSONObject jsonObject = JSON.parseObject(result);
+                String merOrderId = jsonObject.getString("merOrderId");
+                String orderId = jsonObject.getString("parameter1");
+                //确认收货
+                new Timer().schedule(new TimerTask() {
+                    @Override
+                    public void run() {
+                        Order order = orderService.selectById(orderId);
+                        List<Revenue> revenues = revenueService.selectList(new EntityWrapper<Revenue>().eq("userType", 2).eq("orderId", order.getId()));
+                        Receive receive = new Receive();//确认收货
+                        receive.setOriginalMerOrderId(merOrderId);
+                        receive.setRcvAmount(String.valueOf(order.getPayMoney() * 100));
+                        List<ReceiveUser> splitList = new ArrayList<>();
+                        for (Revenue revenue : revenues) {
+                            Driver driver = driverService.selectById(revenue.getUserId());
+                            ReceiveUser receiveUser = new ReceiveUser();
+                            receiveUser.setSplitUserId(driver.getMerchantNumber());
+                            receiveUser.setRcvSplitAmount(revenue.getAmount().toString());
+                            splitList.add(receiveUser);
+                        }
+                        receive.setSplitList(splitList);
+                        TrhRequest<Receive> request1 = new TrhRequest();
+                        InterfaceResponse execute = request1.execute(receive, Receive.SERVICE_CODE);
+                        if(!"0000".equals(execute.getResult())){
+                            System.err.println("确认收货" + execute.getMsg());
+                        }
+                        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+                        String status = jsonObject.getString("status");
+                        if("2".equals(status)){
+                            System.err.println("确认收货失败");
+                        }
+                        if("0".equals(status)){
+                            System.err.println("确认收货处理中");
+                        }
+                    }
+                }, 30000);
+                response.setStatus(200);
+                PrintWriter out = response.getWriter();
+                out.print("OK");
+                out.flush();
+                out.close();
+            } else {//验签失败业务处理逻辑
+                System.err.println("支付回调验签失败");
             }
         }catch (Exception e){
             e.printStackTrace();
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/AgentMapper.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/AgentMapper.java
new file mode 100644
index 0000000..bc8c2a6
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/AgentMapper.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.user.modular.system.dao;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.supersavedriving.user.modular.system.model.Agent;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 11:52
+ */
+public interface AgentMapper extends BaseMapper<Agent> {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DivisionRecordMapper.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DivisionRecordMapper.java
new file mode 100644
index 0000000..088bb93
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DivisionRecordMapper.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.user.modular.system.dao;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.supersavedriving.user.modular.system.model.DivisionRecord;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 16:41
+ */
+public interface DivisionRecordMapper extends BaseMapper<DivisionRecord> {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/PlatformRechargeRecordMapper.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/PlatformRechargeRecordMapper.java
new file mode 100644
index 0000000..f8589f0
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/PlatformRechargeRecordMapper.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.user.modular.system.dao;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.supersavedriving.user.modular.system.model.PlatformRechargeRecord;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 14:09
+ */
+public interface PlatformRechargeRecordMapper extends BaseMapper<PlatformRechargeRecord> {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/AgentMapper.xml b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/AgentMapper.xml
new file mode 100644
index 0000000..1496d17
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/AgentMapper.xml
@@ -0,0 +1,21 @@
+<?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.user.modular.system.dao.AgentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.supersavedriving.user.modular.system.model.Agent">
+        <id column="id" property="id"/>
+        <result column="principal" property="principal"/>
+        <result column="principalPhone" property="principalPhone"/>
+        <result column="email" property="email"/>
+        <result column="provinceName" property="provinceName"/>
+        <result column="provinceCode" property="provinceCode"/>
+        <result column="cityCode" property="cityCode"/>
+        <result column="cityName" property="cityName"/>
+        <result column="status" property="status"/>
+        <result column="createTime" property="createTime"/>
+        <result column="bankDeposit" property="bankDeposit"/>
+        <result column="bankAccount" property="bankAccount"/>
+        <result column="serviceCalls" property="serviceCalls"/>
+    </resultMap>
+</mapper>
\ No newline at end of file
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DivisionRecordMapper.xml b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DivisionRecordMapper.xml
new file mode 100644
index 0000000..ba57e81
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/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.user.modular.system.dao.DivisionRecordMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DriverMapper.xml b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DriverMapper.xml
index 3d62685..47880ea 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DriverMapper.xml
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DriverMapper.xml
@@ -47,5 +47,9 @@
         <result column="commission" property="commission"/>
         <result column="wxCollectionCode" property="wxCollectionCode"/>
         <result column="zfbCollectionCode" property="zfbCollectionCode"/>
+        <result column="merchantNumber" property="merchantNumber"/>
+        <result column="merchantName" property="merchantName"/>
+        <result column="merchantPhone" property="merchantPhone"/>
+        <result column="merchantIDCode" property="merchantIDCode"/>
     </resultMap>
 </mapper>
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/OrderMapper.xml b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/OrderMapper.xml
index d55f4d2..5885545 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/OrderMapper.xml
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/OrderMapper.xml
@@ -97,7 +97,7 @@
     <select id="queryMyOrder" resultType="com.supersavedriving.user.modular.system.warpper.OrderListWarpper">
         select
         id,
-        '超省新代驾' as title,
+        '超省新代驾订单' as title,
         startAddress,
         endAddress,
         state,
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/PlatformRechargeRecordMapper.xml b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/PlatformRechargeRecordMapper.xml
new file mode 100644
index 0000000..5336a6a
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/PlatformRechargeRecordMapper.xml
@@ -0,0 +1,16 @@
+<?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.user.modular.system.dao.PlatformRechargeRecordMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.supersavedriving.user.modular.system.model.PlatformRechargeRecord">
+        <id column="id" property="id"/>
+        <result column="orderId" property="orderId"/>
+        <result column="price" property="price"/>
+        <result column="orderNumber" property="orderNumber"/>
+        <result column="balance" property="balance"/>
+        <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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Agent.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Agent.java
new file mode 100644
index 0000000..5c54a54
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Agent.java
@@ -0,0 +1,105 @@
+package com.supersavedriving.user.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/3/22 22:29
+ */
+@Data
+@TableName("t_agent")
+public class Agent {
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @TableField("id")
+    private Integer id;
+    /**
+     * 负责人姓名
+     */
+    @TableField("principal")
+    private String principal;
+    /**
+     * 负责人电话
+     */
+    @TableField("principalPhone")
+    private String principalPhone;
+    /**
+     * 邮箱
+     */
+    @TableField("email")
+    private String email;
+    /**
+     * 代理区域省名称
+     */
+    @TableField("provinceName")
+    private String provinceName;
+    /**
+     * 代理区域省编号
+     */
+    @TableField("provinceCode")
+    private String provinceCode;
+    /**
+     * 代理区域市编号
+     */
+    @TableField("cityCode")
+    private String cityCode;
+    /**
+     * 代理区域市名称
+     */
+    @TableField("cityName")
+    private String cityName;
+    /**
+     * 状态(1=正常,2=冻结,3=删除)
+     */
+    @TableField("status")
+    private Integer status;
+    /**
+     * 添加时间
+     */
+    @TableField("createTime")
+    private Date createTime;
+    /**
+     * 开户银行
+     */
+    @TableField("bankDeposit")
+    private String bankDeposit;
+    /**
+     * 银行账号
+     */
+    @TableField("bankAccount")
+    private String bankAccount;
+    /**
+     * 客服电话
+     */
+    @TableField("serviceCalls")
+    private String serviceCalls;
+    /**
+     * 商户号
+     */
+    @TableField("merchantNumber")
+    private String merchantNumber;
+    /**
+     * 商户姓名
+     */
+    @TableField("merchantName")
+    private String merchantName;
+    /**
+     * 商户电话
+     */
+    @TableField("merchantPhone")
+    private String merchantPhone;
+    /**
+     * 商户身份证号码
+     */
+    @TableField("merchantIDCode")
+    private String merchantIDCode;
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/DivisionRecord.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/DivisionRecord.java
new file mode 100644
index 0000000..bac85da
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/DivisionRecord.java
@@ -0,0 +1,73 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Driver.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Driver.java
index f80a33a..54ea90c 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Driver.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Driver.java
@@ -227,4 +227,24 @@
      */
     @TableField("zfbCollectionCode")
     private String zfbCollectionCode;
+    /**
+     * 商户号
+     */
+    @TableField("merchantNumber")
+    private String merchantNumber;
+    /**
+     * 商户姓名
+     */
+    @TableField("merchantName")
+    private String merchantName;
+    /**
+     * 商户电话
+     */
+    @TableField("merchantPhone")
+    private String merchantPhone;
+    /**
+     * 商户身份证号码
+     */
+    @TableField("merchantIDCode")
+    private String merchantIDCode;
 }
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Order.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Order.java
index 0294c69..4aa6a66 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Order.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Order.java
@@ -218,6 +218,11 @@
     @TableField("estimatedMileage")
     private Double estimatedMileage;
     /**
+     * 预估时间
+     */
+    @TableField("estimatedTime")
+    private Integer estimatedTime;
+    /**
      * 订单金额
      */
     @TableField("orderMoney")
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/PlatformRechargeRecord.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/PlatformRechargeRecord.java
new file mode 100644
index 0000000..f1ea486
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/PlatformRechargeRecord.java
@@ -0,0 +1,58 @@
+package com.supersavedriving.user.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 14:05
+ */
+@Data
+@TableName("t_platform_recharge_record")
+public class PlatformRechargeRecord {
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+    /**
+     * 订单号
+     */
+    @TableField("orderId")
+    private String orderId;
+    /**
+     * 充值金额
+     */
+    @TableField("price")
+    private Double price;
+    /**
+     * 第三方支付流水号
+     */
+    @TableField("orderNumber")
+    private String orderNumber;
+    /**
+     * 余额
+     */
+    @TableField("balance")
+    private Double balance;
+    /**
+     * 支付状态(1=待支付,2=已支付,3=已取消)
+     */
+    @TableField("state")
+    private Integer state;
+    /**
+     * 支付时间
+     */
+    @TableField("payTime")
+    private Date payTime;
+    /**
+     * 添加时间
+     */
+    @TableField("createTime")
+    private Date createTime;
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/RechargeRecord.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/RechargeRecord.java
index 740115b..5be8070 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/RechargeRecord.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/RechargeRecord.java
@@ -42,6 +42,11 @@
     @TableField("amount")
     private Double amount;
     /**
+     * 未分配金额
+     */
+    @TableField("unallocatedAmount")
+    private Double unallocatedAmount;
+    /**
      * 支付方式(1=微信,2=系统充值)
      */
     @TableField("payType")
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/YouTuiDriver.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/YouTuiDriver.java
index 914bf3d..6d0b610 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/YouTuiDriver.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/YouTuiDriver.java
@@ -51,7 +51,7 @@
      * 优推结束时间
      */
     @TableField("endTime")
-    private Integer endTime;
+    private Date endTime;
     /**
      * 状态(1=未使用,2=使用中,3=已结束)
      */
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IAgentService.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IAgentService.java
new file mode 100644
index 0000000..226b9a5
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IAgentService.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.user.modular.system.service;
+
+import com.baomidou.mybatisplus.service.IService;
+import com.supersavedriving.user.modular.system.model.Agent;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 11:53
+ */
+public interface IAgentService extends IService<Agent> {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDivisionRecordService.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDivisionRecordService.java
new file mode 100644
index 0000000..64381d9
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDivisionRecordService.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.user.modular.system.service;
+
+import com.baomidou.mybatisplus.service.IService;
+import com.supersavedriving.user.modular.system.model.DivisionRecord;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 16:42
+ */
+public interface IDivisionRecordService extends IService<DivisionRecord> {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IPlatformRechargeRecordService.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IPlatformRechargeRecordService.java
new file mode 100644
index 0000000..faf5eff
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IPlatformRechargeRecordService.java
@@ -0,0 +1,11 @@
+package com.supersavedriving.user.modular.system.service;
+
+import com.baomidou.mybatisplus.service.IService;
+import com.supersavedriving.user.modular.system.model.PlatformRechargeRecord;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 14:10
+ */
+public interface IPlatformRechargeRecordService extends IService<PlatformRechargeRecord> {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AgentServiceImpl.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AgentServiceImpl.java
new file mode 100644
index 0000000..b551b06
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AgentServiceImpl.java
@@ -0,0 +1,15 @@
+package com.supersavedriving.user.modular.system.service.impl;
+
+import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import com.supersavedriving.user.modular.system.dao.AgentMapper;
+import com.supersavedriving.user.modular.system.model.Agent;
+import com.supersavedriving.user.modular.system.service.IAgentService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 11:53
+ */
+@Service
+public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements IAgentService {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java
index 02bbbe2..7264bc4 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java
@@ -13,6 +13,10 @@
 import com.supersavedriving.user.modular.system.dao.AppUserMapper;
 import com.supersavedriving.user.modular.system.model.*;
 import com.supersavedriving.user.modular.system.service.*;
+import com.supersavedriving.user.modular.system.util.MallBook.model.InterfaceResponse;
+import com.supersavedriving.user.modular.system.util.MallBook.model.PaymentOrder;
+import com.supersavedriving.user.modular.system.util.MallBook.model.PaymentOrderGood;
+import com.supersavedriving.user.modular.system.util.MallBook.util.TrhRequest;
 import com.supersavedriving.user.modular.system.util.PayMoneyUtil;
 import com.supersavedriving.user.modular.system.util.RedisUtil;
 import com.supersavedriving.user.modular.system.util.ResultUtil;
@@ -27,11 +31,13 @@
 import org.apache.shiro.crypto.hash.Md5Hash;
 import org.apache.shiro.util.ByteSource;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -66,6 +72,12 @@
 
     @Autowired
     private IAccountChangeDetailService accountChangeDetailService;
+
+    @Value("${callbackPath}")
+    private String callbackPath;//支付回调网关地址
+
+    @Value("${wx.appletsAppid}")
+    private String appletsAppid;
 
 
 
@@ -156,6 +168,7 @@
         if(null == appUser){
             appUser = new AppUser();
             appUser.setNickname("亲爱的用户");
+            appUser.setAvatar("https://csxdj.obs.cn-south-1.myhuaweicloud.com:443/66cc269703a84e4da87fb21e2c21ab1f.png");
             appUser.setPhone(purePhoneNumber);
             appUser.setOpenid(openid);
             appUser.setUnionid(code2Session.getUnionid());
@@ -301,8 +314,43 @@
         rechargeRecord.setPayStatus(1);
         rechargeRecord.setPayType(1);
         rechargeRecordService.insert(rechargeRecord);
-        ResultUtil weixinpay = payMoneyUtil.weixinpay("余额充值", "", out_trade_no, amount.toString(), "/base/appUser/rechargeBalanceCallback", "JSAPI", appUser.getOpenid());
-        return weixinpay;
+//        ResultUtil weixinpay = payMoneyUtil.weixinpay("余额充值", "", out_trade_no, amount.toString(), "/base/appUser/rechargeBalanceCallback", "JSAPI", appUser.getOpenid());
+//        return weixinpay;
+
+        PaymentOrder paymentOrder = new PaymentOrder();
+        paymentOrder.setBizOrderId(out_trade_no);
+        paymentOrder.setAmount(String.valueOf(amount * 100));
+        paymentOrder.setOrderName("余额充值");
+        paymentOrder.setPayType("WX_MINI");
+        paymentOrder.setTransferType("0");
+        paymentOrder.setAsynSplitFlag("1");
+        paymentOrder.setAppid(appletsAppid);
+        paymentOrder.setOpenid(appUser.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("");
+        paymentOrder.setNotifyUrl(callbackPath + "/base/appUser/rechargeBalanceCallback");
+        paymentOrder.setParameter1(out_trade_no);
+
+        TrhRequest<PaymentOrder> request = new TrhRequest();
+        InterfaceResponse execute = request.execute(paymentOrder, PaymentOrder.SERVICE_CODE);
+        if(!"0000".equals(execute.getResult())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        if("0".equals(status)){
+            return ResultUtil.error("处理中");
+        }
+        String payCode = jsonObject.getString("payCode");
+        return ResultUtil.success(payCode);
     }
 
 
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DivisionRecordServiceImpl.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DivisionRecordServiceImpl.java
new file mode 100644
index 0000000..fd96cff
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DivisionRecordServiceImpl.java
@@ -0,0 +1,15 @@
+package com.supersavedriving.user.modular.system.service.impl;
+
+import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import com.supersavedriving.user.modular.system.dao.DivisionRecordMapper;
+import com.supersavedriving.user.modular.system.model.DivisionRecord;
+import com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OrderServiceImpl.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OrderServiceImpl.java
index 49c1200..fd6c398 100644
--- a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OrderServiceImpl.java
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OrderServiceImpl.java
@@ -12,11 +12,15 @@
 import com.supersavedriving.user.modular.system.util.*;
 import com.supersavedriving.user.modular.system.util.GaoDe.MapUtil;
 import com.supersavedriving.user.modular.system.util.GaoDe.model.District;
+import com.supersavedriving.user.modular.system.util.MallBook.model.*;
+import com.supersavedriving.user.modular.system.util.MallBook.util.Transfer;
+import com.supersavedriving.user.modular.system.util.MallBook.util.TrhRequest;
 import com.supersavedriving.user.modular.system.util.juhe.WeatherUtil;
 import com.supersavedriving.user.modular.system.util.mongodb.model.Location;
 import com.supersavedriving.user.modular.system.warpper.*;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.geo.Circle;
 import org.springframework.data.geo.Distance;
 import org.springframework.data.geo.Metrics;
@@ -29,6 +33,7 @@
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.math.RoundingMode;
+import java.net.InetAddress;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -89,6 +94,18 @@
 
     @Autowired
     private IRevenueService revenueService;
+
+    @Autowired
+    private IAgentService agentService;
+
+    @Autowired
+    private IPlatformRechargeRecordService platformRechargeRecordService;
+
+    @Autowired
+    private IDivisionRecordService divisionRecordService;
+
+    @Value("${callbackPath}")
+    private String callbackPath;//支付回调网关地址
 
 
 
@@ -370,11 +387,13 @@
         String startAddress = travelOrder.getStartAddress();
         startAddress = startAddress.replaceAll("& #40;", "(");
         startAddress = startAddress.replaceAll("& #41;", ")");
-        travelOrder.setStartAddress(startAddress);;
-        String endAddress = travelOrder.getEndAddress();
-        endAddress = endAddress.replaceAll("& #40;", "(");
-        endAddress = endAddress.replaceAll("& #41;", ")");
-        travelOrder.setEndAddress(endAddress);
+        travelOrder.setStartAddress(startAddress);
+        if(ToolUtil.isNotEmpty(travelOrder.getEndAddress())){
+            String endAddress = travelOrder.getEndAddress();
+            endAddress = endAddress.replaceAll("& #40;", "(");
+            endAddress = endAddress.replaceAll("& #41;", ")");
+            travelOrder.setEndAddress(endAddress);
+        }
 
         order = new Order();
         BeanUtils.copyProperties(travelOrder, order);
@@ -383,7 +402,6 @@
             order.setUserName(appUser.getNickname());
         }
         order.setUserId(uid);
-        order.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(3));
         order.setSource(1);
         order.setHallOrder(0);
         order.setStatus(1);
@@ -397,6 +415,7 @@
             }
             d = Double.valueOf(distance.get("distance")) / 1000;
             order.setEstimatedMileage(d);
+            order.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60);
         }
         String city = "";
         District geocode = MapUtil.geocode(order.getStartLng(), order.getStartLat());
@@ -425,6 +444,7 @@
 
         for (Integer i = 0; i < travelOrder.getDriverNum(); i++) {
             order.setId(null);
+            order.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(3));
             this.insert(order);
 
             //推送状态
@@ -676,6 +696,7 @@
             }
             d = Double.valueOf(distance.get("distance")) / 1000;
             order.setEstimatedMileage(d);
+            order.setEstimatedTime(Integer.valueOf(distance.get("duration")) / 60);
         }
         String city = "";
         District geocode = MapUtil.geocode(order.getStartLng().toString(), order.getStartLat().toString());
@@ -848,9 +869,46 @@
         order.setPayMoney(payMoney);
         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
         String out_trade_no = sdf.format(new Date()) + order.getId();
-        ResultUtil weixinpay = payMoneyUtil.weixinpay("代驾服务费", "", out_trade_no, payMoney.toString(), "/base/order/orderPayCallback", "JSAPI", appUser.getOpenid());
+//        ResultUtil weixinpay = payMoneyUtil.weixinpay("代驾服务费", "", out_trade_no, payMoney.toString(), "/base/order/orderPayCallback", "JSAPI", appUser.getOpenid());
+//        this.updateById(order);
+
+
+
+        PaymentOrder paymentOrder = new PaymentOrder();
+        paymentOrder.setBizOrderId(out_trade_no);
+        paymentOrder.setAmount(String.valueOf(payMoney * 100));
+        paymentOrder.setOrderName("代驾服务费");
+        paymentOrder.setPayType("WX_MINI");
+        paymentOrder.setTransferType("0");
+        paymentOrder.setAsynSplitFlag("1");
+        paymentOrder.setAppid("");
+        paymentOrder.setOpenid(appUser.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("");
+        paymentOrder.setNotifyUrl(callbackPath + "/base/order/orderPayCallback");
+        paymentOrder.setParameter1(order.getId().toString());
+
+        TrhRequest<PaymentOrder> request = new TrhRequest();
+        InterfaceResponse execute = request.execute(paymentOrder, PaymentOrder.SERVICE_CODE);
+        if(!"0000".equals(execute.getResult())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        if("0".equals(status)){
+            return ResultUtil.error("处理中");
+        }
+        String payCode = jsonObject.getString("payCode");
         this.updateById(order);
-        return weixinpay;
+        return ResultUtil.success(payCode);
     }
 
 
@@ -895,6 +953,7 @@
 
 
         AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+        accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
         accountChangeDetail.setUserType(1);
         accountChangeDetail.setUserId(appUser.getId());
         accountChangeDetail.setCreateTime(new Date());
@@ -940,6 +999,7 @@
         payMoney = payMoney > appUser.getAccountBalance() ? payMoney - appUser.getAccountBalance() : 0D;
 
         AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+        accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
         accountChangeDetail.setUserType(1);
         accountChangeDetail.setUserId(appUser.getId());
         accountChangeDetail.setCreateTime(new Date());
@@ -956,88 +1016,127 @@
         if(0 < payMoney){//还需要调起微信支付
             SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
             String out_trade_no = sdf.format(new Date()) + order.getId();
-            ResultUtil weixinpay = payMoneyUtil.weixinpay("代驾服务费", "", out_trade_no, payMoney.toString(), "/base/order/orderPayCallback", "JSAPI", appUser.getOpenid());
+//            ResultUtil weixinpay = payMoneyUtil.weixinpay("代驾服务费", "", out_trade_no, payMoney.toString(), "/base/order/orderPayCallback", "JSAPI", appUser.getOpenid());
 
-            new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        int num = 1;
-                        int wait = 0;
-                        while (num <= 10){
-                            int min = 5000;
-                            wait += (min * num);
-                            Order order1 = OrderServiceImpl.this.selectById(order.getId());
-                            if(order1.getState() != 107){
-                                return;
-                            }
+            PaymentOrder paymentOrder = new PaymentOrder();
+            paymentOrder.setBizOrderId(out_trade_no);
+            paymentOrder.setAmount(String.valueOf(payMoney * 100));
+            paymentOrder.setOrderName("代驾服务费");
+            paymentOrder.setPayType("WX_MINI");
+            paymentOrder.setTransferType("0");
+            paymentOrder.setAsynSplitFlag("1");
+            paymentOrder.setAppid("");
+            paymentOrder.setOpenid(appUser.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("");
+            paymentOrder.setNotifyUrl(callbackPath + "/base/order/orderPayCallback");
+            paymentOrder.setParameter1(order.getId().toString());
 
-                            /**
-                             * 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)){
-                                    AccountChangeDetail accountChangeDetail1 = accountChangeDetailService.selectById(accountChangeDetail.getId());
-                                    AppUser appUser1 = appUserService.selectById(accountChangeDetail1.getUserId());
-                                    Double b = accountChangeDetail1.getOldData() - accountChangeDetail1.getNewData();
-                                    appUser1.setAccountBalance(appUser1.getAccountBalance() + b);
-                                    appUserService.updateById(appUser1);
+            TrhRequest<PaymentOrder> request = new TrhRequest();
+            InterfaceResponse execute = request.execute(paymentOrder, PaymentOrder.SERVICE_CODE);
+            if(!"0000".equals(execute.getResult())){
+                return ResultUtil.error(execute.getMsg());
+            }
+            JSONObject jsonObject = JSON.parseObject(execute.getResult());
+            String status = jsonObject.getString("status");
+            if("2".equals(status)){
+                return ResultUtil.error("失败");
+            }
+            if("0".equals(status)){
+                return ResultUtil.error("处理中");
+            }
+            String payCode = jsonObject.getString("payCode");
+            this.updateById(order);
+            return ResultUtil.success(payCode);
 
-                                    accountChangeDetailService.deleteById(accountChangeDetail.getId());
-                                    return;
-                                }
-                                if("SUCCESS".equals(trade_state)){
-                                    order1.setPayTime(new Date());
-                                    order1.setState(108);
-                                    order1.setOrderNo(transaction_id);
-                                    OrderServiceImpl.this.updateById(order1);
-
-                                    //处理抽成及收入
-                                    saveCommission(order1);
-                                    return;
-                                }
-                                if("USERPAYING".equals(trade_state) || "ACCEPT".equals(trade_state)){
-                                    Thread.sleep(wait);
-                                    num++;
-                                }
-                            }else{
-                                Thread.sleep(wait);
-                                num++;
-                            }
-                            if(10 == num){
-                                AccountChangeDetail accountChangeDetail1 = accountChangeDetailService.selectById(accountChangeDetail.getId());
-                                AppUser appUser1 = appUserService.selectById(accountChangeDetail1.getUserId());
-                                Double b = accountChangeDetail1.getOldData() - accountChangeDetail1.getNewData();
-                                appUser1.setAccountBalance(appUser1.getAccountBalance() + b);
-                                appUserService.updateById(appUser1);
-
-                                accountChangeDetailService.deleteById(accountChangeDetail.getId());
-                            }
-                        }
-                    }catch (Exception e){
-                        e.printStackTrace();
-                    }
-                }
-            }).start();
-            return weixinpay;
+//
+//
+//            new Thread(new Runnable() {
+//                @Override
+//                public void run() {
+//                    try {
+//                        int num = 1;
+//                        int wait = 0;
+//                        while (num <= 10){
+//                            int min = 5000;
+//                            wait += (min * num);
+//                            Order order1 = OrderServiceImpl.this.selectById(order.getId());
+//                            if(order1.getState() != 107){
+//                                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)){
+//                                    AccountChangeDetail accountChangeDetail1 = accountChangeDetailService.selectById(accountChangeDetail.getId());
+//                                    AppUser appUser1 = appUserService.selectById(accountChangeDetail1.getUserId());
+//                                    Double b = accountChangeDetail1.getOldData() - accountChangeDetail1.getNewData();
+//                                    appUser1.setAccountBalance(appUser1.getAccountBalance() + b);
+//                                    appUserService.updateById(appUser1);
+//
+//                                    accountChangeDetailService.deleteById(accountChangeDetail.getId());
+//                                    return;
+//                                }
+//                                if("SUCCESS".equals(trade_state)){
+//                                    order1.setPayTime(new Date());
+//                                    order1.setState(108);
+//                                    order1.setOrderNo(transaction_id);
+//                                    OrderServiceImpl.this.updateById(order1);
+//
+//                                    //处理抽成及收入
+//                                    saveCommission(order1);
+//                                    return;
+//                                }
+//                                if("USERPAYING".equals(trade_state) || "ACCEPT".equals(trade_state)){
+//                                    Thread.sleep(wait);
+//                                    num++;
+//                                }
+//                            }else{
+//                                Thread.sleep(wait);
+//                                num++;
+//                            }
+//                            if(10 == num){
+//                                AccountChangeDetail accountChangeDetail1 = accountChangeDetailService.selectById(accountChangeDetail.getId());
+//                                AppUser appUser1 = appUserService.selectById(accountChangeDetail1.getUserId());
+//                                Double b = accountChangeDetail1.getOldData() - accountChangeDetail1.getNewData();
+//                                appUser1.setAccountBalance(appUser1.getAccountBalance() + b);
+//                                appUserService.updateById(appUser1);
+//
+//                                accountChangeDetailService.deleteById(accountChangeDetail.getId());
+//                            }
+//                        }
+//                    }catch (Exception e){
+//                        e.printStackTrace();
+//                    }
+//                }
+//            }).start();
+//            return weixinpay;
         }
-        order.setPayTime(new Date());
-        this.updateById(order);
+//        order.setPayTime(new Date());
+//        this.updateById(order);
 
 
         return ResultUtil.success();
+
     }
 
     /**
@@ -1066,8 +1165,125 @@
             pushOrderInfoWarpper.setState(order.getState());
             pushUtil.pushOrderInfo(order.getDriverId(), 2, pushOrderInfoWarpper);
         }
+
+        //支付成功---->异步分账----->10s钟后再进行确认收货
+        //确认收货后才能进行提现(结算接口)
+        //异步分账
+        List<Revenue> revenues = revenueService.selectList(new EntityWrapper<Revenue>().eq("orderId", order.getId()));
+        Complete complete = new Complete();
+        complete.setOriginalMerOrderId(transaction_id);
+        complete.setNotifyUrl(callbackPath + "/base/order/ledgerCallback");
+        List<PamentOrderUser> splitList = new ArrayList<>();
+        for (Revenue revenue : revenues) {
+            if(revenue.getUserType() == 2){//司机
+                Driver driver = driverService.selectById(revenue.getUserId());
+                PamentOrderUser pamentOrderUser = new PamentOrderUser();
+                pamentOrderUser.setSplitUserId(driver.getMerchantNumber());
+                pamentOrderUser.setSplitAmount(revenue.getAmount().toString());
+                pamentOrderUser.setSplitType("2");
+                splitList.add(pamentOrderUser);
+
+                DivisionRecord divisionRecord = new DivisionRecord();
+                divisionRecord.setUserType(1);
+                divisionRecord.setUserId(revenue.getUserId());
+                divisionRecord.setOrderId(order.getId());
+                divisionRecord.setMerOrderId(transaction_id);
+                divisionRecord.setSourceType(1);
+                divisionRecord.setAmount(revenue.getAmount());
+                divisionRecord.setMerchantNumber(driver.getMerchantNumber());
+                divisionRecord.setState(1);
+                divisionRecord.setCreateTime(new Date());
+                divisionRecordService.insert(divisionRecord);
+            }
+            if(revenue.getUserType() == 3){//代理商
+                Agent agent = agentService.selectById(revenue.getUserId());
+                PamentOrderUser pamentOrderUser = new PamentOrderUser();
+                pamentOrderUser.setSplitUserId(agent.getMerchantNumber());
+                pamentOrderUser.setSplitAmount(revenue.getAmount().toString());
+                pamentOrderUser.setSplitType("2");
+                splitList.add(pamentOrderUser);
+
+                DivisionRecord divisionRecord = new DivisionRecord();
+                divisionRecord.setUserType(2);
+                divisionRecord.setUserId(revenue.getUserId());
+                divisionRecord.setOrderId(order.getId());
+                divisionRecord.setMerOrderId(transaction_id);
+                divisionRecord.setSourceType(1);
+                divisionRecord.setAmount(revenue.getAmount());
+                divisionRecord.setMerchantNumber(agent.getMerchantNumber());
+                divisionRecord.setState(1);
+                divisionRecord.setCreateTime(new Date());
+                divisionRecordService.insert(divisionRecord);
+            }
+
+        }
+        complete.setSplitList(splitList);
+        TrhRequest<Complete> request = new TrhRequest();
+        InterfaceResponse execute = request.execute(complete, Complete.SERVICE_CODE);
+        if(!"0000".equals(execute.getResult())){
+            return ResultUtil.error(execute.getMsg());
+        }
+        JSONObject jsonObject = JSON.parseObject(execute.getResult());
+        String status = jsonObject.getString("status");
+        if("2".equals(status)){
+            return ResultUtil.error("失败");
+        }
+        if("0".equals(status)){
+            return ResultUtil.error("处理中");
+        }
+
+        //使用优惠券的情况,通过转账接口将优惠券的收入转到司机电子账簿
+        if(null != order.getCouponId()){
+            List<PlatformRechargeRecord> platformRechargeRecords = platformRechargeRecordService.selectList(new EntityWrapper<PlatformRechargeRecord>().eq("state", 2).last(" and balance > 0 order by payTime"));
+            Double discountedPrice = order.getDiscountedPrice();
+            Driver driver = driverService.selectById(order.getDriverId());
+            for (PlatformRechargeRecord platformRechargeRecord : platformRechargeRecords) {
+                if(discountedPrice == 0){
+                    break;
+                }
+
+                if(platformRechargeRecord.getBalance().compareTo(discountedPrice) >= 0){
+                    discountedPrice = 0D;
+                    platformRechargeRecord.setBalance(platformRechargeRecord.getBalance() - discountedPrice);
+                    platformRechargeRecordService.updateById(platformRechargeRecord);
+                }else{
+
+                }
+
+                Transfer transfer = new Transfer();
+                transfer.setDepositMerOrderId("6831518911582834611");
+                transfer.setToUserId(driver.getMerchantNumber());
+                transfer.setAmount(discountedPrice.toString());
+                transfer.setOrderName("");
+                transfer.setNotifyUrl("");
+                transfer.setParameter1(order.getId().toString());
+
+                TrhRequest<Transfer> request1 = new TrhRequest();
+                InterfaceResponse execute1 = request1.execute(transfer, Transfer.SERVICE_CODE);
+                if(!"0000".equals(execute1.getResult())){
+                    return ResultUtil.error(execute1.getMsg());
+                }
+                JSONObject jsonObject1 = JSON.parseObject(execute1.getResult());
+                String status1 = jsonObject1.getString("status");
+                if("2".equals(status1)){
+                    return ResultUtil.error("失败");
+                }
+                if("0".equals(status1)){
+                    return ResultUtil.error("处理中");
+                }
+            }
+        }
+
+
         return ResultUtil.success();
     }
+
+
+
+
+
+
+
 
 
     /**
@@ -1106,6 +1322,7 @@
 
                 //增加积分变动记录
                 AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                 accountChangeDetail.setUserType(2);
                 accountChangeDetail.setUserId(order.getDriverId());
                 accountChangeDetail.setCreateTime(new Date());
@@ -1126,6 +1343,7 @@
 
                 //增加积分变动记录
                 AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                 accountChangeDetail.setUserType(2);
                 accountChangeDetail.setUserId(order.getDriverId());
                 accountChangeDetail.setCreateTime(new Date());
@@ -1174,6 +1392,7 @@
                         if(num1 > 0){
                             Driver driver1 = driverService.selectById(appUser.getInviterId());
                             AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                            accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                             accountChangeDetail.setUserType(2);
                             accountChangeDetail.setUserId(driver1.getId());
                             accountChangeDetail.setType(1);
@@ -1220,6 +1439,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver1.getId());
                                     accountChangeDetail.setType(1);
@@ -1245,6 +1465,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver2.getId());
                                     accountChangeDetail.setType(1);
@@ -1270,6 +1491,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver3.getId());
                                     accountChangeDetail.setType(1);
@@ -1298,6 +1520,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver1.getId());
                                     accountChangeDetail.setType(1);
@@ -1323,6 +1546,7 @@
                                     revenueService.insert(revenue);
 
                                     AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                    accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                     accountChangeDetail.setUserType(2);
                                     accountChangeDetail.setUserId(driver2.getId());
                                     accountChangeDetail.setType(1);
@@ -1351,6 +1575,7 @@
                                 revenueService.insert(revenue);
 
                                 AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+                                accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
                                 accountChangeDetail.setUserType(2);
                                 accountChangeDetail.setUserId(driver1.getId());
                                 accountChangeDetail.setType(1);
@@ -1391,6 +1616,7 @@
         revenueService.insert(revenue);
 
         AccountChangeDetail accountChangeDetail = new AccountChangeDetail();
+        accountChangeDetail.setCode(System.currentTimeMillis() + UUIDUtil.getNumberRandom(3));
         accountChangeDetail.setUserType(2);
         accountChangeDetail.setUserId(driver.getId());
         accountChangeDetail.setType(1);
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/PlatformRechargeRecordServiceImpl.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/PlatformRechargeRecordServiceImpl.java
new file mode 100644
index 0000000..3e70fff
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/PlatformRechargeRecordServiceImpl.java
@@ -0,0 +1,15 @@
+package com.supersavedriving.user.modular.system.service.impl;
+
+import com.baomidou.mybatisplus.service.impl.ServiceImpl;
+import com.supersavedriving.user.modular.system.dao.PlatformRechargeRecordMapper;
+import com.supersavedriving.user.modular.system.model.PlatformRechargeRecord;
+import com.supersavedriving.user.modular.system.service.IPlatformRechargeRecordService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zhibing.pu
+ * @date 2023/5/6 14:11
+ */
+@Service
+public class PlatformRechargeRecordServiceImpl extends ServiceImpl<PlatformRechargeRecordMapper, PlatformRechargeRecord> implements IPlatformRechargeRecordService {
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/config/ChannelConfig.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/config/ChannelConfig.java
new file mode 100644
index 0000000..dc41f73
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/config/ChannelConfig.java
@@ -0,0 +1,60 @@
+package com.supersavedriving.user.modular.system.util.MallBook.config;
+
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.core.io.ClassPathResource;
+
+import java.util.Properties;
+
+/**
+ * @Author xiaogc
+ * @Date 2022/2/10 10:03
+ */
+public class ChannelConfig {
+    /**
+     * mallbook 测试环境地址
+     */
+    public static String payUrl;
+
+    /**
+     * 业务系统商户平台编号
+     */
+    public static String merchantNo;
+    /**
+     * 接口版本号,不同版本号触发不同接口业务
+     */
+    public static String version;
+    /*
+     * 渠道类型 HF:汇付
+     */
+    public static String channelType;
+
+    /**
+     * 商户平台私钥路径
+     */
+    public static String merchantPrivateKey;
+    /**
+     * mallbook公钥路径
+     */
+    public static String mallBookPublicKey;
+
+    static {
+        YamlPropertiesFactoryBean yamlProFb = new YamlPropertiesFactoryBean();
+        yamlProFb.setResources(new ClassPathResource("application.yaml"));
+        Properties properties = yamlProFb.getObject();
+        System.out.println("mallbook 参数配置初始化");
+        System.out.println("--------------------------------");
+        System.out.println("环境地址:" + properties.get("mallbook.pay_url"));
+        System.out.println("商户平台编号:" + properties.get("mallbook.merchant_no"));
+        System.out.println("接口版本号:" + properties.get("mallbook.version"));
+        System.out.println("渠道类型:" + properties.get("mallbook.channel_type"));
+        System.out.println("商户平台私钥:" + properties.get("mallbook.merchant_private_key"));
+        System.out.println("mallbook 公钥:" + properties.get("mallbook.mall_book_public_key"));
+        System.out.println("--------------------------------");
+        payUrl = properties.get("mallbook.pay_url").toString();
+        merchantNo = properties.get("mallbook.merchant_no").toString();
+        version = properties.get("mallbook.version").toString();
+        channelType = properties.get("mallbook.channel_type").toString();
+        merchantPrivateKey = properties.get("mallbook.merchant_private_key").toString();
+        mallBookPublicKey = properties.get("mallbook.mall_book_public_key").toString();
+    }
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Complete.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Complete.java
new file mode 100644
index 0000000..4d8c718
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Complete.java
@@ -0,0 +1,58 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceRequest.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceRequest.java
new file mode 100644
index 0000000..bd0eb13
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceRequest.java
@@ -0,0 +1,176 @@
+/**
+ *
+ */
+package com.supersavedriving.user.modular.system.util.MallBook.model;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.supersavedriving.user.modular.system.util.MallBook.config.ChannelConfig;
+import com.supersavedriving.user.modular.system.util.MallBook.util.RSASignature;
+import com.supersavedriving.user.modular.system.util.MallBook.util.StringUtil;
+
+import java.io.Serializable;
+
+/**
+ * 接口请求包
+ *
+ */
+public class InterfaceRequest<T> implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8130938432046696213L;
+
+
+    /**
+     * 商户平台编号
+     */
+    private String merchantNo = ChannelConfig.merchantNo;
+
+    /**
+     * 接口版本号,不同版本号触发不同接口业务
+     */
+    private String version = ChannelConfig.version;
+    /*
+     * 渠道类型  HF:汇付
+     */
+    private String channelType = ChannelConfig.channelType;
+
+
+    /**
+     * 业务系统订单ID
+     */
+    private String merOrderId;
+
+    /**
+     * 签名
+     */
+    private String sign;
+
+    /**
+     * 业务类型编号
+     */
+    private String serverCode;
+
+    /**
+     * 业务参数,json格式
+     */
+    private String params;
+
+    /**
+     * 时间戳
+     */
+    private String date;
+
+
+    public String getChannelType() {
+        return channelType;
+    }
+
+    public void setChannelType(String channelType) {
+        this.channelType = channelType;
+    }
+
+    public String getMerOrderId() {
+        return merOrderId;
+    }
+
+    public void setMerOrderId(String merOrderId) {
+        this.merOrderId = merOrderId;
+    }
+
+    public String getMerchantNo() {
+        return merchantNo;
+    }
+
+    public void setMerchantNo(String merchantNo) {
+        this.merchantNo = merchantNo;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getServerCode() {
+        return serverCode;
+    }
+
+    public void setServerCode(String serverCode) {
+        this.serverCode = serverCode;
+    }
+
+    public String getParams() {
+        return params;
+    }
+
+    public void setParams(String params) {
+        this.params = params;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+
+    /**
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     *  订单号 + 商户号 + 渠道类型 +  时间戳 + 业务参数json
+     * @return 待签名字符串
+     */
+    public String content() {
+        return StrUtil.builder()
+                .append(StringUtil.convertNull(merOrderId))
+                .append(StringUtil.convertNull(merchantNo))
+                .append(StringUtil.convertNull(channelType))
+                .append(StringUtil.convertNull(date))
+                .append(StringUtil.convertNull(params))
+                .toString();
+    }
+
+    public InterfaceRequest() {
+    }
+
+    public InterfaceRequest(T obj, String serverCode) {
+        this.merOrderId = IdUtil.fastSimpleUUID();
+        this.serverCode = serverCode;
+        this.date = System.currentTimeMillis() + "";
+        this.params = JSONUtil.toJsonStr(obj);
+        // todo 使用商户平台私钥生成sign,需要修改证书对应路径
+        this.sign = RSASignature.sign(content());
+    }
+
+
+    @Override
+    public String toString() {
+        return "InterfaceRequest{" +
+                "merOrderId='" + merOrderId + '\'' +
+                ", merchantNo='" + merchantNo + '\'' +
+                ", sign='" + sign + '\'' +
+                ", serverCode='" + serverCode + '\'' +
+                ", params='" + params + '\'' +
+                ", date='" + date + '\'' +
+                ", version='" + version + '\'' +
+                ", channelType='" + channelType + '\'' +
+                '}';
+    }
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceResponse.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceResponse.java
new file mode 100644
index 0000000..ac4211a
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/InterfaceResponse.java
@@ -0,0 +1,121 @@
+/**
+ *
+ */
+package com.supersavedriving.user.modular.system.util.MallBook.model;
+
+
+import cn.hutool.core.util.StrUtil;
+import com.supersavedriving.user.modular.system.util.MallBook.util.StringUtil;
+
+import java.io.Serializable;
+
+
+public class InterfaceResponse implements Serializable {
+
+
+    /**
+     * 结果字符串,json格式
+     */
+    private String result;
+
+    /**
+     * 签名,由code+msg+date+result根据私钥生成, 如果有参数为null,签名串中应当做空字符串("")来处理
+     */
+    private String sign;
+
+    /**
+     * 结果代码
+     */
+    private String code;
+
+    /**
+     * 结果信息
+     */
+    private String msg;
+
+    /**
+     * 时间戳
+     */
+    private String date;
+
+    /**
+     * 接口版本号
+     */
+    private String version;
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getDate() {
+        return date;
+    }
+
+    public void setDate(String date) {
+        this.date = date;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    @Override
+    public String toString() {
+        return "InterfaceResponse{" +
+                "result='" + result + '\'' +
+                ", sign='" + sign + '\'' +
+                ", code='" + code + '\'' +
+                ", msg='" + msg + '\'' +
+                ", date='" + date + '\'' +
+                ", version='" + version + '\'' +
+                '}';
+    }
+
+    /**
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     * 签名顺序必须一致!!!
+     *  结果代码 + 结果信息 + 渠道类型 +  时间戳 + 结果字符串json
+     * @return 待签名字符串
+     */
+    public String content() {
+        return StrUtil.builder()
+                .append(StringUtil.convertNull(code))
+                .append(StringUtil.convertNull(msg))
+                .append(StringUtil.convertNull(date))
+                .append(StringUtil.convertNull(result))
+                .toString();
+    }
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PamentOrderUser.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PamentOrderUser.java
new file mode 100644
index 0000000..67cea1d
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PamentOrderUser.java
@@ -0,0 +1,46 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrder.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrder.java
new file mode 100644
index 0000000..08fe408
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrder.java
@@ -0,0 +1,293 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrderGood.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrderGood.java
new file mode 100644
index 0000000..5ec7180
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/PaymentOrderGood.java
@@ -0,0 +1,48 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Receive.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Receive.java
new file mode 100644
index 0000000..3f82606
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/Receive.java
@@ -0,0 +1,102 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveGood.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveGood.java
new file mode 100644
index 0000000..a9108ac
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveGood.java
@@ -0,0 +1,48 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveUser.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveUser.java
new file mode 100644
index 0000000..58abff3
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/model/ReceiveUser.java
@@ -0,0 +1,27 @@
+package com.supersavedriving.user.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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Base64.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Base64.java
new file mode 100644
index 0000000..f685ee7
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Base64.java
@@ -0,0 +1,288 @@
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+
+/**
+ * @Author xiaogc
+ * @Date 2021/12/21 14:23
+ */
+public class Base64 {
+    static private final int BASELENGTH = 128;
+    static private final int LOOKUPLENGTH = 64;
+    static private final int TWENTYFOURBITGROUP = 24;
+    static private final int EIGHTBIT = 8;
+    static private final int SIXTEENBIT = 16;
+    static private final int FOURBYTE = 4;
+    static private final int SIGN = -128;
+    static private final char PAD = '=';
+    static private final boolean fDebug = false;
+    static final private byte[] base64Alphabet = new byte[BASELENGTH];
+    static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
+
+    static {
+        for (int i = 0; i < BASELENGTH; ++i) {
+            base64Alphabet[i] = -1;
+        }
+        for (int i = 'Z'; i >= 'A'; i--) {
+            base64Alphabet[i] = (byte) (i - 'A');
+        }
+        for (int i = 'z'; i >= 'a'; i--) {
+            base64Alphabet[i] = (byte) (i - 'a' + 26);
+        }
+
+        for (int i = '9'; i >= '0'; i--) {
+            base64Alphabet[i] = (byte) (i - '0' + 52);
+        }
+
+        base64Alphabet['+'] = 62;
+        base64Alphabet['/'] = 63;
+
+        for (int i = 0; i <= 25; i++) {
+            lookUpBase64Alphabet[i] = (char) ('A' + i);
+        }
+
+        for (int i = 26, j = 0; i <= 51; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('a' + j);
+        }
+
+        for (int i = 52, j = 0; i <= 61; i++, j++) {
+            lookUpBase64Alphabet[i] = (char) ('0' + j);
+        }
+        lookUpBase64Alphabet[62] = (char) '+';
+        lookUpBase64Alphabet[63] = (char) '/';
+
+    }
+
+    private static boolean isWhiteSpace(char octect) {
+        return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
+    }
+
+    private static boolean isPad(char octect) {
+        return (octect == PAD);
+    }
+
+    private static boolean isData(char octect) {
+        return (octect < BASELENGTH && base64Alphabet[octect] != -1);
+    }
+
+    /**
+     * Encodes hex octects into Base64
+     *
+     * @param binaryData
+     *            Array containing binaryData
+     * @return Encoded Base64 array
+     */
+    public static String encode(byte[] binaryData) {
+
+        if (binaryData == null) {
+            return null;
+        }
+
+        int lengthDataBits = binaryData.length * EIGHTBIT;
+        if (lengthDataBits == 0) {
+            return "";
+        }
+
+        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
+        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
+        int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
+                : numberTriplets;
+        char encodedData[] = null;
+
+        encodedData = new char[numberQuartet * 4];
+
+        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
+
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        if (fDebug) {
+            System.out.println("number of triplets = " + numberTriplets);
+        }
+
+        for (int i = 0; i < numberTriplets; i++) {
+            b1 = binaryData[dataIndex++];
+            b2 = binaryData[dataIndex++];
+            b3 = binaryData[dataIndex++];
+
+            if (fDebug) {
+                System.out.println("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
+            }
+
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                    : (byte) ((b2) >> 4 ^ 0xf0);
+            byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
+                    : (byte) ((b3) >> 6 ^ 0xfc);
+
+            if (fDebug) {
+                System.out.println("val2 = " + val2);
+                System.out.println("k4   = " + (k << 4));
+                System.out.println("vak  = " + (val2 | (k << 4)));
+            }
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
+        }
+
+        // form integral number of 6-bit groups
+        if (fewerThan24bits == EIGHTBIT) {
+            b1 = binaryData[dataIndex];
+            k = (byte) (b1 & 0x03);
+            if (fDebug) {
+                System.out.println("b1=" + b1);
+                System.out.println("b1<<2 = " + (b1 >> 2));
+            }
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
+            encodedData[encodedIndex++] = PAD;
+            encodedData[encodedIndex++] = PAD;
+        } else if (fewerThan24bits == SIXTEENBIT) {
+            b1 = binaryData[dataIndex];
+            b2 = binaryData[dataIndex + 1];
+            l = (byte) (b2 & 0x0f);
+            k = (byte) (b1 & 0x03);
+
+            byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
+                    : (byte) ((b1) >> 2 ^ 0xc0);
+            byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
+                    : (byte) ((b2) >> 4 ^ 0xf0);
+
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
+            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
+            encodedData[encodedIndex++] = PAD;
+        }
+
+        return new String(encodedData);
+    }
+
+    /**
+     * Decodes Base64 data into octects
+     *
+     * @param encoded
+     *            string containing Base64 data
+     * @return Array containind decoded data.
+     */
+    public static byte[] decode(String encoded) {
+
+        if (encoded == null) {
+            return null;
+        }
+
+        char[] base64Data = encoded.toCharArray();
+        // remove white spaces
+        int len = removeWhiteSpace(base64Data);
+
+        if (len % FOURBYTE != 0) {
+            return null;// should be divisible by four
+        }
+
+        int numberQuadruple = (len / FOURBYTE);
+
+        if (numberQuadruple == 0) {
+            return new byte[0];
+        }
+
+        byte decodedData[] = null;
+        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
+        char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
+
+        int i = 0;
+        int encodedIndex = 0;
+        int dataIndex = 0;
+        decodedData = new byte[(numberQuadruple) * 3];
+
+        for (; i < numberQuadruple - 1; i++) {
+
+            if (!isData((d1 = base64Data[dataIndex++]))
+                    || !isData((d2 = base64Data[dataIndex++]))
+                    || !isData((d3 = base64Data[dataIndex++]))
+                    || !isData((d4 = base64Data[dataIndex++]))) {
+                return null;
+            }// if found "no data" just return null
+
+            b1 = base64Alphabet[d1];
+            b2 = base64Alphabet[d2];
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+        }
+
+        if (!isData((d1 = base64Data[dataIndex++]))
+                || !isData((d2 = base64Data[dataIndex++]))) {
+            return null;// if found "no data" just return null
+        }
+
+        b1 = base64Alphabet[d1];
+        b2 = base64Alphabet[d2];
+
+        d3 = base64Data[dataIndex++];
+        d4 = base64Data[dataIndex++];
+        if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
+            if (isPad(d3) && isPad(d4)) {
+                if ((b2 & 0xf) != 0)// last 4 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 1];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
+                return tmp;
+            } else if (!isPad(d3) && isPad(d4)) {
+                b3 = base64Alphabet[d3];
+                if ((b3 & 0x3) != 0)// last 2 bits should be zero
+                {
+                    return null;
+                }
+                byte[] tmp = new byte[i * 3 + 2];
+                System.arraycopy(decodedData, 0, tmp, 0, i * 3);
+                tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+                tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+                return tmp;
+            } else {
+                return null;
+            }
+        } else { // No PAD e.g 3cQl
+            b3 = base64Alphabet[d3];
+            b4 = base64Alphabet[d4];
+            decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
+            decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
+            decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
+
+        }
+
+        return decodedData;
+    }
+
+    /**
+     * remove WhiteSpace from MIME containing encoded Base64 data.
+     *
+     * @param data
+     *            the byte array of base64 data (with WS)
+     * @return the new length
+     */
+    private static int removeWhiteSpace(char[] data) {
+        if (data == null) {
+            return 0;
+        }
+
+        // count characters that's not whitespace
+        int newSize = 0;
+        int len = data.length;
+        for (int i = 0; i < len; i++) {
+            if (!isWhiteSpace(data[i])) {
+                data[newSize++] = data[i];
+            }
+        }
+        return newSize;
+    }
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/CacheUtils.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/CacheUtils.java
new file mode 100644
index 0000000..0c0f81c
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/CacheUtils.java
@@ -0,0 +1,39 @@
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+
+import cn.hutool.cache.CacheUtil;
+import cn.hutool.cache.impl.TimedCache;
+
+/**
+ * @author linqy
+ * 缓存工具类,生产建议使用其他缓存中间件
+ */
+public class CacheUtils {
+    private static final TimedCache<String, String> TIMED_CACHE = CacheUtil.newTimedCache(5000);
+
+    static {
+        /** 每1s检查一次过期 */
+        TIMED_CACHE.schedulePrune(1000);
+    }
+
+    /**
+     * 存入键值对,提供消逝时间
+     *
+     * @param key
+     * @param value
+     * @param timeout
+     */
+    public static void put(String key, String value, Long timeout) {
+        /** 设置消逝时间 */
+        TIMED_CACHE.put(key, value, timeout);
+    }
+
+    /**
+     * 每次重新get一次缓存,均会重新刷新消逝时间
+     * @param key
+     * @return
+     */
+    public static String get(String key) {
+        return TIMED_CACHE.get(key);
+    }
+
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSAEncryptGeneration.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSAEncryptGeneration.java
new file mode 100644
index 0000000..4686fee
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSAEncryptGeneration.java
@@ -0,0 +1,65 @@
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+
+/**
+ * 公私钥代码生成
+ * @Author xiaogc
+ * @Date 2021/12/21 14:22
+ */
+public class RSAEncryptGeneration {
+
+    public static void main(String[] args) {
+        // 生成一对公私钥到指定路径下  .pfx私钥 .cer公钥
+        RSAEncryptGeneration.genKeyPair("D:\\tools");
+    }
+    /**
+     * 随机生成密钥对
+     */
+    public static void genKeyPair(String filePath) {
+        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
+        KeyPairGenerator keyPairGen = null;
+        try {
+            keyPairGen = KeyPairGenerator.getInstance("RSA");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        // 初始化密钥对生成器,密钥大小为96-1024位
+        keyPairGen.initialize(1024, new SecureRandom());
+        // 生成一个密钥对,保存在keyPair中
+        KeyPair keyPair = keyPairGen.generateKeyPair();
+        // 得到私钥
+        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
+        // 得到公钥
+        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+        try {
+            // 得到公钥字符串
+            String publicKeyString = Base64.encode(publicKey.getEncoded());
+            System.out.println("公钥字符串:"+publicKeyString);
+            // 得到私钥字符串
+            String privateKeyString = Base64.encode(privateKey.getEncoded());
+            System.out.println("私钥字符串:"+privateKeyString);
+            // 将密钥对写入到文件  .pfx私钥 .cer公钥
+            FileWriter pubfw = new FileWriter(filePath + "/merchant_no.cer");
+            FileWriter prifw = new FileWriter(filePath + "/merchant_no.pfx");
+            BufferedWriter pubbw = new BufferedWriter(pubfw);
+            BufferedWriter pribw = new BufferedWriter(prifw);
+            pubbw.write(publicKeyString);
+            pribw.write(privateKeyString);
+            pubbw.flush();
+            pubbw.close();
+            pubfw.close();
+            pribw.flush();
+            pribw.close();
+            prifw.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSASignature.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSASignature.java
new file mode 100644
index 0000000..74a3440
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/RSASignature.java
@@ -0,0 +1,118 @@
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+
+
+import com.supersavedriving.user.modular.system.util.MallBook.config.ChannelConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+/**
+ * @author RSA签名验签类
+ */
+public class RSASignature {
+
+    public static Logger logger = LoggerFactory.getLogger(RSASignature.class);
+
+    /**
+     * 签名算法
+     */
+    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
+
+
+    /**
+     * 商户平台私钥签名
+     *
+     * @param content
+     * @return
+     */
+    public static String sign(String content) {
+        try {
+            String privateKey = ChannelConfig.merchantPrivateKey;
+            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
+            KeyFactory keyf = KeyFactory.getInstance("RSA");
+            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+            signature.initSign(priKey);
+            signature.update(content.getBytes());
+            byte[] signed = signature.sign();
+            return Base64.encode(signed);
+        } catch (Exception e) {
+            logger.error("签名失败{}", e);
+        }
+        return null;
+    }
+
+
+    /**
+     * 读取证书
+     *
+     * @param filePath 证书文件路径
+     */
+    public static String loadKey(String filePath) throws Exception {
+        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
+            String readLine;
+            StringBuilder sb = new StringBuilder();
+            while ((readLine = br.readLine()) != null) {
+                sb.append(readLine);
+            }
+            return sb.toString();
+        } catch (IOException e) {
+            throw new Exception("私钥数据读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("私钥输入流为空");
+        }
+    }
+
+
+    /**
+     * mallbook公钥验签
+     *
+     * @param content 待签名数据
+     * @param sign    签名值
+     * @return false 验签失败 true 成功
+     */
+    public static boolean validate(String content, String sign) {
+        boolean verify = false;
+        try {
+            String publicKey = ChannelConfig.mallBookPublicKey;
+            verify = RSASignature.doCheck(content, sign, publicKey, "utf-8");
+        } catch (Exception e) {
+            logger.error("验签失败:{}", e);
+        }
+        return verify;
+    }
+
+
+    /**
+     * RSA验签
+     *
+     * @param content   待签名数据
+     * @param sign      签名值
+     * @param publicKey 分配给开发商公钥
+     * @param encode    字符集编码
+     * @return 布尔值
+     */
+    public static boolean doCheck(String content, String sign, String publicKey, String encode) {
+        try {
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            byte[] encodedKey = Base64.decode(publicKey);
+            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
+            signature.initVerify(pubKey);
+            signature.update(content.getBytes(encode));
+            return signature.verify(Base64.decode(sign));
+        } catch (Exception e) {
+            logger.error("验签失败{}", e);
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/StringUtil.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/StringUtil.java
new file mode 100644
index 0000000..bc465c1
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/StringUtil.java
@@ -0,0 +1,23 @@
+
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+
+import cn.hutool.core.util.StrUtil;
+
+
+public class StringUtil extends StrUtil {
+
+    /**
+     * null转为空字符串
+     *
+     * @param str
+     * @return
+     */
+    public static String convertNull(String str) {
+        if (str == null) {
+            return "";
+        }
+        return str;
+    }
+
+
+}
diff --git a/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Transfer.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Transfer.java
new file mode 100644
index 0000000..1101797
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/Transfer.java
@@ -0,0 +1,76 @@
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+
+public class Transfer {
+    /**业务类型编号,必须和接口文档一致*/
+    public static String SERVICE_CODE = "transfer";
+    //充值订单号
+    private String depositMerOrderId;
+    //收款方子商户号
+    private String toUserId;
+    //转账金额
+    private String amount;
+    //订单信息
+    private String orderName;
+    //后台回调地址
+    private String notifyUrl;
+    //自定义参数1
+    private String parameter1;
+    //自定义参数2
+    private String parameter2;
+
+    public String getDepositMerOrderId() {
+        return depositMerOrderId;
+    }
+
+    public void setDepositMerOrderId(String depositMerOrderId) {
+        this.depositMerOrderId = depositMerOrderId;
+    }
+
+    public String getToUserId() {
+        return toUserId;
+    }
+
+    public void setToUserId(String toUserId) {
+        this.toUserId = toUserId;
+    }
+
+    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 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/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/TrhRequest.java b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/TrhRequest.java
new file mode 100644
index 0000000..dcff13d
--- /dev/null
+++ b/user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MallBook/util/TrhRequest.java
@@ -0,0 +1,31 @@
+package com.supersavedriving.user.modular.system.util.MallBook.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.exceptions.ValidateException;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import com.supersavedriving.user.modular.system.util.MallBook.config.ChannelConfig;
+import com.supersavedriving.user.modular.system.util.MallBook.model.InterfaceRequest;
+import com.supersavedriving.user.modular.system.util.MallBook.model.InterfaceResponse;
+
+/**
+ * @Author xiaogc
+ * @Date 2022/1/24 13:45
+ */
+public class TrhRequest<T> {
+
+    public InterfaceResponse execute(T t, String serverCode) {
+        InterfaceRequest<T> request = new InterfaceRequest(t, serverCode);
+        System.out.println("mallbook请求参数:" + JSONUtil.toJsonStr(request));
+        String result = HttpUtil.post(ChannelConfig.payUrl, BeanUtil.beanToMap(request));
+        System.out.println("mallbook响应参数:" + result);
+        InterfaceResponse response = JSONUtil.toBean(result, InterfaceResponse.class);
+        boolean verify = RSASignature.validate(response.content(), response.getSign());
+        if (!verify) {
+            throw new ValidateException("签名验证失败");
+        } else {
+            System.out.printf("签名验证通过");
+        }
+        return response;
+    }
+}
diff --git a/user/guns-admin/src/main/resources/application.yml b/user/guns-admin/src/main/resources/application.yml
index 3cdee0e..b050295 100644
--- a/user/guns-admin/src/main/resources/application.yml
+++ b/user/guns-admin/src/main/resources/application.yml
@@ -13,8 +13,8 @@
   application:
     name: user-server
   profiles:
-#    active: dev
-    active: produce
+    active: dev
+#    active: produce
   mvc:
     static-path-pattern: /static/**
     view:
@@ -55,8 +55,8 @@
   datasource:
     url: jdbc:mysql://127.0.0.1:3306/super_save_driving?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
-    password: f4OfRjqoN3jSiNGiUoiNsQdOBtCOKYRj
-#    password: 123456
+#    password: f4OfRjqoN3jSiNGiUoiNsQdOBtCOKYRj
+    password: 123456
     db-name: guns #用来搜集数据库的所有表
     filters: wall,mergeStat
 
@@ -130,5 +130,24 @@
 spring:
   data:
     mongodb:
-      uri: mongodb://root:CEtyLdKjPk0yeHNo@127.0.0.1:27017/admin
-#      uri: mongodb://127.0.0.1:27017/admin
\ No newline at end of file
+#      uri: mongodb://root:CEtyLdKjPk0yeHNo@127.0.0.1:27017/admin
+      uri: mongodb://127.0.0.1:27017/admin
+
+
+#  mallbook 调起接口参数配置
+mallbook:
+  # pay_url:mallbook接口地址    测试环境: http://ld.mallbook.cn:12000/api   生产环境:https://cloudpay.mallbook.cn/api
+  pay_url: http://ld.mallbook.cn:12000/api
+  # merchant_no 业务系统商户平台编号,需替换为mallbook工作人员提供的商户编号
+  merchant_no:  需要替换内容
+  # version 接口版本号
+  version: 1.0.0
+  # channel_type 渠道类型 HF:汇付
+  channel_type: HF
+  # merchant_private_key 商户平台私钥,需要替换成商户平台自己生成的私钥
+  merchant_private_key: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIoGARvX6k6rVwuUW6HjAPkzXVntCtDI8q/niGZbeILc5T/noer+UNDECSy9f8T6ENw7tEKWaHOFcicrqgRv+wXeo2hPiJI2iYsUNs6I8ckd8i4uy/PBEDMW78GlnQLAatk0NC44HKjn8cuIHaETKNG2Vk3rwGBzNgDZ/God1L6JAgMBAAECgYBhCsOwzehBk5pJ2+9pLO+8Rm72EQGvtflb0BBI1zst1x2gBr4DOPedMJe6yymQVrmP/rJItvONdV/DRqHtKMZ2Wa4ul/U1mDnAtS/FkpRYBA5FaXV2hNEW11xBLhL5iGk35P23Bzaa0MJw9Vsd0vjeykridIw/PweDyTdeRBwC2QJBANS+iOaKRuf6BRwCKDmBSHOiZmc/kKnpx2f5BD3h+LWEX3JsNxObMbW1SxQIf2/qwqzIoEm/WbWaOyuwtRZkXQ8CQQCmFjTm5l+Ws2LoQgM+5+eLmPyMyRFOu4G8yqsUkhKuANHK/qrsS1GTbv6SN341NijjNYl05e0h6Jq1T9UZmtrnAkEAwTfzmn7H+3RmI5QJ+IBkzzEWFHv05X0/8DyID7QmcKWzEncaZqIzObdYYu983qa2/LqSaahyz68uQnYRYi7xHQJATr3SgPIRuaH8r360iTtrRHzYp2qgYQJ25On1KECEyKgszp/kqzieSVbjLLFQjavKwMXeEGT+AwiDaJibwJLxWwJAXZApORsqGqdxc9FTxt5iiqG2ZP5DTXxc6E+ihmlmoVl9KncgTf9ez0Q0Qz/4KUTPTHNVgzt1nyBxiLtnyzFavA==
+  # 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
+
diff --git a/user/guns-admin/src/main/resources/redis.properties b/user/guns-admin/src/main/resources/redis.properties
index 307358b..8e63a9f 100644
--- a/user/guns-admin/src/main/resources/redis.properties
+++ b/user/guns-admin/src/main/resources/redis.properties
@@ -1,19 +1,19 @@
 #redis���ÿ�ʼ
 # Redis���ݿ�������Ĭ��Ϊ0��
 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
-## Redis�������������루Ĭ��Ϊ�գ�
-#spring.redis.password=123456
+### Redis���������Ӷ˿�
+#spring.redis.port=16379
+### Redis�������������루Ĭ��Ϊ�գ�
+#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

--
Gitblit v1.7.1