mitao
2025-11-20 cac9cdf5a3d095e7ed6a77bbd263e3b401d1147b
管理后台企业进件
2个文件已添加
14个文件已修改
1122 ■■■■■ 已修改文件
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/UserWithdrawalController.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/UserWithdrawal.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-core/src/main/java/com/stylefeng/guns/core/util/RequestSeqUtil.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TEnterpriseWithdrawalController.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TEnterpriseWithdrawal.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/resources/application.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_add.html 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_edit.html 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_fail.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/src/main/webapp/static/modular/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_info.js 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-core/src/main/java/com/stylefeng/guns/core/util/RequestSeqUtil.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/ElectronicLedgerController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/UserWithdrawal.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/UserWithdrawalController.java
@@ -115,7 +115,7 @@
        userWithdrawal.setOutRequestNo(ToolUtil.getRandomString(32));
        try {
            // 司机进件
            Map<String, Object> resultMap = douGongBasicDataBiz.userBasicDataIndv(userWithdrawalReq);
            Map<String, Object> resultMap = douGongBasicDataBiz.userBasicDataIndv(userWithdrawal);
            String respCode = (String) resultMap.get("resp_code");
            if(!"00000000".equals(respCode)) {
                return ResultUtil.error((String) resultMap.get("resp_desc"));
@@ -131,7 +131,7 @@
            userWithdrawal.setImgUrlOne(userWithdrawalReq.getIdCardReversePicture());
            userWithdrawal.setIdCardFrontPicture(userWithdrawalReq.getCopy1());
            userWithdrawal.setIdCardReversePicture(userWithdrawalReq.getCopy2());
            userWithdrawal.setHuiFuId((String) resultMap.get("huifu_id"));
            userWithdrawal.setHuifuId((String) resultMap.get("huifu_id"));
            //调用汇付业务入驻接口
            Map<String, Object> map = douGongBasicDataBiz.userBusinessOpen(userWithdrawal);
            if (!"00000000".equals(map.get("resp_code"))){
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java
@@ -70,8 +70,10 @@
        paramsInfo.put("name", userWithdrawal.getOpenAccountName());
        // 个人证件号码
        paramsInfo.put("cert_no", userWithdrawal.getCertificateCode());
        // 管理员账号
        paramsInfo.put("login_name", userWithdrawal.getPhone());
        // 是否发送短信标识
        paramsInfo.put("sms_send_flag", "1");
        paramsInfo.put("sms_send_flag", "Y");
        // 3. 发起API调用
        log.info("个人用户基本信息开户请求参数:{}", paramsInfo);
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/indv", paramsInfo, null, false);
@@ -98,7 +100,7 @@
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd"));
        // 汇付客户Id
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
        String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
        String startDateStr = certificateExpireDateArr[0];
        // 个人证件有效期开始日期
@@ -138,7 +140,7 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
@@ -150,7 +152,7 @@
        // 结算卡信息
        JSONObject cardInfo = new JSONObject();
        cardInfo.put("card_type", "1");
        cardInfo.put("card_name", userWithdrawal.getBindAcctName());
        cardInfo.put("card_name", userWithdrawal.getOpenAccountName());
        cardInfo.put("card_no", userWithdrawal.getBankCardCode());
        cardInfo.put("prov_id", userWithdrawal.getBankCardProvinceCode());
        cardInfo.put("area_id", userWithdrawal.getBankCardCityCode());
@@ -194,7 +196,7 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
@@ -228,7 +230,7 @@
        paramsInfo.put("card_info", cardInfo.toJSONString());
        log.info("用户业务入驻修改返回参数:{}", paramsInfo);
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);;
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/modify", paramsInfo, null, false);;
        log.info("用户业务入驻修改返回参数:{}", response);
        return response;
    }
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/UserWithdrawal.java
@@ -168,7 +168,7 @@
    private Integer type;
    @ApiModelProperty(value = "汇付ID")
    private String huiFuId;
    private String huifuId;
    @ApiModelProperty(value = "取现卡序列号")
    private String tokenNo;
DriverJYXTravel/guns-core/src/main/java/com/stylefeng/guns/core/util/RequestSeqUtil.java
New file
@@ -0,0 +1,217 @@
package com.stylefeng.guns.core.util;
import java.security.SecureRandom;
import java.util.concurrent.atomic.AtomicLong;
/**
 * 请求流水号生成工具类
 *
 * <p>用于生成32位唯一请求流水号,格式:[前缀2位][日期8位][时间6位][毫秒3位][序列号13位]</p>
 * <p>示例:rQ202511141540078404299875651</p>
 *
 * <p>特性:</p>
 * <ul>
 *   <li>线程安全:使用AtomicLong保证高并发环境下的唯一性</li>
 *   <li>高性能:避免重复创建对象,优化内存使用</li>
 *   <li>可配置:支持自定义前缀适应不同业务场景</li>
 *   <li>高可靠:时间戳+随机数+序列号三重保障唯一性</li>
 * </ul>
 *
 * @author harley
 * @since 2025-11-14
 */
public class RequestSeqUtil {
    /**
     * 默认前缀
     */
    private static final String DEFAULT_PREFIX = "RQ";
    /**
     * 序列号生成器,保证线程安全
     */
    private static final AtomicLong SEQUENCE_GENERATOR = new AtomicLong(0);
    /**
     * 安全随机数生成器
     */
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
    /**
     * 流水号总长度
     */
    private static final int TOTAL_LENGTH = 32;
    /**
     * 前缀长度
     */
    private static final int PREFIX_LENGTH = 2;
    /**
     * 日期长度 (yyyyMMdd)
     */
    private static final int DATE_LENGTH = 8;
    /**
     * 时间长度 (HHmmss)
     */
    private static final int TIME_LENGTH = 6;
    /**
     * 毫秒长度
     */
    private static final int MILLIS_LENGTH = 3;
    /**
     * 序列号长度
     */
    private static final int SEQUENCE_LENGTH = 13;
    /**
     * 私有构造函数,防止实例化
     */
    private RequestSeqUtil() {
        throw new UnsupportedOperationException("工具类不允许实例化");
    }
    /**
     * 生成默认前缀的32位请求流水号
     *
     * @return 32位请求流水号,格式:RQ + 时间信息 + 序列号
     */
    public static String generate() {
        return generate(DEFAULT_PREFIX);
    }
    /**
     * 生成指定前缀的32位请求流水号
     *
     * <p>流水号格式:[前缀2位][日期8位][时间6位][毫秒3位][序列号13位]</p>
     * <p>示例:rQ202511141540078404299875651</p>
     *
     * @param prefix 自定义前缀,建议2位字符
     * @return 32位请求流水号
     * @throws IllegalArgumentException 当前缀为空或长度不符合要求时抛出
     */
    public static String generate(String prefix) {
        // 参数校验
        if (prefix == null || prefix.isEmpty()) {
            throw new IllegalArgumentException("前缀不能为空");
        }
        if (prefix.length() != PREFIX_LENGTH) {
            throw new IllegalArgumentException("前缀长度必须为" + PREFIX_LENGTH + "位");
        }
        long currentTime = System.currentTimeMillis();
        // 构建流水号各个部分
        String datePart = DateUtil.format(new java.util.Date(currentTime), "yyyyMMdd");
        String timePart = DateUtil.format(new java.util.Date(currentTime), "HHmmss");
        String millisPart = String.format("%03d", currentTime % 1000);
        // 生成序列号(时间戳后7位 + 随机数6位)
        long sequence = SEQUENCE_GENERATOR.incrementAndGet();
        String sequencePart = String.format("%013d", Math.abs(sequence % 1000000000000L));
        // 组装完整的流水号
        StringBuilder seqBuilder = new StringBuilder(TOTAL_LENGTH);
        seqBuilder.append(prefix)
                  .append(datePart)
                  .append(timePart)
                  .append(millisPart)
                  .append(sequencePart);
        return seqBuilder.toString();
    }
    /**
     * 生成带业务标识的流水号
     *
     * <p>常用的业务前缀:</p>
     * <ul>
     *   <li>rQ - 汇付请求</li>
     *   <li>OR - 订单业务</li>
     *   <li>PY - 支付业务</li>
     *   <li>RF - 退款业务</li>
     * </ul>
     *
     * @param businessCode 业务代码前缀
     * @return 32位业务流水号
     */
    public static String generateForBusiness(String businessCode) {
        return generate(businessCode);
    }
    /**
     * 生成汇付相关的请求流水号
     *
     * @return 以"rQ"为前缀的32位流水号
     */
    public static String generateForHuiFu() {
        return generate("rQ");
    }
    /**
     * 验证流水号格式是否正确
     *
     * @param sequence 要验证的流水号
     * @return 验证结果
     */
    public static boolean isValid(String sequence) {
        if (sequence == null || sequence.length() != TOTAL_LENGTH) {
            return false;
        }
        // 验证时间部分格式(第3-16位应该是数字)
        String timePart = sequence.substring(2, 16);
        if (!timePart.matches("\\d+")) {
            return false;
        }
        // 验证最后13位序列号是否为数字
        String sequencePart = sequence.substring(19);
        if (!sequencePart.matches("\\d+")) {
            return false;
        }
        return true;
    }
    /**
     * 从流水号中提取前缀
     *
     * @param sequence 流水号
     * @return 流水号前缀
     */
    public static String extractPrefix(String sequence) {
        if (sequence == null || sequence.length() < PREFIX_LENGTH) {
            return null;
        }
        return sequence.substring(0, PREFIX_LENGTH);
    }
    /**
     * 从流水号中提取时间信息
     *
     * @param sequence 流水号
     * @return 格式化的时间字符串,格式:yyyy-MM-dd HH:mm:ss.SSS
     */
    public static String extractDateTime(String sequence) {
        if (!isValid(sequence)) {
            return null;
        }
        String dateStr = sequence.substring(2, 10);  // yyyyMMdd
        String timeStr = sequence.substring(10, 16); // HHmmss
        String millisStr = sequence.substring(16, 19); // 毫秒
        return dateStr.substring(0, 4) + "-" +
               dateStr.substring(4, 6) + "-" +
               dateStr.substring(6, 8) + " " +
               timeStr.substring(0, 2) + ":" +
               timeStr.substring(2, 4) + ":" +
               timeStr.substring(4, 6) + "." +
               millisStr;
    }
}
ManagementJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java
@@ -148,52 +148,66 @@
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(), "yyyyMMdd"));
        // 企业用户名称
        paramsInfo.put("reg_name", "企业商户名称8225");
        paramsInfo.put("reg_name", tEnterpriseWithdrawal.getBusinessLicenseCompanyName());
        // 营业执照编号
        paramsInfo.put("license_code", "20220222013747149");
        // 证照有效期类型
        paramsInfo.put("license_validity_type", "1");
        paramsInfo.put("license_code", tEnterpriseWithdrawal.getBusinessLicenseCode());
        String[] businessExpireTimeArr = tEnterpriseWithdrawal.getBusinessExpireTime().split(",");
        String startDateStr = businessExpireTimeArr[0];
        // 证照有效期起始日期
        paramsInfo.put("license_begin_date", "20200117");
        // 证照有效期结束日期日期格式:yyyyMMdd; 非长期有效时必填;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:20320905&lt;/font&gt;
        paramsInfo.put("license_end_date", "20400117");
        paramsInfo.put("license_begin_date", startDateStr.replace("-", ""));
        // 照有效期结束日期日期格式:yyyyMMdd; 非长期有效时必填;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:20320905&lt;/font&gt;
        String endDateStr = businessExpireTimeArr[1];
        if (!"长期".equals(endDateStr)) {
            String formatEndDate = endDateStr.replace("-", "");
            paramsInfo.put("license_end_date", formatEndDate);
            // 证照有效期类型
            paramsInfo.put("license_validity_type", "0");
        } else {
            // 证照有效期类型
            paramsInfo.put("license_validity_type", "1");
        }
        // 注册地址(省)
        paramsInfo.put("reg_prov_id", "310000");
        paramsInfo.put("reg_prov_id", tEnterpriseWithdrawal.getBusinessLicenseProvinceCode());
        // 注册地址(市)
        paramsInfo.put("reg_area_id", "310100");
        paramsInfo.put("reg_area_id", tEnterpriseWithdrawal.getBusinessLicenseCityCode());
        // 注册地址(区)
        paramsInfo.put("reg_district_id", "310104");
        paramsInfo.put("reg_district_id", tEnterpriseWithdrawal.getBusinessLicenseDistrictCode());
        // 注册地址(详细信息)
        paramsInfo.put("reg_detail", "上海市宜山路");
        paramsInfo.put("reg_detail", tEnterpriseWithdrawal.getBusinessLicenseAddress());
        // 法人姓名
        paramsInfo.put("legal_name", "陈立五");
        paramsInfo.put("legal_name", tEnterpriseWithdrawal.getCorporateIdCardReversePicture());
        // 法人证件类型
        paramsInfo.put("legal_cert_type", "00");
        paramsInfo.put("legal_cert_type", tEnterpriseWithdrawal.getCorporateCertificateType().equals(1) ? "00" : "11");
        // 法人证件号码
        paramsInfo.put("legal_cert_no", "321084198912066582");
        // 法人证件有效期类型
        paramsInfo.put("legal_cert_validity_type", "1");
        paramsInfo.put("legal_cert_no", tEnterpriseWithdrawal.getCertificateCode());
        String[] certificateExpireTimeArr = tEnterpriseWithdrawal.getCertificateExpireTime().split(",");
        String expireStartDateStr = certificateExpireTimeArr[0];
        // 法人证件有效期开始日期
        paramsInfo.put("legal_cert_begin_date", "20120801");
        paramsInfo.put("legal_cert_begin_date", expireStartDateStr.replace("-", ""));
        // 法人证件有效期截止日期日期格式:yyyyMMdd; 非长期有效时必填,长期有效为空;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:20320905&lt;/font&gt;
        paramsInfo.put("legal_cert_end_date", "20300801");
        // 法人国籍法人的证件类型为外国人居留证时,必填,参见《[国籍编码](https://cloudpnrcdn.oss-cn-shanghai.aliyuncs.com/opps/api/prod/download_file/area/%E5%9B%BD%E7%B1%8D.xlsx)》&lt;font color&#x3D;&quot;green&quot;&gt;示例值:CHN&lt;/font&gt;
        paramsInfo.put("legal_cert_nationality", "test");
        String expireEndDateStr = certificateExpireTimeArr[1];
        if (!"长期".equals(endDateStr)) {
            String formatEndDate = expireEndDateStr.replace("-", "");
            paramsInfo.put("legal_cert_end_date", formatEndDate);
            // 法人证件有效期类型
            paramsInfo.put("legal_cert_validity_type", "0");
        } else {
            // 法人证件有效期类型
            paramsInfo.put("legal_cert_validity_type", "1");
        }
        // 联系人姓名
        paramsInfo.put("contact_name", "小的");
        paramsInfo.put("contact_name", tEnterpriseWithdrawal.getCorporateName());
        // 联系人手机号
        paramsInfo.put("contact_mobile", "13764462211");
        paramsInfo.put("contact_mobile", tEnterpriseWithdrawal.getCorporatePhone());
        // 管理员账号如需短信通知则必填;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:Lg20220222013747&lt;/font&gt;
        paramsInfo.put("login_name", "Lg2022022201374721361");
        paramsInfo.put("login_name", tEnterpriseWithdrawal.getCorporatePhone());
        // 经营简称
        paramsInfo.put("short_name", "企业商户");
        // 联系人电子邮箱
        paramsInfo.put("contact_email", "jeff.peng@huifu.com");
        paramsInfo.put("short_name", tEnterpriseWithdrawal.getMerchantAbbreviation());
        // 是否发送短信标识
        paramsInfo.put("sms_send_flag", "1");
        paramsInfo.put("sms_send_flag", "Y");
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/ent", paramsInfo, null, false);
        ;
        log.info("企业用户基本信息开户返回参数:{}", JSONObject.toJSONString(response));
        return response;
    }
