mitao
2025-11-26 1045d8a4913ae1a4f91b14089afe0520c98e529c
司机端提现修改
3个文件已添加
10个文件已修改
748 ■■■■■ 已修改文件
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/AccountController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/UserWithdrawalController.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/model/TUserBankAccount.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/WithdrawalController.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongWithdrawBiz.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/FenZhangUtil.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/controller/DouGongNotifyController.java 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/BankCard.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Withdrawal.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IWithdrawalService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/WithdrawalServiceImpl.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/TaskUtil.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/AccountController.java
@@ -97,7 +97,7 @@
            // TODO 司机进件信息
            List<UserWithdrawal> userWithdrawalList = userWithdrawalService.selectList(new EntityWrapper<UserWithdrawal>()
                    .eq("userId", driver.getId())
                    .eq("userType",2));
                    .eq("type", 1));
            if(userWithdrawalList.size()==0){
                return ResultUtil.error("请先进行个人用户进件信息填写");
            }
@@ -106,7 +106,7 @@
            // TODO 司机进件信息
            UserWithdrawal userWithdrawal = userWithdrawalService.selectOne(new EntityWrapper<UserWithdrawal>()
                    .eq("phone",driver.getPhone())
                    .eq("status", true)
                    .eq("status", true).eq("type", 1)
                    .last("LIMIT 1"));
            // 创建电子账簿
@@ -129,6 +129,8 @@
            bankCard.setOutRequestNo(ToolUtil.getRandomString(32));
            bankCard.setBankAcctType("1");
            bankCard.setDriverId(driverId);
            bankCard.setBankCardProvinceCode(userBankAccount.getBankCardProvinceCode());
            bankCard.setBankCardCityCode(userBankAccount.getBankCardCityCode());
            bankCardService.insert(bankCard);
//            UserBankAccountReq userBankAccountReq = electronicLedgerService.createUserBankAccountReq(bankCard,userWithdrawal.getCusId(),userBankAccount.getCode());
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/controller/UserWithdrawalController.java
@@ -2,8 +2,11 @@
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.util.DateUtil;
import com.stylefeng.guns.core.util.RequestSeqUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.account.model.TBankNext;
import com.stylefeng.guns.modular.account.model.TEnterpriseWithdrawal;
import com.stylefeng.guns.modular.account.req.UserWithdrawalReq;
import com.stylefeng.guns.modular.account.service.*;
import com.stylefeng.guns.modular.account.util.Base64Util;
@@ -12,11 +15,16 @@
import com.stylefeng.guns.modular.cloudPayment.req.BalanceAcctReq;
import com.stylefeng.guns.modular.cloudPayment.req.UserBankAccountReq;
import com.stylefeng.guns.modular.huifu.biz.DouGongBasicDataBiz;
import com.stylefeng.guns.modular.huifu.biz.DouGongWithdrawBiz;
import com.stylefeng.guns.modular.huifu.biz.FenZhangUtil;
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.modular.system.service.IBankCardService;
import com.stylefeng.guns.modular.system.service.ICompanyService;
import com.stylefeng.guns.modular.system.service.IDriverService;
import com.stylefeng.guns.modular.system.service.IRegionService;
import com.stylefeng.guns.modular.system.service.ISysWithdrawalPoundageService;
import com.stylefeng.guns.modular.system.service.IWithdrawalService;
import com.stylefeng.guns.modular.system.service.impl.WithdrawalServiceImpl;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.unionpay.upyzt.exception.InvalidRequestException;
import com.unionpay.upyzt.exception.UpyztException;
@@ -26,6 +34,7 @@
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.bytebuddy.asm.Advice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
@@ -61,12 +70,18 @@
    private final ITBankNextService bankNextService;
    private final DouGongBasicDataBiz douGongBasicDataBiz;
    private final IRegionService regionService;
    private final ITEnterpriseWithdrawalService enterpriseWithdrawalService;
    private final DouGongWithdrawBiz douGongWithdrawBiz;
    private final ISysWithdrawalPoundageService sysWithdrawalPoundageService;
    private final IWithdrawalService withdrawalService;
    @Autowired
    public UserWithdrawalController(ElectronicLedgerService electronicLedgerService,
                                    UserWithdrawalService userWithdrawalService, UserBankAccountService userBankAccountService,
                                    IBankCardService bankCardService, IDriverService driverService, ICompanyService companyService,
                                    ITBankNextService bankNextService, DouGongBasicDataBiz douGongBasicDataBiz,IRegionService regionService) {
                                    ITBankNextService bankNextService, DouGongBasicDataBiz douGongBasicDataBiz,IRegionService regionService,
                                    ITEnterpriseWithdrawalService enterpriseWithdrawalService,DouGongWithdrawBiz douGongWithdrawBiz,
                                    ISysWithdrawalPoundageService sysWithdrawalPoundageService,IWithdrawalService withdrawalService) {
        this.electronicLedgerService = electronicLedgerService;
        this.userWithdrawalService = userWithdrawalService;
        this.userBankAccountService = userBankAccountService;
@@ -76,6 +91,10 @@
        this.bankNextService = bankNextService;
        this.douGongBasicDataBiz = douGongBasicDataBiz;
        this.regionService = regionService;
        this.enterpriseWithdrawalService = enterpriseWithdrawalService;
        this.douGongWithdrawBiz = douGongWithdrawBiz;
        this.sysWithdrawalPoundageService = sysWithdrawalPoundageService;
        this.withdrawalService = withdrawalService;
    }
@@ -415,8 +434,8 @@
        // 查询当前操作电子用户
        // 司机进件信息
        UserWithdrawal userWithdrawal = userWithdrawalService.selectOne(new EntityWrapper<UserWithdrawal>()
                .eq("phone",driver.getPhone())
                .eq("applicationStatus","succeeded")
                .eq("phone",driver.getPhone()).eq("type", 1)
                //.eq("applicationStatus","succeeded")
                .last("LIMIT 1"));
        System.out.println("司机电子账簿信息====:"+userWithdrawal);
