puzhibing
2023-05-16 a6354b57ab2614b6211fbb89e24c5c8bec76ce86
修改bug
19个文件已修改
18个文件已添加
2206 ■■■■■ 已修改文件
driver/guns-admin/pom.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DriverBankMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverBankMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DriverBank.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IAgentService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IBranchOfficeService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverBankService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AccountChangeDetailServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/AgentServiceImpl.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/BranchOfficeServiceImpl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverBankServiceImpl.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/config/ChannelConfig.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/BindAccount.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceRequest.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceResponse.java 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Register.java 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/UnbindAccount.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/Base64.java 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/CacheUtils.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSAEncryptGeneration.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSASignature.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/StringUtil.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/TrhRequest.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/OCRUtil.java 269 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/DriverInfoWarpper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/resources/application.yml 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/resources/redis.properties 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/test/java/com/supersavedriving/driver/GunsApplicationTest.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
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());
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/DriverBankMapper.java
New file
@@ -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> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverBankMapper.xml
New file
@@ -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>
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>
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,
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;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/DriverBank.java
New file
@@ -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;
}
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;
}
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
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IDriverBankService.java
New file
@@ -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;
}
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;
}
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;
                }
            }
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;
    }
}
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获取开通区域
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverBankServiceImpl.java
New file
@@ -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();
    }
}
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();
    }
}
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("您正在上班中");
        }
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);
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/config/ChannelConfig.java
New file
@@ -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();
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/BindAccount.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceRequest.java
New file
@@ -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 + '\'' +
                '}';
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/InterfaceResponse.java
New file
@@ -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();
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/Register.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/model/UnbindAccount.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/Base64.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/CacheUtils.java
New file
@@ -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);
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSAEncryptGeneration.java
New file
@@ -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();
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/RSASignature.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/StringUtil.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/MallBook/util/TrhRequest.java
New file
@@ -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;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/OCRUtil.java
New file
@@ -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",
    //"副本": ""
    //},
}
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;
}
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("用户名称")
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
  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
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
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();
//    }
//}