@@ -211,11 +225,74 @@
        merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey());
        merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey());
        BasePay.initWithMerConfig(merConfig);
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        log.info("个人用户基本信息修改返回参数:{}", paramsInfo);
        // 请求流水号(动态生成,确保唯一性)
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(), "yyyyMMdd"));
        paramsInfo.put("huifu_id", tEnterpriseWithdrawal.getHuifuId());
        // 企业用户名称
        paramsInfo.put("reg_name", tEnterpriseWithdrawal.getBusinessLicenseCompanyName());
        // 经营简称
        paramsInfo.put("short_name", tEnterpriseWithdrawal.getMerchantAbbreviation());
        // 营业执照编号
        paramsInfo.put("license_code", tEnterpriseWithdrawal.getBusinessLicenseCode());
        String[] businessExpireTimeArr = tEnterpriseWithdrawal.getBusinessExpireTime().split(",");
        String startDateStr = businessExpireTimeArr[0];
        // 证照有效期起始日期
        paramsInfo.put("license_begin_date", startDateStr.replace("-", ""));
        // 照有效期结束日期日期格式:yyyyMMdd; 非长期有效时必填;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:20320905&lt;/font&gt;
        String endDateStr = businessExpireTimeArr[1];
        if (!"长期".equals(endDateStr)) {
            String formatEndDate = endDateStr.replace("-", "");
            paramsInfo.put("license_end_date", formatEndDate);
            // 证照有效期类型
            paramsInfo.put("license_validity_type", "0");
        } else {
            // 证照有效期类型
            paramsInfo.put("license_validity_type", "1");
        }
        // 注册地址(省)
        paramsInfo.put("reg_prov_id", tEnterpriseWithdrawal.getBusinessLicenseProvinceCode());
        // 注册地址(市)
        paramsInfo.put("reg_area_id", tEnterpriseWithdrawal.getBusinessLicenseCityCode());
        // 注册地址(区)
        paramsInfo.put("reg_district_id", tEnterpriseWithdrawal.getBusinessLicenseDistrictCode());
        // 注册地址(详细信息)
        paramsInfo.put("reg_detail", tEnterpriseWithdrawal.getBusinessLicenseAddress());
        // 法人姓名
        paramsInfo.put("legal_name", tEnterpriseWithdrawal.getCorporateIdCardReversePicture());
        // 法人证件类型
        paramsInfo.put("legal_cert_type", tEnterpriseWithdrawal.getCorporateCertificateType().equals(1) ? "00" : "11");
        // 法人证件号码
        paramsInfo.put("legal_cert_no", tEnterpriseWithdrawal.getCertificateCode());
        String[] certificateExpireTimeArr = tEnterpriseWithdrawal.getCertificateExpireTime().split(",");
        String expireStartDateStr = certificateExpireTimeArr[0];
        // 法人证件有效期开始日期
        paramsInfo.put("legal_cert_begin_date", expireStartDateStr.replace("-", ""));
        // 法人证件有效期截止日期日期格式:yyyyMMdd; 非长期有效时必填,长期有效为空;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:20320905&lt;/font&gt;
        String expireEndDateStr = certificateExpireTimeArr[1];
        if (!"长期".equals(endDateStr)) {
            String formatEndDate = expireEndDateStr.replace("-", "");
            paramsInfo.put("legal_cert_end_date", formatEndDate);
            // 法人证件有效期类型
            paramsInfo.put("legal_cert_validity_type", "0");
        } else {
            // 法人证件有效期类型
            paramsInfo.put("legal_cert_validity_type", "1");
        }
        // 联系人姓名
        paramsInfo.put("contact_name", tEnterpriseWithdrawal.getCorporateName());
        // 联系人手机号
        paramsInfo.put("contact_mobile", tEnterpriseWithdrawal.getCorporatePhone());
        // 管理员账号如需短信通知则必填;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:Lg20220222013747&lt;/font&gt;
        paramsInfo.put("login_name", tEnterpriseWithdrawal.getCorporatePhone());
        // 是否发送短信标识
        paramsInfo.put("sms_send_flag", "Y");
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/indv/modify", paramsInfo, null, false);
        log.info("个人用户基本信息修改返回参数:{}", response);
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/ent", paramsInfo, null, false);
        log.info("企业用户基本信息修改返回参数:{}", JSONObject.toJSONString(response));
        return response;
    }