@@ -427,21 +446,61 @@
        // 查询平台账户
        Company company = companyService.selectOne(new EntityWrapper<Company>()
                .eq("type", 1));
        TEnterpriseWithdrawal tEnterpriseWithdrawal = enterpriseWithdrawalService.selectOne(new EntityWrapper<TEnterpriseWithdrawal>().eq("companyId", company.getId())
                .eq("type", 1).last("LIMIT 1"));
        if (Objects.isNull(tEnterpriseWithdrawal)) {
            return ResultUtil.error("分公司未配置账户信息");
        }
        // 查询平台开户信息
        ElectronicLedger electronicLedger = electronicLedgerService.selectOne(new EntityWrapper<ElectronicLedger>()
                .eq("userId", company.getId())
                .eq("userType", 3)
                .last("LIMIT 1"));
        //ElectronicLedger electronicLedger = electronicLedgerService.selectOne(new EntityWrapper<ElectronicLedger>()
        //        .eq("userId", company.getId())
        //        .eq("userType", 3)
        //        .last("LIMIT 1"));
        try {
            // 进行平台分账到司机电子账簿
            System.out.println("平台分账到司机电子账簿=========");
            AllocationReq allocationReq = userWithdrawalService.createAllocationReq(userWithdrawal.getBalanceAcctId(), electronicLedger.getBalanceAcctId(), amount,userWithdrawal.getTransactionAuthorizationCode());
            AllocationResp allocationResp = AllocationExample.create(allocationReq);
            System.out.println("平台分账到司机电子账簿完成=========:{}"+allocationResp);
            System.out.println("平台分a账到司机电子账簿=========");
            String fzReqSeqId = RequestSeqUtil.generate("FZ");
            Map<String, Object> fenzhng = FenZhangUtil.fenzhang(fzReqSeqId, DateUtil.format(new Date(), "yyyyMMdd"), amount.toString(), userWithdrawal.getHuifuId());
            if (!"00000000".equals(fenzhng.get("resp_code"))){
                System.err.println("平台分a账到司机电子账簿" + fenzhng);
                return ResultUtil.error("提现失败:"+fenzhng.get("resp_desc"));
            }
            Withdrawal withdrawal = new Withdrawal();
            withdrawal.setBankName(userWithdrawal.getBankName());
            withdrawal.setCode(userWithdrawal.getBankCode());
            withdrawal.setFlag(1);
            withdrawal.setInsertTime(new Date());
            withdrawal.setMoney(amount.doubleValue());
            withdrawal.setName(userWithdrawal.getOpenAccountName());
            withdrawal.setState(1);
            withdrawal.setUserId(userWithdrawal.getUserId());
            withdrawal.setUserType(2);
            withdrawal.setType(2);
            withdrawal.setWithdrawalType(1);//线上
            withdrawal.setRealGetMoney(amount - (amount*(sysWithdrawalPoundageService.selectOne(null).getPercentage()/100)));
            withdrawal.setFzReqSeqId(fzReqSeqId);
            withdrawalService.insert(withdrawal);
            if ("00000000".equals(fenzhng.get("resp_code")) && "S".equals(fenzhng.get("trans_stat"))){
                String txReqSeqId = RequestSeqUtil.generate("TX");
                withdrawal.setReqSeqId(txReqSeqId);
                Map<String, Object> tx = douGongWithdrawBiz.encashment(txReqSeqId, BigDecimal.valueOf(amount), userWithdrawal.getHuifuId(), userWithdrawal.getTokenNo(), 2);
                withdrawal.setHfSeqId(tx.get("huifu_id").toString());
                if (!"00000000".equals(tx.get("resp_code"))){
                    System.err.println("平台分a账到司机电子账簿" + tx);
                    return ResultUtil.error("提现失败:"+tx.get("resp_desc"));
                }
                if ("00000000".equals(tx.get("resp_code")) && "S".equals(tx.get("trans_stat"))){
                    withdrawal.setState(2);
                }
                withdrawalService.updateById(withdrawal);
            }
            //AllocationReq allocationReq = userWithdrawalService.createAllocationReq(userWithdrawal.getBalanceAcctId(), electronicLedger.getBalanceAcctId(), amount,userWithdrawal.getTransactionAuthorizationCode());
            //AllocationResp allocationResp = AllocationExample.create(allocationReq);
            //System.out.println("平台分账到司机电子账簿完成=========:{}"+allocationResp);
            // 用户电子账簿进行提现操作
            WithdrawalResp withdrawalResp = WithdrawalExample.create(userWithdrawalService.createWithdrawalReq(userWithdrawal.getBalanceAcctId(), amount, userWithdrawal.getTransactionAuthorizationCode(), bankAcctNo));
            System.out.println("司机电子账簿提现完成=========:{}"+withdrawalResp);
            //WithdrawalResp withdrawalResp = WithdrawalExample.create(userWithdrawalService.createWithdrawalReq(userWithdrawal.getBalanceAcctId(), amount, userWithdrawal.getTransactionAuthorizationCode(), bankAcctNo));
            //System.out.println("司机电子账簿提现完成=========:{}"+withdrawalResp);
            return ResultUtil.success();
        }catch (Exception e){
            System.out.println("司机提现失败=========:{}"+e.getMessage());
@@ -469,22 +528,23 @@
//                    .eq("userId", driverId)
//                    .eq("userType", 2));
            userWithdrawal = userWithdrawalService.selectOne(new EntityWrapper<UserWithdrawal>()
                    .eq("userId", driver.getId())
                    .eq("userType", 2)
                    .eq("applicationStatus","succeeded")
                    .eq("phone", driver.getPhone())
                            .eq("type", 1)
                    .last("LIMIT 1"));
            if(Objects.isNull(userWithdrawal)){
                return ResultUtil.error("该司机开户信息为空");
            }
            BalanceAcctReq balanceAcctReq = new BalanceAcctReq();
            balanceAcctReq.setCusId(userWithdrawal.getCusId());
            balanceAcctListResp = BalanceAcctExample.retrieveByUserId(balanceAcctReq);
            System.err.println(balanceAcctListResp);
            BigDecimal balance = douGongBasicDataBiz.balanceQuery(userWithdrawal.getHuifuId());
            //System.err.println(balance);
            return ResultUtil.success(balance);
            //BalanceAcctReq balanceAcctReq  = new BalanceAcctReq();
            //balanceAcctReq.setCusId(userWithdrawal.getCusId());
            //balanceAcctListResp = BalanceAcctExample.retrieveByUserId(balanceAcctReq);
        } catch (Exception e) {
            log.error("电子账簿可提现余额查询失败:{}",e.getMessage());
            e.printStackTrace();
        }
        if(Objects.isNull(balanceAcctListResp)){
 /*       if(Objects.isNull(balanceAcctListResp)){
            log.error("电子账簿可提现余额查询失败");
            return ResultUtil.error("电子账簿可提现余额查询失败");
        }
@@ -498,7 +558,7 @@
            if(userWithdrawal.getBalanceAcctId().equals(balanceAcct.getBalanceAcctId())){
                return ResultUtil.success(new BigDecimal(balanceAcct.getSettledAmount()).divide(new BigDecimal(100)));
            }
        }
        }*/
        return ResultUtil.success(BigDecimal.ZERO);
    }
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/account/model/TUserBankAccount.java
@@ -23,4 +23,8 @@
    private String bankCode;
    @ApiModelProperty(value = "开户银行联行号")
    private String bankBranchCode;
}
    @ApiModelProperty(value = "开户行所在省编码")
    private String bankCardProvinceCode;
    @ApiModelProperty(value = "开户行所在市编码")
    private String bankCardCityCode;
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/api/WithdrawalController.java
@@ -6,6 +6,8 @@
import com.stylefeng.guns.modular.account.service.ITBankNextService;
import com.stylefeng.guns.modular.account.service.UserWithdrawalService;
import com.stylefeng.guns.modular.cloudPayment.example.CusApplicationExample;
import com.stylefeng.guns.modular.huifu.biz.DouGongBasicDataBiz;
import com.stylefeng.guns.modular.huifu.biz.FenZhangUtil;
import com.stylefeng.guns.modular.system.model.BankCard;
import com.stylefeng.guns.modular.system.model.Driver;
import com.stylefeng.guns.modular.system.model.UserWithdrawal;
@@ -55,6 +57,8 @@
    private IBankCardService bankCardService;
    @Autowired
    private ITBankNextService bankNextService;
    @Autowired
    private DouGongBasicDataBiz douGongBasicDataBiz;
    /**
@@ -74,7 +78,7 @@
            @ApiImplicitParam(value = "银行名称", name = "bankName", required = true, dataType = "string"),
            @ApiImplicitParam(value = "银行卡号", name = "code", required = true, dataType = "string"),
            @ApiImplicitParam(value = "银行卡持有人姓名", name = "name", required = true, dataType = "string"),
            @ApiImplicitParam(value = "验证码", name = "smsCode", required = true, dataType = "string"),
            @ApiImplicitParam(value = "验证码-废弃", name = "smsCode", required = true, dataType = "string"),
            @ApiImplicitParam(value = "提现类型(1=活动收入提现,2=业务收入提现)", name = "type", required = true, dataType = "int"),
            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
@@ -104,37 +108,48 @@
            }
            UserWithdrawal userWithdrawal = userWithdrawalService.selectOne(new EntityWrapper<UserWithdrawal>()
                    .eq("userId", driver.getId())
                    .eq("userType", 2)
                            .eq("type", 1)
                    .last("LIMIT 1"));
            if (Objects.isNull(userWithdrawal)) {
                return ResultUtil.error("请先进行个人用户进件信息填写");
            }
            TBankNext bankNext = bankNextService.selectOne(new EntityWrapper<TBankNext>()
                    .eq("bankName", bankName)
                    .last("LIMIT 1"));
            //TBankNext bankNext = bankNextService.selectOne(new EntityWrapper<TBankNext>()
            //        .eq("bankName", bankName)
            //        .last("LIMIT 1"));
            userWithdrawal.setBankName(bankName);
            userWithdrawal.setBankCode(bankNext.getDrecCode());
            userWithdrawal.setBankBranchCode(bankNext.getBankCode());
            //userWithdrawal.setBankCode(bankNext.getDrecCode());
            //userWithdrawal.setBankBranchCode(bankNext.getBankCode());
            userWithdrawal.setBankCardProvinceCode(bankCard.getBankCardProvinceCode());
            userWithdrawal.setBankCardCityCode(bankCard.getBankCardCityCode());
            userWithdrawal.setBankCardCode(code);
            userWithdrawal.setCode(smsCode);
            CusApplicationResp renew = CusApplicationExample.renew(userWithdrawal);
            System.err.println("修改个人用户进件信息返回" + renew);
            if ("succeeded".equals(renew.getApplicationStatus())) {
                // 修改银行卡信息
                bankCard.setVerifyStatus("succeeded");
                bankCard.setSettleAcctId(renew.getSettleAcctId());
                bankCardService.updateById(bankCard);
                userWithdrawal.setBankCardCode(code);
                userWithdrawal.setBankName(bankCard.getBank());
                userWithdrawal.setSettleAcctId(renew.getSettleAcctId());
                userWithdrawal.setBalanceAcctId(renew.getBalanceAcctId());
                userWithdrawal.setBankCode(bankCard.getBankCode());
                userWithdrawal.setBankBranchCode(bankCard.getBankBranchCode());
                userWithdrawalService.updateById(userWithdrawal);
            //userWithdrawal.setCode(smsCode);
            Map<String, Object> map = douGongBasicDataBiz.userBasicDataIndvModify(userWithdrawal);
            if (!"00000000".equals(map.get("resp_code"))) {
                return ResultUtil.error("修改个人用户进件信息失败,原因:" + map.get("resp_desc"));
            }
            Map<String, Object> res =  douGongBasicDataBiz.userBusinessOpenModify(userWithdrawal);
            if (!"00000000".equals(res.get("resp_code"))) {
                return ResultUtil.error("修改个人用户进件信息失败,原因:" + res.get("resp_desc"));
            }
            //CusApplicationResp renew = CusApplicationExample.renew(userWithdrawal);
            //System.err.println("修改个人用户进件信息返回" + renew);
            // 修改银行卡信息
            bankCard.setVerifyStatus("succeeded");
            //bankCard.setSettleAcctId(renew.getSettleAcctId());
            bankCardService.updateById(bankCard);
            userWithdrawal.setBankCardCode(code);
            userWithdrawal.setBankName(bankCard.getBank());
            //userWithdrawal.setSettleAcctId(renew.getSettleAcctId());
            //userWithdrawal.setBalanceAcctId(renew.getBalanceAcctId());
            userWithdrawal.setHuifuId((String) map.get("huifu_id"));
            String tokenNo = (String) res.get("token_no");
            userWithdrawal.setTokenNo(tokenNo);
            userWithdrawal.setBankCode(bankCard.getBankCode());
            userWithdrawal.setBankBranchCode(bankCard.getBankBranchCode());
            userWithdrawalService.updateById(userWithdrawal);
            return withdrawalService.withdrawal(money, bankName, code, name, uid, type);
        } catch (Exception e) {
            e.printStackTrace();
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongBasicDataBiz.java
@@ -14,6 +14,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -267,4 +268,38 @@
        log.info("用户业务入驻修改返回参数:{}", response);
        return response;
    }
    /**
     * 电子账户余额查询
     *
     * @return
     * @throws Exception
     */
    public BigDecimal balanceQuery(String huifuId) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(huiFuProperties.getProductId());
        merConfig.setSysId(huiFuProperties.getSysId());
        merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey());
        merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey());
        BasePay.initWithMerConfig(merConfig);
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 汇付ID
        paramsInfo.put("huifu_id", huifuId);
        // 请求流水号
        paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu());
        // 请求日期
        paramsInfo.put("req_date", com.stylefeng.guns.core.util.DateUtil.format(new Date(), "yyyyMMdd"));
        log.info("账户余额信息查询返回参数:{}", paramsInfo);
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/acctpayment/balance/query", paramsInfo, null, false);
        log.info("账户余额信息查询返回参数:{}", response);
        JSONArray accountList = JSONArray.parseArray(response.get("acctInfo_list").toString());
        if (accountList != null && !accountList.isEmpty()) {
            JSONObject acctInfo = accountList.getJSONObject(0);
            log.info("账户余额信息查询返回余额:{}", acctInfo.getString("avail_bal"));
            return acctInfo.getBigDecimal("avl_bal");
        }
        return BigDecimal.ZERO;
    }
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/DouGongWithdrawBiz.java
New file
@@ -0,0 +1,78 @@
package com.stylefeng.guns.modular.huifu.biz;
import com.alibaba.fastjson.JSONObject;
import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
import com.huifu.bspay.sdk.opps.core.net.BasePayRequest;
import com.stylefeng.guns.modular.huifu.properties.HuiFuProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * 斗拱提现业务
 * @author mitao
 * @date 2025/11/21
 */
