liujie
2025-11-17 ca3fbc48e934a782db59099873661d6848a916cc
Merge branch 'master' of http://120.76.84.145:10101/gitblit/r/java/JiaYiXing2025
3个文件已添加
6个文件已修改
286 ■■■■■ 已修改文件
.gitignore 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/pom.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ManagementJYXTravel/guns-admin/lib/upyzt-sdk-1.3.6.jar 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/lib/upyzt-sdk-1.3.6.jar 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/ElectronicLedgerController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/req/UserWithdrawalReq.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/UserWithdrawal.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserJYXTravel/guns-core/src/main/java/com/stylefeng/guns/core/util/RequestSeqUtil.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -12,7 +12,6 @@
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
DriverJYXTravel/guns-admin/pom.xml
@@ -221,7 +221,12 @@
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!--斗拱sdk-->
        <dependency>
            <groupId>com.huifu.bspay.sdk</groupId>
            <artifactId>dg-java-sdk</artifactId>
            <version>3.0.31</version>
        </dependency>
    </dependencies>
    <build>
ManagementJYXTravel/guns-admin/lib/upyzt-sdk-1.3.6.jar
Binary files differ
UserJYXTravel/guns-admin/lib/upyzt-sdk-1.3.6.jar
Binary files differ
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/ElectronicLedgerController.java
@@ -3,6 +3,8 @@
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.util.ToolUtil;
@@ -123,10 +125,14 @@
            userWithdrawal.setImgUrlOne(userWithdrawalReq.getIdCardReversePicture());
            userWithdrawal.setIdCardFrontPicture(userWithdrawalReq.getCopy1());
            userWithdrawal.setIdCardReversePicture(userWithdrawalReq.getCopy2());
            userWithdrawal.setCusId((String) resultMap.get("huifu_id"));
            userWithdrawalService.insert(userWithdrawal);
            //调用汇付业务入驻接口 todo
            Map<String, Object> map = douGongBasicDataBiz.userBusinessOpen(userWithdrawalReq);
            Map<String, Object> map = douGongBasicDataBiz.userBusinessOpen(userWithdrawal);
            if (!"200".equals((String) map.get("resp_code"))){
                return ResultUtil.error((String) map.get("resp_desc"));
            }
            UserWithdrawal userWithdrawal1 = new UserWithdrawal();
            userWithdrawal1.setId(userWithdrawal.getId());
            BeanUtils.copyProperties(cusApplicationResp, userWithdrawal1);
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/req/UserWithdrawalReq.java
@@ -105,6 +105,10 @@
    @ApiModelProperty(value = "身份证反面id")
    private String copy2;
    @ApiModelProperty(value = "开户行所在省编码")
    private String bankCardProvinceCode;
    @ApiModelProperty(value = "开户行所在市编码")
    private String bankCardCityCode;
}
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java
@@ -1,6 +1,7 @@
package com.stylefeng.guns.modular.huifu.biz;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
@@ -126,7 +127,7 @@
     * @return
     * @throws Exception
     */
    public Map<String, Object> userBusinessOpen(UserWithdrawalReq userWithdrawalReq) throws Exception {
    public Map<String, Object> userBusinessOpen(UserWithdrawal userWithdrawal) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(huiFuProperties.getProductId());
@@ -137,21 +138,39 @@
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", "6666000105765113");
        paramsInfo.put("huifu_id", userWithdrawal.getCusId());
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
        paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd"));
        // 渠道商/商户汇付Id
        paramsInfo.put("upper_huifu_id", "6666000003084836");
        // 乐接活配置当合作平台为乐接活,必填
        paramsInfo.put("ljh_data", "test");
        // 汇薪云配置当合作平台为汇薪云,必填
        paramsInfo.put("hxy_data", "test");
        // 结算信息配置
        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\"}");
        // 结算卡信息
        paramsInfo.put("card_info", "{\"card_type\":\"0\",\"card_name\":\"交通银行股份有限公司\",\"card_no\":\"6217001210064762121\",\"prov_id\":\"310000\",\"area_id\":\"310100\",\"branch_code\":\"105305264815\",\"cert_type\":\"00\",\"cert_no\":\"110101197003077513\",\"cert_validity_type\":\"0\",\"cert_begin_date\":\"20210806\",\"cert_end_date\":\"20410806\",\"mp\":\"15556622368\"}");
        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");
        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");
        }
        paramsInfo.put("card_info", cardInfo.toJSONString());
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);;
        log.info("用户业务入驻返回参数:" + response);
UserJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/UserWithdrawal.java
@@ -151,6 +151,12 @@
    @TableField(exist = false)
    private String code;
    @ApiModelProperty(value = "开户行所在省编码")
    private String bankCardProvinceCode;
    @ApiModelProperty(value = "开户行所在市编码")
    private String bankCardCityCode;
    /*
    @TableField("companyId")
    @ApiModelProperty(value = "分公司ID")
UserJYXTravel/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;
    }
}