@@ -225,7 +302,7 @@
     * @return
     * @throws Exception
     */
    public Map<String, Object> userBusinessOpen(UserWithdrawal userWithdrawal) throws Exception {
    public Map<String, Object> entBusinessOpen(TEnterpriseWithdrawal enterpriseWithdrawal) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(huiFuProperties.getProductId());
@@ -236,45 +313,28 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", enterpriseWithdrawal.getHuifuId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(), "yyyyMMdd"));
        // 渠道商/商户汇付Id
        paramsInfo.put("upper_huifu_id", huiFuProperties.getUpperHuifuId());
        //// 结算信息配置
        // 结算信息配置
        //paramsInfo.put("settle_config", "{\"settle_cycle\":\"D1\",\"min_amt\":\"0.01\",\"remained_amt\":\"10.00\",\"settle_abstract\":\"结算摘要\",\"out_settle_flag\":\"2\",\"settle_batch_no\":\"300\",\"fixed_ratio\":\"2\"}");
        // 结算卡信息
        JSONObject cardInfo = new JSONObject();
        cardInfo.put("card_type", "1");
        cardInfo.put("card_name", userWithdrawal.getBindAcctName());
        cardInfo.put("card_no", userWithdrawal.getBankCardCode());
        cardInfo.put("prov_id", userWithdrawal.getBankCardProvinceCode());
        cardInfo.put("area_id", userWithdrawal.getBankCardCityCode());
        cardInfo.put("cert_type", "00");
        cardInfo.put("cert_no", userWithdrawal.getCertificateCode());
        String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
        String startDateStr = certificateExpireDateArr[0];
        // 个人证件有效期开始日期
        cardInfo.put("cert_begin_date", startDateStr.replace("-", ""));
        // 个人证件有效期截止日期
        String endDateStr = certificateExpireDateArr[1];
        if (!"长期".equals(endDateStr)) {
            String formatEndDate = endDateStr.replace("-", "");
            cardInfo.put("cert_end_date", formatEndDate);
            // 个人证件有效期类型
            cardInfo.put("cert_validity_type", "0");
        } else {
            // 个人证件有效期类型
            cardInfo.put("cert_validity_type", "1");
        }
        cardInfo.put("card_type", "0");
        cardInfo.put("card_name", enterpriseWithdrawal.getDepositName());
        cardInfo.put("card_no", enterpriseWithdrawal.getBankAccount());
        cardInfo.put("prov_id", enterpriseWithdrawal.getBankCardProvinceCode());
        cardInfo.put("area_id", enterpriseWithdrawal.getBankCardCityCode());
        cardInfo.put("branch_code", enterpriseWithdrawal.getBankBranchCode());
        paramsInfo.put("card_info", cardInfo.toJSONString());
        log.info("用户业务入驻返回参数:{}", paramsInfo);
        log.info("企业业务入驻返回参数:{}", paramsInfo);
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);
        ;
        log.info("用户业务入驻返回参数:{}", response);
        log.info("企业业务入驻返回参数:{}", response);
        return response;
    }