@Slf4j
@Component
public class DouGongWithdrawBiz {
    @Autowired
    private HuiFuProperties huiFuProperties;
    @Value("${callbackPath}")
    private String callbackPath;
    /**
     * 主动取现接口
     *
     * @param cashAmt 取现金额,单位元
     * @param huifuId 取现方ID号
     * @param tokenNo 取现卡序列号
     * @param type 提现类型 1:企业 2:用户/司机
     * @return 请求结果
     */
    public Map<String,Object> encashment(String reqSeqId,BigDecimal cashAmt, String huifuId, String tokenNo, Integer type) throws Exception {
        log.info("开始调用斗拱提现接口,取现方ID: {}, 取现金额: {}", huifuId, cashAmt);
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(huiFuProperties.getProductId());
        merConfig.setSysId(huiFuProperties.getSysId());
        merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey());
        merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey());
        BasePay.initWithMerConfig(merConfig);
        // 2.组装请求参数
        Map<String, Object> data = new HashMap<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String reqDate = dateFormat.format(new Date());
        data.put("req_date", reqDate);
        data.put("req_seq_id", reqSeqId);
        data.put("cash_amt", cashAmt.setScale(2, RoundingMode.HALF_UP).toString());
        data.put("huifu_id", huifuId);
        /**
         * D0:当日到账;当日交易资金当天可取现到账;
         * T1:次工作日到账;
         * D1:次自然日到账;
         * DM:当日到账;到账资金不包括当天的交易资金;
         * 示例值:D0
         */
        data.put("into_acct_date_type", "D1");
        data.put("token_no", tokenNo);
        String notifyUrl = type.equals(1) ? "/base/dougong/ent/encashment" : "/base/dougong/user/encashment";
        data.put("notify_url", callbackPath + notifyUrl);
        String dataStr = JSONObject.toJSONString(data);
        log.info("业务参数data: {}", dataStr);
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/settlement/encashment", data, null, false);
        log.info("斗拱提现接口响应内容: {}", JSONObject.toJSONString(response));
        return response;
    }
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/biz/FenZhangUtil.java
New file
@@ -0,0 +1,159 @@
package com.stylefeng.guns.modular.huifu.biz;
import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
import com.huifu.bspay.sdk.opps.core.net.BasePayRequest;
import com.stylefeng.guns.modular.huifu.properties.HuiFuProperties;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
/**
 * 余额支付 - 示例
 */
public class FenZhangUtil {
    @Autowired
    private HuiFuProperties huiFuProperties;
//    public static void main(String[] args) throws Exception {
//        // 1. 数据初始化,填入对应的商户配置
//        MerConfig merConfig = new MerConfig();
////        merConfig.setProcutId(huiFuProperties.getProductId());
////        merConfig.setSysId(huiFuProperties.getSysId());
////        merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey());
////        merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey());
//        merConfig.setProcutId("KAZX");
//        merConfig.setSysId("6666000182995771");
//        merConfig.setRsaPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCR6W3ynQJL7f2C8vFYMcQkcirpkif9ZhLq1374jIlV87nv0T9uIm6DoW8LyNEl9w2Yc5qoBv70tt/oVpemA6IZY6NXzE2USNi/sv2qUTtapcIRYxe4acCfY8K+x+p7W2e6wUWIpl9qgZA+UnFmHQ0HT6Ywzq2jJL92JdIs147Ud1aVi3aX8LYItj0z3ZKwZQkaJawZSWQk2+EdPfN059L2qFkPtnT7JIthAdUTJYZA13K4tzw6mXp/DbgwVmLhrlmwl/ccSv2Q0ABfEk7jIxF1nZmCmSy3HrEw9xWyrg1BC+DgXBdyF0OEtpNfv+UW080syUVBNN0irHVuDP81BaAjAgMBAAECggEAGlBZprZQErdxz6rWgYxADj6UpJjaI2XEJZwFZveZUOnqb2hyIv+MpKp5Z0upBErApey7SHAyjJlqWfE72hGvqxp/+7Z5izNz+2ZhPtT1ekyIajBPt89CkLwiA9vz2plKZLC0RIeUj5WcGNEvaDX3AomHtCehwtk+uiTp+XJKbOBtkkQszcdCGY1DVoQ0ppFoINnM9VLbEzaFaG7VS3eFkU4cf2CwcrnJB1RncyPFK+bGFvjkLM/eQbsh8YxkBqaGz/8UM1Na1SEidqdyUF71ltqnI0u8pLe0V+5jugVW+3lPL/p1C3i7mAbQOs4yqRWlFaGVTzOawoQUOPVwDpzeeQKBgQDs1P7F4wURqX1qZR0hSTqOigg48ychaOF66new3SuWk2CVBy8Q8b7odGSPyxJSGZvFLoznPYuSaXCtQ935WWfjB7Z5JpSWCi9BmJnkh41k/KvgMqAEGkZP6ul/zFnDWj94VwXEBz3TuRk574vK2coWoxjM6h1dlJjRBVVTs8dnrQKBgQCduKCjPDUuOHbcNn3VsaHEZX1XyiXN5gds08o61PjiHM42wYXxfUt59nBJmg2yAVRIrKYHfswJcxb5XUTDI5ZhCBnIPrdrQzj7FNadm/7mKDvSsvZdpfTiHY341XnvCq7OcNNj8g5fVsWF769strepQReSug7xgX7ojPvVcAZhDwKBgD57KwP2Er5IIuhQ6NCBS0uTqvurWqV70BDnjtBAaWF+XDq0/HvR63XUTzuIbbrvOqNY1p+jIxFrc+iiQQupxLimrkNkJEs5QKJjqiYahPkhmA68DG9Ip0gqR5QJy5y4UIplGwZOiscyzC72vcC0mJZETSSylzC7JV3vtEUy5ua5AoGAEwlDqjAMIyYBgpa5HV+xLKkrNbtaUL2gy8vMLsmhuHjNkuJMrlb3EyNhbiC/4moyqArehy0Qp1tSvIo7UGotLkzx/69CKBoW+IcNWDyJyXG1trqO7cKoCdqTViM98lIRwyzu9rMydONeN8o0HCT5id4nYDhAsXl1vc+2XY6F1pUCgYEA0dxGHBTKD/WzIvTYGYD6Xx224Y84mO6x2Mu16zFoq/NjuIdKi2O+92yrKDCMMCqaY77fXvWD3eI7QYYlbKAOqdLKVipTbhnBccDyNbtYHVg59t4xS+K6HyD+quVkL9n40UkxSZbKZBQhqt+vlQy0FUgONFii1ACZO0A8Sc/bvn4=");
//        merConfig.setRsaPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWrruP9JBxrUd8uEX5Z8y7pg/UIr5RNHSgDnHqNI1hbi2MfTzB5vZ275wSFFaLDD9BesgDWqsUepPS/opROlDCg9y6WYH8mkN23NmHL9F8kT48OMmH722am+Hp0XVMMwXqA0oNt4f7oW6kDemjZW8/RT4vIE7cyxoxSsVRvjqSpx9wDgFLPWh3o0pHQaoxLyeUsGBATHFrxEDlosBvsuXjMcgjPKXALrcemzKOhBmBkLgyxNVmh61ZK+FNXd+/X4PeZlnWf54NRQAUKe1308E6IIaszo+CjneKuhj1m/X4f7AIvxAqlhuCV5E/DfKRmGopxaWqdtE960Y/H4SmBh2wIDAQAB");
//        BasePay.initWithMerConfig(merConfig);
//
//        // 2.组装请求参数
//        Map<String, Object> paramsInfo = new HashMap<>();
//        // 请求流水号
//        paramsInfo.put("req_seq_id", "rQ20251119164316677154");
//        // 请求日期
//        paramsInfo.put("req_date", "20251119");
//        // 出款方商户号
//        paramsInfo.put("out_huifu_id", "6666000182995771");
//        // 支付金额
//        paramsInfo.put("ord_amt", "0.01");
//        // 分账对象
//        paramsInfo.put("acct_split_bunch", "{\"acct_infos\":[{\"div_amt\":\"0.01\",\"huifu_id\":\"6666000183361451\"}]}");
//        // 安全信息
//        paramsInfo.put("risk_check_data", "{\"sub_product\":\"1\",\"transfer_type\":\"05\"}");
//        // 手续费承担方标识余额支付手续费承担方标识;商户余额支付扣收规则为接口指定承担方时必填!枚举值:&lt;br/&gt;OUT:出款方;&lt;br/&gt;IN:分账接受方。&lt;br/&gt;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:IN&lt;/font&gt;
//        paramsInfo.put("trans_fee_take_flag", "OUT");
//        // 核验值verify_type不为空时必填。当verify_type&#x3D;SMS时,填写用户收到的短信验证码
////        paramsInfo.put("verify_value", "test");
//        // 3. 发起API调用
//        Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/acctpayment/pay", paramsInfo, null, false);;
//        System.out.println(response);
//    }
    public static  Map<String, Object> fenzhang(String req_seq_id,String req_date,String ord_amt,String huifu_id) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
//        merConfig.setProcutId(huiFuProperties.getProductId());
//        merConfig.setSysId(huiFuProperties.getSysId());
//        merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey());
//        merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey());
        merConfig.setProcutId("KAZX");
        merConfig.setSysId("6666000182995771");
        merConfig.setRsaPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCR6W3ynQJL7f2C8vFYMcQkcirpkif9ZhLq1374jIlV87nv0T9uIm6DoW8LyNEl9w2Yc5qoBv70tt/oVpemA6IZY6NXzE2USNi/sv2qUTtapcIRYxe4acCfY8K+x+p7W2e6wUWIpl9qgZA+UnFmHQ0HT6Ywzq2jJL92JdIs147Ud1aVi3aX8LYItj0z3ZKwZQkaJawZSWQk2+EdPfN059L2qFkPtnT7JIthAdUTJYZA13K4tzw6mXp/DbgwVmLhrlmwl/ccSv2Q0ABfEk7jIxF1nZmCmSy3HrEw9xWyrg1BC+DgXBdyF0OEtpNfv+UW080syUVBNN0irHVuDP81BaAjAgMBAAECggEAGlBZprZQErdxz6rWgYxADj6UpJjaI2XEJZwFZveZUOnqb2hyIv+MpKp5Z0upBErApey7SHAyjJlqWfE72hGvqxp/+7Z5izNz+2ZhPtT1ekyIajBPt89CkLwiA9vz2plKZLC0RIeUj5WcGNEvaDX3AomHtCehwtk+uiTp+XJKbOBtkkQszcdCGY1DVoQ0ppFoINnM9VLbEzaFaG7VS3eFkU4cf2CwcrnJB1RncyPFK+bGFvjkLM/eQbsh8YxkBqaGz/8UM1Na1SEidqdyUF71ltqnI0u8pLe0V+5jugVW+3lPL/p1C3i7mAbQOs4yqRWlFaGVTzOawoQUOPVwDpzeeQKBgQDs1P7F4wURqX1qZR0hSTqOigg48ychaOF66new3SuWk2CVBy8Q8b7odGSPyxJSGZvFLoznPYuSaXCtQ935WWfjB7Z5JpSWCi9BmJnkh41k/KvgMqAEGkZP6ul/zFnDWj94VwXEBz3TuRk574vK2coWoxjM6h1dlJjRBVVTs8dnrQKBgQCduKCjPDUuOHbcNn3VsaHEZX1XyiXN5gds08o61PjiHM42wYXxfUt59nBJmg2yAVRIrKYHfswJcxb5XUTDI5ZhCBnIPrdrQzj7FNadm/7mKDvSsvZdpfTiHY341XnvCq7OcNNj8g5fVsWF769strepQReSug7xgX7ojPvVcAZhDwKBgD57KwP2Er5IIuhQ6NCBS0uTqvurWqV70BDnjtBAaWF+XDq0/HvR63XUTzuIbbrvOqNY1p+jIxFrc+iiQQupxLimrkNkJEs5QKJjqiYahPkhmA68DG9Ip0gqR5QJy5y4UIplGwZOiscyzC72vcC0mJZETSSylzC7JV3vtEUy5ua5AoGAEwlDqjAMIyYBgpa5HV+xLKkrNbtaUL2gy8vMLsmhuHjNkuJMrlb3EyNhbiC/4moyqArehy0Qp1tSvIo7UGotLkzx/69CKBoW+IcNWDyJyXG1trqO7cKoCdqTViM98lIRwyzu9rMydONeN8o0HCT5id4nYDhAsXl1vc+2XY6F1pUCgYEA0dxGHBTKD/WzIvTYGYD6Xx224Y84mO6x2Mu16zFoq/NjuIdKi2O+92yrKDCMMCqaY77fXvWD3eI7QYYlbKAOqdLKVipTbhnBccDyNbtYHVg59t4xS+K6HyD+quVkL9n40UkxSZbKZBQhqt+vlQy0FUgONFii1ACZO0A8Sc/bvn4=");
        merConfig.setRsaPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWrruP9JBxrUd8uEX5Z8y7pg/UIr5RNHSgDnHqNI1hbi2MfTzB5vZ275wSFFaLDD9BesgDWqsUepPS/opROlDCg9y6WYH8mkN23NmHL9F8kT48OMmH722am+Hp0XVMMwXqA0oNt4f7oW6kDemjZW8/RT4vIE7cyxoxSsVRvjqSpx9wDgFLPWh3o0pHQaoxLyeUsGBATHFrxEDlosBvsuXjMcgjPKXALrcemzKOhBmBkLgyxNVmh61ZK+FNXd+/X4PeZlnWf54NRQAUKe1308E6IIaszo+CjneKuhj1m/X4f7AIvxAqlhuCV5E/DfKRmGopxaWqdtE960Y/H4SmBh2wIDAQAB");
        BasePay.initWithMerConfig(merConfig);
        ord_amt = new BigDecimal(ord_amt).toString();
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 请求流水号
        paramsInfo.put("req_seq_id",req_seq_id);
        // 请求日期
        paramsInfo.put("req_date", req_date);
        // 出款方商户号
        paramsInfo.put("out_huifu_id", "6666000182995771");
        // 支付金额
        paramsInfo.put("ord_amt", ord_amt);
        // 分账对象
        paramsInfo.put("acct_split_bunch", "{\"acct_infos\":[{\"div_amt\":\""+ord_amt+"\",\"huifu_id\":\""+huifu_id+"\"}]}");
        // 安全信息
        paramsInfo.put("risk_check_data", "{\"sub_product\":\"1\",\"transfer_type\":\"05\"}");
        // 手续费承担方标识余额支付手续费承担方标识;商户余额支付扣收规则为接口指定承担方时必填!枚举值:&lt;br/&gt;OUT:出款方;&lt;br/&gt;IN:分账接受方。&lt;br/&gt;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:IN&lt;/font&gt;
        paramsInfo.put("trans_fee_take_flag", "OUT");
        // 核验值verify_type不为空时必填。当verify_type&#x3D;SMS时,填写用户收到的短信验证码
//        paramsInfo.put("verify_value", "test");
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/acctpayment/pay", paramsInfo, null, false);;
        return response;
    }
    public static  Map<String, Object> queryFenzhang(String req_seq_id,String req_date) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId("KAZX");
        merConfig.setSysId("6666000182995771");
        merConfig.setRsaPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCR6W3ynQJL7f2C8vFYMcQkcirpkif9ZhLq1374jIlV87nv0T9uIm6DoW8LyNEl9w2Yc5qoBv70tt/oVpemA6IZY6NXzE2USNi/sv2qUTtapcIRYxe4acCfY8K+x+p7W2e6wUWIpl9qgZA+UnFmHQ0HT6Ywzq2jJL92JdIs147Ud1aVi3aX8LYItj0z3ZKwZQkaJawZSWQk2+EdPfN059L2qFkPtnT7JIthAdUTJYZA13K4tzw6mXp/DbgwVmLhrlmwl/ccSv2Q0ABfEk7jIxF1nZmCmSy3HrEw9xWyrg1BC+DgXBdyF0OEtpNfv+UW080syUVBNN0irHVuDP81BaAjAgMBAAECggEAGlBZprZQErdxz6rWgYxADj6UpJjaI2XEJZwFZveZUOnqb2hyIv+MpKp5Z0upBErApey7SHAyjJlqWfE72hGvqxp/+7Z5izNz+2ZhPtT1ekyIajBPt89CkLwiA9vz2plKZLC0RIeUj5WcGNEvaDX3AomHtCehwtk+uiTp+XJKbOBtkkQszcdCGY1DVoQ0ppFoINnM9VLbEzaFaG7VS3eFkU4cf2CwcrnJB1RncyPFK+bGFvjkLM/eQbsh8YxkBqaGz/8UM1Na1SEidqdyUF71ltqnI0u8pLe0V+5jugVW+3lPL/p1C3i7mAbQOs4yqRWlFaGVTzOawoQUOPVwDpzeeQKBgQDs1P7F4wURqX1qZR0hSTqOigg48ychaOF66new3SuWk2CVBy8Q8b7odGSPyxJSGZvFLoznPYuSaXCtQ935WWfjB7Z5JpSWCi9BmJnkh41k/KvgMqAEGkZP6ul/zFnDWj94VwXEBz3TuRk574vK2coWoxjM6h1dlJjRBVVTs8dnrQKBgQCduKCjPDUuOHbcNn3VsaHEZX1XyiXN5gds08o61PjiHM42wYXxfUt59nBJmg2yAVRIrKYHfswJcxb5XUTDI5ZhCBnIPrdrQzj7FNadm/7mKDvSsvZdpfTiHY341XnvCq7OcNNj8g5fVsWF769strepQReSug7xgX7ojPvVcAZhDwKBgD57KwP2Er5IIuhQ6NCBS0uTqvurWqV70BDnjtBAaWF+XDq0/HvR63XUTzuIbbrvOqNY1p+jIxFrc+iiQQupxLimrkNkJEs5QKJjqiYahPkhmA68DG9Ip0gqR5QJy5y4UIplGwZOiscyzC72vcC0mJZETSSylzC7JV3vtEUy5ua5AoGAEwlDqjAMIyYBgpa5HV+xLKkrNbtaUL2gy8vMLsmhuHjNkuJMrlb3EyNhbiC/4moyqArehy0Qp1tSvIo7UGotLkzx/69CKBoW+IcNWDyJyXG1trqO7cKoCdqTViM98lIRwyzu9rMydONeN8o0HCT5id4nYDhAsXl1vc+2XY6F1pUCgYEA0dxGHBTKD/WzIvTYGYD6Xx224Y84mO6x2Mu16zFoq/NjuIdKi2O+92yrKDCMMCqaY77fXvWD3eI7QYYlbKAOqdLKVipTbhnBccDyNbtYHVg59t4xS+K6HyD+quVkL9n40UkxSZbKZBQhqt+vlQy0FUgONFii1ACZO0A8Sc/bvn4=");
        merConfig.setRsaPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWrruP9JBxrUd8uEX5Z8y7pg/UIr5RNHSgDnHqNI1hbi2MfTzB5vZ275wSFFaLDD9BesgDWqsUepPS/opROlDCg9y6WYH8mkN23NmHL9F8kT48OMmH722am+Hp0XVMMwXqA0oNt4f7oW6kDemjZW8/RT4vIE7cyxoxSsVRvjqSpx9wDgFLPWh3o0pHQaoxLyeUsGBATHFrxEDlosBvsuXjMcgjPKXALrcemzKOhBmBkLgyxNVmh61ZK+FNXd+/X4PeZlnWf54NRQAUKe1308E6IIaszo+CjneKuhj1m/X4f7AIvxAqlhuCV5E/DfKRmGopxaWqdtE960Y/H4SmBh2wIDAQAB");
        BasePay.initWithMerConfig(merConfig);
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 商户号
        paramsInfo.put("huifu_id", "6666000182995771");
        // 原交易请求日期
        paramsInfo.put("org_req_date", req_date);
        // 原交易请求流水号
        paramsInfo.put("org_req_seq_id", req_seq_id);
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/acctpayment/pay/query", paramsInfo, null, false);;
        System.out.println(response);
        return response;
    }
    public static Map<String, Object> payFromUser(String req_seq_id, String req_date, String ord_amt, String huifu_id) throws Exception {
        // 1. 数据初始化,填入对应的商户配置
        MerConfig merConfig = new MerConfig();
//        merConfig.setProcutId(huiFuProperties.getProductId());
//        merConfig.setSysId(huiFuProperties.getSysId());
//        merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey());
//        merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey());
        merConfig.setProcutId("KAZX");
        merConfig.setSysId("6666000182995771");
        merConfig.setRsaPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCR6W3ynQJL7f2C8vFYMcQkcirpkif9ZhLq1374jIlV87nv0T9uIm6DoW8LyNEl9w2Yc5qoBv70tt/oVpemA6IZY6NXzE2USNi/sv2qUTtapcIRYxe4acCfY8K+x+p7W2e6wUWIpl9qgZA+UnFmHQ0HT6Ywzq2jJL92JdIs147Ud1aVi3aX8LYItj0z3ZKwZQkaJawZSWQk2+EdPfN059L2qFkPtnT7JIthAdUTJYZA13K4tzw6mXp/DbgwVmLhrlmwl/ccSv2Q0ABfEk7jIxF1nZmCmSy3HrEw9xWyrg1BC+DgXBdyF0OEtpNfv+UW080syUVBNN0irHVuDP81BaAjAgMBAAECggEAGlBZprZQErdxz6rWgYxADj6UpJjaI2XEJZwFZveZUOnqb2hyIv+MpKp5Z0upBErApey7SHAyjJlqWfE72hGvqxp/+7Z5izNz+2ZhPtT1ekyIajBPt89CkLwiA9vz2plKZLC0RIeUj5WcGNEvaDX3AomHtCehwtk+uiTp+XJKbOBtkkQszcdCGY1DVoQ0ppFoINnM9VLbEzaFaG7VS3eFkU4cf2CwcrnJB1RncyPFK+bGFvjkLM/eQbsh8YxkBqaGz/8UM1Na1SEidqdyUF71ltqnI0u8pLe0V+5jugVW+3lPL/p1C3i7mAbQOs4yqRWlFaGVTzOawoQUOPVwDpzeeQKBgQDs1P7F4wURqX1qZR0hSTqOigg48ychaOF66new3SuWk2CVBy8Q8b7odGSPyxJSGZvFLoznPYuSaXCtQ935WWfjB7Z5JpSWCi9BmJnkh41k/KvgMqAEGkZP6ul/zFnDWj94VwXEBz3TuRk574vK2coWoxjM6h1dlJjRBVVTs8dnrQKBgQCduKCjPDUuOHbcNn3VsaHEZX1XyiXN5gds08o61PjiHM42wYXxfUt59nBJmg2yAVRIrKYHfswJcxb5XUTDI5ZhCBnIPrdrQzj7FNadm/7mKDvSsvZdpfTiHY341XnvCq7OcNNj8g5fVsWF769strepQReSug7xgX7ojPvVcAZhDwKBgD57KwP2Er5IIuhQ6NCBS0uTqvurWqV70BDnjtBAaWF+XDq0/HvR63XUTzuIbbrvOqNY1p+jIxFrc+iiQQupxLimrkNkJEs5QKJjqiYahPkhmA68DG9Ip0gqR5QJy5y4UIplGwZOiscyzC72vcC0mJZETSSylzC7JV3vtEUy5ua5AoGAEwlDqjAMIyYBgpa5HV+xLKkrNbtaUL2gy8vMLsmhuHjNkuJMrlb3EyNhbiC/4moyqArehy0Qp1tSvIo7UGotLkzx/69CKBoW+IcNWDyJyXG1trqO7cKoCdqTViM98lIRwyzu9rMydONeN8o0HCT5id4nYDhAsXl1vc+2XY6F1pUCgYEA0dxGHBTKD/WzIvTYGYD6Xx224Y84mO6x2Mu16zFoq/NjuIdKi2O+92yrKDCMMCqaY77fXvWD3eI7QYYlbKAOqdLKVipTbhnBccDyNbtYHVg59t4xS+K6HyD+quVkL9n40UkxSZbKZBQhqt+vlQy0FUgONFii1ACZO0A8Sc/bvn4=");
        merConfig.setRsaPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWrruP9JBxrUd8uEX5Z8y7pg/UIr5RNHSgDnHqNI1hbi2MfTzB5vZ275wSFFaLDD9BesgDWqsUepPS/opROlDCg9y6WYH8mkN23NmHL9F8kT48OMmH722am+Hp0XVMMwXqA0oNt4f7oW6kDemjZW8/RT4vIE7cyxoxSsVRvjqSpx9wDgFLPWh3o0pHQaoxLyeUsGBATHFrxEDlosBvsuXjMcgjPKXALrcemzKOhBmBkLgyxNVmh61ZK+FNXd+/X4PeZlnWf54NRQAUKe1308E6IIaszo+CjneKuhj1m/X4f7AIvxAqlhuCV5E/DfKRmGopxaWqdtE960Y/H4SmBh2wIDAQAB");
        BasePay.initWithMerConfig(merConfig);
        ord_amt=new BigDecimal(ord_amt).setScale(2, RoundingMode.HALF_UP).toString();
        // 2.组装请求参数
        Map<String, Object> paramsInfo = new HashMap<>();
        // 请求流水号
        paramsInfo.put("req_seq_id",req_seq_id);
        // 请求日期
        paramsInfo.put("req_date", req_date);
        // 出款方商户号
        paramsInfo.put("out_huifu_id", huifu_id);
        // 支付金额
        paramsInfo.put("ord_amt", ord_amt);
        // 分账对象
        paramsInfo.put("acct_split_bunch", "{\"acct_infos\":[{\"div_amt\":\"" + ord_amt + "\",\"huifu_id\":\"6666000182995771\"}]}");
        // 安全信息
        paramsInfo.put("risk_check_data", "{\"sub_product\":\"1\",\"transfer_type\":\"05\"}");
        // 手续费承担方标识余额支付手续费承担方标识;商户余额支付扣收规则为接口指定承担方时必填!枚举值:&lt;br/&gt;OUT:出款方;&lt;br/&gt;IN:分账接受方。&lt;br/&gt;&lt;font color&#x3D;&quot;green&quot;&gt;示例值:IN&lt;/font&gt;
        paramsInfo.put("trans_fee_take_flag", "OUT");
        // 核验值verify_type不为空时必填。当verify_type&#x3D;SMS时,填写用户收到的短信验证码
//        paramsInfo.put("verify_value", "test");
        // 3. 发起API调用
        Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/acctpayment/pay", paramsInfo, null, false);;
        return response;
    }
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/huifu/controller/DouGongNotifyController.java
New file
@@ -0,0 +1,177 @@
package com.stylefeng.guns.modular.huifu.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.huifu.bspay.sdk.opps.core.utils.RsaUtils;
import com.stylefeng.guns.modular.huifu.properties.HuiFuProperties;
import com.stylefeng.guns.modular.system.model.Driver;
import com.stylefeng.guns.modular.system.model.DriverService;
import com.stylefeng.guns.modular.system.model.TCompanyWithdraw;
import com.stylefeng.guns.modular.system.model.TDriver;
import com.stylefeng.guns.modular.system.model.TOrderCrossCity;
import com.stylefeng.guns.modular.system.model.TOrderLogistics;
import com.stylefeng.guns.modular.system.model.TPubWithdrawal;
import com.stylefeng.guns.modular.system.model.TUser;
import com.stylefeng.guns.modular.system.model.User;
import com.stylefeng.guns.modular.system.model.Withdrawal;
import com.stylefeng.guns.modular.system.service.IDriverService;
import com.stylefeng.guns.modular.system.service.ITCompanyWithdrawService;
import com.stylefeng.guns.modular.system.service.ITDriverService;
import com.stylefeng.guns.modular.system.service.ITOrderCrossCityService;
import com.stylefeng.guns.modular.system.service.ITOrderLogisticsService;
import com.stylefeng.guns.modular.system.service.ITPubWithdrawalService;
import com.stylefeng.guns.modular.system.service.ITUserService;
import com.stylefeng.guns.modular.system.service.IUserService;
import com.stylefeng.guns.modular.system.service.IWithdrawalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Objects;
/**
 * @author mitao
 * @date 2025/11/21
 */