@@ -284,7 +344,7 @@
     * @return
     * @throws Exception
     */
    public Map<String, Object> userBusinessOpenModify(UserWithdrawal userWithdrawal) throws Exception {
    public Map<String, Object> entBusinessOpenModify(TEnterpriseWithdrawal enterpriseWithdrawal) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(huiFuProperties.getProductId());
@@ -295,43 +355,28 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", enterpriseWithdrawal.getHuifuId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(), "yyyyMMdd"));
        // 渠道商/商户汇付Id
        paramsInfo.put("upper_huifu_id", huiFuProperties.getUpperHuifuId());
        // 结算信息配置
        //paramsInfo.put("settle_config", "{\"settle_cycle\":\"D1\",\"min_amt\":\"0.01\",\"remained_amt\":\"10.00\",\"settle_abstract\":\"结算摘要\",\"out_settle_flag\":\"2\",\"settle_batch_no\":\"300\",\"fixed_ratio\":\"2\"}");
        // 结算卡信息
        JSONObject cardInfo = new JSONObject();
        cardInfo.put("card_type", "1");
        cardInfo.put("card_name", userWithdrawal.getBindAcctName());
        cardInfo.put("card_no", userWithdrawal.getBankCardCode());
        cardInfo.put("prov_id", userWithdrawal.getBankCardProvinceCode());
        cardInfo.put("area_id", userWithdrawal.getBankCardCityCode());
        cardInfo.put("cert_type", "00");
        cardInfo.put("cert_no", userWithdrawal.getCertificateCode());
        String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
        String startDateStr = certificateExpireDateArr[0];
        // 个人证件有效期开始日期
        cardInfo.put("cert_begin_date", startDateStr.replace("-", ""));
        // 个人证件有效期截止日期
        String endDateStr = certificateExpireDateArr[1];
        if (!"长期".equals(endDateStr)) {
            String formatEndDate = endDateStr.replace("-", "");
            cardInfo.put("cert_end_date", formatEndDate);
            // 个人证件有效期类型
            cardInfo.put("cert_validity_type", "0");
        } else {
            // 个人证件有效期类型
            cardInfo.put("cert_validity_type", "1");
        }
        cardInfo.put("card_type", "0");
        cardInfo.put("card_name", enterpriseWithdrawal.getDepositName());
        cardInfo.put("card_no", enterpriseWithdrawal.getBankAccount());
        cardInfo.put("prov_id", enterpriseWithdrawal.getBankCardProvinceCode());
        cardInfo.put("area_id", enterpriseWithdrawal.getBankCardCityCode());
        cardInfo.put("branch_code", enterpriseWithdrawal.getBankBranchCode());
        paramsInfo.put("card_info", cardInfo.toJSONString());
        log.info("用户业务入驻修改返回参数:{}", paramsInfo);
        log.info("企业业务入驻修改返回参数:{}", paramsInfo);
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);
        ;
        log.info("用户业务入驻修改返回参数:{}", response);
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/modify", paramsInfo, null, false);
        log.info("企业业务入驻修改返回参数:{}", response);
        return response;
    }
}
ManagementJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/general/TEnterpriseWithdrawalController.java
@@ -2,19 +2,23 @@
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.util.SinataUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.cloudPayment.example.MchApplicationExample;
import com.stylefeng.guns.modular.huifu.biz.DouGongBasicDataBiz;
import com.stylefeng.guns.modular.system.controller.util.Base64Util;
import com.stylefeng.guns.modular.system.model.TBank;
import com.stylefeng.guns.modular.system.model.TBankNext;
import com.stylefeng.guns.modular.system.model.TImgMid;
import com.stylefeng.guns.modular.system.model.TRegion;
import com.stylefeng.guns.modular.system.service.ITBankNextService;
import com.stylefeng.guns.modular.system.service.ITBankService;
import com.stylefeng.guns.modular.system.service.ITImgMidService;
import com.stylefeng.guns.modular.system.service.ITRegionService;
import com.unionpay.upyzt.exception.UpyztException;
import com.unionpay.upyzt.resp.MchApplicationResp;
import com.unionpay.upyzt.resp.MchApplicationStoreResp;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -30,8 +34,10 @@
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * 控制器
@@ -54,12 +60,19 @@
    @Autowired
    private ITBankNextService bankNextService;
    @Autowired
    private ITRegionService tRegionService;
    @Autowired
    private DouGongBasicDataBiz douGongBasicDataBiz;
    /**
     * 跳转到首页
     */
    @RequestMapping("")
    public String index(Model model) throws UpyztException {
        TEnterpriseWithdrawal companyId = tEnterpriseWithdrawalService.selectOne(new EntityWrapper<TEnterpriseWithdrawal>().eq("companyId", ShiroKit.getUser().getObjectId()));
        List<TRegion> provinceList = tRegionService.selectList(new EntityWrapper<TRegion>().eq("parent_id", 0));
        model.addAttribute("provinceList",provinceList);
        if(companyId!=null){
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            model.addAttribute("item",companyId);
@@ -76,6 +89,18 @@
            model.addAttribute("bankNext",tBankNext.getBankName());
            model.addAttribute("bankCode",bankCode.getBankCode());
            model.addAttribute("bankNextCode",tBankNext.getId());
            String businessLicenseProvinceCode = companyId.getBusinessLicenseProvinceCode();
            TRegion province = tRegionService.selectOne(new EntityWrapper<TRegion>().eq("code", businessLicenseProvinceCode));
            if (Objects.nonNull(province)) {
                List<TRegion> cityList = tRegionService.selectList(new EntityWrapper<TRegion>().eq("parent_id", province.getId()));
                model.addAttribute("cityList", cityList);
                String businessLicenseCityCode = companyId.getBusinessLicenseCityCode();
                TRegion city = tRegionService.selectOne(new EntityWrapper<TRegion>().eq("code", businessLicenseCityCode));
                if (Objects.nonNull(city)) {
                    List<TRegion> districtList = tRegionService.selectList(new EntityWrapper<TRegion>().eq("parent_id", city.getId()));
                    model.addAttribute("districtList", districtList);
                }
            }
            if("auditing".equals(companyId.getApplicationStatus()) || "".equals(companyId.getApplicationStatus())){
                return PREFIX + "tEnterpriseWithdrawal_detail.html";
            }else if("account_need_verify".equals(companyId.getApplicationStatus())){
@@ -189,13 +214,18 @@
            tEnterpriseWithdrawal.setCopy2(itImgMidService.selectOne(new EntityWrapper<TImgMid>().eq("url",tEnterpriseWithdrawal.getCorporateIdCardFrontPicture())).getMid());
            tEnterpriseWithdrawal.setCopy3(itImgMidService.selectOne(new EntityWrapper<TImgMid>().eq("url",tEnterpriseWithdrawal.getCorporateIdCardReversePicture())).getMid());
            System.out.println("----------"+"进件gogogo"+"----------");
            MchApplicationStoreResp mchApplicationStoreResp = MchApplicationExample.create(tEnterpriseWithdrawal);
            System.out.println("----------"+mchApplicationStoreResp+"----------");
            tEnterpriseWithdrawal.setOutRequestNo(mchApplicationStoreResp.getOutRequestNo());
            tEnterpriseWithdrawal.setMchApplicationId(mchApplicationStoreResp.getMchApplicationId());
            //MchApplicationStoreResp mchApplicationStoreResp = MchApplicationExample.create(tEnterpriseWithdrawal);
            Map<String, Object> resultMap = douGongBasicDataBiz.userBasicDataEnt(tEnterpriseWithdrawal);
            String respCode = (String) resultMap.get("resp_code");
            if(!"00000000".equals(respCode)) {
                return new ErrorTip(500, (String) resultMap.get("resp_desc"));
            }
            Map<String, Object> map = douGongBasicDataBiz.entBusinessOpen(tEnterpriseWithdrawal);
            if(!"00000000".equals(map.get("resp_code"))) {
                return new ErrorTip(500, (String) resultMap.get("resp_desc"));
            }
            tEnterpriseWithdrawal.setHuifuId((String) resultMap.get("huifu_id"));
            tEnterpriseWithdrawal.setTokenNo((String) map.get("token_no"));
            tEnterpriseWithdrawal.setTransactionAuthorizationCode(Base64Util.encode(tEnterpriseWithdrawal.getTransactionAuthorizationCode()));
            tEnterpriseWithdrawal.setBusinessLicense(tEnterpriseWithdrawal.getBusinessLicense());
            tEnterpriseWithdrawal.setCorporateIdCardFrontPicture(tEnterpriseWithdrawal.getCorporateIdCardFrontPicture());
@@ -252,21 +282,25 @@
        }
        try {
            TEnterpriseWithdrawal enterpriseWithdrawal = tEnterpriseWithdrawalService.selectById(tEnterpriseWithdrawal.getId());
            MchApplicationResp mchApplicationResp = MchApplicationExample.retrieveById(enterpriseWithdrawal.getMchApplicationId());
            System.err.println(mchApplicationResp);
            if(enterpriseWithdrawal.getMchId()!=null){
                tEnterpriseWithdrawal.setMchId(enterpriseWithdrawal.getMchId());
            }else {
                tEnterpriseWithdrawal.setMchId(mchApplicationResp.getMchId());
            Map<String, Object> map = douGongBasicDataBiz.userBasicDataEntModify(tEnterpriseWithdrawal);
            if(!"00000000".equals(map.get("resp_code"))) {
                return new ErrorTip(500, (String) map.get("resp_desc"));
            }
            TEnterpriseWithdrawal enterpriseWithdrawal = tEnterpriseWithdrawalService.selectById(tEnterpriseWithdrawal.getId());
            //MchApplicationResp mchApplicationResp = MchApplicationExample.retrieveById(enterpriseWithdrawal.getMchApplicationId());
            //System.err.println(mchApplicationResp);
            //if(enterpriseWithdrawal.getMchId()!=null){
            //    tEnterpriseWithdrawal.setMchId(enterpriseWithdrawal.getMchId());
            //}else {
            //    tEnterpriseWithdrawal.setMchId(mchApplicationResp.getMchId());
            //}
            tEnterpriseWithdrawal.setOutRequestNo(ToolUtil.getRandomString(32));
            String copy1 = tEnterpriseWithdrawalService.getmid(tEnterpriseWithdrawal.getCorporateIdCardFrontPicture());
            String copy2 = tEnterpriseWithdrawalService.getmid(tEnterpriseWithdrawal.getCorporateIdCardReversePicture());
            String copy3 = tEnterpriseWithdrawalService.getmid(tEnterpriseWithdrawal.getBusinessLicense());
            tEnterpriseWithdrawal.setCopy1(copy3);
            tEnterpriseWithdrawal.setCopy2(copy1);
            tEnterpriseWithdrawal.setCopy3(copy2);
            //String copy1 = tEnterpriseWithdrawalService.getmid(tEnterpriseWithdrawal.getCorporateIdCardFrontPicture());
            //String copy2 = tEnterpriseWithdrawalService.getmid(tEnterpriseWithdrawal.getCorporateIdCardReversePicture());
            //String copy3 = tEnterpriseWithdrawalService.getmid(tEnterpriseWithdrawal.getBusinessLicense());
            //tEnterpriseWithdrawal.setCopy1(copy3);
            //tEnterpriseWithdrawal.setCopy2(copy1);
            //tEnterpriseWithdrawal.setCopy3(copy2);
            tEnterpriseWithdrawal.setBankBranchCode(tEnterpriseWithdrawal.getBankBranchCode());
            String depositBank = tEnterpriseWithdrawal.getDepositBank();
            TBankNext tBankNext = bankNextService.selectById(depositBank);
@@ -274,9 +308,13 @@
            tEnterpriseWithdrawal.setBankBranchCode(tBankNext.getBankCode());
            MchApplicationResp renew = MchApplicationExample.renew(tEnterpriseWithdrawal);
            tEnterpriseWithdrawal.setOutRequestNo(renew.getOutRequestNo());
            tEnterpriseWithdrawal.setMchApplicationId(renew.getMchApplicationId());
            //MchApplicationResp renew = MchApplicationExample.renew(tEnterpriseWithdrawal);
            //tEnterpriseWithdrawal.setOutRequestNo(renew.getOutRequestNo());
            //tEnterpriseWithdrawal.setMchApplicationId(renew.getMchApplicationId());
            Map<String, Object> resultMap = douGongBasicDataBiz.entBusinessOpenModify(tEnterpriseWithdrawal);
            if(!"00000000".equals(resultMap.get("resp_code"))) {
                return new ErrorTip(500, (String) map.get("resp_desc"));
            }
            tEnterpriseWithdrawalService.updateById(tEnterpriseWithdrawal);
            return SUCCESS_TIP;
        }catch (Exception e){
@@ -293,4 +331,16 @@
    public Object detail(@PathVariable("tEnterpriseWithdrawalId") Integer tEnterpriseWithdrawalId) {
        return tEnterpriseWithdrawalService.selectById(tEnterpriseWithdrawalId);
    }
    @RequestMapping(value = "/change")
    @ResponseBody
    public Object change(@RequestParam Integer code) {
        List<TRegion> list = new ArrayList<>();
        if (SinataUtil.isNotEmpty(code)){
            TRegion region = tRegionService.selectOne(new EntityWrapper<TRegion>().eq("code", code));
            if (Objects.nonNull(region)) {
                list = tRegionService.selectList(new EntityWrapper<TRegion>().eq("parent_id", region.getId()));
            }
        }
        return list;
    }
}
ManagementJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/TEnterpriseWithdrawal.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@@ -62,6 +63,19 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private String businessExpireTime;
    /**
     * 营业执照注册地址省编码
     */
    private String businessLicenseProvinceCode;
    /**
     * 营业执照注册地址市编码
     */
    private String businessLicenseCityCode;
    /**
     * 营业执照注册地址区编码
     */
    private String businessLicenseDistrictCode;
    /**
     * 统一社会信用代码
     */
    private String unifiedSocialCreditCode;
@@ -97,6 +111,15 @@
     * 银行账号
     */
    private String bankAccount;
    /**
     * 开户行所在省编码
     */
    private String bankCardProvinceCode;
    /**
     * 开户行所在市编码
     */
    private String bankCardCityCode;
    /**
     * 法人姓名
     */
@@ -162,6 +185,20 @@
    private String failureMsgsReason;
    //varchar 64 0 -1 0 0 0    电子账簿账簿号   utf8mb4 utf8mb4_bin 0 0 0 0 0 0 0
    private String relAcctNo ;
    /**
     * 汇付ID
     */
    private String huifuId;
    /**
     * 取现卡序列号
     */
    private String tokenNo;
    /**
     * 进件类型 0:江苏银行;1:汇付
     */
    private String type;
    @TableField(exist = false)
    private String copy1;
@@ -182,6 +219,70 @@
    @TableField(exist = false)
    private String bankBranchCode;
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getHuifuId() {
        return huifuId;
    }
    public void setHuifuId(String huifuId) {
        this.huifuId = huifuId;
    }
    public String getBankCardProvinceCode() {
        return bankCardProvinceCode;
    }
    public void setBankCardProvinceCode(String bankCardProvinceCode) {
        this.bankCardProvinceCode = bankCardProvinceCode;
    }
    public String getBankCardCityCode() {
        return bankCardCityCode;
    }
    public void setBankCardCityCode(String bankCardCityCode) {
        this.bankCardCityCode = bankCardCityCode;
    }
    public String getTokenNo() {
        return tokenNo;
    }
    public void setTokenNo(String tokenNo) {
        this.tokenNo = tokenNo;
    }
    public String getBusinessLicenseProvinceCode() {
        return businessLicenseProvinceCode;
    }
    public void setBusinessLicenseProvinceCode(String businessLicenseProvinceCode) {
        this.businessLicenseProvinceCode = businessLicenseProvinceCode;
    }
    public String getBusinessLicenseCityCode() {
        return businessLicenseCityCode;
    }
    public void setBusinessLicenseCityCode(String businessLicenseCityCode) {
        this.businessLicenseCityCode = businessLicenseCityCode;
    }
    public String getBusinessLicenseDistrictCode() {
        return businessLicenseDistrictCode;
    }
    public void setBusinessLicenseDistrictCode(String businessLicenseDistinctCode) {
        this.businessLicenseDistrictCode = businessLicenseDistinctCode;
    }
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }
ManagementJYXTravel/guns-admin/src/main/resources/application.yml
@@ -37,7 +37,7 @@
    db-column-underline: false
  configuration:
    configuration.map-underscore-to-camel-case: true #是否开启自动驼峰命名规则(camel case)映射
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl #输出Sql,如需打印Sql注释该配置
#    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl #输出Sql,如需打印Sql注释该配置
#eureka:
ManagementJYXTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_add.html
@@ -16,11 +16,23 @@
                            </select>
                        </div>
                    </div>
                <#input id="merchantAbbreviation" name="商户简称" />
                            <#avatar id="businessLicense" name="营业执照" />
                            <#input id="businessLicenseCode" name="营业执照注册号"/>
                            <#input id="businessLicenseCompanyName" name="营业执照公司名称"/>
                            <#input id="businessLicenseAddress" name="营业执照注册地址"/>
                    <#input id="merchantAbbreviation" name="商户简称" />
                    <#avatar id="businessLicense" name="营业执照" />
                    <#input id="businessLicenseCode" name="营业执照注册号"/>
                    <#input id="businessLicenseCompanyName" name="营业执照公司名称"/>
                    <#input id="businessLicenseAddress" name="营业执照注册地址"/>
                    <#select id="businessLicenseProvinceCode" name="营业执照注册省:" onchange="TEnterpriseWithdrawalInfoDlg.provinceChange(1)">
                        <option value="">选择省</option>
                        @for(province in provinceList){
                        <option value="${province.code}">${province.name}</option>
                        @}
                    </#select>
                    <#select id="businessLicenseCityCode" name="营业执照注册市:" onchange="TEnterpriseWithdrawalInfoDlg.cityChange()">
                        <option value="">选择市</option>
                    </#select>
                    <#select id="businessLicenseDistrictCode" name="营业执照注册区:">
                        <option value="">选择区</option>
                    </#select>
                <div class="form-group">
                    <label class="col-sm-3 control-label">营业期限:</label>
                    <div class="col-sm-3" >
@@ -51,7 +63,6 @@
                        </div>
                    </div>
                    <#input id="contactsEmail" name="邮箱地址"/>
                </div>
                          <div class="col-sm-6" >
@@ -82,6 +93,15 @@
                                   </select>
                           </div>
                       </div>
                        <#select id="bankCardProvinceCode" name="银行所在省:" onchange="TEnterpriseWithdrawalInfoDlg.provinceChange(2)">
                        <option value="">选择省</option>
                        @for(province in provinceList){
                        <option value="${province.code}">${province.name}</option>
                        @}
                        </#select>
                        <#select id="bankCardCityCode" name="银行所在市:" onchange="TEnterpriseWithdrawalInfoDlg.cityChange()">
                        <option value="">选择市</option>
                        </#select>
                            <#input id="depositName" name="开户名称" />
                            <#input id="bankAccount" name="银行账号"/>
                            <#input id="corporateName" name="法人姓名"/>
@@ -113,20 +133,20 @@
                </div>
            </div>
                            <#input id="corporatePhone" name="法人手机号" />
            <div class="form-group">
                <label class="col-sm-3 control-label">验证码:</label>
                <div class="col-sm-7">
                    <input class="form-control" id="code" name="code" type="text">
                </div>
                &nbsp;&nbsp;&nbsp;
                <input type="button"  id="sendCode" onclick="sendSMSCode(this)" style="
    background-color: #0e9aef;
    border: 0;
    border-radius: 5px;
    width: 80px;
    height: 30px;color: white;
" value="获取验证码">
            </div>
<!--            <div class="form-group">-->
<!--                <label class="col-sm-3 control-label">验证码:</label>-->
<!--                <div class="col-sm-7">-->
<!--                    <input class="form-control" id="code" name="code" type="text">-->
<!--                </div>-->
<!--                &nbsp;&nbsp;&nbsp;-->
<!--                <input type="button" id="sendCode" onclick="sendSMSCode(this)" style="-->
<!--                background-color: #0e9aef;-->
<!--                border: 0;-->
<!--                border-radius: 5px;-->
<!--                width: 80px;-->
<!--                height: 30px;color: white;-->
<!--            " value="获取验证码">-->
<!--            </div>-->
                         <#avatar id="corporateIdCardFrontPicture" name="法人身份证照片正面" />
                         <#avatar id="corporateIdCardReversePicture" name="法人身份证照反面" />
                </div>
ManagementJYXTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_edit.html
@@ -1,7 +1,7 @@
@layout("/common/_container.html"){
<div class="ibox float-e-margins">
    <div class="ibox-content">
        <div class="form-horizontal" >
        <div class="form-horizontal"  id="enForm">
            <input hidden id="id" value="${item.id}">
            <input hidden id="enterpriseType_" value="${item.enterpriseType}">
            <input hidden id="accountType_" value="${item.accountType}">
@@ -24,6 +24,32 @@
                            <#input id="businessLicenseCode" name="营业执照注册号" value="${item.businessLicenseCode}" />
                            <#input id="businessLicenseCompanyName" name="营业执照公司名称" value="${item.businessLicenseCompanyName}" />
                            <#input id="businessLicenseAddress" name="营业执照注册地址" value="${item.businessLicenseAddress}" />
                    <#select id="businessLicenseProvinceCode" name="营业执照注册省:" onchange="TEnterpriseWithdrawalInfoDlg.provinceChange(1)">
                        <option value="">选择省</option>
                        @for(province in provinceList){
                        <option value="${province.code}" ${item.businessLicenseProvinceCode == province.code ? 'selected' : ''}>${province.name}</option>
                        @}
                    </#select>
                    <#select id="businessLicenseCityCode" name="营业执照注册市:" onchange="TEnterpriseWithdrawalInfoDlg.cityChange()">
                    @if(isNotEmpty(cityList)){
                        <option value="">选择市</option>
                        @for(city in cityList){
                        <option value="${city.code}" ${item.businessLicenseCityCode == city.code ? 'selected' : ''}>${city.name}</option>
                        @}
                    @}else{
                        <option value="">选择市</option>
                    @}
                    </#select>
                <#select id="businessLicenseDistrictCode" name="营业执照注册区:">
                    @if(isNotEmpty(districtList)){
                        <option value="">选择区</option>
                        @for(district in districtList){
                        <option value="${district.code}" ${item.businessLicenseDistrictCode == district.code ? 'selected' : ''}>${district.name}</option>
                        @}
                    @}else{
                        <option value="">选择区</option>
                    @}
                </#select>
                    <div class="form-group">
                        <label class="col-sm-3 control-label">营业期限:</label>
                        <div class="col-sm-3" >
@@ -85,6 +111,22 @@
                    </select>
                </div>
            </div>
            <#select id="bankCardProvinceCode" name="营业执照注册省:" onchange="TEnterpriseWithdrawalInfoDlg.provinceChange(2)">
            <option value="">选择省</option>
            @for(province in provinceList){
            <option value="${province.code}" ${item.bankCardProvinceCode == province.code ? 'selected' : ''}>${province.name}</option>
            @}
            </#select>
            <#select id="bankCardCityCode" name="营业执照注册市:" onchange="TEnterpriseWithdrawalInfoDlg.cityChange()">
            @if(isNotEmpty(cityList)){
            <option value="">选择市</option>
            @for(city in cityList){
            <option value="${city.code}" ${item.bankCardCityCode == city.code ? 'selected' : ''}>${city.name}</option>
            @}
            @}else{
            <option value="">选择市</option>
            @}
            </#select>
                            <#input id="depositName" name="开户名称" value="${item.depositName}" />
                            <#input id="bankAccount" name="银行账号" value="${item.bankAccount}"/>
                            <#input id="corporateName" name="法人姓名" value="${item.corporateName}"/>
ManagementJYXTravel/guns-admin/src/main/webapp/WEB-INF/view/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_fail.html
@@ -24,6 +24,32 @@
                            <#input id="businessLicenseCode" name="营业执照注册号" value="${item.businessLicenseCode}" />
                            <#input id="businessLicenseCompanyName" name="营业执照公司名称" value="${item.businessLicenseCompanyName}" />
                            <#input id="businessLicenseAddress" name="营业执照注册地址" value="${item.businessLicenseAddress}" />
                    <#select id="businessLicenseProvinceCode" name="营业执照注册省:" onchange="TEnterpriseWithdrawalInfoDlg.provinceChange(1)">
                        <option value="">选择省</option>
                        @for(province in provinceList){
                        <option value="${province.code}" ${item.businessLicenseProvinceCode == province.code ? 'selected' : ''}>${province.name}</option>
                        @}
                    </#select>
                    <#select id="businessLicenseCityCode" name="营业执照注册市:" onchange="TEnterpriseWithdrawalInfoDlg.cityChange()">
                        @if(isNotEmpty(cityList)){
                        <option value="">选择市</option>
                        @for(city in cityList){
                        <option value="${city.code}" ${item.businessLicenseCityCode == city.code ? 'selected' : ''}>${city.name}</option>
                        @}
                        @}else{
                        <option value="">选择市</option>
                        @}
                    </#select>
                    <#select id="businessLicenseDistrictCode" name="营业执照注册区:">
                        @if(isNotEmpty(districtList)){
                        <option value="">选择区</option>
                        @for(district in districtList){
                        <option value="${district.code}" ${item.businessLicenseDistrictCode == district.code ? 'selected' : ''}>${district.name}</option>
                        @}
                        @}else{
                        <option value="">选择区</option>
                        @}
                    </#select>
                    <div class="form-group">
                        <label class="col-sm-3 control-label">营业期限:</label>
                        <div class="col-sm-3" >
@@ -88,6 +114,22 @@
                    </select>
                </div>
            </div>
                <#select id="bankCardProvinceCode" name="营业执照注册省:" onchange="TEnterpriseWithdrawalInfoDlg.provinceChange(2)">
                <option value="">选择省</option>
                @for(province in provinceList){
                <option value="${province.code}" ${item.bankCardProvinceCode == province.code ? 'selected' : ''}>${province.name}</option>
                @}
                </#select>
                <#select id="bankCardCityCode" name="营业执照注册市:" onchange="TEnterpriseWithdrawalInfoDlg.cityChange()">
                @if(isNotEmpty(cityList)){
                <option value="">选择市</option>
                @for(city in cityList){
                <option value="${city.code}" ${item.bankCardCityCode == city.code ? 'selected' : ''}>${city.name}</option>
                @}
                @}else{
                <option value="">选择市</option>
                @}
                </#select>
                            <#input id="depositName" name="开户名称" value="${item.depositName}" />
                            <#input id="bankAccount" name="银行账号" value="${item.bankAccount}"/>
                            <#input id="corporateName" name="法人姓名" value="${item.corporateName}"/>
ManagementJYXTravel/guns-admin/src/main/webapp/static/modular/system/tEnterpriseWithdrawal/tEnterpriseWithdrawal_info.js
@@ -46,6 +46,27 @@
                }
            }
        },
        businessLicenseProvinceCode: {
            validators: {
                notEmpty: {
                    message: '营业执照注册地址省不能为空'
                }
            }
        },
        businessLicenseCityCode: {
            validators: {
                notEmpty: {
                    message: '营业执照注册市不能为空'
                }
            }
        },
        businessLicenseDistrictCode: {
            validators: {
                notEmpty: {
                    message: '营业执照注册区不能为空'
                }
            }
        },
        unifiedSocialCreditCode: {
            validators: {
                notEmpty: {
@@ -85,6 +106,20 @@
            validators: {
                notEmpty: {
                    message: '开户名称不能为空'
                }
            }
        },
        bankCardProvinceCode: {
            validators: {
                notEmpty: {
                    message: '银行所在省不能为空'
                }
            }
        },
        bankCardCityCode: {
            validators: {
                notEmpty: {
                    message: '银行所在市不能为空'
                }
            }
        },
@@ -209,6 +244,11 @@
    .set('businessLicenseCompanyName')
    .set('businessLicenseAddress')
    .set('businessExpireTime')
    .set('businessLicenseProvinceCode')
    .set('businessLicenseCityCode')
    .set('businessLicenseDistrictCode')
    .set('bankCardProvinceCode')
    .set('bankCardCityCode')
    .set('unifiedSocialCreditCode')
    .set('unifiedSocialCreditCodeExpireTime')
    .set('companyPhone')
@@ -331,7 +371,45 @@
    console.log(this.tEnterpriseWithdrawalInfoData)
    ajax.start();
}
/**
 * 省改变时执行
 */
TEnterpriseWithdrawalInfoDlg.provinceChange = function (type) {
    let code = type == 1 ? code = $("#businessLicenseProvinceCode").val() : $("#bankCardProvinceCode").val();
    var ajax = new $ax(Feng.ctxPath + "/tEnterpriseWithdrawal/change", function(data){
        if(data!=null){
            var content='<option value="">选择市</option>';
            $.each(data, function(k,v) {
                content += "<option value='"+v.code+"'>"+v.name+"</option>";
            });
            if (type == 1) {
                $("#businessLicenseCityCode").empty().append(content);
                $("#businessLicenseDistinctCode").empty().append('<option value="">选择区</option>');
            }else if (type == 2) {
                $("#bankCardCityCode").empty().append(content);
            }
        }
    });
    ajax.set("code", code);
    ajax.start();
}
/**
 * 市改变时执行
 */
TEnterpriseWithdrawalInfoDlg.cityChange = function () {
    var businessLicenseCityCode = $("#businessLicenseCityCode").val();
    var ajax = new $ax(Feng.ctxPath + "/tEnterpriseWithdrawal/change", function(data){
        if(data!=null){
            var content='<option value="">选择区</option>';
            $.each(data, function(k,v) {
                content += "<option value='"+v.code+"'>"+v.name+"</option>";
            });
            $("#businessLicenseDistinctCode").empty().append(content);
        }
    });
    ajax.set("code",businessLicenseCityCode);
    ajax.start();
}
$(function() {
    Feng.initValidator("enForm", TEnterpriseWithdrawalInfoDlg.validateFields);
    var businessLicense = new $WebUpload("businessLicense");
ManagementJYXTravel/guns-core/src/main/java/com/stylefeng/guns/core/util/RequestSeqUtil.java
New file
@@ -0,0 +1,217 @@
package com.stylefeng.guns.core.util;
import java.security.SecureRandom;
import java.util.concurrent.atomic.AtomicLong;
/**
 * 请求流水号生成工具类
 *
 * <p>用于生成32位唯一请求流水号,格式:[前缀2位][日期8位][时间6位][毫秒3位][序列号13位]</p>
 * <p>示例:rQ202511141540078404299875651</p>
 *
 * <p>特性:</p>
 * <ul>
 *   <li>线程安全:使用AtomicLong保证高并发环境下的唯一性</li>
 *   <li>高性能:避免重复创建对象,优化内存使用</li>
 *   <li>可配置:支持自定义前缀适应不同业务场景</li>
 *   <li>高可靠:时间戳+随机数+序列号三重保障唯一性</li>
 * </ul>
 *
 * @author harley
 * @since 2025-11-14
 */
public class RequestSeqUtil {
    /**
     * 默认前缀
     */
    private static final String DEFAULT_PREFIX = "RQ";
    /**
     * 序列号生成器,保证线程安全
     */
    private static final AtomicLong SEQUENCE_GENERATOR = new AtomicLong(0);
    /**
     * 安全随机数生成器
     */
    private static final SecureRandom SECURE_RANDOM = new SecureRandom();
    /**
     * 流水号总长度
     */
    private static final int TOTAL_LENGTH = 32;
    /**
     * 前缀长度
     */
    private static final int PREFIX_LENGTH = 2;
    /**
     * 日期长度 (yyyyMMdd)
     */
    private static final int DATE_LENGTH = 8;
    /**
     * 时间长度 (HHmmss)
     */
    private static final int TIME_LENGTH = 6;
    /**
     * 毫秒长度
     */
    private static final int MILLIS_LENGTH = 3;
    /**
     * 序列号长度
     */
    private static final int SEQUENCE_LENGTH = 13;
    /**
     * 私有构造函数,防止实例化
     */
    private RequestSeqUtil() {
        throw new UnsupportedOperationException("工具类不允许实例化");
    }
    /**
     * 生成默认前缀的32位请求流水号
     *
     * @return 32位请求流水号,格式:RQ + 时间信息 + 序列号
     */
    public static String generate() {
        return generate(DEFAULT_PREFIX);
    }
    /**
     * 生成指定前缀的32位请求流水号
     *
     * <p>流水号格式:[前缀2位][日期8位][时间6位][毫秒3位][序列号13位]</p>
     * <p>示例:rQ202511141540078404299875651</p>
     *
     * @param prefix 自定义前缀,建议2位字符
     * @return 32位请求流水号
     * @throws IllegalArgumentException 当前缀为空或长度不符合要求时抛出
     */
    public static String generate(String prefix) {
        // 参数校验
        if (prefix == null || prefix.isEmpty()) {
            throw new IllegalArgumentException("前缀不能为空");
        }
        if (prefix.length() != PREFIX_LENGTH) {
            throw new IllegalArgumentException("前缀长度必须为" + PREFIX_LENGTH + "位");
        }
        long currentTime = System.currentTimeMillis();
        // 构建流水号各个部分
        String datePart = DateUtil.format(new java.util.Date(currentTime), "yyyyMMdd");
        String timePart = DateUtil.format(new java.util.Date(currentTime), "HHmmss");
        String millisPart = String.format("%03d", currentTime % 1000);
        // 生成序列号(时间戳后7位 + 随机数6位)
        long sequence = SEQUENCE_GENERATOR.incrementAndGet();
        String sequencePart = String.format("%013d", Math.abs(sequence % 1000000000000L));
        // 组装完整的流水号
        StringBuilder seqBuilder = new StringBuilder(TOTAL_LENGTH);
        seqBuilder.append(prefix)
                  .append(datePart)
                  .append(timePart)
                  .append(millisPart)
                  .append(sequencePart);
        return seqBuilder.toString();
    }
    /**
     * 生成带业务标识的流水号
     *
     * <p>常用的业务前缀:</p>
     * <ul>
     *   <li>rQ - 汇付请求</li>
     *   <li>OR - 订单业务</li>
     *   <li>PY - 支付业务</li>
     *   <li>RF - 退款业务</li>
     * </ul>
     *
     * @param businessCode 业务代码前缀
     * @return 32位业务流水号
     */
    public static String generateForBusiness(String businessCode) {
        return generate(businessCode);
    }
    /**
     * 生成汇付相关的请求流水号
     *
     * @return 以"rQ"为前缀的32位流水号
     */
    public static String generateForHuiFu() {
        return generate("rQ");
    }
    /**
     * 验证流水号格式是否正确
     *
     * @param sequence 要验证的流水号
     * @return 验证结果
     */
    public static boolean isValid(String sequence) {
        if (sequence == null || sequence.length() != TOTAL_LENGTH) {
            return false;
        }
        // 验证时间部分格式(第3-16位应该是数字)
        String timePart = sequence.substring(2, 16);
        if (!timePart.matches("\\d+")) {
            return false;
        }
        // 验证最后13位序列号是否为数字
        String sequencePart = sequence.substring(19);
        if (!sequencePart.matches("\\d+")) {
            return false;
        }
        return true;
    }
    /**
     * 从流水号中提取前缀
     *
     * @param sequence 流水号
     * @return 流水号前缀
     */
    public static String extractPrefix(String sequence) {
        if (sequence == null || sequence.length() < PREFIX_LENGTH) {
            return null;
        }
        return sequence.substring(0, PREFIX_LENGTH);
    }
    /**
     * 从流水号中提取时间信息
     *
     * @param sequence 流水号
     * @return 格式化的时间字符串,格式:yyyy-MM-dd HH:mm:ss.SSS
     */
    public static String extractDateTime(String sequence) {
        if (!isValid(sequence)) {
            return null;
        }
        String dateStr = sequence.substring(2, 10);  // yyyyMMdd
        String timeStr = sequence.substring(10, 16); // HHmmss
        String millisStr = sequence.substring(16, 19); // 毫秒
        return dateStr.substring(0, 4) + "-" +
               dateStr.substring(4, 6) + "-" +
               dateStr.substring(6, 8) + " " +
               timeStr.substring(0, 2) + ":" +
               timeStr.substring(2, 4) + ":" +
               timeStr.substring(4, 6) + "." +
               millisStr;
    }
}
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/ElectronicLedgerController.java
@@ -125,7 +125,7 @@
            userWithdrawal.setImgUrlOne(userWithdrawalReq.getIdCardReversePicture());
            userWithdrawal.setIdCardFrontPicture(userWithdrawalReq.getCopy1());
            userWithdrawal.setIdCardReversePicture(userWithdrawalReq.getCopy2());
            userWithdrawal.setHuiFuId((String) resultMap.get("huifu_id"));
            userWithdrawal.setHuifuId((String) resultMap.get("huifu_id"));
            //调用汇付业务入驻接口
            Map<String, Object> map = douGongBasicDataBiz.userBusinessOpen(userWithdrawal);
            if (!"00000000".equals(map.get("resp_code"))){
@@ -232,7 +232,7 @@
            UserWithdrawal userWithdrawal1 = userWithdrawalService.selectOne(new EntityWrapper<UserWithdrawal>()
                    .eq("phone", userInfo.getPhone()).eq("type", 1)
                    .last("LIMIT 1"));
            if(userWithdrawal1==null|| userWithdrawal1.getHuiFuId()==null){
            if(userWithdrawal1==null|| userWithdrawal1.getHuifuId()==null){
                return ResultUtil.runErr();
            }
            UserWithdrawal userWithdrawal = new UserWithdrawal();
@@ -272,7 +272,7 @@
            userWithdrawal1.setBankName(bankName);
            userWithdrawal1.setImgUrl(idCardFrontPicture);
            userWithdrawal1.setImgUrlOne(idCardReversePicture);
            userWithdrawal1.setHuiFuId((String) resultMap.get("huifu_id"));
            userWithdrawal1.setHuifuId((String) resultMap.get("huifu_id"));
            userWithdrawal1.setTokenNo((String) map.get("token_no"));
            userWithdrawalService.updateById(userWithdrawal1);
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java
@@ -73,8 +73,10 @@
        paramsInfo.put("name", userWithdrawal.getOpenAccountName());
        // 个人证件号码
        paramsInfo.put("cert_no", userWithdrawal.getCertificateCode());
        // 管理员账号
        paramsInfo.put("login_name", userWithdrawal.getPhone());
        // 是否发送短信标识
        paramsInfo.put("sms_send_flag", "1");
        paramsInfo.put("sms_send_flag", "Y");
        // 3. 发起API调用
        log.info("个人用户基本信息开户请求参数:{}", paramsInfo);
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/indv", paramsInfo, null, false);
@@ -101,7 +103,7 @@
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd"));
        // 汇付客户Id
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
        String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
        String startDateStr = certificateExpireDateArr[0];
        // 个人证件有效期开始日期
@@ -141,7 +143,7 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
@@ -197,7 +199,7 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", userWithdrawal.getHuiFuId());
        paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
@@ -231,7 +233,7 @@
        paramsInfo.put("card_info", cardInfo.toJSONString());
        log.info("用户业务入驻修改返回参数:{}", paramsInfo);
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);;
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/modify", paramsInfo, null, false);;
        log.info("用户业务入驻修改返回参数:{}", response);
        return response;
    }
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/UserWithdrawal.java
@@ -161,7 +161,7 @@
    private Integer type;
    @ApiModelProperty(value = "汇付ID")
    private String huiFuId;
    private String huifuId;
    @ApiModelProperty(value = "取现卡序列号")
    private String tokenNo;