@Slf4j
@RestController
@RequestMapping("/base/dougong")
public class DouGongNotifyController {
    @Autowired
    private HuiFuProperties huiFuProperties;
    @Autowired
    private IWithdrawalService withdrawalService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IDriverService driverService;
    /**
     * 斗拱主动取现接口回调
     * @param request
     * @param response
     */
    @PostMapping("/user/encashment")
    public void userEncashment(HttpServletRequest request, HttpServletResponse response) {
        String sign =request.getParameter("sign");
        String resp_data = request.getParameter("resp_data");
        log.info("斗拱用户提现回调响应内容:{}", resp_data);
        // 使用汇付公钥验签
        resp_data =  resp_data.replaceAll("& #40;", "(").replaceAll("& #41;",")");
        boolean verify = RsaUtils.verify(resp_data, huiFuProperties.getRsaPublicKey(), sign);
        if(verify){
            JSONObject respDataJson = JSONObject.parseObject(resp_data);
            String reqSeqId = respDataJson.getString("req_seq_id");
            String hfSeqId = respDataJson.getString("hf_seq_id");
            String transStat = respDataJson.getString("trans_stat");//S:成功 F:失败 P:处理中;示例值:S
            Withdrawal pubWithdrawal = withdrawalService.selectOne(new EntityWrapper<Withdrawal>().eq("reqSeqId", reqSeqId).or().eq("hfSeqId", hfSeqId).last("limit 1"));
            if (Objects.isNull(pubWithdrawal)) {
                return;
            }
            if ("S".equalsIgnoreCase(transStat)) {
                pubWithdrawal.setState(2);
            } else if ("F".equalsIgnoreCase(transStat)) {
                pubWithdrawal.setState(3);
                if (pubWithdrawal.getUserType() == 2) {
                    Driver driver = driverService.selectById(pubWithdrawal.getUserId());
                    driver.setLaveBusinessMoney(BigDecimal.valueOf(driver.getLaveBusinessMoney()).add(BigDecimal.valueOf(pubWithdrawal.getMoney())).doubleValue());
                    driverService.updateById(driver);
                }
            }
            withdrawalService.updateById(pubWithdrawal);
            log.info("更新用户/司机提现记录成功,更新内容“{}", JSONObject.toJSON(pubWithdrawal));
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            writer.print("200");
            writer.close();
        }
    }
    /**
     * 斗拱主动取现接口回调
     * @param request
     * @param response
     */
    @PostMapping("/refund-logistics")
    public void refundLogistics(HttpServletRequest request, HttpServletResponse response) {
        String sign =request.getParameter("sign");
        String resp_data = request.getParameter("resp_data");
        log.info("斗拱用户提现回调响应内容:{}", resp_data);
        // 使用汇付公钥验签
        resp_data =  resp_data.replaceAll("& #40;", "(").replaceAll("& #41;",")");
        boolean verify = RsaUtils.verify(resp_data, huiFuProperties.getRsaPublicKey(), sign);
        if(verify){
            JSONObject respDataJson = JSONObject.parseObject(resp_data);
            String reqSeqId = respDataJson.getString("req_seq_id");
            String orgReqSeqId = respDataJson.getString("org_req_seq_id");
            String transStat = respDataJson.getString("trans_stat");//S:成功 F:失败 P:处理中;示例值:S
            TOrderLogistics orderLogistics = orderLogisticsService.selectOne(new EntityWrapper<TOrderLogistics>()
                    .eq("refundReqSeqId", reqSeqId).or().eq("outTradeNo", orgReqSeqId).last("limit 1"));
            if (Objects.isNull(orderLogistics)) {
                return;
            }
            if ("S".equalsIgnoreCase(transStat)) {
                orderLogistics.setState(10);
            }
            orderLogisticsService.updateById(orderLogistics);
            log.info("更新小件物流取消订单状态成功,更新内容“{}", JSONObject.toJSON(orderLogistics));
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            writer.print("200");
            writer.close();
        }
    }
    /**
     * 斗拱主动取现接口回调
     * @param request
     * @param response
     */
    @PostMapping("/refund-crosscity")
    public void refundCrossCity(HttpServletRequest request, HttpServletResponse response) {
        String sign =request.getParameter("sign");
        String resp_data = request.getParameter("resp_data");
        log.info("斗拱用户提现回调响应内容:{}", resp_data);
        // 使用汇付公钥验签
        resp_data =  resp_data.replaceAll("& #40;", "(").replaceAll("& #41;",")");
        boolean verify = RsaUtils.verify(resp_data, huiFuProperties.getRsaPublicKey(), sign);
        if(verify){
            JSONObject respDataJson = JSONObject.parseObject(resp_data);
            String reqSeqId = respDataJson.getString("req_seq_id");
            String orgReqSeqId = respDataJson.getString("org_req_seq_id");
            String transStat = respDataJson.getString("trans_stat");//S:成功 F:失败 P:处理中;示例值:S
            TOrderCrossCity orderCrossCity = orderCrossCityService.selectOne(new EntityWrapper<TOrderCrossCity>()
                    .eq("refundReqSeqId", reqSeqId).or().eq("outTradeNo", orgReqSeqId).last("limit 1"));
            if (Objects.isNull(orderCrossCity)) {
                return;
            }
            if ("S".equalsIgnoreCase(transStat)) {
                orderCrossCity.setState(10);
            }
            orderCrossCityService.updateById(orderCrossCity);
            log.info("更新跨城订单取消订单状态成功,更新内容“{}", JSONObject.toJSON(orderCrossCity));
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            writer.print("200");
            writer.close();
        }
    }
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/BankCard.java
@@ -92,6 +92,28 @@
    @TableField("ifDefault")
    private Boolean ifDefault;
    @ApiModelProperty(value = "开户行所在省编码")
    private String bankCardProvinceCode;
    @ApiModelProperty(value = "开户行所在市编码")
    private String bankCardCityCode;
    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 Boolean getIfDefault() {
        return ifDefault;
    }
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Withdrawal.java
@@ -101,6 +101,48 @@
    @TableField("realGetMoney")
    private Double realGetMoney;
    /**
     * 请求流水号
     */
    @TableField("reqSeqId")
    private String reqSeqId;
    /**
     * 汇付全局流水号
     */
    @TableField("hfSeqId")
    private String hfSeqId;
    /**
     * 司机提现,公司余额支付流水号
     */
    @TableField("fzReqSeqId")
    private String fzReqSeqId;
    public String getFzReqSeqId() {
        return fzReqSeqId;
    }
    public void setFzReqSeqId(String fzReqSeqId) {
        this.fzReqSeqId = fzReqSeqId;
    }
    public String getReqSeqId() {
        return reqSeqId;
    }
    public void setReqSeqId(String reqSeqId) {
        this.reqSeqId = reqSeqId;
    }
    public String getHfSeqId() {
        return hfSeqId;
    }
    public void setHfSeqId(String hfSeqId) {
        this.hfSeqId = hfSeqId;
    }
    public Double getRealGetMoney() {
        return realGetMoney;
    }
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IWithdrawalService.java
@@ -38,4 +38,6 @@
     * @throws Exception
     */
    ResultUtil withdrawalAudit(Integer id, Integer state) throws Exception;
    void taskDayFenzhang() throws Exception;
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/WithdrawalServiceImpl.java
@@ -1,10 +1,18 @@
package com.stylefeng.guns.modular.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.util.DateUtil;
import com.stylefeng.guns.core.util.RequestSeqUtil;
import com.stylefeng.guns.modular.account.service.UserWithdrawalService;
import com.stylefeng.guns.modular.huifu.biz.DouGongWithdrawBiz;
import com.stylefeng.guns.modular.huifu.biz.FenZhangUtil;
import com.stylefeng.guns.modular.system.dao.UserInfoMapper;
import com.stylefeng.guns.modular.system.dao.WithdrawalMapper;
import com.stylefeng.guns.modular.system.model.Driver;
import com.stylefeng.guns.modular.system.model.UserInfo;
import com.stylefeng.guns.modular.system.model.UserWithdrawal;
import com.stylefeng.guns.modular.system.model.Withdrawal;
import com.stylefeng.guns.modular.system.service.IDriverService;
import com.stylefeng.guns.modular.system.service.ISysWithdrawalPoundageService;
@@ -45,6 +53,10 @@
    @Autowired
    private ISysWithdrawalPoundageService sysWithdrawalPoundageService;
    @Autowired
    private DouGongWithdrawBiz douGongWithdrawBiz;
    @Autowired
    private UserWithdrawalService userWithdrawalService;
@@ -253,4 +265,36 @@
        }
        return ResultUtil.success();
    }
    @Override
    public void taskDayFenzhang() throws Exception {
        List<Withdrawal> withdrawals = selectList(new EntityWrapper<Withdrawal>().eq("userType", 2).eq("state", 1).isNotNull("reqSeqId"));
        if (CollUtil.isNotEmpty(withdrawals)) {
            for (Withdrawal withdrawal : withdrawals) {
                Map<String, Object> map = null;
                try {
                    map = FenZhangUtil.queryFenzhang(withdrawal.getReqSeqId(), DateUtil.format(withdrawal.getInsertTime(), "yyyyMMdd"));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                Driver driver = driverService.selectById(withdrawal.getUserId());
                if (Objects.nonNull(driver)) {
                    UserWithdrawal userWithdrawal = userWithdrawalService.selectOne(new EntityWrapper<UserWithdrawal>()
                            .eq("phone", driver.getPhone()).eq("type", 1).last("limit 1"));
                    System.out.println("分账定时查询:" + map.toString());
                    if ("00000000".equals(map.get("resp_code")) && "S".equals(map.get("trans_stat").toString())) {
                        String txReqSeqId = RequestSeqUtil.generate("TX");
                        withdrawal.setReqSeqId(txReqSeqId);
                        Map<String, Object> tx = douGongWithdrawBiz.encashment(txReqSeqId, BigDecimal.valueOf(withdrawal.getMoney()),
                                userWithdrawal.getHuifuId(), userWithdrawal.getTokenNo(), 2);
                        withdrawal.setHfSeqId(tx.get("huifu_id").toString());
                        if ("00000000".equals(tx.get("resp_code")) && "S".equals(tx.get("trans_stat"))) {
                            withdrawal.setState(2);
                            this.updateById(withdrawal);
                        }
                    }
                }
            }
        }
    }
}
DriverJYXTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/TaskUtil.java
@@ -7,6 +7,7 @@
import com.stylefeng.guns.modular.system.service.IDriverService;
import com.stylefeng.guns.modular.system.service.IOrderService;
import com.stylefeng.guns.modular.system.service.IUserMerchantCouponService;
import com.stylefeng.guns.modular.system.service.IWithdrawalService;
import com.unionpay.upyzt.resp.CusApplicationResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
@@ -38,6 +39,8 @@
    @Autowired
    private UserWithdrawalService userWithdrawalService;
    @Autowired
    private IWithdrawalService withdrawalService;
    public Set<Integer> driverIds = new HashSet<>();//存储需要提醒司机预约单的司机id
@@ -113,6 +116,15 @@
            e.printStackTrace();
        }
    }
    @Scheduled(fixedRate = 1000 * 60)
    public void taskDayFenzhang() {
        try {
            withdrawalService.taskDayFenzhang(); // 分账业务
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//