package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.huifu.bspay.sdk.opps.core.utils.RsaUtils;
import com.huifu.bspay.sdk.opps.core.utils.SequenceTools;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.constants.SmsConstants;
import com.zbkj.common.constants.SysConfigConstants;
import com.zbkj.common.dto.*;
import com.zbkj.common.excel.ExcelUtil;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.exception.CrmebWalletException;
import com.zbkj.common.model.huifu.*;
import com.zbkj.common.model.order.Order;
import com.zbkj.common.utils.DateUtils;
import com.zbkj.common.utils.IdcardUtils;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.service.config.PaymentChannel;
import com.zbkj.service.dao.*;
import com.zbkj.service.huifu.constants.*;
import com.zbkj.service.huifu.v2.V2ApiRequest;
import com.zbkj.service.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <b>  </b>
 * @author ZXF
 * @create 2023/07/31 0031 11:30
 * @version
 * @注意事项 </b>
 */
@Service
@Component("huifuWalletServiceImpl")
public class HuifuWalletServiceImpl extends ServiceImpl<HuifuWalletDao, HuifuWallet> implements HuifuWalletService {

    private static final Logger logger = LoggerFactory.getLogger(HuifuWalletService.class);

    @Resource
    private HuifuWalletDao huifuWalletDao;

    @Resource
    private HuifuWalletAccountDao huifuWalletAccountDao;

    @Resource
    private HuifuWalletBusiDao huifuWalletBusiDao;

    @Resource
    private HuifuWalletAccountDetailDao huifuWalletAccountDetailDao;

    @Resource
    private HuifuWalletProcessDao huifuWalletProcessDao;

    @Resource
    private HuifuWalletTradeDao huifuWalletTradeDao;

    @Resource
    private JsPayTradeDao jsPayTradeDao;

    @Resource
    private HuifuWalletTranslogDao huifuWalletTranslogDao;

    @Resource
    private BankConfigDao bankConfigDao;

    @Resource
    private HuifuWalletReconciliationDao huifuWalletReconciliationDao;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    HuifuReconcileService huifuReconcileService;
    @Autowired
    TransactionLogService transactionLogService;
    @Autowired
    CommonWalletService commonWalletService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private RedissonClient redisson;

    @Autowired
    TaskResidualService taskResidualService;

    private final static String TRANSFERKEY = "Callback:";
    private final static String TRANSFERFROZENKEY = "TransferFrozen:";
    private final static String SCHKEY = "SchTask:";

    private static final int expireTime = 10 * 60;

    private static final DecimalFormat decimalFormat = new DecimalFormat(Constants.DECIMAL_FORMAT);

    /**
     * <b> 异步执行平台分账 </b>
     * @author ZXF
     * @create 2023/09/15 0015 17:48
     * @version
     * @注意事项 </b>
     */
    @Async
    public void syncTransferToPlat(HuifuWalletTransferDto dto){
        try{
            dto.setPayChannel(PaymentChannel.HUIFU.toString());
            if(!transferToPlat(dto)){
                taskResidualService.saveTaskResidual("transferToPlat","平台分账补偿","com.zbkj.service.service.impl.HuifuWalletServiceImpl",1,"com.zbkj.common.dto.HuifuWalletTransferDto",JSONObject.toJSONString(dto));
            }
        }catch (Exception e){
            logger.error(">>>>>>>>> 企业分账给平台transferToPlat.执行异常："+e.getMessage());
            taskResidualService.saveTaskResidual("transferToPlat","平台分账补偿","com.zbkj.service.service.impl.HuifuWalletServiceImpl",1,"com.zbkj.common.dto.HuifuWalletTransferDto",JSONObject.toJSONString(dto));
        }
    }

    /**
     * <b> 异步执行冻结金额计算 </b>
     * @author ZXF
     * @create 2023/09/15 0015 17:48
     * @version
     * @注意事项 </b>
     */
    @Async
    public void syncUpdateSumFrozenAmount(String uniId, BigDecimal amount){
        try{
            if(amount.compareTo(BigDecimal.ZERO) == 0){
                return;
            }
            logger.error(">>>>>>>>> 企业冻结金额计算modifyBalance.开始：");
            if(!commonWalletService.modifyBalance(uniId,amount,PaymentChannel.HUIFU.toString())){
                taskResidualService.saveTaskResidual("modifyBalance","冻结金额计算补偿","com.zbkj.service.service.CommonWalletService",3,"String,BigDecimal,String",uniId+","+amount+","+PaymentChannel.HUIFU.toString());
            }
        }catch (Exception e){
            logger.error(">>>>>>>>> 企业冻结金额计算modifyBalance.执行异常："+e.getMessage());
            taskResidualService.saveTaskResidual("modifyBalance","冻结金额计算补偿","com.zbkj.service.service.CommonWalletService",3,"String,BigDecimal,String",uniId+","+amount+","+PaymentChannel.HUIFU.toString());
        }
    }

    /**
     * <b> 异步执行平台退款 </b>
     * @author ZXF
     * @create 2023/09/15 0015 17:48
     * @version
     * @注意事项 </b>
     */
    @Async
    public void syncRefundToPlat(HuifuWalletTransferDto dto){
        try{
            dto.setPayChannel(PaymentChannel.HUIFU.toString());
            if(!refundToPlat(dto)){
                taskResidualService.saveTaskResidual("refundToPlat","平台退款给企业补偿","com.zbkj.service.service.impl.HuifuWalletServiceImpl",1,"com.zbkj.common.dto.HuifuWalletTransferDto",JSONObject.toJSONString(dto));
            }
        }catch (Exception e){
            logger.error(">>>>>>>>> 平台退款给企业refundToPlat.执行异常："+e.getMessage());
            taskResidualService.saveTaskResidual("refundToPlat","平台退款给企业补偿","com.zbkj.service.service.impl.HuifuWalletServiceImpl",1,"com.zbkj.common.dto.HuifuWalletTransferDto",JSONObject.toJSONString(dto));
        }
    }


    /**
     * 获取企业钱包服务开通情况
     *
     * @param huifuWallet
     * @return
     * @author llc
     * @date 2019-06-21
     */
    @Override
    public Map<String, String> getHuifuWalletServiceOpenInfo(HuifuWallet huifuWallet) {
        if (huifuWallet.getUniId() == null) {
            return null;
        }
        huifuWallet = huifuWalletDao.getHuifuWalletByUniId(huifuWallet.getUniId(), PaymentChannel.HUIFU.toString());

        /*** 如果未查询到数据则表示未授权 ***/
        Map<String, String> resultMap = new HashMap<>();
        if (huifuWallet == null) {
            resultMap.put("isCompleteOpen", Constants.N); // 是否开通服务
            resultMap.put("isAuthorize", Constants.N); // 未授权服务
        } else {
            resultMap.put("isCompleteOpen", huifuWallet.getIsCompleteOpen()); // 是否开通服务
            resultMap.put("isAuthorize", Constants.Y); // 已授权服务
        }
        resultMap.put("openRegTime", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_HF_OPEN_REG_TIME)); // 开放入驻时间
        resultMap.put("openWalletTime", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_HF_OPEN_WALLET_TIME)); // 开放钱包时间
        return resultMap;
    }

    /**
     * 获取企业钱包服务当前开通步骤(因富民银行开户流程调整作废)
     *
     * @param dto
     * @return
     * @author llc
     * @date 2019-06-21
     */
    @Override
    public HuifuWalletProcess getHuifuWalletCurrentProcess(HuifuWalletProcess dto) {
        if (StringUtils.isEmpty(dto.getUniId())) {
            return null;
        }
        HuifuWalletProcess buildProcess = huifuWalletProcessDao.getHuifuWalletCurrentProcess(dto.getUniId(), PaymentChannel.HUIFU.toString());
        /*** 未查到数据则初始化数据 ***/
        if (buildProcess == null) {
            /* 插入企业钱包开户流程 ***/
            buildProcess = new HuifuWalletProcess();
            buildProcess.setUniId(dto.getUniId());
            buildProcess.setCreateTime(new Date());
            buildProcess.setStep(OpenProcess.QYKH.getSort());
            buildProcess.setIsComplete(Constants.N);
            buildProcess.setDescription(OpenProcess.QYKH.getDesc());
            buildProcess.setPayChannel(PaymentChannel.HUIFU.toString());
            huifuWalletProcessDao.insert(buildProcess);
            /*int count = huifuWalletProcessDao.isProcess(buildProcess);
            if(count==0){
                huifuWalletProcessDao.insert(buildProcess);
            }*/
            /*** 更新企业钱包服务为已完成 ***/
            HuifuWallet huifuWallet = new HuifuWallet();
            huifuWallet.setUniId(dto.getUniId());
            huifuWallet.setCreateTime(new Date());
            huifuWallet.setIsCompleteOpen(Constants.N);
            huifuWallet.setPayChannel(PaymentChannel.HUIFU.toString());
            huifuWalletDao.insertHuifuWallet(huifuWallet);
//            processDB = huifuWalletProcessDao.getHuifuWalletCurrentProcess(dto.getUniId(), PaymentChannel.HUIFU.toString());
        }
        return buildProcess;
    }

    private void checkValidateCode(String phone, String code) throws CrmebWalletException {
        Object validateCode = redisUtil.get(SmsConstants.SMS_VALIDATE_PHONE + phone);
        if (ObjectUtil.isNull(validateCode)) {
            throw new CrmebWalletException("验证码已过期");
        }
        if (!validateCode.toString().equals(code)) {
            throw new CrmebWalletException("验证码错误");
        }
        //删除验证码
        redisUtil.delete(SmsConstants.SMS_VALIDATE_PHONE + phone);
    }

    /**
     * <b> 返回常量包装 </b>
     * @param type 1获取code 2获取desc
     * @author ZXF
     * @create 2023/09/12 0012 11:22
     * @version
     * @注意事项 </b>
     */
    public static String RET(Map<String, Object> response,int type){
        if(type == 1){
            return response.get("resp_code").toString();
        }
        return response.get("resp_desc").toString();
    }

    /**
     * 保存开户资料第一步
     * TODO 当前对接汇付
     * 步骤1提交会员档案录入
     * 步骤2查询会员档案获取 保证金账号 当 钱包账号 存储
     * @param dto
     * @return
     * @author llc
     * @date 2019-06-21
     * @update by zxf 2023-02-07
     */
    @Override
    public String saveAccountInfo(HuifuWalletAccountDto dto) throws CrmebWalletException {
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("ID不能为空");
        }
        if (StringUtil.isEmpty(dto.getActiveCode())) {
            throw new CrmebWalletException("验证码不能为空");
        }
//        checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        if (StringUtil.isEmpty(dto.getComName())) {
            throw new CrmebWalletException("企业名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getHfComType())) {
            throw new CrmebWalletException("企业类型不能为空");
        }
        if (StringUtil.isEmpty(dto.getContactPhone())) {
            throw new CrmebWalletException("联系电话不能为空");
        }
        if (StringUtil.isEmpty(dto.getLicenseValidityType())) {
            throw new CrmebWalletException("证照有效期类型不能为空");
        }
        if (StringUtil.isEmpty(dto.getLicenseBeginDate())) {
            throw new CrmebWalletException("证照有效期起始日期不能为空");
        }
        if (StringUtil.isEmpty(dto.getRegProvId())) {
            throw new CrmebWalletException("注册地址(省)不能为空");
        }
        if (StringUtil.isEmpty(dto.getRegAreaId())) {
            throw new CrmebWalletException("注册地址(市)不能为空");
        }
        /*if (StringUtil.isEmpty(dto.getRegDistrictId())) {
            throw new CrmebWalletException("注册地址(区)不能为空");
        }*/
        if (StringUtil.isEmpty(dto.getRegAddress())) {
            throw new CrmebWalletException("注册地址(详细信息)不能为空");
        }
        if (StringUtil.isEmpty(dto.getLegalRepName())) {
            throw new CrmebWalletException("法定代表人姓名不能为空");
        }
        if (StringUtil.isEmpty(dto.getIdcardType())) {
            throw new CrmebWalletException("法定代表人证件类型不能为空");
        }
        if (StringUtil.isEmpty(dto.getIdcardNo())) {
            throw new CrmebWalletException("法定代表人证件号码不能为空");
        } else {
            if ("00".equals(dto.getIdcardType())&&!IdcardUtils.validateCard(dto.getIdcardNo())) {
                throw new CrmebWalletException("法人身份证不合法");
            }
        }
        if (StringUtil.isEmpty(dto.getLegalCertValidityType())) {
            throw new CrmebWalletException("证照有效期类型不能为空");
        }
        if (StringUtil.isEmpty(dto.getLegalCertBeginDate())) {
            throw new CrmebWalletException("身份证有效期开始日期不能为空");
        }
        /*if (StringUtil.isEmpty(dto.getLegalCertEndDate())) {
            throw new CrmebWalletException("身份证有效期截止日期不能为空");
        }*/
        if (StringUtil.isEmpty(dto.getContactName())) {
            throw new CrmebWalletException("联系人姓名不能为空");
        }
        dto.setPayChannel(PaymentChannel.HUIFU.toString());
        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getUniId(),PaymentChannel.HUIFU.toString());

        /*** 调用支付平台接口完成开户资料上传 ***/
        Map<String, Object> p = new HashMap<>();
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("regName", dto.getComName());
        p.put("shortName", dto.getShortName());
        p.put("licenseValidityType", dto.getLicenseValidityType());
        p.put("licenseBeginDate", dto.getLicenseBeginDate());
        p.put("licenseEndDate", dto.getLicenseEndDate());
        p.put("licenseCode", dto.getComCerNo());
        p.put("regProvId", dto.getRegProvId());
        p.put("regAreaId", dto.getRegAreaId());
        p.put("regDistrictId", dto.getRegDistrictId());
        p.put("regDetail", dto.getRegAddress());
        p.put("legalName", dto.getLegalRepName());
        p.put("legalCertNo", dto.getIdcardNo());
        p.put("legalCertType", dto.getIdcardType());
        p.put("legalCertValidityType", dto.getLegalCertValidityType());
        p.put("legalCertBeginDate", dto.getLegalCertBeginDate());
        p.put("legalCertEndDate", dto.getLegalCertEndDate());
        p.put("contactName", dto.getContactName());
        p.put("contactMobile", dto.getContactPhone());
        Map<String, Object> response;
        String operType;
        HFBusiCode hFBusiCode;
        try {
            if(account!=null){//修改
                operType = Constants.OPER_TYPE_UPD;
                hFBusiCode = HFBusiCode.ENTMODIFY;
                p.put("huifuId", account.getWalletAccountNo());
                response = V2ApiRequest.api(hFBusiCode,p);
            }else{//新增
                operType = Constants.OPER_TYPE_ADD;
                hFBusiCode = HFBusiCode.ENT;
                response = V2ApiRequest.api(hFBusiCode,p);
            }
        }catch (Exception e){
            transactionLogService.save("saveAccountInfo",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }
        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            final HuifuWalletAccountDto hwaDto = dto;
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                Date now = new Date();
                //新增
                if(Constants.OPER_TYPE_ADD.equals(operType)){
                    hwaDto.setCreateTime(now);
                    hwaDto.setWalletAccountNo(String.valueOf(response.get("huifu_id")));
                    huifuWalletAccountDao.insertHuifuWalletAccount(hwaDto);

                    /*** 更新企业钱包开户流程 ***/
                    //结束第一个流程
                    HuifuWalletProcess huifuWalletProcess = huifuWalletProcessDao.getHuifuWalletCurrentProcess(dto.getUniId(), PaymentChannel.HUIFU.toString());
                    if(huifuWalletProcess == null){
                        /* 插入企业钱包开户流程 ***/
                        huifuWalletProcess = new HuifuWalletProcess();
                        huifuWalletProcess.setUniId(hwaDto.getUniId());
                        huifuWalletProcess.setCreateTime(new Date());
                        huifuWalletProcess.setStep(OpenProcess.QYKH.getSort());
                        huifuWalletProcess.setIsComplete(Constants.Y);
                        huifuWalletProcess.setDescription(OpenProcess.QYKH.getDesc());
                        huifuWalletProcess.setPayChannel(PaymentChannel.HUIFU.toString());
                        huifuWalletProcessDao.insert(huifuWalletProcess);
                        /*** 更新企业钱包服务为已完成 ***/
                        HuifuWallet huifuWallet = new HuifuWallet();
                        huifuWallet.setUniId(hwaDto.getUniId());
                        huifuWallet.setCreateTime(new Date());
                        huifuWallet.setIsCompleteOpen(Constants.N);
                        huifuWallet.setPayChannel(PaymentChannel.HUIFU.toString());
                        huifuWalletDao.insertHuifuWallet(huifuWallet);
                    }else{
                        if(OpenProcess.QYKH.getSort() == huifuWalletProcess.getStep()){
                            huifuWalletProcess.setUpdateTime(now);
                            huifuWalletProcess.setIsComplete(Constants.Y);
                            huifuWalletProcessDao.updateById(huifuWalletProcess);
                        }
                    }
                    //增加业务入驻流程
                    HuifuWalletProcess buildProcess = new HuifuWalletProcess();
                    buildProcess.setUniId(hwaDto.getUniId());
                    buildProcess.setCreateTime(now);
                    buildProcess.setStep(OpenProcess.YWRZ.getSort());
                    buildProcess.setIsComplete(Constants.N);
                    buildProcess.setDescription(OpenProcess.YWRZ.getDesc());
                    buildProcess.setPayChannel(PaymentChannel.HUIFU.toString());
                    int count = huifuWalletProcessDao.isProcess(buildProcess);
                    if(count==0){
                        huifuWalletProcessDao.insert(buildProcess);
                    }

                }else if(Constants.OPER_TYPE_UPD.equals(operType)){
                    hwaDto.setUpdateTime(now);
                    huifuWalletAccountDao.updateHuifuWalletAccountAll(hwaDto);
                } else {
//                    throw new CrmebWalletException("类型不匹配，业务无效");
                    return Boolean.FALSE;
                }
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new CrmebWalletException("企业钱包-开户数据-操作失败");
            }
            HuifuWalletAccountDto hwa = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getUniId(),PaymentChannel.HUIFU.toString());
            return hwa.getId()+"";
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }

    }

    /**
     * 保存开户资料第二步
     *
     * @param dto
     * @return
     * @author llc
     * @date 2019-06-21
     */
    @Override
    public String saveAccountInfoStepTwo(HuifuWalletBusiDto dto) throws CrmebWalletException {

        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("ID不能为空");
        }
        if (StringUtil.isEmpty(dto.getCardName())) {
            throw new CrmebWalletException("卡户名不能为空");
        }
        if (StringUtil.isEmpty(dto.getCardNo())) {
            throw new CrmebWalletException("卡号不能为空");
        }
        if (StringUtil.isEmpty(dto.getProvId())) {
            throw new CrmebWalletException("银行所在省不能为空");
        }
        if (StringUtil.isEmpty(dto.getAreaId())) {
            throw new CrmebWalletException("银行所在市不能为空");
        }
        if (StringUtil.isEmpty(dto.getCashType())) {
            throw new CrmebWalletException("业务类型不能为空");
        }
        if (StringUtil.isEmpty(dto.getCardType())) {
            throw new CrmebWalletException("卡类型不能为空");
        }
        if (StringUtil.isEmpty(dto.getBankCode())) {
            throw new CrmebWalletException("银行号不能为空");
        }
        if (StringUtil.isEmpty(dto.getBranchCode())) {
            throw new CrmebWalletException("支行联行号不能为空");
        }
        if (StringUtil.isEmpty(dto.getBranchName())) {
            throw new CrmebWalletException("支行名称不能为空");
        }
        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getUniId(),PaymentChannel.HUIFU.toString());
        if (account == null) {
            throw new CrmebWalletException("未完成企业开户");
        }
        //如果银行编码只有7位需要最前面补0
        if(dto.getBankCode().length()==7){
            dto.setBankCode("0"+dto.getBankCode());
        }
        HuifuWalletBusiDto busi = huifuWalletBusiDao.getHuifuWalletBusiByAccountId(account.getId());
        dto.setReqSeqId(SequenceTools.getReqSeqId32());
        /*** 调用支付平台接口完成开户资料上传 ***/
        Map<String, Object> p = new HashMap<>();
        p.put("huifuId", account.getWalletAccountNo());
        p.put("reqSeqId", dto.getReqSeqId());
        p.put("card_type", dto.getCardType());
        p.put("cash_type", dto.getCashType());
        p.put("card_name", dto.getCardName());
        p.put("card_no", dto.getCardNo());
        p.put("prov_id", dto.getProvId());
        p.put("area_id", dto.getAreaId());
        p.put("bank_code", dto.getBankCode());
        p.put("branch_code", dto.getBranchCode());
        p.put("branch_name", dto.getBranchName());
        p.put("mp", dto.getMp());

        Map<String, Object> response;
        String operType;
        HFBusiCode hFBusiCode;
        try {
            if(busi!=null){//修改
                operType = Constants.OPER_TYPE_UPD;
                hFBusiCode = HFBusiCode.BUSIMODIFY;
                response = V2ApiRequest.api(hFBusiCode,p);
            }else{//新增
                operType = Constants.OPER_TYPE_ADD;
                hFBusiCode = HFBusiCode.BUSIOPEN;
                response = V2ApiRequest.api(hFBusiCode,p);
            }
        }catch (Exception e){
            transactionLogService.save("saveAccountInfoStepTwo",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }
        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            //如果存在其它要素异常直接抛出
            if(response.get("resp_business") != null){
                List<JSONObject> list = JSONObject.parseArray(response.get("resp_business").toString(),JSONObject.class);
                String errMsg="";
                for (JSONObject json:list) {
                    if("F".equals(json.get("code")+"")){
                        errMsg += json.get("msg") + ";";
                    }
                }
                if(StringUtils.isNotEmpty(errMsg)){
                    transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                    throw new CrmebWalletException(errMsg);
                }
            }
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                Date now = new Date();
                //新增
                if(Constants.OPER_TYPE_ADD.equals(operType)){
                    dto.setCreateTime(now);
                    dto.setTokenNo(String.valueOf(response.get("token_no")));
                    dto.setAccountId(account.getId());
                    dto.setPayChannel(PaymentChannel.HUIFU.toString());
                    huifuWalletBusiDao.insertHuifuWalletBusi(dto);

                    HuifuWallet huifuWallet = huifuWalletDao.getHuifuWalletByUniId(account.getUniId(),PaymentChannel.HUIFU.toString());
                    /*** 更新业务入驻流程 ***/
                    HuifuWalletProcess huifuWalletProcess = huifuWalletProcessDao.getHuifuWalletCurrentProcess(account.getUniId(), PaymentChannel.HUIFU.toString());
                    if(OpenProcess.YWRZ.getSort() == huifuWalletProcess.getStep()){
                        huifuWalletProcess.setUpdateTime(now);
                        huifuWalletProcess.setIsComplete(Constants.Y);
                        huifuWalletProcessDao.updateById(huifuWalletProcess);
                    }
                    /*** 更新企业钱包服务为已完成 ***/
                    huifuWallet.setUniId(account.getUniId());
                    huifuWallet.setUpdateTime(now);
                    huifuWallet.setIsCompleteOpen(Constants.Y);
                    huifuWallet.setOpenTime(now);
                    huifuWallet.setPayChannel(PaymentChannel.HUIFU.toString());
                    huifuWalletDao.updateHuifuWallet(huifuWallet);
                }else if(Constants.OPER_TYPE_UPD.equals(operType)){
                    dto.setUpdateTime(now);
                    dto.setId(busi.getId());
                    dto.setTokenNo(String.valueOf(response.get("token_no")));
                    huifuWalletBusiDao.updateHuifuWalletBusiAll(dto);
                } else {
//                    throw new CrmebWalletException("类型不匹配，业务无效");
                    return Boolean.FALSE;
                }
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new CrmebWalletException("企业钱包-业务入驻-操作失败");
            }
            return "1";
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    @Override
    public String getActiveUrl(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    @Override
    public String getACXLoginUrl(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    @Override
    public HuifuWalletAccountDto getHuifuWalletAccountStatus(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    @Override
    public HuifuWalletAccountDto huifuWalletAccountUpdateStatus(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    @Override
    public HuifuWalletAccountDto huifuWalletAccountActiveStatus(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    @Override
    public Object getHuifuWalletAccountDetail(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    /**
     * 获取企业钱包账户
     *
     * @param huifuWalletAccount
     * @return
     * @author llc
     * @date 2019-06-21
     */
    @Override
    public HuifuWalletAccountDto getHuifuWalletAccount(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        if (StringUtils.isEmpty(huifuWalletAccount.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        /*** 查出本地的钱包账户资料 ***/
        HuifuWalletAccountDto dto = huifuWalletAccountDao.getHuifuWalletAccountByUniId(huifuWalletAccount.getUniId(),PaymentChannel.HUIFU.toString());
        if(dto == null){
            return new HuifuWalletAccountDto();
        }
        HuifuWalletBusiDto busi = huifuWalletBusiDao.getHuifuWalletBusiByAccountId(dto.getId());
        if(busi != null){
            dto.setBranchName(busi.getBranchName());
            dto.setBankCode(busi.getBankCode());
            dto.setBranchCode(busi.getBranchCode());
            dto.setCashType(busi.getCashType());
            dto.setCardNo(busi.getCardNo());;
            dto.setCardName(busi.getCardName());
            dto.setCardType(busi.getCardType());
            dto.setProvId(busi.getProvId());
            dto.setAreaId(busi.getAreaId());
        }
        if(StringUtils.isEmpty(dto.getAcctStat())){
            /*** 调用支付平台接口获取账户相关资料 ***/
            Map<String, Object> p = new HashMap<>();
            p.put("huifuId", dto.getWalletAccountNo());
            p.put("reqSeqId", SequenceTools.getReqSeqId32());

            Map<String, Object> response;
            HFBusiCode hFBusiCode;
            try {
                hFBusiCode = HFBusiCode.YEQUERY;
                response = V2ApiRequest.api(hFBusiCode,p);
            }catch (Exception e){
                transactionLogService.save("getHuifuWalletAccount",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
                throw new CrmebWalletException(e.getMessage());
            }
            if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
                Boolean execute = transactionTemplate.execute(e -> {
                    transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                    List<Map> list = JSONArray.parseArray(String.valueOf(response.get("acctInfo_list")),Map.class);
                    if(list.size()>0){
                        Map map = list.get(0);
                        dto.setAcctStat(map.get("acct_stat").toString());
                        if("N".equals(map.get("acct_stat"))){
                            dto.setAccountStatus("1");
                        }else{
                            dto.setAccountStatus("0");
                        }
                        huifuWalletAccountDao.updateHuifuWalletAcctStat(dto.getId(),map.get("acct_stat").toString());
                    }
                    return Boolean.TRUE;
                });
                if (!execute) {
                    throw new CrmebWalletException("企业钱包-账户查询-操作失败");
                }
            }else{
                transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                throw new CrmebWalletException(RET(response,2));
            }
        }
        return dto;
    }

    @Override
    public void getHuifuWalletAccountArrangementStatus(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {

    }

    @Override
    public String checkArrangementAudit(HuifuWalletAccountDto huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    /**
     * <b> 获取钱包可用余额 </b>
     * @author ZXF
     * @create 2023/09/12 0012 10:26
     * @version
     * @注意事项 </b>
     */
    @Override
    public BigDecimal getHuifuWallectBalanceByUniId(String uniId) throws CrmebWalletException {
        Map<String, String> amounts = requestHuifuWalletAmount(uniId);
        return new BigDecimal(amounts.get("availableAmount"));
    }

    /**
     * 获取企业钱包账户金额
     *
     * @param huifuWalletAccount
     * @return
     * @author llc
     * @date 2019-06-24
     */
    @Override
    public Map<String, String> getHuifuWalletAccountAmount(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {

        if (StringUtils.isEmpty(huifuWalletAccount.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        return requestHuifuWalletAmount(huifuWalletAccount.getUniId());
    }

    @Override
    public Map<String, String> getAccountBlanance(HuifuWalletAccount huifuWalletAccount) throws CrmebWalletException {
        return null;
    }

    private Map<String, String> requestHuifuWalletAmount(String uniId) throws CrmebWalletException {
        HuifuWalletAccount account = huifuWalletAccountDao.getHuifuWalletAccountByUniId(uniId,PaymentChannel.HUIFU.toString());
        if (account == null) {
            throw new CrmebWalletException("未找到账户信息！");
        }
        Map<String, Object> p = new HashMap<>();
        p.put("huifuId", account.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEQUERY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("getHuifuWalletAccountAmount",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            List<Map> list = JSONArray.parseArray(String.valueOf(response.get("acctInfo_list")),Map.class);
            String ledger_bal = "0";
            if(list.size()>0){
                Map map = list.get(0);
                ledger_bal =  String.valueOf(map.get("balance_amt"));
            }
            Map<String, String> resultMap = new HashMap<>();
            BigDecimal availableAmount = BigDecimal.ZERO;
            //冻结金额取线程安全里的值，线程安全的值初始通过接口加载
            if(Double.parseDouble(ledger_bal)>0){
                availableAmount = (new BigDecimal(ledger_bal)).subtract(new BigDecimal(account.getFrozenAmount()));
            }
            /*** 账户总额 ***/
            ledger_bal = decimalFormat.format(new BigDecimal(ledger_bal));
            resultMap.put("totalAmount", ledger_bal);
            /*** 可用余额 ***/
            String aAmount = decimalFormat.format(availableAmount);
            resultMap.put("availableAmount", aAmount);
            /*** 冻结金额 ***/
            resultMap.put("frozenAmount", account.getFrozenAmount());
            return resultMap;
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    private synchronized BigDecimal findBalance(String walletAccountNo) throws CrmebWalletException {
        Map<String, Object> p = new HashMap<>();
        p.put("huifuId", walletAccountNo);
        p.put("reqSeqId", SequenceTools.getReqSeqId32());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEQUERY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("getHuifuWalletAccountAmount",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            List<Map> list = JSONArray.parseArray(String.valueOf(response.get("acctInfo_list")),Map.class);
            if(list.size()>0){
                Map map = list.get(0);
                String ledger_bal =  String.valueOf(map.get("balance_amt"));
                /*** 账户总额 ***/
                return new BigDecimal(ledger_bal);
            }
            return BigDecimal.ZERO;

        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    /**
     * <b> 获取企业钱包账户交易明细（请求转存数据，当天只能查到昨天的数据） </b>
     * @author ZXF
     * @create 2023/04/23 0023 10:37
     * @version
     * @注意事项 </b>
     */
    @Override
    public PageInfo<HuifuWalletAccountDetail> thisHuifuWalletAccountTradeDetail(HuifuWalletAccountDetailDto dto) throws CrmebWalletException {
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        if (dto.getPageNumber() == null) {
            throw new CrmebWalletException("第几页不能为空");
        }
        if (dto.getPageSize() == null) {
            throw new CrmebWalletException("每页多少行不能为空");
        }
        if (StringUtil.isEmpty(dto.getStartDate())) {
            throw new CrmebWalletException("开始日期不能为空");
        }
        if (StringUtil.isEmpty(dto.getEndDate())) {
            throw new CrmebWalletException("结束日期不能为空");
        }
        dto.setStartDate(dto.getStartDate().replace("-",""));
        dto.setEndDate(dto.getEndDate().replace("-",""));
        dto.setIsHideCheck("1");
        PageHelper.startPage(dto.getPageNumber(), dto.getPageSize());
        List<HuifuWalletAccountDetail> detailList = huifuWalletAccountDetailDao.selectByUniIdAndDate(dto);
        return new PageInfo(detailList);
    }

    /**
     * 导出企业钱包账户交易明细数据
     *
     * @author llc
     * @date 2019-09-20
     */
    @Override
    public String exportHuifuWalletAccountTradeDetail(HuifuWalletAccountDetailDto dto, HttpServletResponse response) throws CrmebWalletException {
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        if (StringUtil.isEmpty(dto.getStartDate())) {
            throw new CrmebWalletException("开始日期不能为空");
        }
        if (StringUtil.isEmpty(dto.getEndDate())) {
            throw new CrmebWalletException("结束日期不能为空");
        }
        OutputStream os = null;
        HSSFWorkbook wb = new HSSFWorkbook();
        try {
            String fileName = "收支明细" + DateUtil.format(new Date(),"yyyyMMddHHmmss") + ".xls";
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
            os = response.getOutputStream();
            HSSFSheet sheet1 = wb.createSheet("收支明细");


            /*** 查询企业钱包账户交易明细数据列表 ***/
            dto.setStartDate(dto.getStartDate().replace("-",""));
            dto.setEndDate(dto.getEndDate().replace("-",""));
            dto.setIsHideCheck("1");
            List<HuifuWalletAccountDetail> detailList = huifuWalletAccountDetailDao.selectByUniIdAndDate(dto);

            /*** 填充文本样式 ***/
            CellStyle stringStyle = ExcelUtil.getStringStyle(wb);

            /**** 生成sheet1的内容 ***/
            HSSFFont titleFont = wb.createFont();
            HSSFCellStyle titleStyle = wb.createCellStyle();
            titleFont.setFontHeightInPoints((short) 11);
            titleFont.setColor(HSSFColor.BLUE.index);
            titleFont.setFontName("黑体");
            titleStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
            titleStyle.setFont(titleFont);
            titleStyle.setWrapText(true);
            HSSFDataFormat format = wb.createDataFormat();
            titleStyle.setDataFormat(format.getFormat("@"));

            /**** 生成sheet1的内容 ***/
            /*** 获取企业钱包账户对账统计数据 ***/
//            Map<String, Object> map = huifuWalletReconciliationDao.getWalletReconciliationSum(dto);
            String headerTitle = "";
//            if (map == null) {
//                headerTitle = MessageFormat.format("总笔数：【{0}】笔 | 总金额：【{1}】元 | 成功笔数：【{2}】笔 | 成功金额：【{3}】元 | 失败笔数：【{4}】笔 | 失败金额：【{5}】元 | 处理中笔数：【{6}】笔 | 处理中金额：【{7}】元",
//                        0, 0, 0, 0, 0, 0, 0, 0);
            headerTitle = MessageFormat.format("总笔数：【{0}】笔",
                    detailList.size());
//            } else {
//                headerTitle = MessageFormat.format("总笔数：【{0}】笔 | 总金额：【{1}】元 | 成功笔数：【{2}】笔 | 成功金额：【{3}】元 | 失败笔数：【{4}】笔 | 失败金额：【{5}】元 | 处理中笔数：【{6}】笔 | 处理中金额：【{7}】元",
//                        map.get("totalCount"), map.get("sumAmount"), map.get("successCount"), map.get("successAmount"), map.get("errorCount"), map.get("errorAmount"), map.get("processingCount"), map.get("processingAmount"));
//            }
            /*** 填充第一行数据 ***/
            HSSFCellStyle titleStyle1 = wb.createCellStyle();
            HSSFFont titleFont1 = wb.createFont();
            titleFont1.setFontHeightInPoints((short) 11);
            titleFont1.setColor(HSSFColor.RED.index);
            titleFont1.setFontName("黑体");
            titleStyle1.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
            titleStyle1.setFont(titleFont1);
            titleStyle1.setWrapText(true);
            HSSFRow rowFirst = sheet1.createRow(0); // 第一个sheet的第一行为标题
            rowFirst.setHeight((short) (1000));
            sheet1.addMergedRegion(new CellRangeAddress(0, (short) 0, 0, 13));
            HSSFCell titleCell = rowFirst.createCell(0);
            titleCell.setCellValue(headerTitle);
            titleCell.setCellStyle(titleStyle1);

            /*** 填充第二行数据 ***/
            HSSFRow secondFirst = sheet1.createRow(1);
            String[] secondArr = {"序号", "交易流水号", "业务流水号", "交易类型", "交易状态", "创建时间", "交易金额", "交易后余额", "出账方名称", "出账方商户号", "入账方名称", "入账方商户号", "交易日期", "交易时间", "备注", "支付渠道"};
            int column;
            for (int i = 0; i < secondArr.length; i++) {
                HSSFCell cell = secondFirst.createCell(i); // 获取第二行的每个单元格
                if (i == 0) {
                    column = 1500;
                } else if (i == 5) {
                    column = 5000;
                } else if (i == 1 || i == 2 || i == 8 || i == 10) {
                    column = 10000;
                } else if (i == 14) {
                    column = 14000;
                } else {
                    column = 4000;
                }
                sheet1.setColumnWidth(i, column); // 设置每列的列宽
                sheet1.setDefaultColumnStyle(i, stringStyle); // 设置单元格格式 --文本格式
                cell.setCellStyle(titleStyle); // 文本格式
            }

            /*** 填充第二行数据 ***/
            for (int i = 0; i < secondArr.length; i++) {
                HSSFCell cell = secondFirst.createCell(i); // 获取第一行的每个单元格
                cell.setCellValue(secondArr[i]);
                cell.setCellStyle(titleStyle);
            }

            /*** 字体颜色样式 ***/
            CellStyle greenStyle = ExcelUtil.getColorStyle(wb, IndexedColors.SEA_GREEN.index);// 青绿色样式
            CellStyle redStyle = ExcelUtil.getColorStyle(wb, IndexedColors.RED.index); // 红色样式
            CellStyle blueStyle = ExcelUtil.getColorStyle(wb, IndexedColors.BLUE.index); // 红色样式
            HSSFRow row = null;
            int rowIndex = 2;
            for (HuifuWalletAccountDetail result : detailList) {
                row = sheet1.createRow(rowIndex);
                HSSFCell cell0 = row.createCell(0);
                cell0.setCellValue(rowIndex - 1);
                HSSFCell cell1 = row.createCell(1);
                cell1.setCellValue(result.getTradeFlowNo() != null ? result.getTradeFlowNo().toString() : null); // 交易流水号
                HSSFCell cell1_2 = row.createCell(2);
                cell1_2.setCellValue(result.getFlowNo() != null ? result.getFlowNo().toString() : null); // 业务流水号
                HSSFCell cell2 = row.createCell(3);
                cell2.setCellValue(result.getTradeType() != null ? result.getTradeType().toString() : null); // 银行交易类型
                HSSFCell cell3 = row.createCell(4);
                cell3.setCellValue(result.getHandStatus() != null ? result.getHandStatus().toString() : null); // 交易状态
                if (ObjectUtil.equal(result.getHandStatus(), "成功")) {
                    cell3.setCellStyle(greenStyle);
                } else if (ObjectUtil.equal(result.getHandStatus(), "失败")) {
                    cell3.setCellStyle(redStyle);
                } else {
                    cell3.setCellStyle(blueStyle);
                }
                HSSFCell cell4 = row.createCell(5);
                cell4.setCellValue(result.getCreateDate() != null ? result.getCreateDate().toString() : null); // 交易订单创建时间
                HSSFCell cell5 = row.createCell(6);
                cell5.setCellValue(result.getAmount() != null ? result.getAmount().toString() : null); // 交易金额
                cell5.setCellStyle(redStyle);
                HSSFCell cell5_7 = row.createCell(7);
                cell5_7.setCellValue(result.getBalance() != null ? result.getBalance().toString() : null); // 交易后余额
                HSSFCell cell6 = row.createCell(8);
                cell6.setCellValue(result.getAccountOutName() != null ? result.getAccountOutName().toString() : null);// 出账方户名
                HSSFCell cell7 = row.createCell(9);
                cell7.setCellValue(result.getAccountOut() != null ? result.getAccountOut().toString() : null);// 出账方账号
                HSSFCell cell8 = row.createCell(10);
                cell8.setCellValue(result.getAccountInName() != null ? result.getAccountInName().toString() : null);// 入账方户名
                HSSFCell cell9 = row.createCell(11);
                cell9.setCellValue(result.getAccountIn() != null ? result.getAccountIn().toString() : null);// 入账方账号
                HSSFCell cell10 = row.createCell(12);
                cell10.setCellValue(result.getTradeDate() != null ? result.getTradeDate().toString() : null);// 入账方银行
                HSSFCell cell11 = row.createCell(13);
                cell11.setCellValue(result.getAccountsDealDate() != null ? result.getAccountsDealDate().toString() : null);// 入账方证件号
                HSSFCell cell12 = row.createCell(14);
                cell12.setCellValue(result.getMemo() != null ? result.getMemo().toString() : null);// 备注
                HSSFCell cell13 = row.createCell(15);
                cell13.setCellValue(result.getPayChannel() != null ? result.getPayChannel().toString() : null);// 备注
                rowIndex++;
            }
            wb.write(os);
            os.close();
            wb.close();
        } catch (Exception e) {
            throw new CrmebWalletException(e.getMessage());
        } finally {
            try {
                os.close();
                wb.close();
            } catch (IOException e1) {
            }
        }
        return "0";
    }

    /**
     * 获取企业钱包账户交易明细 TODO 依据账务流水生成收支明细 当天生成前一天的数据
     * @return
     */
    @Override
    public String huifuWalletAccountTradeDetailSch() {
        return huifuWalletAccountTradeDetailTask("","");
    }

    /**
     * 获取企业钱包账户交易明细 账务
     *
     * @return
     * @author lp
     * @date 2019-12-09
     */
    @Override
    public String huifuWalletAccountTradeDetailTask(String startDate, String endDate) {
        if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
            startDate = DateUtil.formatDate(DateUtil.yesterday());
            endDate = DateUtil.formatDate(DateUtil.date());
        }
        //昨天、今天产生交易记录的交易双方账户信息
        List<HuifuWalletAccountDto> accountList = huifuWalletAccountDao.getLastDayTradeHuifuWalletAccount(startDate+" 00:00:00",endDate+" 23:59:59",PaymentChannel.HUIFU.toString());
        Map<String,String> kvMap = Maps.newHashMap();
        for (HuifuWalletAccountDto dto:accountList) {
            kvMap.put(dto.getWalletAccountNo(),dto.getComName());
        }
        List<HuifuWalletAccountDetailDto> detailList = Lists.newArrayList();

        /*  需要剔除掉已经存在的，防止重复下载 */
        List<String> existsFlowNoList = huifuWalletAccountDetailDao.selectFlowNoByDate(startDate.replace("-",""), endDate.replace("-",""),PaymentChannel.HUIFU.toString());

        for (HuifuWalletAccountDto account : accountList) {
            int pageNumber = 1;
            while (true) {
                try{
                    /* 调用支付平台接口获取账户交易明细 ***/
                    Map<String, Object> p = new HashMap<>();
                    p.put("huifuId", account.getWalletAccountNo());
                    p.put("reqSeqId", SequenceTools.getReqSeqId32());
                    p.put("acctDate", startDate.replace("-",""));
                    p.put("pageNum", pageNumber);
                    p.put("pageSize", 100);
                    Map<String, Object> response;
                    HFBusiCode hFBusiCode;
                    try {
                        hFBusiCode = HFBusiCode.CWQUERY;
                        response = V2ApiRequest.api(hFBusiCode,p);
                    }catch (Exception e){
                        transactionLogService.save("huifuWalletAccountTradeDetailTask",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
                        throw new CrmebWalletException(e.getMessage());
                    }

                    if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
                        transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                        if (StringUtils.isEmpty(response.get("result_count").toString()) || Integer.parseInt(response.get("result_count").toString()) == 0) {
                            break;
                        }
                        /*** 解析返回的列表数据 ***/
                        ArrayList<Map> recordlist = JSON.parseObject(response.get("acct_log_list").toString(),
                                new TypeReference<ArrayList<Map>>() {
                                });
                        for (Map<String, Object> record : recordlist) {
                            HuifuWalletAccountDetailDto detail = packHuifuWalletAccountDetail(record,kvMap);
                            detail.setUniId(account.getUniId());
                            detail.setWalletAccountNo(account.getWalletAccountNo());
                            detail.setPayChannel(PaymentChannel.HUIFU.toString());
                            /* 记录不存在才允许进行添加 */
                            if (!existsFlowNoList.contains(detail.getTradeFlowNo()+account.getUniId())) {
                                detailList.add(detail);
                            }
                        }
                        /* 如果记录数小于100 说明没有下一页了*/
                        if (recordlist.size() < 100) {
                            break;
                        }
                        pageNumber++;
                    }else{
                        transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                        log.error(RET(response,2));
                        /* 如果返回数据异常，则直接循环下一个钱包数据 */
                        break;
                    }
                }catch (Exception e){
                    break;
                }
            }
        }
        /* 数据为空，则下面不需要执行了 */
        if (CollectionUtil.isEmpty(detailList)) {
            return "1";
        }
        /* 批量插入数据 */
        huifuWalletAccountDetailDao.insertBatch(detailList);
        return "1";
    }

    @Override
    public void updateBalance(String startDate, String endDate) {
        if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
            startDate = DateUtil.formatDate(DateUtil.yesterday());
            endDate = DateUtil.formatDate(DateUtil.date());
        }
        //昨天、今天产生交易记录的交易双方账户信息
        List<HuifuWalletAccountDto> accountList = huifuWalletAccountDao.getLastDayTradeHuifuWalletAccount(startDate+" 00:00:00",endDate+" 23:59:59",PaymentChannel.HUIFU.toString());

        for (HuifuWalletAccountDto account : accountList) {
            int pageNumber = 1;
            while (true) {
                try{
                    /* 调用支付平台接口获取账户交易明细 ***/
                    Map<String, Object> p = new HashMap<>();
                    p.put("huifuId", account.getWalletAccountNo());
                    p.put("reqSeqId", SequenceTools.getReqSeqId32());
                    p.put("acctDate", startDate.replace("-",""));
                    p.put("pageNum", pageNumber);
                    p.put("pageSize", 100);
                    Map<String, Object> response;
                    HFBusiCode hFBusiCode;
                    try {
                        hFBusiCode = HFBusiCode.CWQUERY;
                        response = V2ApiRequest.api(hFBusiCode,p);
                    }catch (Exception e){
                        transactionLogService.save("huifuWalletAccountTradeDetailTask",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
                        log.error(e.getMessage());
                        break;
                    }

                    if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
                        transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                        if (StringUtils.isEmpty(response.get("result_count").toString()) || Integer.parseInt(response.get("result_count").toString()) == 0) {
                            break;
                        }
                        /*** 解析返回的列表数据 ***/
                        ArrayList<Map> recordlist = JSON.parseObject(response.get("acct_log_list").toString(),
                                new TypeReference<ArrayList<Map>>() {
                                });
                        for (Map<String, Object> record : recordlist) {
                            huifuWalletAccountDetailDao.updateBalance(account.getUniId(),record.get("hf_seq_id").toString(),record.get("balance_amt").toString());
                        }
                        /* 如果记录数小于100 说明没有下一页了*/
                        if (recordlist.size() < 100) {
                            break;
                        }
                        pageNumber++;
                    }else{
                        transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                        log.error(RET(response,2));
                        /* 如果返回数据异常，则直接循环下一个钱包数据 */
                        break;
                    }
                }catch (Exception e){
                    break;
                }
            }
        }
    }

    /**
     * <b> 余额支付交易分账明细查询 定时任务 TODO 实时依据余额支付接口生成收支明细 </b>
     * @author ZXF
     * @create 2023/11/13 0013 23:31
     * @version
     * @注意事项 </b>
     */
    @Override
    public void payTradeDetailTaskSch() {
//        查询所有未生成明细的单子
        List<Map<String, String>> list = huifuWalletTradeDao.findHuifuWalletTradeByDay(PaymentChannel.HUIFU.toString());
        for (Map<String, String> map:list) {
            getPayTradeDetailTask(map.get("uniId"),map.get("accountNo"),map.get("hfSeqId"),map.get("tradeDate"));
        }
    }

    @Async
    @Override
    public void getPayTradeDetailTask(String uniId,String accountNo,String hfSeqId,String tradeDate) {
        String lockId = SCHKEY+hfSeqId;
        RLock lock = redisson.getLock(lockId);
        try {
            if(lock.tryLock(3,10, TimeUnit.SECONDS)){
                logger.debug(lockId+":getLock: " + Thread.currentThread().getId());
                HuifuWalletAccountDto aDto = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(accountNo);
                //如果已经存在就结束
                int cf = huifuWalletAccountDetailDao.checkFlowNo(hfSeqId,aDto.getUniId());
                if(cf>0){
                    return;
                }
                /* 调用支付平台接口获取账户交易明细 ***/
                Map<String, Object> p = new HashMap<>();
                p.put("huifuId", accountNo);
                p.put("hfSeqId", hfSeqId);
                p.put("OrgReqDate", tradeDate);
                Map<String, Object> response;
                HFBusiCode hFBusiCode;
                try {
                    hFBusiCode = HFBusiCode.APQUERY;
                    response = V2ApiRequest.api(hFBusiCode,p);
                }catch (Exception e){
                    transactionLogService.save("payTradeDetailTask",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
                    throw new CrmebException(e.getMessage());
                }

                if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
                    transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                    HuifuWalletTrade huifuWalletTrade = huifuWalletTradeDao.getHuifuWalletTradeByHfSeqId(hfSeqId);
                    List<HuifuWalletAccountDetailDto> detailList = Lists.newArrayList();
                    HuifuWalletAccountDetailDto detail = new HuifuWalletAccountDetailDto();
                    detail.setUniId(huifuWalletTrade.getUniId());
                    detail.setWalletAccountNo(accountNo);

                    String splitType = response.get("delay_acct_flag").toString();
                    detail.setTradeDate(response.get("org_req_date").toString()); // 交易时间
                    detail.setTradeFlowNo(response.get("org_hf_seq_id").toString()); // 交易流水号
                    detail.setFlowNo(huifuWalletTrade.getBusinessPartnerSeq()); // 汇付交易订单号
                    detail.setAccountsDealType("内部户处理"); //账务处理类型
                    detail.setAccountsDealDate(response.get("trans_finish_time").toString());// 账务处理时间
                    detail.setAmount(response.get("ord_amt").toString()); // 交易金额
//                    detail.setBalance(response.get("balance_amt").toString()); // 交易后余额,工行没有交易后余额的数据
                    detail.setDirection("出账"); // 资金流向
                    String transStat = response.get("trans_stat").toString();
                    transStat = transStat.equals("S")?"成功":transStat.equals("F")?"失败":"处理中";
                    detail.setHandStatus(transStat); // 处理状态
                    String tradeType = StringUtils.isNotEmpty(huifuWalletTrade.getRemark())&&huifuWalletTrade.getRemark().contains("退款")?"反向交易":"正向交易";
                    detail.setTradeType(tradeType); // 交易类型
                    detail.setCreateDate(DateUtils.formatDate(huifuWalletTrade.getCreateTime(),"yyyy-MM-dd HH:mm:ss")); // 订单创建时间
                    detail.setServiceType("N".equals(splitType)?"实时":"延时"); // 服务类型
                    detail.setAccountIn(huifuWalletTrade.getIncomeAccountNo());// 收款方账户
                    detail.setAccountOut(response.get("out_huifu_id").toString());// 付款方账户
                    detail.setMemo(response.get("remark").toString()); // 备注
                    detail.setPayChannel(aDto.getPayChannel());
                    HuifuWalletAccountDto accountIn = null;
                    HuifuWalletAccountDto accountOut = null;
                    if (StringUtil.isEmpty(detail.getAccountIn())) {
                        detail.setAccountInName("无");// 收款方账户
                    } else {
                        accountIn = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(detail.getAccountIn());
                        detail.setAccountInName(StringUtils.isEmpty(accountIn.getComName()) ? "无" : accountIn.getComName()); // 收款方账户中文
                    }
                    if (StringUtil.isEmpty(detail.getAccountOut())) {
                        detail.setAccountOutName("无"); // 付款方账户
                    } else {
                        accountOut = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(detail.getAccountOut());
                        detail.setAccountOutName(StringUtils.isEmpty(accountOut.getComName()) ? "无" : accountOut.getComName()); // 付款方账户中文
                    }

                    if(accountOut!=null && accountIn!=null){//转账
                        int count = huifuWalletAccountDetailDao.checkFlowNo(detail.getTradeFlowNo(),detail.getUniId());
                        if(count==0){
                            detailList.add(detail);
                        }
                        HuifuWalletAccountDetailDto detail2 = new HuifuWalletAccountDetailDto();
                        BeanUtils.copyProperties(detail,detail2);
                        detail2.setUniId(accountIn.getUniId());
                        detail2.setWalletAccountNo(accountIn.getWalletAccountNo());
                        detail2.setDirection("入账"); // 资金流向
                        count = huifuWalletAccountDetailDao.checkFlowNo(detail2.getTradeFlowNo(),detail2.getUniId());
                        if(count==0){
                            detailList.add(detail2);
                        }
                    }else if(accountOut!=null && accountIn==null){//提现
                        int count = huifuWalletAccountDetailDao.checkFlowNo(detail.getTradeFlowNo(),detail.getUniId());
                        if(count==0){
                            detailList.add(detail);
                        }
                    }else if(accountIn!=null && accountOut==null){//充值
                        detail.setDirection("入账"); // 资金流向
                        int count = huifuWalletAccountDetailDao.checkFlowNo(detail.getTradeFlowNo(),detail.getUniId());
                        if(count==0){
                            detailList.add(detail);
                        }
                    }
                    if(detailList.size()>0){
                        /* 批量插入数据 */
                        huifuWalletAccountDetailDao.insertBatch(detailList);
                    }
                }else{
                    transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                    logger.error(RET(response,2));
                }
            }
        } catch (InterruptedException e) {
            logger.error("huifuWalletRechargeCallback error", e);
        }finally {
            if (lock.isHeldByCurrentThread()) {
                logger.debug(lockId+":unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }
    }

    /**
     * 交易分账明细查询接口（废弃）
     *
     * @param accountNo 商户号
     * @param hfSeqId 全局流水号
     * @param ordType 交易类型 0反向1正向
     * @return
     * @author lp
     * @date 2019-12-09
     */
    @Override
    public void tradeDetailTask(String accountNo,String hfSeqId,int ordType) throws CrmebWalletException {
        try{
            /* 调用支付平台接口获取账户交易明细 ***/
            Map<String, Object> p = new HashMap<>();
            p.put("huifuId", accountNo);
            p.put("hfSeqId", hfSeqId);
            p.put("ordType", ordType == 1?"consume":"refund");
            Map<String, Object> response;
            HFBusiCode hFBusiCode;
            try {
                hFBusiCode = HFBusiCode.JYFZQUERY;
                response = V2ApiRequest.api(hFBusiCode,p);
            }catch (Exception e){
                transactionLogService.save("tradeDetailTask",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
                throw new CrmebWalletException(e.getMessage());
            }

            if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                if (StringUtils.isEmpty(response.get("total_size").toString()) || Integer.parseInt(response.get("total_size").toString()) == 0) {
                    return;
                }
                /*** 解析返回的列表数据 ***/
                ArrayList<Map> recordlist = JSON.parseObject(response.get("split_trans_responses").toString(),
                        new TypeReference<ArrayList<Map>>() {
                        });
                HuifuWalletTrade huifuWalletTrade = huifuWalletTradeDao.getHuifuWalletTradeByHfSeqId(hfSeqId);
                List<HuifuWalletAccountDetailDto> detailList = Lists.newArrayList();
                for (Map<String, Object> record : recordlist) {
                    HuifuWalletAccountDetailDto detail = new HuifuWalletAccountDetailDto();
                    detail.setUniId(huifuWalletTrade.getUniId());
                    detail.setWalletAccountNo(accountNo);

                    String direction = record.get("ord_type").toString();
                    String splitType = record.get("split_type").toString();
                    detail.setTradeDate(record.get("req_date").toString()); // 交易时间
                    detail.setTradeFlowNo(record.get("hf_seq_id").toString()); // 交易流水号
                    detail.setFlowNo(record.get("trans_ord_id").toString()); // 汇付交易订单号
                    detail.setAccountsDealType("内部户处理"); //账务处理类型
                    detail.setAccountsDealDate(record.get("trans_finish_time").toString());// 账务处理时间
                    detail.setAmount(record.get("split_amt").toString()); // 交易金额
//                    detail.setBalance(record.get("balance_amt").toString()); // 交易后余额,工行没有交易后余额的数据
                    detail.setDirection("consume".equals(direction)?"出账":"入账"); // 资金流向
                    detail.setHandStatus("成功"); // 处理状态
                    detail.setTradeType("consume".equals(direction)?"正向交易":"反向交易"); // 交易类型
                    detail.setCreateDate(DateUtils.formatDate(huifuWalletTrade.getCreateTime(),"yyyy-MM-dd HH:mm:ss")); // 订单创建时间
                    detail.setServiceType("realTime".equals(splitType)?"实时":"延时"); // 服务类型
                    detail.setAccountIn(record.get("in_huifu_id").toString());// 收款方账户
                    detail.setAccountOut(record.get("huifu_id").toString());// 付款方账户
                    detail.setPayChannel(huifuWalletTrade.getPayChannel());
                    if (StringUtil.isEmpty(detail.getAccountIn())) {
                        detail.setAccountInName("无");// 收款方账户
                    } else {
                        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(detail.getAccountIn());
                        detail.setAccountInName(StringUtils.isEmpty(account.getComName()) ? "无" : account.getComName()); // 收款方账户中文
                    }
                    if (StringUtil.isEmpty(detail.getAccountOut())) {
                        detail.setAccountOutName("无"); // 付款方账户
                    } else {
                        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(detail.getAccountOut());
                        detail.setAccountOutName(StringUtils.isEmpty(account.getComName()) ? "无" : account.getComName()); // 付款方账户中文
                    }
                    detail.setMemo(huifuWalletTrade.getRemark()); // 备注
                    int count = huifuWalletAccountDetailDao.checkFlowNo(detail.getTradeFlowNo(),detail.getUniId());
                    /* 记录不存在才允许进行添加 */
                    if (count>0) {
                        detailList.add(detail);
                    }
                }
                if(detailList.size()>0){
                    /* 批量插入数据 */
                    huifuWalletAccountDetailDao.insertBatch(detailList);
                }
            }else{
                transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                log.error(RET(response,2));
            }
        }catch (Exception e){
            throw new CrmebWalletException(e.getMessage());
        }
    }


    private HuifuWalletAccountDetailDto packHuifuWalletAccountDetail(Map<String, Object> record,Map<String,String> kvMap) {
        String direction = record.get("debit_type").toString();
        HuifuWalletAccountDetailDto detail = new HuifuWalletAccountDetailDto();
        detail.setTradeDate(record.get("trans_date_time").toString()); // 交易时间
        detail.setTradeFlowNo(record.get("hf_seq_id").toString()); // 交易流水号
        detail.setFlowNo(record.get("acct_log_id").toString()); // 账务流水号（业务流水号）
        detail.setAccountsDealType("内部户处理"); //账务处理类型
        detail.setAccountsDealDate(record.get("acct_date").toString());// 账务处理时间
        detail.setAmount(record.get("trans_amt").toString()); // 交易金额
        detail.setBalance(record.get("balance_amt").toString()); // 交易后余额,工行没有交易后余额的数据
        detail.setDirection("D".equals(direction)?"出账":"入账"); // 资金流向
        detail.setHandStatus("成功"); // 处理状态
        detail.setTradeType(record.get("acct_trans_type").toString()); // 交易类型
//        detail.setCreateDate(DateUtils.formatDate(huifuWalletTrade.getCreateTime(),null)); // 订单创建时间
//        detail.setServiceType(record.get("acct_trans_type").toString()); // 服务类型
//        detail.setTradeType(huifuWalletTrade.getTradeType()); // 交易类型
//        detail.setAccountIn(huifuWalletTrade.getIncomeAccountNo());// 收款方账户
//        detail.setAccountOut(huifuWalletTrade.getExpendAccountNo());// 付款方账户
//        if (StringUtil.isEmpty(huifuWalletTrade.getIncomeAccountNo())) {
//            detail.setAccountInName("无");// 收款方账户
//        } else {
//            String fullName = kvMap.get(huifuWalletTrade.getIncomeAccountNo());
//            detail.setAccountInName(StringUtils.isEmpty(fullName) ? "无" : fullName); // 收款方账户中文
//        }
//        if (StringUtil.isEmpty(huifuWalletTrade.getExpendAccountNo())) {
//            detail.setAccountOutName("无"); // 付款方账户
//        } else {
//            String fullName = kvMap.get(huifuWalletTrade.getExpendAccountNo());
//            detail.setAccountOutName(StringUtils.isEmpty(fullName) ? "无" : fullName); // 付款方账户中文
//        }
//        detail.setMemo(huifuWalletTrade.getRemark()); // 备注
        return detail;
    }

    /**
     * 获取企业钱包充值token
     *
     * @param dto
     * @return
     * @author llc
     * @date 2019-06-21
     */
    @Override
    public String getWalletRechargeToken(HuifuWalletAccountDto dto) throws CrmebWalletException {
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("ID不能为空");
        }
        if (StringUtil.isEmpty(dto.getWalletAccountNo())) {
            throw new CrmebWalletException("企业钱包账户号不能为空");
        }
        if (dto.getAmount() == null) {
            throw new CrmebWalletException("金额不能为空");
        }
        if (dto.getAmount().compareTo(new BigDecimal(HFProfileConstants.RECHARGE_HANDLING_FEE_MIN)) < 1) {
            throw new CrmebWalletException("金额必须大于"+HFProfileConstants.RECHARGE_HANDLING_FEE_MIN+"元");
        }
        //当前每次充值都扣客户手续费
        BigDecimal fzAmt = new BigDecimal(HFProfileConstants.RECHARGE_HANDLING_FEE_MIN);
        //手续费 定义：大于5000时分账给企业不扣除手续费，小于5000时分账给企业要先扣8块的手续费
//        BigDecimal fzAmt = BigDecimal.ZERO;
//        if (dto.getAmount().compareTo(new BigDecimal(HFProfileConstants.RECHARGE_HANDLING_FEE_MAX)) < 0) {
//            fzAmt = new BigDecimal(HFProfileConstants.RECHARGE_HANDLING_FEE_MIN);
//        }
        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(dto.getWalletAccountNo());
        Map<String, Object> p = new HashMap<>();
        p.put("acctId", dto.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("transAmt", decimalFormat.format(dto.getAmount())); // 金额
        p.put("divAmt", decimalFormat.format(dto.getAmount().subtract(fzAmt))); // 分账金额（充值金额-手续费）
        p.put("bankId", "");
//        p.put("bankId", account.getBankCode());
        p.put("goodsDesc", "账户余额充值");
        p.put("orderType", "P");//订单类型P：支付，R：充值，默认：P（支付）；
        p.put("frontUrl", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_KEY_FRONT_PAY_CALLBACK_URL)+HFConstants.PAYWALLET_SUCCESS);// 回调页面
        p.put("notifyUrl", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_HF_API_URL)+HFConstants.RECHARGE_CALLBACK); // 回调接口

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.WYPAY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("getWalletRechargeToken",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
            huifuWalletTrade.setUniId(account.getUniId());
            huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
            huifuWalletTrade.setIncomeAccountNo(account.getWalletAccountNo());
            huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
            huifuWalletTrade.setAmount(new BigDecimal(response.get("trans_amt").toString()));
            huifuWalletTrade.setGoodDesc("余额+"+response.get("trans_amt")+"元");
            huifuWalletTrade.setRemark("账户余额充值（手续费"+decimalFormat.format(fzAmt)+"元）");
            huifuWalletTrade.setErrorMsg(RET(response,2));
            huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString()));
            huifuWalletTrade.setTradeType(Constants.TRADETYPE_QYZHCZ);
            huifuWalletTrade.setCreateTime(new Date());
            huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
            /*** 更新企业钱包账户交易记录 ***/
            huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
            //返回汇付收银台访问地址
            return response.get("form_url").toString();
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    /**
     * 企业钱包充值回调
     *
     * @param dto
     * @return
     * @author llc
     * @date 2019-06-28
     */
    @Override
    public String huifuWalletRechargeCallback(HuifuRequestDataDto dto) {
        transactionLogService.save("huifuWalletRechargeCallback",Constants.Y, JSON.toJSONString(dto),"ok",PaymentChannel.HUIFU.toString());
        if(!HFConstants.REQUEST_SUCC_CODE.equals(dto.getResp_code())){
            return "";
        }
        // 使用汇付公钥验签
        if (!RsaUtils.verify(dto.getData(), HFProfileConstants.RSA_PUBLIC_KEY, dto.getSign())) {
            logger.info("企业钱包充值回调，异步回调开始，fail=验签失败");
            // 验签失败处理
            return "";
        }
        Map<String, Object> response = JSON.parseObject(dto.getData(), Map.class);
        String status = Constants.tradeStatus(response.get("trans_stat").toString());

        String reqSeqId = response.get("req_seq_id").toString();
        String lockId = TRANSFERKEY+reqSeqId;
        RLock lock = redisson.getLock(lockId);
        try {
            if(lock.tryLock(3,10, TimeUnit.SECONDS)){
                logger.debug(lockId+":getLock: " + Thread.currentThread().getId());
                HuifuWalletTrade huifuWalletTrade = huifuWalletTradeDao.getHuifuWalletTradeByHfSeqId(response.get("hf_seq_id").toString());
                if(status.equals(huifuWalletTrade.getTradeStatus())){
                    return "RECV_ORD_ID_"+huifuWalletTrade.getHfSeqId();
                }
                Boolean execute = transactionTemplate.execute(e -> {
                    huifuWalletTrade.setTransFinishTime(response.get("trans_date")+""+response.get("trans_time"));
                    huifuWalletTrade.setErrorMsg(RET(response,2));
                    huifuWalletTrade.setTradeStatus(status);
                    huifuWalletTrade.setUpdateTime(new Date());
                    /*** 更新企业钱包账户交易记录 ***/
                    huifuWalletTradeDao.updateHuifuWalletTrade(huifuWalletTrade);
                    logger.info("企业钱包充值回调，异步回调开始，succ2={},errorMsg={}", reqSeqId, huifuWalletTrade.getErrorMsg());
                    return Boolean.TRUE;
                });
                if (!execute) {
                    logger.error("企业钱包充值回调，异步回调入库失败，request={}", response.get("resp_data").toString());
                    return "";
                }
                return "RECV_ORD_ID_" + reqSeqId;
            }else{
                return "";
            }
        } catch (InterruptedException e) {
            logger.error("huifuWalletRechargeCallback error", e);
            return "";
        }finally {
            if (lock.isHeldByCurrentThread()) {
                logger.debug(lockId+":unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }
    }

    /**
     * 企业钱包提现回调
     *
     * @param messageBody
     * @return
     * @author llc
     * @date 2019-06-28
     */
    @Override
    public String huifuWalletExtractCallback(String messageBody) {
        Map<String, Object> response = pathToJson(messageBody);
        logger.info("企业钱包提现回调，异步回调开始，参数，response={}", response.toString());
        transactionLogService.save("huifuWalletExtractCallback", Constants.Y, response.toString(), "ok",PaymentChannel.HUIFU.toString());
        if (!HFConstants.REQUEST_SUCC_CODE.equals(response.get("resp_code").toString())) {
            return "ok";
        }
        // 验签请参sign
        String sign = response.get("sign").toString();
        // 使用汇付公钥验签
        if (!RsaUtils.verify(response.get("resp_data").toString(), HFProfileConstants.RSA_PUBLIC_KEY, sign)) {
            logger.info("企业钱包提现回调，异步回调开始，fail=验签失败");
            // 验签失败处理
            return "";
        }
        JSONObject dataObj = JSON.parseObject(response.get("resp_data").toString());
        String reqSeqId = dataObj.getString("req_seq_id");
        String lockId = TRANSFERKEY+reqSeqId;
        RLock lock = redisson.getLock(lockId);
        try {
            if(lock.tryLock(3,10, TimeUnit.SECONDS)){
                logger.debug(lockId+":getLock: " + Thread.currentThread().getId());
                HuifuWalletTrade huifuWalletTrade = huifuWalletTradeDao.getHuifuWalletTradeByHfSeqId(dataObj.get("hf_seq_id").toString());
                // 支付成功记录已存在
                if (Constants.TRADESTATUS_JYCG.equals(huifuWalletTrade.getTradeStatus())) {
                    logger.info("企业钱包提现回调，异步回调开始，succ1={}", reqSeqId);
                    return "RECV_ORD_ID_" + reqSeqId;
                }
                Boolean execute = transactionTemplate.execute(e -> {
                    huifuWalletTrade.setTransFinishTime(dataObj.get("req_date").toString());
                    huifuWalletTrade.setErrorMsg(RET(response,2));
                    huifuWalletTrade.setTradeStatus(Constants.tradeStatus(dataObj.get("trans_stat").toString()));
                    huifuWalletTrade.setUpdateTime(new Date());
                    /*** 更新企业钱包账户交易记录 ***/
                    huifuWalletTradeDao.updateHuifuWalletTrade(huifuWalletTrade);
                    logger.info("企业钱包提现回调，异步回调开始，succ2={},errorMsg={}", reqSeqId, huifuWalletTrade.getErrorMsg());
                    return Boolean.TRUE;
                });
                if (!execute) {
                    logger.error("企业钱包提现回调，异步回调入库失败，request={}", response.get("resp_data").toString());
                    return "";
                }
                return "RECV_ORD_ID_" + reqSeqId;
            }else{
                return "";
            }
        } catch (InterruptedException e) {
            logger.error("huifuWalletExtractCallback error", e);
            return "";
        }finally {
            if (lock.isHeldByCurrentThread()) {
                logger.debug(lockId+":unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }
    }

    private Map<String, Object> pathToJson(String urlData){
        String data = null;
        try {
            data = URLDecoder.decode(urlData, "UTF-8");
        }catch (Exception e){
            logger.error("解码失败：{}", e);
        }
        Map<String, Object> collect = Arrays.stream(data.split("&"))
                .map(str -> str.split("="))
                .collect(Collectors.toMap(x -> x[0], x -> x.length == 2 ? x[1] : "",
                        (u, v) -> {
                            throw new IllegalStateException(String.format("Duplicate key %s", u));
                        }, LinkedHashMap::new));
        return collect;
    }

    /**
     * 企业钱包查询交易流水记录
     *
     * @param huifuWalletTrade
     * @return
     * @author llc
     * @date 2019-06-28
     */
    @Override
    public HuifuWalletTrade getWalletTradeInfo(HuifuWalletTrade huifuWalletTrade) throws CrmebWalletException {
        if (huifuWalletTrade.getId() == null) {
            throw new CrmebWalletException("企业钱包交易流水号不能为空");
        }
        /*** 查询企业钱包交易信息 ***/
        huifuWalletTrade = huifuWalletTradeDao.getHuifuWalletTradeById(huifuWalletTrade.getId());
        return huifuWalletTrade;
    }

    /**
     * <b> 根据业务编码或业务交易流水号查询交易信息 </b>
     * @author ZXF
     * @create 2023/03/23 0023 10:20
     * @version
     * @注意事项 </b>
     */
    @Override
    public List<HuifuWalletTrade> getHuifuWalletTradeBySeqAndCode(HuifuWalletTrade huifuWalletTrade) throws CrmebWalletException {
        if (huifuWalletTrade.getBusinessCode() == null) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        /*** 查询企业钱包交易信息 ***/
        List<HuifuWalletTrade> list = huifuWalletTradeDao.getHuifuWalletTradeBySeqAndCode(huifuWalletTrade);
        return list;
    }


    /**
     * 企业钱包账户提现
     *
     * @param dto
     * @return
     * @author llc
     * @date 2019-06-21
     */
    @Override
    public String huifuWalletAccountExtract(HuifuWalletAccountDto dto) throws CrmebWalletException {
        Date date = new Date();
        if (StringUtil.isEmpty(dto.getWalletAccountNo())) {
            throw new CrmebWalletException("企业钱包账户号不能为空");
        }
        if (StringUtil.isEmpty(dto.getIntoAcctDateType())) {
            throw new CrmebWalletException("到账日期类型不能为空");
        }
        if (dto.getAmount() == null) {
            throw new CrmebWalletException("金额不能为空");
        }
        if("D0".equals(dto.getIntoAcctDateType())){
            //D0需要手续费，所以金额必须大于0.01元
            if (dto.getAmount().compareTo(new BigDecimal("0.01")) < 1) {
                throw new CrmebWalletException("金额必须大于0.01元");
            }
        }else {
            if (dto.getAmount().compareTo(BigDecimal.ZERO) < 1) {
                throw new CrmebWalletException("金额必须大于0元");
            }
        }

        if (StringUtil.isEmpty(dto.getContactPhone())) {
            throw new CrmebWalletException("手机号不能为空");
        }
        if (StringUtil.isEmpty(dto.getActiveCode())) {
            throw new CrmebWalletException("短信验证码不能为空");
        }
        checkValidateCode(dto.getContactPhone(),dto.getActiveCode());

        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getUniId(),PaymentChannel.HUIFU.toString());
        //查询账户余额比对提现金额
        Map<String, String> map = getHuifuWalletAccountAmount(account);
        if(map != null && map.get("availableAmount")!=null){
            BigDecimal availableAmount = new BigDecimal(String.valueOf(map.get("availableAmount")));
            if (availableAmount.compareTo(dto.getAmount()) < 0) {
                throw new CrmebWalletException("提现金额不能大于可用余额");
            }
        }else {
            throw new CrmebWalletException("未读取到账户余额相关信息");
        }
        String cashAmt = decimalFormat.format(dto.getAmount());
        /* 调用支付平台接口钱包账户提现 ***/
        Map<String, Object> p = new HashMap<>();
        p.put("huifuId", account.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("cashAmt", cashAmt); // 金额
        p.put("intoAcctDateType", dto.getIntoAcctDateType()); //
        p.put("tokenNo", account.getTokenNo()); //
        p.put("notifyUrl", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_HF_API_URL)+HFConstants.EXTRACT_CALLBACK); //回调接口

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.ENCHASHMENT;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("huifuWalletAccountExtract",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                /* 插入企业钱包账户交易记录 ***/
                HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
                huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
                huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
                huifuWalletTrade.setCreateTime(date);
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setUniId(account.getUniId());
                huifuWalletTrade.setExpendAccountNo(account.getWalletAccountNo());
                huifuWalletTrade.setTransFinishTime(response.get("req_date").toString());
                huifuWalletTrade.setAmount(new BigDecimal(cashAmt));
                huifuWalletTrade.setGoodDesc("余额-"+cashAmt+"元");
                String sxf = "D0".equals(dto.getIntoAcctDateType())?HFProfileConstants.CASH_HANDLING_FEE:"0.00元";
                huifuWalletTrade.setRemark("账户余额提现（手续费"+sxf+"）");
                huifuWalletTrade.setErrorMsg(RET(response,2));
                huifuWalletTrade.setTradeType(Constants.TRADETYPE_QYZHTX); // 企业账户提现
                huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString()));
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);return Boolean.TRUE;
            });
            if (!execute) {
                throw new CrmebWalletException("企业钱包-提现-操作失败");
            }
            return "1";
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    @Override
    public String huifuWalletAccountExtractConfirm(HuifuWalletAccountDto dto) throws CrmebWalletException {
        return null;
    }

    @Override
    public Map<String, Object> executeReconcile(String tradeDate) throws CrmebWalletException {
        return null;
    }

    /**
     * <b> 企业账户金额 冻结 </b>
     * @author ZXF
     * @create 2023/11/10 0010 10:52
     * @version
     * @注意事项 </b>
     */
    @Override
    public String freeze(HuifuWalletTransferDto dto) throws CrmebWalletException {
        dto.setTradeType("04");
        return huifuWalletAccountLock(dto);
    }

    /**
     * <b> 企业账户金额 解冻 </b>
     * @author ZXF
     * @create 2023/11/10 0010 10:52
     * @version
     * @注意事项 </b>
     */
    @Override
    public String thaw(HuifuWalletTransferDto dto) throws CrmebWalletException {
        dto.setTradeType("05");
        return huifuWalletAccountLock(dto);
    }

    /**
     * 企业账户金额冻结/解冻
     *
     * @param dto
     * @return
     * @author lp
     * @date 2019-08-27
     */
    @Override
    public String huifuWalletAccountLock(HuifuWalletTransferDto dto) throws CrmebWalletException {
        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.param:"+JSON.toJSONString(dto));
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
//        String oldBusinessPartnerSeq = dto.getBusinessPartnerSeq();
        String businessPartnerSeq;
        String platBusinessPartnerSeq;

        if("05".equals(dto.getTradeType())) {
            Order order = orderService.getByOrderNo(dto.getBusinessPartnerSeq());
//            oldBusinessPartnerSeq = order.getPlatOrderNo();
            //校验：业务流水号必须能匹配到历史冻结的业务记录，否则判定未非法解冻操作
//            int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByOldReq(oldBusinessPartnerSeq, "04");
//            int countJSTrade = jsPayTradeDao.getJsPayTradeByOldReq(oldBusinessPartnerSeq, "04");
//            if (countTrade == 0 && countJSTrade == 0) {
//                throw new CrmebWalletException("未匹配到历史冻结业务，无法完成解冻，BusinessPartnerSeq="+dto.getBusinessPartnerSeq());
//            }

            businessPartnerSeq = order.getPlatOrderNo()+"Y"+dto.getBusinessPartnerSeq();
            platBusinessPartnerSeq = order.getPlatOrderNo()+"-P"+dto.getSellFeePriority()+"Y"+dto.getBusinessPartnerSeq();
            int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(businessPartnerSeq, dto.getTradeType());
            if (countTrade>0) {
                logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.交易已完成，请勿重复操作，BusinessPartnerSeq="+dto.getBusinessPartnerSeq());
                return "";
            }
            int isThaw = huifuWalletTradeDao.calculateTheThawingAmounByReq(order.getPlatOrderNo(), dto.getAmount(),"-P");
            if (isThaw == 0) {
                throw new CrmebWalletException("当前解冻金额超出剩余可解冻额度，无法完成解冻，BusinessPartnerSeq="+dto.getBusinessPartnerSeq());
            }
        }else{
            businessPartnerSeq = dto.getBusinessPartnerSeq();
            platBusinessPartnerSeq = businessPartnerSeq+"-P"+dto.getSellFeePriority();
            int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(businessPartnerSeq, dto.getTradeType());
            if (countTrade>0) {
                logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.交易已完成，请勿重复操作，BusinessPartnerSeq="+dto.getBusinessPartnerSeq());
                return "";
            }
        }
        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:2");
        boolean redisRepetition = redisUtil.getRedisRepetition(businessPartnerSeq);
        if (!redisRepetition) {
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }

        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:3");
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        HuifuWalletAccountDto inAccount;
        HuifuWalletAccountDto platAccount;
        String lockAmount;
        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            lockAmount = decimalFormat.format(new BigDecimal(dto.getPlatAmount()));
            dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }else{
            // 买方 -> 商家 -> 平台
            lockAmount = decimalFormat.format(new BigDecimal(dto.getAmount()).subtract(new BigDecimal(dto.getPlatAmount())));
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }
        if(inAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:4");
        //冻结/解冻业务逻辑判断，计算记录冻结金额并入库  TODO 现在钱冻结在入账方 所以冻结解冻都是对入账方金额处理
        //冻结/解冻金额 = 订单金额-平台费用
//        String lockAmount = decimalFormat.format(new BigDecimal(dto.getAmount()).subtract(new BigDecimal(dto.getPlatAmount())));
//        BigDecimal frozenAmount = extractedLock(dto.getInId(), dto.getTradeType(), lockAmount);
        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.frozenAmount:"+lockAmount);
        String finalBusinessPartnerSeq = businessPartnerSeq;
        String finalPlatBusinessPartnerSeq = platBusinessPartnerSeq;
        HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
        Boolean execute = transactionTemplate.execute(e -> {
            //更新冻结金额
            syncUpdateSumFrozenAmount(inAccount.getUniId(),"04".equals(dto.getTradeType())?(new BigDecimal(lockAmount)):"05".equals(dto.getTradeType())?(new BigDecimal("-"+lockAmount)):BigDecimal.ZERO);
//            huifuWalletAccountDao.updateFrozenAmount(dto.getInId(),frozenAmount.toString());
            logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:5");
            /* 插入企业钱包账户交易记录 ***/
            huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
            huifuWalletTrade.setBusinessPartnerSeq(finalBusinessPartnerSeq);
            huifuWalletTrade.setReqSeqId(SequenceTools.getReqSeqId32());
            huifuWalletTrade.setCreateTime(DateUtil.date());
            huifuWalletTrade.setUpdateTime(new Date());
            huifuWalletTrade.setGoodDesc(dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
            huifuWalletTrade.setTransFinishTime(DateUtils.getDateTime());
            huifuWalletTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
            huifuWalletTrade.setRemark(dto.getComment());
            huifuWalletTrade.setUniId(dto.getInId());
            huifuWalletTrade.setAmount(new BigDecimal(dto.getAmount()));
            huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
            huifuWalletTrade.setTradeStatus(Constants.TRADESTATUS_JYCG); // 交易成功
            huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
            huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
            logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:6");
            //平台分账业务
            if(Double.parseDouble(dto.getPlatAmount())>0){
                HuifuWalletTrade pTrade = new HuifuWalletTrade();
                BeanUtils.copyProperties(huifuWalletTrade,pTrade);
                //冻结/解冻业务逻辑判断，计算记录冻结金额并入库  TODO 现在钱冻结在入账方 所以冻结解冻都是对入账方金额处理
//                BigDecimal frozenPAmount = extractedLock(platAccount.getUniId(), dto.getTradeType(), dto.getPlatAmount());
                //更新冻结金额
                syncUpdateSumFrozenAmount(platAccount.getUniId(),"04".equals(dto.getTradeType())?(new BigDecimal(dto.getPlatAmount())):"05".equals(dto.getTradeType())?(new BigDecimal("-"+dto.getPlatAmount())):BigDecimal.ZERO);
//                huifuWalletAccountDao.updateFrozenAmount(platAccount.getUniId(),frozenPAmount.toString());
                pTrade.setAmount(new BigDecimal(dto.getPlatAmount()));
                pTrade.setReqSeqId(SequenceTools.getReqSeqId32());
                pTrade.setUniId(platAccount.getUniId());
                pTrade.setIncomeAccountNo(platAccount.getWalletAccountNo());
                pTrade.setRemark("订单【"+finalPlatBusinessPartnerSeq+"】支付平台服务费："+dto.getPlatAmount()+"元"+("05".equals(dto.getTradeType())?" 确认":""));
                pTrade.setBusinessPartnerSeq(finalPlatBusinessPartnerSeq);
                huifuWalletTradeDao.insertHuifuWalletTrade(pTrade);
                logger.info(">>>>>>>>> 企业账户金额冻结/解冻.huifuWalletAccountLock：接口请求7");
            }
            return Boolean.TRUE;
        });
        if (!execute) {
            logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:8");
            throw new CrmebWalletException("企业钱包-订单交易（D/J）-操作失败");
        }

        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:end");
        return huifuWalletTrade.getReqSeqId();
    }

    /**
     * (平台分账业务)企业账户金额冻结/解冻
     *
     * @param dto
     * @return
     * @author lp
     * @date 2019-08-27
     */
    @Override
    public String platHuifuWalletAccountLock(HuifuWalletTransferDto dto) throws CrmebWalletException {
        logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.param:"+JSON.toJSONString(dto));
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        String platBusinessPartnerSeq;
        logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.步骤:1");
        if("05".equals(dto.getTradeType())) {
            Order order = orderService.getByOrderNo(dto.getBusinessPartnerSeq());
            String businessPartnerSeq = order.getPlatOrderNo()+"-P"+dto.getSellFeePriority();
            platBusinessPartnerSeq = businessPartnerSeq+"Y"+dto.getBusinessPartnerSeq();
            //校验：业务流水号必须能匹配到历史冻结的业务记录，否则判定未非法解冻操作
//            int countTrade = huifuWalletTradeDao.getPlatHuifuWalletTradeByOldReq(dto.getBusinessPartnerSeq(),dto.getSellFeePriority(), "04");
//            if (countTrade == 0) {
//                throw new CrmebWalletException("未匹配到历史冻结业务，无法完成解冻");
//            }
            int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(platBusinessPartnerSeq, dto.getTradeType());
            if (countTrade>0) {
                logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.交易已完成，请勿重复操作，BusinessPartnerSeq="+platBusinessPartnerSeq);
                return "";
            }
            int isThaw = huifuWalletTradeDao.calculateTheThawingAmounByReq(businessPartnerSeq, dto.getAmount(),"");
            if (isThaw == 0) {
                throw new CrmebWalletException("当前解冻金额超出剩余可解冻额度，无法完成解冻，BusinessPartnerSeq="+platBusinessPartnerSeq);
            }
        }else{
            platBusinessPartnerSeq = dto.getBusinessPartnerSeq()+"-P"+dto.getSellFeePriority();
            int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(platBusinessPartnerSeq, dto.getTradeType());
            if (countTrade>0) {
                logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.交易已完成，请勿重复操作，BusinessPartnerSeq="+platBusinessPartnerSeq);
                return "";
            }
        }
        boolean redisRepetition = redisUtil.getRedisRepetition(platBusinessPartnerSeq);
        if (!redisRepetition) {
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }

        logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.步骤:3");
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        HuifuWalletAccountDto inAccount;
        HuifuWalletAccountDto platAccount;
        String lockAmount;
        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            lockAmount = decimalFormat.format(new BigDecimal(dto.getPlatAmount()));
            dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }else{
            // 买方 -> 商家 -> 平台
            lockAmount = decimalFormat.format(new BigDecimal(dto.getAmount()).subtract(new BigDecimal(dto.getPlatAmount())));
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }
        if(inAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.frozenAmount:"+lockAmount);
        //平台分账业务
        if(Double.parseDouble(dto.getPlatAmount())>0) {
            HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
            String finalPlatBusinessPartnerSeq = platBusinessPartnerSeq;
            Boolean execute = transactionTemplate.execute(e -> {
                /* 插入企业钱包账户交易记录 ***/
                huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
                huifuWalletTrade.setBusinessPartnerSeq(finalPlatBusinessPartnerSeq);
                huifuWalletTrade.setCreateTime(DateUtil.date());
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setGoodDesc(dto.getGoodsName() + "×" + dto.getGoodsNumber() + dto.getGoodsUnit());
                huifuWalletTrade.setTransFinishTime(DateUtils.getDateTime());
                huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                huifuWalletTrade.setTradeStatus(Constants.TRADESTATUS_JYCG); // 交易成功
                //更新冻结金额
                syncUpdateSumFrozenAmount(platAccount.getUniId(), "04".equals(dto.getTradeType()) ? (new BigDecimal(dto.getPlatAmount())) : "05".equals(dto.getTradeType()) ? (new BigDecimal("-" + dto.getPlatAmount())) : BigDecimal.ZERO);
                huifuWalletTrade.setAmount(new BigDecimal(dto.getPlatAmount()));
                huifuWalletTrade.setReqSeqId(SequenceTools.getReqSeqId32());
                huifuWalletTrade.setUniId(platAccount.getUniId());
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTrade.setIncomeAccountNo(platAccount.getWalletAccountNo());
                huifuWalletTrade.setRemark("订单【" + dto.getBusinessPartnerSeq() + "】支付平台服务费：" + dto.getPlatAmount() + "元"+("05".equals(dto.getTradeType()) ? " 确认":""));
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
                logger.info(">>>>>>>>> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock：接口请求7");
                return Boolean.TRUE;
            });
            if (!execute) {
                logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.步骤:8");
                throw new CrmebWalletException("企业钱包-订单交易（D/J）-操作失败");
            }
            return huifuWalletTrade.getReqSeqId();
        }
        logger.info("=======> (平台分账业务)企业账户金额冻结/解冻.platHuifuWalletAccountLock.步骤:end");
        return "";
    }

    /**
     * <b> 冻结/解冻业务逻辑判断，计算记录冻结金额并入库 </b>
     * @param uniId 被冻结企业id
     * @param tradeType 交易类型 04冻结05解冻
     * @param amount 交易金额
     * @author ZXF
     * @create 2023/03/31 0031 9:58
     * @version
     * @注意事项 </b>
     */
    @Override
    public BigDecimal extractedLock(String uniId, String tradeType, String amount) throws CrmebWalletException {

        //可用余额
        BigDecimal availableAmount;
        //冻结金额
        BigDecimal frozenAmount;
        //当前要操作金额
        BigDecimal updAmount = new BigDecimal(amount);
        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByUniId(uniId,PaymentChannel.HUIFU.toString());
        if(account == null){
            throw new CrmebWalletException("企业未开通钱包功能");
        }
        //查询账户余额比对提现金额
        Map<String,String> map = getHuifuWalletAccountAmount(account);
        if(map != null && map.get("availableAmount")!=null){
            frozenAmount = new BigDecimal(String.valueOf(map.get("frozenAmount")));
            availableAmount = new BigDecimal(String.valueOf(map.get("availableAmount")));
            if("04".equals(tradeType)){
                //冻结金额加 可用<变化 TODO 培训学校只增加冻结
//                if(availableAmount.compareTo(updAmount) < 0){
//                    throw new CrmebWalletException("钱包可用金额不足");
//                }
                frozenAmount = frozenAmount.add(updAmount);
            }else if("05".equals(tradeType)){
                if(frozenAmount.compareTo(updAmount) < 0){
                    throw new CrmebWalletException("金额划拨不对等，请联系管理员");
                }
                //付方冻结金额 减少
                frozenAmount = frozenAmount.subtract(updAmount);
            }else if("03".equals(tradeType)){
                if(availableAmount.compareTo(updAmount) < 0){
                    throw new CrmebWalletException("账户余额不足，无法确认支付，请充值或确认订单付款已账后再做确认。");
                }
            }
        }else {
            throw new CrmebWalletException("未读取到账户余额相关信息");
        }
        logger.info(">>>>>>>>> extractedLock.冻结账户uniId："+uniId+"，操作类型："+tradeType+"，原冻结金额："+map.get("frozenAmount")+"，现冻结金额："+frozenAmount);
        return frozenAmount;
    }

    /**
     * <b> 企业 转账+解冻 接口 </b>
     * @author ZXF
     * @create 2023/11/10 0010 11:02
     * @version
     * @注意事项 </b>
     */
    @Override
    public String payAndThaw(HuifuWalletTransferDto dto) throws CrmebWalletException {
        dto.setTradeType("05");
        return huifuWalletAccountTransfer(dto);
    }

    /**
     * <b> 企业 转账 接口 </b>
     * @author ZXF
     * @create 2023/11/10 0010 11:02
     * @version
     * @注意事项 </b>
     */
    @Override
    public String pay(HuifuWalletTransferDto dto) throws CrmebWalletException {
        dto.setTradeType("03");
        return huifuWalletAccountTransfer(dto);
    }

    /**
     * 线下支付业务新增平台分账业务 转账接口
     *
     * @param dto
     * @return
     * @author lp
     * @date 2019-08-27
     */
    @Override
    public void offlinePayPlatTransfer(HuifuWalletTransferDto dto) throws CrmebWalletException {
        logger.info(">>>>>>>>> 企业转账接口offlinePayPlatTransfer.param："+JSONObject.toJSONString(dto));
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (dto.getSellFeePriority()==null) {
            throw new CrmebWalletException("销售分账优先级不能为空");
        }
        if (StringUtil.isEmpty(dto.getPlatAmount())) {
            throw new CrmebWalletException("平台分账金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"04":dto.getTradeType();
        HuifuWalletAccountDto inAccount;//入账方 商家
        HuifuWalletAccountDto platAccount;//入账方 平台
        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }else{
            // 买方 -> 商家 -> 平台
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }
        if(inAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        //平台分账业务
        if(Double.parseDouble(dto.getPlatAmount())>0){
            logger.info(">>>>>>>>> 企业转账接口offlinePayPlatTransfer：接口请求7");
            HuifuWalletTransferDto dtoP = new HuifuWalletTransferDto();
            BeanUtils.copyProperties(dto,dtoP);
            dtoP.setAmount(dto.getPlatAmount());
            dtoP.setOutId(inAccount.getUniId());
            dtoP.setInId(platAccount.getUniId());
            String comment = dto.getSellFeePriority()==0?"订单【"+dtoP.getBusinessPartnerSeq()+"】支付商品费："+dto.getPlatAmount()+"元":"订单【"+dtoP.getBusinessPartnerSeq()+"】支付平台服务费："+dto.getPlatAmount()+"元";
            dtoP.setComment(comment);
            dtoP.setBusinessPartnerSeq(dtoP.getBusinessPartnerSeq()+"-P"+dto.getSellFeePriority());
            dtoP.setTradeType(tradeType);
            logger.info(">>>>>>>>> 企业转账接口offlinePayPlatTransfer：接口请求8");
            //线下支付情况下需要先校验能完成转账否则打回
            extractedLock(dtoP.getOutId(), "03", dtoP.getAmount());
            //异步 二级分账业务
            syncTransferToPlat(dtoP);
            logger.info(">>>>>>>>> 企业转账接口offlinePayPlatTransfer：接口请求9");
        }
    }

    /**
     * 企业转账接口
     *
     * @param dto
     * @return
     * @author lp
     * @date 2019-08-27
     */
    @Override
    public String huifuWalletAccountTransfer(HuifuWalletTransferDto dto) throws CrmebWalletException {
        Date date = new Date();
        logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer："+dto.getBusinessPartnerSeq()+",开始");
        logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer.param："+JSONObject.toJSONString(dto));
        //>>>>>>>>> 企业转账接口huifuWalletAccountTransfer.param：{"amount":"0.03","businessCode":"2","businessPartnerSeq":"PT769171703686656312734"
        // ,"comment":"考培服务-保安员资格证-培训服务(默认) * 1","goodsName":"考培服务-保安员资格证-培训服务"
        // ,"goodsNumber":"1","goodsUnit":"默认","inId":"ZeDzOsvz","needActiveCode":"0","outId":"aSuXCEfz","platAmount":"0.01","sellFeePriority":0,"tradeType":"04"}
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (dto.getSellFeePriority()==null) {
            throw new CrmebWalletException("销售分账优先级不能为空");
        }
        if (StringUtil.isEmpty(dto.getPlatAmount())) {
            throw new CrmebWalletException("平台分账金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        boolean redisRepetition = redisUtil.getRedisRepetition(dto.getBusinessPartnerSeq());
        if (!redisRepetition) {
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer："+dto.getBusinessPartnerSeq()+",交易已提交，请勿重复操作");
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }
        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(dto.getBusinessPartnerSeq(), dto.getTradeType());
        if (countTrade>0) {
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer："+dto.getBusinessPartnerSeq()+",交易已完成，请勿重复操作");
            throw new CrmebWalletException("交易已完成，请勿重复操作");
        }
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"04":dto.getTradeType();
        if("04".equals(tradeType)){
            //判断出账方余额是否充足
            extractedLock(dto.getOutId(), "03", dto.getAmount());
        }

        String objId = dto.getInId();
        if("03".equals(tradeType)){
            objId = dto.getOutId();
        }
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        HuifuWalletAccountDto inAccount;//入账方 商家
        HuifuWalletAccountDto platAccount;//入账方 平台
        outAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getOutId(),PaymentChannel.HUIFU.toString());
        if(outAccount == null){
            throw new CrmebWalletException("企业未开通钱包功能");
        }
        String lockAmount;
        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            lockAmount = dto.getPlatAmount();
            dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }else{
            //冻结/解冻业务逻辑判断，计算记录冻结金额并入库(实际转账交易类型默认为 04 冻结)
            //冻结/解冻金额 = 订单金额-平台费用
            lockAmount = decimalFormat.format(new BigDecimal(dto.getAmount()).subtract(new BigDecimal(dto.getPlatAmount())));
            // 买方 -> 商家 -> 平台
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }
        if(inAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
//        BigDecimal frozenAmount = extractedLock(objId, tradeType, lockAmount);
        logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer："+dto.getBusinessPartnerSeq()+",冻结金额："+lockAmount);
        p.put("outHuifuId", outAccount.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("ordAmt", dto.getAmount());
        p.put("isPlatAcct", "0");
        p.put("platAmount", "0.00");
        p.put("inAmount", dto.getAmount());
        p.put("inWalletAccountNo", inAccount.getWalletAccountNo());
        p.put("comment", dto.getComment());
        p.put("goodDesc", dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
        logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：参数设置完成");
        BigDecimal useAmount = "0304".contains(dto.getTradeType())?new BigDecimal(dto.getAmount()):"05".equals(dto.getTradeType())?new BigDecimal("-"+dto.getAmount()):BigDecimal.ZERO;
        String outBalance = decimalFormat.format(findBalance(outAccount.getWalletAccountNo()).subtract(useAmount));
        String inBalance = decimalFormat.format(findBalance(inAccount.getWalletAccountNo()).add(useAmount));
        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEPAY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("huifuWalletAccountTransfer",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }
        logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求3："+response.toString());
        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
                huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
                huifuWalletTrade.setBusinessPartnerSeq(dto.getBusinessPartnerSeq());
                huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
                huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
                huifuWalletTrade.setCreateTime(date);
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setGoodDesc(dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
                huifuWalletTrade.setTransFinishTime(response.get("trans_finish_time").toString());//20211021163242 TODO 得做转换
                huifuWalletTrade.setExpendAccountNo(outAccount.getWalletAccountNo());
                huifuWalletTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
                huifuWalletTrade.setRemark(dto.getComment());
                huifuWalletTrade.setUniId(outAccount.getUniId());
                huifuWalletTrade.setAmount(new BigDecimal(dto.getAmount()));
                huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
                if("04".equals(tradeType)) {
                    //更新冻结金额
                    syncUpdateSumFrozenAmount(inAccount.getUniId(),"04".equals(dto.getTradeType())?new BigDecimal(lockAmount):"05".equals(dto.getTradeType())?new BigDecimal("-"+lockAmount):BigDecimal.ZERO);
//                    huifuWalletAccountDao.updateFrozenAmount(inAccount.getUniId(), frozenAmount.toString());
                }
                return Boolean.TRUE;
            });
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求5");
            if (!execute) {
                throw new CrmebWalletException("企业钱包-交易支付-操作失败");
            }
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求6");
            //平台分账业务
            if(Double.parseDouble(dto.getPlatAmount())>0){
                logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求7");
                HuifuWalletTransferDto dtoP = new HuifuWalletTransferDto();
                BeanUtils.copyProperties(dto,dtoP);
                dtoP.setAmount(dto.getPlatAmount());
                dtoP.setOutId(inAccount.getUniId());
                dtoP.setInId(platAccount.getUniId());
                String comment = dto.getSellFeePriority()==0?"订单【"+dtoP.getBusinessPartnerSeq()+"】支付商品费："+dto.getPlatAmount()+"元":"订单【"+dtoP.getBusinessPartnerSeq()+"】支付平台服务费："+dto.getPlatAmount()+"元";
                dtoP.setComment(comment);
                dtoP.setBusinessPartnerSeq(dtoP.getBusinessPartnerSeq()+"-P"+dto.getSellFeePriority());
                dtoP.setTradeType(tradeType);
                logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求8");
                //异步 二级分账业务
                syncTransferToPlat(dtoP);
                logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求9");
            }

            //生成收支明细记录
            String trans_finish_time = DateUtil.format(DateUtil.parse(response.get("trans_finish_time").toString()),"yyyyMMdd");
            getPayTradeDetailTask(outAccount.getUniId(),outAccount.getWalletAccountNo(),response.get("hf_seq_id").toString(),trans_finish_time);

            logger.info("===>huifuWalletAccountTransfer.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer："+dto.getBusinessPartnerSeq()+",支付确认：succ");
            return response.get("req_seq_id").toString();
        }else{
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer：接口请求10");
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    @Override
    public String refundQuery(HuifuWalletAccountDto dto) throws CrmebWalletException {
        return null;
    }

    @Override
    public String batchQuery(HuifuWalletAccountDto dto) throws CrmebWalletException {
        return null;
    }

    @Override
    public String refundApply(HuifuWalletAccountDto dto) throws CrmebWalletException {
        return null;
    }

    @Override
    public String huifuWalletAccountRefundApply(HuifuWalletAccountDto dto) throws CrmebWalletException {
        return null;
    }

    @Override
    public Map<String, Object> huifuWalletAccountRefundQuery(HuifuWalletAccountDto dto) throws CrmebWalletException {
        return null;
    }

    /**
     * 二级分账业务（原是用来给平台分账，现在不区分给谁分，可能是平台也可能是商户，由调用方定义）
     *
     * @param dto
     * @return
     * @author lp
     * @date 2019-08-27
     */
    @Override
    public Boolean transferToPlat(HuifuWalletTransferDto dto) throws CrmebWalletException {
        if(StringUtils.isNotEmpty(dto.getPayChannel()) && !PaymentChannel.HUIFU.toString().equals(dto.getPayChannel())){
            return false;
        }
        Date date = new Date();
        logger.info(">>>>>>>>> 二级分账业务transferToPlat："+dto.getBusinessPartnerSeq()+",开始");
        logger.info(">>>>>>>>> 二级分账业务transferToPlat.param："+JSONObject.toJSONString(dto));
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            return false;
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            return false;
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            return false;
        }
        boolean redisRepetition = redisUtil.getRedisRepetition(dto.getBusinessPartnerSeq());
        if (!redisRepetition) {
            return false;
        }
        logger.info(">>>>>>>>> 二级分账业务transferToPlat：1");
        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(dto.getBusinessPartnerSeq(), dto.getTradeType());
        if (countTrade>0) {
            return true;
        }
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"04":dto.getTradeType();
        logger.info(">>>>>>>>> 二级分账业务transferToPlat：2");
//        if("04".equals(tradeType)) {
        //判断出账方余额是否充足
        extractedLock(dto.getOutId(), "03", dto.getAmount());
        logger.info(">>>>>>>>> 二级分账业务transferToPlat：3");
//        }
//        String objId = dto.getInId();
//        if("03".equals(tradeType)){
//            objId = dto.getOutId();
//        }
        //冻结/解冻业务逻辑判断，计算记录冻结金额并入库(实际转账交易类型默认为 04 冻结)
//        BigDecimal frozenAmount = extractedLock(objId, tradeType, dto.getAmount());
        logger.info(">>>>>>>>> 二级分账业务transferToPlat："+dto.getBusinessPartnerSeq()+",冻结金额："+dto.getAmount());
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        HuifuWalletAccountDto inAccount;
        outAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getOutId(),PaymentChannel.HUIFU.toString());
        if(outAccount == null){
            logger.error("===>transferToPlat.二级分账异常：企业未开通钱包功能");
            return false;
        }
        inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        if(outAccount == null){
            logger.error("===>transferToPlat.二级分账异常：商户数据异常，请联系管理员");
            return false;
        }
        p.put("outHuifuId", outAccount.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("ordAmt", dto.getAmount());
//        p.put("isPlatAcct", "0");
//        p.put("platAmount", "0.00");
        p.put("inAmount", decimalFormat.format(new BigDecimal(dto.getAmount())));
        p.put("inWalletAccountNo", inAccount.getWalletAccountNo());
        p.put("comment", dto.getComment());
        p.put("goodDesc", dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEPAY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("transferToPlat",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            logger.error("===>transferToPlat.二级分账异常："+e.getMessage());
            return false;
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
                huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
                huifuWalletTrade.setBusinessPartnerSeq(dto.getBusinessPartnerSeq());
                huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
                huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
                huifuWalletTrade.setCreateTime(date);
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setGoodDesc(dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
                huifuWalletTrade.setTransFinishTime(response.get("trans_finish_time").toString());//20211021163242 TODO 得做转换
                huifuWalletTrade.setExpendAccountNo(outAccount.getWalletAccountNo());
                huifuWalletTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
                huifuWalletTrade.setRemark(dto.getComment());
                huifuWalletTrade.setUniId(outAccount.getUniId());
                huifuWalletTrade.setAmount(new BigDecimal(dto.getAmount()));
                huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
                if("04".equals(tradeType)) {
                    //更新冻结金额
                    syncUpdateSumFrozenAmount(inAccount.getUniId(),"04".equals(dto.getTradeType())?(new BigDecimal(dto.getAmount())):"05".equals(dto.getTradeType())?(new BigDecimal("-"+dto.getAmount())):BigDecimal.ZERO);
//                    huifuWalletAccountDao.updateFrozenAmount(inAccount.getUniId(), frozenAmount.toString());
                }
                return Boolean.TRUE;
            });
            if (!execute) {
                logger.error("===>transferToPlat.二级分账异常：企业钱包-交易支付-操作失败");
                return false;
            }

            //生成收支明细记录
            String trans_finish_time = DateUtil.format(DateUtil.parse(response.get("trans_finish_time").toString()),"yyyyMMdd");
            getPayTradeDetailTask(outAccount.getUniId(),outAccount.getWalletAccountNo(),response.get("hf_seq_id").toString(),trans_finish_time);

            logger.info("===>huifuWalletAccountTransfer.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> 企业转账接口huifuWalletAccountTransfer："+dto.getBusinessPartnerSeq()+","+response.get("req_seq_id").toString()+",支付确认：succ");
            return true;
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            logger.error("===>transferToPlat.二级分账异常："+RET(response,2));
        }
        return false;
    }

    /**
     * <b> 线下支付业务 退款接口 </b>
     * @author ZXF
     * @create 2023/11/15 0015 19:17
     * @version
     * @注意事项 </b>
     */
    @Override
    public void offlinePayPlatRefund(HuifuWalletTransferDto dto) throws CrmebWalletException {
        logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund.param："+JSONObject.toJSONString(dto));
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getPlatAmount())) {
            throw new CrmebWalletException("平台分账金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        String oldBusinessPartnerSeq = dto.getBusinessPartnerSeq();
        dto.setBusinessPartnerSeq(oldBusinessPartnerSeq+"T");
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"05":dto.getTradeType();

        HuifuWalletAccountDto outAccount;
        HuifuWalletAccountDto platAccount;

        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
            outAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }else{
            // 买方 -> 商家 -> 平台
            outAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }
        if(outAccount == null){
            throw new CrmebWalletException("企业未开通钱包功能");
        }

        //平台分账业务
        if(Double.parseDouble(dto.getPlatAmount())>0){
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求7");
            HuifuWalletTransferDto dtoP = new HuifuWalletTransferDto();
            BeanUtils.copyProperties(dto,dtoP);
            dtoP.setAmount(dto.getPlatAmount());
            dtoP.setOutId(platAccount.getUniId());
            dtoP.setInId(outAccount.getUniId());
            dtoP.setComment("订单【"+dtoP.getBusinessPartnerSeq()+"】支付平台服务费退款："+dto.getPlatAmount()+"元");
            dtoP.setBusinessPartnerSeq(oldBusinessPartnerSeq+"-PT");
            dtoP.setTradeType(tradeType);
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求8");
            //异步
            syncRefundToPlat(dtoP);
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求9");
        }
    }

    /**
     * <b> 企业退款接口 </b>
     * @author ZXF
     * @create 2023/11/15 0015 19:17
     * @version
     * @注意事项 </b>
     */
    @Override
    public String huifuWalletAccountRefund(HuifuWalletTransferDto dto) throws CrmebWalletException {
        Date date = new Date();
        logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund："+dto.getBusinessPartnerSeq()+",开始");
        logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund.param："+JSONObject.toJSONString(dto));
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getPlatAmount())) {
            throw new CrmebWalletException("平台分账金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        String businessPartnerSeq = dto.getBusinessPartnerSeq();
        if("05".equals(dto.getTradeType())){
            Order order = orderService.getByOrderNo(dto.getBusinessPartnerSeq());
            businessPartnerSeq = order.getPlatOrderNo()+"T"+dto.getBusinessPartnerSeq();
            //校验：业务流水号必须能匹配到历史冻结的业务记录，否则判定未非法解冻操作
//            int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByOldReq(oldBusinessPartnerSeq, "04");
//            if (countTrade==0) {
//                throw new CrmebWalletException("未匹配到历史冻结业务，无法完成退款");
//            }
            //TODO 加1个字段判断是否企业支付交易，如果是要判断业务编码不包含“-P”符号
            int isThaw = huifuWalletTradeDao.calculateTheThawingAmounByReq(order.getPlatOrderNo(), dto.getAmount(),"-P");
            if (isThaw == 0) {
                throw new CrmebWalletException("当前解冻金额超出剩余可解冻额度，无法完成解冻，BusinessPartnerSeq="+businessPartnerSeq);
            }
        }else{
            throw new CrmebWalletException("当前为退款业务，仅支持解冻操作，BusinessPartnerSeq="+dto.getBusinessPartnerSeq());
        }
        boolean redisRepetition = redisUtil.getRedisRepetition(businessPartnerSeq);
        if (!redisRepetition) {
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund："+businessPartnerSeq+",交易已提交，请勿重复操作");
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }
        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(businessPartnerSeq, dto.getTradeType());
        if (countTrade>0) {
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund："+businessPartnerSeq+",交易已完成，请勿重复操作");
            throw new CrmebWalletException("交易已完成，请勿重复操作");
        }
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"05":dto.getTradeType();

        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        HuifuWalletAccountDto inAccount;
        HuifuWalletAccountDto platAccount;
        //退款 ，入账方是买方
        inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getOutId(),PaymentChannel.HUIFU.toString());
        if(inAccount == null){
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：入账方存在");
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
//        outAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId());

        String lockAmount;
        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            lockAmount = dto.getPlatAmount();
            dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
            outAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }else{
            // 买方 -> 商家 -> 平台
            //冻结/解冻业务逻辑判断，计算记录冻结金额并入库(实际转账交易类型默认为 05 解冻)
            //冻结/解冻金额 = 订单金额-平台费用
            lockAmount = decimalFormat.format(new BigDecimal(dto.getAmount()).subtract(new BigDecimal(dto.getPlatAmount())));
            outAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
            platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }
        extractedLock(outAccount.getUniId(), tradeType, lockAmount);
        logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund："+businessPartnerSeq+",冻结金额："+lockAmount);
        if(outAccount == null){
            throw new CrmebWalletException("企业未开通钱包功能");
        }
        p.put("outHuifuId", outAccount.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("ordAmt", dto.getAmount());
        p.put("isPlatAcct", "0");
        p.put("platAmount", "0.00");
        p.put("inAmount", dto.getAmount());
        p.put("inWalletAccountNo", inAccount.getWalletAccountNo());
        p.put("comment", dto.getComment()+" 退款");
        p.put("goodDesc", dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
        logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：参数设置完成");

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEPAY;
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求1");
            response = V2ApiRequest.api(hFBusiCode,p);
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求2");
        }catch (Exception e){
            transactionLogService.save("huifuWalletAccountRefund",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }
        logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求3："+response.toString());

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求4");
            String finalBusinessPartnerSeq = businessPartnerSeq;
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
                huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
                huifuWalletTrade.setBusinessPartnerSeq(finalBusinessPartnerSeq);
                huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
                huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
                huifuWalletTrade.setCreateTime(date);
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setGoodDesc(dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
                huifuWalletTrade.setTransFinishTime(response.get("trans_finish_time").toString());//20211021163242 TODO 得做转换
                huifuWalletTrade.setExpendAccountNo(outAccount.getWalletAccountNo());
                huifuWalletTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
                huifuWalletTrade.setRemark(dto.getComment()+" 退款");
                huifuWalletTrade.setUniId(outAccount.getUniId());
                huifuWalletTrade.setAmount(new BigDecimal(dto.getAmount()));
                huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
                if("05".equals(tradeType)) {
                    //更新冻结金额
                    syncUpdateSumFrozenAmount(outAccount.getUniId(),"04".equals(dto.getTradeType())?(new BigDecimal(lockAmount)):"05".equals(dto.getTradeType())?(new BigDecimal("-"+lockAmount)):BigDecimal.ZERO);
//                    huifuWalletAccountDao.updateFrozenAmount(outAccount.getUniId(), frozenAmount.toString());
                }
                return Boolean.TRUE;
            });
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求5");
            if (!execute) {
                throw new CrmebWalletException("企业钱包-交易支付-操作失败");
            }
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求6");
            //平台分账业务
            if(Double.parseDouble(dto.getPlatAmount())>0){
                logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求7");
                HuifuWalletTransferDto dtoP = new HuifuWalletTransferDto();
                BeanUtils.copyProperties(dto,dtoP);
                dtoP.setAmount(dto.getPlatAmount());
                dtoP.setOutId(platAccount.getUniId());
                dtoP.setInId(outAccount.getUniId());
                dtoP.setComment("订单【"+dtoP.getBusinessPartnerSeq()+"】支付平台服务费退款："+dto.getPlatAmount()+"元");
                dtoP.setBusinessPartnerSeq(dto.getBusinessPartnerSeq());
//                dtoP.setBusinessPartnerSeq(oldBusinessPartnerSeq+"-PT");
                dtoP.setTradeType(tradeType);
                logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求8");
                //异步
                syncRefundToPlat(dtoP);
                logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求9");
            }

            //生成收支明细记录
            String trans_finish_time = DateUtil.format(DateUtil.parse(response.get("trans_finish_time").toString()),"yyyyMMdd");
            getPayTradeDetailTask(outAccount.getUniId(),outAccount.getWalletAccountNo(),response.get("hf_seq_id").toString(),trans_finish_time);

            logger.info("===>企业退款接口huifuWalletAccountRefund.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund："+businessPartnerSeq+",支付确认：succ");
            return response.get("req_seq_id").toString();
        }else{
            logger.info(">>>>>>>>> 企业退款接口huifuWalletAccountRefund：接口请求10");
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    /**
     * <b> 平台退款给企业 </b>
     * @author ZXF
     * @create 2023/11/15 0015 19:17
     * @version
     * @注意事项 </b>
     */
    @Override
    public Boolean refundToPlat(HuifuWalletTransferDto dto) throws CrmebWalletException {
        if(StringUtils.isNotEmpty(dto.getPayChannel()) && !PaymentChannel.HUIFU.toString().equals(dto.getPayChannel())){
            return false;
        }
        Date date = new Date();
        logger.info(">>>>>>>>> 平台退款给企业refundToPlat.平台支付异常："+dto.getBusinessPartnerSeq()+",开始");
        logger.info(">>>>>>>>> 平台退款给企业refundToPlat.param："+JSONObject.toJSONString(dto));
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            logger.error(">>>>>>>>> 平台退款给企业refundToPlat.平台支付异常：订单金额不能为空");
            return false;
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            logger.error(">>>>>>>>> 平台退款给企业refundToPlat.平台支付异常：业务编码不能为空");
            return false;
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            logger.error(">>>>>>>>> 平台退款给企业refundToPlat.平台支付异常：业务交易流水号不能为空");
            return false;
        }
        Order order = orderService.getByOrderNo(dto.getBusinessPartnerSeq());
        String businessPartnerSeq = order.getPlatOrderNo()+"-P"+dto.getSellFeePriority();
        String businessPartnerSeq2 = businessPartnerSeq+"T"+dto.getBusinessPartnerSeq();
        boolean redisRepetition = redisUtil.getRedisRepetition(businessPartnerSeq2);
        if (!redisRepetition) {
            logger.info(">>>>>>>>> 平台退款给企业refundToPlat.平台支付异常："+businessPartnerSeq2+",交易已提交，请勿重复操作");
            return false;
        }
        int isThaw = huifuWalletTradeDao.calculateTheThawingAmounByReq(businessPartnerSeq, dto.getAmount(),"");
        if (isThaw == 0) {
            throw new CrmebWalletException("当前解冻金额超出剩余可解冻额度，无法完成解冻，BusinessPartnerSeq="+businessPartnerSeq2);
        }
        logger.info("=======> 企业账户金额冻结/解冻.huifuWalletAccountLock.步骤:1.1");
//        dto.setBusinessPartnerSeq(dto.getBusinessPartnerSeq()+"T"+System.currentTimeMillis());
//        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(dto.getBusinessPartnerSeq(), dto.getTradeType());
//        if (countTrade>0) {
//            logger.error(">>>>>>>>> 平台退款给企业refundToPlat.平台支付异常："+dto.getBusinessPartnerSeq()+",交易已完成，请勿重复操作");
//            return false;
//        }
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        /*if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }*/
        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"05":dto.getTradeType();
        //冻结/解冻业务逻辑判断，计算记录冻结金额并入库(实际转账交易类型默认为 05 解冻) TODO 250908 暂时注释不校验平台余额
//        extractedLock(dto.getOutId(), tradeType, dto.getAmount());
        logger.info(">>>>>>>>> 平台退款给企业refundToPlat："+businessPartnerSeq2+",冻结金额："+dto.getAmount());
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        HuifuWalletAccountDto inAccount;
        outAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getOutId(),PaymentChannel.HUIFU.toString());
        if(outAccount == null){
            logger.error("===>平台退款给企业refundToPlat.平台支付异常：企业未开通钱包功能");
            return false;
        }
        inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        if(inAccount == null){
            logger.error("===>平台退款给企业refundToPlat.平台支付异常：商户数据异常，请联系管理员");
            return false;
        }
        p.put("outHuifuId", outAccount.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("ordAmt", dto.getAmount());
        p.put("isPlatAcct", "0");
        p.put("platAmount", "0.00");
        p.put("inAmount", dto.getAmount());
        p.put("inWalletAccountNo", inAccount.getWalletAccountNo());
        p.put("comment", dto.getComment());
        p.put("goodDesc", dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEPAY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("refundToPlat",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            logger.error("===>平台退款给企业refundToPlat.平台支付异常："+e.getMessage());
            return false;
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
                huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
                huifuWalletTrade.setBusinessPartnerSeq(businessPartnerSeq2);
                huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
                huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
                huifuWalletTrade.setCreateTime(date);
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setGoodDesc(dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
                huifuWalletTrade.setTransFinishTime(response.get("trans_finish_time").toString());//20211021163242 TODO 得做转换
                huifuWalletTrade.setExpendAccountNo(outAccount.getWalletAccountNo());
                huifuWalletTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
                huifuWalletTrade.setRemark(dto.getComment());
                huifuWalletTrade.setUniId(outAccount.getUniId());
                huifuWalletTrade.setAmount(new BigDecimal(dto.getAmount()));
                huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);
                if("05".equals(tradeType)) {
                    //更新冻结金额
                    syncUpdateSumFrozenAmount(outAccount.getUniId(),"04".equals(dto.getTradeType())?(new BigDecimal(dto.getAmount())):"05".equals(dto.getTradeType())?(new BigDecimal("-"+dto.getAmount())):BigDecimal.ZERO);
//                    huifuWalletAccountDao.updateFrozenAmount(outAccount.getUniId(), frozenAmount.toString());
                }
                return Boolean.TRUE;
            });
            if (!execute) {
                logger.error("===>平台退款给企业refundToPlat.平台支付异常：企业钱包-交易支付-操作失败");
                return false;
            }

            //生成收支明细记录
            String trans_finish_time = DateUtil.format(DateUtil.parse(response.get("trans_finish_time").toString()),"yyyyMMdd");
            getPayTradeDetailTask(outAccount.getUniId(),outAccount.getWalletAccountNo(),response.get("hf_seq_id").toString(),trans_finish_time);

            logger.info("===>平台退款给企业refundToPlat.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> 平台退款给企业refundToPlat："+businessPartnerSeq2+","+response.get("req_seq_id").toString()+",支付确认：succ");
            return true;
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            logger.error("===>huifuWalletAccountTransfer.平台支付异常："+RET(response,2));
        }
        return false;
    }

    /**
     * <b> 平台分销转账接口 </b>
     * @author ZXF
     * @create 2023/08/24 0024 14:57
     * @version
     * @注意事项 </b>
     */
    @Override
    public String platAccountRetailTransfer(HuifuWalletTransferDto dto) throws CrmebWalletException {
        Date date = new Date();
        logger.info(">>>>>>>>> 平台分销转账接口platAccountRetailTransfer："+dto.getBusinessPartnerSeq()+",开始");
        logger.info(">>>>>>>>> 平台分销转账接口platAccountRetailTransfer.param："+JSONObject.toJSONString(dto));
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        boolean redisRepetition = redisUtil.getRedisRepetition(dto.getBusinessPartnerSeq());
        if (!redisRepetition) {
            logger.info(">>>>>>>>> 平台分销转账接口platAccountRetailTransfer："+dto.getBusinessPartnerSeq()+",交易已提交，请勿重复操作");
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }
        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(dto.getBusinessPartnerSeq(), dto.getTradeType());
        if (countTrade>0) {
            logger.info(">>>>>>>>> 平台分销转账接口platAccountRetailTransfer："+dto.getBusinessPartnerSeq()+",交易已完成，请勿重复操作");
            throw new CrmebWalletException("交易已完成，请勿重复操作");
        }
        if (StringUtil.isEmpty(dto.getGoodsName())) {
            throw new CrmebWalletException("订单商品名称不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsNumber())) {
            throw new CrmebWalletException("订单商品数量不能为空");
        }
        if (StringUtil.isEmpty(dto.getGoodsUnit())) {
            throw new CrmebWalletException("订单商品单位不能为空");
        }
        if (StringUtil.isEmpty(dto.getNeedActiveCode())) {
            throw new CrmebWalletException("是否需要验证码不能为空");
        }
        if (Constants.Y.equals(dto.getNeedActiveCode())) {
            if (StringUtil.isEmpty(dto.getContactPhone())) {
                throw new CrmebWalletException("手机号不能为空");
            }
            if (StringUtil.isEmpty(dto.getActiveCode())) {
                throw new CrmebWalletException("短信验证码不能为空");
            }

            checkValidateCode(dto.getContactPhone(),dto.getActiveCode());
        }
        //分销分账固定拿平台当出账方
        HuifuWalletAccountDto platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        //平台往外分账，这里固定出方取平台账户
        dto.setOutId(platAccount.getUniId());

        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"05":dto.getTradeType();
        //冻结/解冻业务逻辑判断，计算记录冻结金额并入库(实际转账交易类型默认为 05 解冻) TODO 从平台转出去的就不再查询余额，直接让汇付转账判断
//        extractedLock(dto.getOutId(), "03", dto.getAmount());
//        extractedLock(dto.getOutId(), tradeType, dto.getAmount());
        logger.info(">>>>>>>>> 平台分销转账接口platAccountRetailTransfer："+dto.getBusinessPartnerSeq()+",冻结金额："+dto.getAmount());
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        HuifuWalletAccountDto inAccount;
        outAccount = platAccount;
        if(outAccount == null){
            throw new CrmebWalletException("企业未开通钱包功能");
        }
        inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        if(outAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        p.put("outHuifuId", outAccount.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("ordAmt", dto.getAmount());
//        p.put("isPlatAcct", dto.getIsPlatAcct());
//        p.put("platAmount", dto.getPlatAmount());
        //计算入账方金额
        String inAmount = dto.getAmount();
        /*if("1".equals(dto.getIsPlatAcct())){
            inAmount = (new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString();
        }*/
        inAmount = decimalFormat.format(new BigDecimal(inAmount));
        p.put("inAmount", inAmount);
        p.put("inWalletAccountNo", inAccount.getWalletAccountNo());
        p.put("comment", dto.getComment());
        p.put("goodDesc", dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.YEPAY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("platAccountRetailTransfer",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            final String ina = inAmount;
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                HuifuWalletTrade huifuWalletTrade = new HuifuWalletTrade();
                huifuWalletTrade.setBusinessCode(dto.getBusinessCode());
                huifuWalletTrade.setBusinessPartnerSeq(dto.getBusinessPartnerSeq());
                huifuWalletTrade.setReqSeqId(response.get("req_seq_id").toString());
                huifuWalletTrade.setHfSeqId(response.get("hf_seq_id").toString());
                huifuWalletTrade.setCreateTime(date);
                huifuWalletTrade.setUpdateTime(new Date());
                huifuWalletTrade.setGoodDesc(dto.getGoodsName()+"×"+dto.getGoodsNumber()+dto.getGoodsUnit());
                huifuWalletTrade.setTransFinishTime(response.get("trans_finish_time").toString());//20211021163242 TODO 得做转换
                huifuWalletTrade.setExpendAccountNo(outAccount.getWalletAccountNo());
                huifuWalletTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
                huifuWalletTrade.setRemark(dto.getComment());
                huifuWalletTrade.setUniId(outAccount.getUniId());
                huifuWalletTrade.setAmount(new BigDecimal(ina));
                huifuWalletTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                huifuWalletTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                huifuWalletTrade.setPayChannel(PaymentChannel.HUIFU.toString());
                huifuWalletTradeDao.insertHuifuWalletTrade(huifuWalletTrade);

                //更新冻结金额
                syncUpdateSumFrozenAmount(inAccount.getUniId(),"04".equals(dto.getTradeType())?(new BigDecimal(dto.getAmount())):"05".equals(dto.getTradeType())?(new BigDecimal("-"+dto.getAmount())):BigDecimal.ZERO);
//                huifuWalletAccountDao.updateFrozenAmount(outAccount.getUniId(),frozenAmount.toString());
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new CrmebWalletException("企业钱包-交易支付-操作失败");
            }
            logger.info("===>平台分销转账接口platAccountRetailTransfer.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> 平台分销转账接口platAccountRetailTransfer："+dto.getBusinessPartnerSeq()+",支付确认：succ");
            return response.get("req_seq_id").toString();
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    /**
     * 电子回单
     *
     * @param dto
     * @return
     * @author lp
     * @date 2019-07-08
     */
    @Override
    public String getHuifuAccountTradeVoucher(HuifuWalletTradeDto dto) throws CrmebWalletException {
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("用户ID不能为空");
        }
        if (StringUtil.isEmpty(dto.getTradeFlowNo())) {
            throw new CrmebWalletException("全局流水号不能为空");
        }
        HuifuWalletAccountDto account = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getUniId(),PaymentChannel.HUIFU.toString());
        HuifuWalletReconciliation re = huifuWalletReconciliationDao.selectById(dto.getTradeFlowNo());
        String showFeemat = "0";
        String templateType = "1";
        String isDiv = "0";
        String payType = "BALANCE_PAY";
        if("提现".equals(re.getBankTradeType())&&StringUtils.isNotEmpty(re.getIncomeAccountNo()) && re.getIncomeAccountNo().contains("***")){
            showFeemat = "1";
            templateType = "2";
            payType = "CASHOUT";
        }
        if("消费".equals(re.getBankTradeType())){//充值
            showFeemat = "1";
            payType = "ONLINE_PAY";
            templateType = "2";
            isDiv = "1";
        }
        /*** 调用支付平台接口获取电子回单 ***/
        Map<String, Object> p = Maps.newHashMap();
//        p.put("huifuId", dto.getExpendAccountNo());
        p.put("huifuId", account.getWalletAccountNo());
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("orgHfSeqId", re.getTradeSerialNo());
//        p.put("orgReqSeqId", re.getRequestSerialNo());
        p.put("showFeemat", showFeemat);//支付类型
        p.put("payType", payType);//支付类型
        p.put("templateType", templateType);//模板类型
        p.put("isDiv", isDiv);//是否分账
        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.HDQUERY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("getHuifuAccountTradeVoucher",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
//            huifuWalletAccountDetailDao.updateVoucherUrlById(detail.getId(),response.get("download_url").toString(),dto.getTradeFlowNo());
            return response.get("download_url").toString();
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    @Override
    public String getBatchTradeVoucher(HuifuWalletTradeDto dto) throws CrmebWalletException {
        return null;
    }

    /**
     * <b> 电子回单获取任务 </b>
     * @author ZXF
     * @create 2023/04/21 0021 17:06
     * @version
     * @注意事项 </b>
     */
    @Override
    public String taskTradeVoucher(String tradeDate) {
        /*if(StringUtils.isEmpty(tradeDate)){
            try {
                tradeDate = DateUtils.dateAdd(CrmebWalletException(.BLANK_CHAR,DateUtils.getDate(),"yyyy-MM-dd",-1).replace("-","");
                String tradeDate2 = DateUtils.dateAdd(CrmebWalletException(.BLANK_CHAR,DateUtils.getDate(),"yyyy-MM-dd",-2).replace("-","");
                new Thread(()->{ //每次跑昨天的电子回单都异步跑下前天的电子回单
                    try {
                        taskTradeVoucher(tradeDate2);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }).start();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        Map<Object, Object> p = Maps.newHashMap();
        p.put("tradeDate", tradeDate);

        String token = JwtUtil.createJWT(p);//加密生成token
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("token", token);
        String platUrl = commonService.getSystemConfig(CrmebWalletException(.PAYMENT_PLATFORM_URL);
        String resultStr = HttpUtil.post(platUrl + PaymentServiceConst.ACCOUNT_TRADE_VOUCHERBATCHDECOMPRESSION, requestMap);
        Result result = JSON.parseObject(resultStr, Result.class);
        *//*** 如果返回成功 ***//*
        if (Result.SUCCESS.equals(result.getRetType())) {
            return "1";
        }
        throw new CrmebWalletException("文件拉取失败");*/
        return "1";
    }


    /**
     * <b> 初始生成化对账单配置 </b>
     * @author ZXF
     * @create 2023/08/12 0012 13:33
     * @version
     * @注意事项 </b>
     */
    @Override
    public String setReconciliationConfig() throws CrmebWalletException {
        Map<String, Object> p = Maps.newHashMap();
        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.ZDCONFIG;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("setReconciliationConfig",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            return "1";
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    /**
     * <b> 交易结算对账文件重新生成 </b>
     * @param tradeDate 指定日期，例：20230816
     * @author ZXF
     * @create 2023/08/12 0012 13:33
     * @version
     * @注意事项 </b>
     */
    @Override
    public String reconciliationReplay(String tradeDate) {
        //指定日期有做过交易的汇付号进行对账单查询
        huifuReconcileService.reconcileOrder(tradeDate,HFProfileConstants.HUIFU_ID);
        huifuReconcileService.reconcileSettle(tradeDate,HFProfileConstants.HUIFU_ID);
        huifuReconcileService.reconcileOutcash(tradeDate,HFProfileConstants.HUIFU_ID);
        huifuReconcileService.reconcileSplit(tradeDate,HFProfileConstants.HUIFU_ID);
        return "1";
    }

    /**
     * 企业钱包账户对账数据生成
     *
     * @author llc
     * @date 2019-08-20
     */
    @Override
    public String createHuifuWalletReconciliation() {
//        String days[] = {"20230816"};
//        String days[] = {"20230810","20230811","20230812","20230813","20230814","20230815"};
        String days[] = {DateUtils.formatDate(DateUtils.addDays(new Date(),-2),"yyyyMMdd"),DateUtils.formatDate(DateUtils.addDays(new Date(),-1),"yyyyMMdd"),DateUtils.formatDate(new Date(),"yyyyMMdd")};
        for(String day : days){
            //指定日期有做过交易的汇付号进行对账单查询
            huifuReconcileService.reconcileOrder(day,HFProfileConstants.HUIFU_ID);
            huifuReconcileService.reconcileSettle(day,HFProfileConstants.HUIFU_ID);
            huifuReconcileService.reconcileOutcash(day,HFProfileConstants.HUIFU_ID);
            huifuReconcileService.reconcileSplit(day,HFProfileConstants.HUIFU_ID);
        }
        return "1";
    }

    /**
     * 获取企业钱包账户对账数据
     *
     * @author llc
     * @date 2019-09-19
     */
    @Override
    public Map<String, Object> getHuifuWalletReconciliation(HuifuWalletTradeDto dto) throws CrmebWalletException {
        if (dto.getPageNumber() == null) {
            throw new CrmebWalletException("第几页不能为空");
        }
        if (dto.getPageSize() == null) {
            throw new CrmebWalletException("每页多少行不能为空");
        }
        if (StringUtil.isEmpty(dto.getFundFlowType())) {
            throw new CrmebWalletException("资金流向不能为空");
        }
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        if (StringUtil.isNotEmpty(dto.getStartDate())) {
            dto.setStartDate(dto.getStartDate().replace("-",""));
        }
        if (StringUtil.isNotEmpty(dto.getEndDate())) {
            dto.setEndDate(dto.getEndDate().replace("-",""));
        }
        PageHelper.startPage(dto.getPageNumber(), dto.getPageSize());
        /*** 查询企业钱包账户对账数据列表 ***/
        List<Map<String, Object>> list = huifuWalletReconciliationDao.getWalletReconciliationList(dto);

        /*** 获取企业钱包账户对账统计数据 ***/
        Map<String, Object> map = huifuWalletReconciliationDao.getWalletReconciliationSum(dto);

        PageInfo pageInfo = new PageInfo(list);

        if (map != null) {
            map.put("pageInfo", pageInfo); // 分页信息
        }
        return map;

    }

    /**
     * 导出企业钱包账户对账数据
     *
     * @author llc
     * @date 2019-09-20
     */
    @Override
    public String exportHuifuWalletReconciliation(HuifuWalletTradeDto dto, HttpServletResponse response) throws CrmebWalletException {
        if (StringUtil.isEmpty(dto.getFundFlowType())) {
            throw new CrmebWalletException("资金流向不能为空");
        }
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        if (StringUtils.isNotEmpty(dto.getStartDate())) {
            dto.setStartDate(dto.getStartDate().replace("-",""));
        }
        if (StringUtils.isNotEmpty(dto.getEndDate())) {
            dto.setEndDate(dto.getEndDate().replace("-",""));
        }
        OutputStream os = null;
        HSSFWorkbook wb = new HSSFWorkbook();
        try {
            String fileName = "对账数据" + DateUtil.format(new Date(),"yyyyMMddHHmmss") + ".xls";
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
            os = response.getOutputStream();
            HSSFSheet sheet1 = wb.createSheet("对账数据");


            /*** 查询企业钱包账户对账数据列表 ***/
            List<Map<String, Object>> list = huifuWalletReconciliationDao.getWalletReconciliationList(dto);

            /*** 填充文本样式 ***/
            CellStyle stringStyle = ExcelUtil.getStringStyle(wb);

            /**** 生成sheet1的内容 ***/
            HSSFFont titleFont = wb.createFont();
            HSSFCellStyle titleStyle = wb.createCellStyle();
            titleFont.setFontHeightInPoints((short) 11);
            titleFont.setColor(HSSFColor.BLUE.index);
            titleFont.setFontName("黑体");
            titleStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
            titleStyle.setFont(titleFont);
            titleStyle.setWrapText(true);
            HSSFDataFormat format = wb.createDataFormat();
            titleStyle.setDataFormat(format.getFormat("@"));

            /**** 生成sheet1的内容 ***/
            /*** 获取企业钱包账户对账统计数据 ***/
            Map<String, Object> map = huifuWalletReconciliationDao.getWalletReconciliationSum(dto);
            String headerTitle = "";
            if (map == null) {
                headerTitle = MessageFormat.format("总笔数：【{0}】笔 | 总金额：【{1}】元 | 成功笔数：【{2}】笔 | 成功金额：【{3}】元 | 失败笔数：【{4}】笔 | 失败金额：【{5}】元 | 处理中笔数：【{6}】笔 | 处理中金额：【{7}】元",
                        0, 0, 0, 0, 0, 0, 0, 0);
            } else {
                headerTitle = MessageFormat.format("总笔数：【{0}】笔 | 总金额：【{1}】元 | 成功笔数：【{2}】笔 | 成功金额：【{3}】元 | 失败笔数：【{4}】笔 | 失败金额：【{5}】元 | 处理中笔数：【{6}】笔 | 处理中金额：【{7}】元",
                        String.valueOf(map.get("totalCount")), String.valueOf(map.get("sumAmount")), String.valueOf(map.get("successCount")), String.valueOf(map.get("successAmount")), String.valueOf(map.get("errorCount")), String.valueOf(map.get("errorAmount")), String.valueOf(map.get("processingCount")), String.valueOf(map.get("processingAmount")));
            }
            /*** 填充第一行数据 ***/
            HSSFCellStyle titleStyle1 = wb.createCellStyle();
            HSSFFont titleFont1 = wb.createFont();
            titleFont1.setFontHeightInPoints((short) 11);
            titleFont1.setColor(HSSFColor.RED.index);
            titleFont1.setFontName("黑体");
            titleStyle1.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
            titleStyle1.setFont(titleFont1);
            titleStyle1.setWrapText(true);
            HSSFRow rowFirst = sheet1.createRow(0); // 第一个sheet的第一行为标题
            rowFirst.setHeight((short) (1000));
            sheet1.addMergedRegion(new CellRangeAddress(0, (short) 0, 0, 13));
            HSSFCell titleCell = rowFirst.createCell(0);
            titleCell.setCellValue(headerTitle);
            titleCell.setCellStyle(titleStyle1);

            /*** 填充第二行数据 ***/
            HSSFRow secondFirst = sheet1.createRow(1);
            String[] secondArr = {"序号", "交易流水号", "银行交易类型", "交易状态", "交易订单创建时间", "交易金额", "出账方户名", "出账方账号", "出账方银行", "入账方户名", "入账方账号", "入账方银行", "入账方证件号", "备注", "支付渠道"};
            int column;
            for (int i = 0; i < secondArr.length; i++) {
                HSSFCell cell = secondFirst.createCell(i); // 获取第二行的每个单元格
                if (i == 0) {
                    column = 1500;
                } else if (i == 4) {
                    column = 5000;
                } else if (i == 1 || i == 7 || i == 10 || i == 13) {
                    column = 8000;
                } else if (i == 6 || i == 9) {
                    column = 10000;
                } else if (i == 13) {
                    column = 14000;
                } else {
                    column = 4000;
                }
                sheet1.setColumnWidth(i, column); // 设置每列的列宽
                sheet1.setDefaultColumnStyle(i, stringStyle); // 设置单元格格式 --文本格式
                cell.setCellStyle(titleStyle); // 文本格式
            }

            /*** 填充第二行数据 ***/
            for (int i = 0; i < secondArr.length; i++) {
                HSSFCell cell = secondFirst.createCell(i); // 获取第一行的每个单元格
                cell.setCellValue(secondArr[i]);
                cell.setCellStyle(titleStyle);
            }

            /*** 字体颜色样式 ***/
            CellStyle greenStyle = ExcelUtil.getColorStyle(wb, IndexedColors.SEA_GREEN.index);// 青绿色样式
            CellStyle redStyle = ExcelUtil.getColorStyle(wb, IndexedColors.RED.index); // 红色样式
            CellStyle blueStyle = ExcelUtil.getColorStyle(wb, IndexedColors.BLUE.index); // 红色样式
            HSSFRow row = null;
            int rowIndex = 2;
            for (Map<String, Object> result : list) {
                row = sheet1.createRow(rowIndex);
                HSSFCell cell0 = row.createCell(0);
                cell0.setCellValue(rowIndex - 1);
                HSSFCell cell1 = row.createCell(1);
                cell1.setCellValue(result.get("tradeSerialNo") != null ? result.get("tradeSerialNo").toString() : null); // 交易流水号
                HSSFCell cell2 = row.createCell(2);
                cell2.setCellValue(result.get("bankTradeType") != null ? result.get("bankTradeType").toString() : null); // 银行交易类型
                HSSFCell cell3 = row.createCell(3);
                cell3.setCellValue(result.get("tradeStatus") != null ? result.get("tradeStatus").toString() : null); // 交易状态
                if (ObjectUtil.equal(result.get("tradeStatus"), "交易成功")) {
                    cell3.setCellStyle(greenStyle);
                } else if (ObjectUtil.equal(result.get("tradeStatus"), "交易失败")) {
                    cell3.setCellStyle(redStyle);
                } else {
                    cell3.setCellStyle(blueStyle);
                }
                HSSFCell cell4 = row.createCell(4);
                cell4.setCellValue(result.get("tradeStartTime") != null ? result.get("tradeStartTime").toString() : null); // 交易订单创建时间
                HSSFCell cell5 = row.createCell(5);
                cell5.setCellValue(result.get("tradeAmount") != null ? result.get("tradeAmount").toString() : null); // 交易金额
                cell5.setCellStyle(redStyle);
                HSSFCell cell6 = row.createCell(6);
                cell6.setCellValue(result.get("expendAccountName") != null ? result.get("expendAccountName").toString() : null);// 出账方户名
                HSSFCell cell7 = row.createCell(7);
                cell7.setCellValue(result.get("expendAccountNo") != null ? result.get("expendAccountNo").toString() : null);// 出账方账号
                HSSFCell cell8 = row.createCell(8);
                cell8.setCellValue(result.get("expendBank") != null ? result.get("expendBank").toString() : null);// 出账方银行
                HSSFCell cell9 = row.createCell(9);
                cell9.setCellValue(result.get("incomeAccountName") != null ? result.get("incomeAccountName").toString() : null);// 入账方户名
                HSSFCell cell10 = row.createCell(10);
                cell10.setCellValue(result.get("incomeAccountNo") != null ? result.get("incomeAccountNo").toString() : null);// 入账方账号
                HSSFCell cell11 = row.createCell(11);
                cell11.setCellValue(result.get("incomeBank") != null ? result.get("incomeBank").toString() : null);// 入账方银行
                HSSFCell cell12 = row.createCell(12);
                cell12.setCellValue(result.get("incomeCerNo") != null ? result.get("incomeCerNo").toString() : null);// 入账方证件号
                HSSFCell cell13 = row.createCell(13);
                cell13.setCellValue(result.get("remark") != null ? result.get("remark").toString() : null);// 备注
                HSSFCell cell14 = row.createCell(14);
                cell14.setCellValue(result.get("payChannel") != null ? result.get("payChannel").toString() : null);// 支付渠道
                rowIndex++;
            }
            wb.write(os);
            os.close();
            wb.close();
        } catch (Exception e) {
            throw new CrmebWalletException(e.getMessage());
        } finally {
            try {
                os.close();
                wb.close();
            } catch (IOException e1) {
            }
        }
        return "0";
    }

    /**
     * <b> 获取企业钱包账户结算记录 TODO 定时任务未调整 </b>
     * @author ZXF
     * @create 2023/08/06 0006 13:02
     * @version
     * @注意事项 </b>
     */
    @Override
    public String huifuWalletAccountTranslogTask(String startDate, String endDate) {
        //查昨天跟今天
        if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
            startDate = DateUtil.formatDate(DateUtil.yesterday());
            endDate = DateUtil.formatDate(DateUtil.date());
        }
        //昨天、今天产生交易记录的交易双方账户信息 yyyy-MM-dd
        List<HuifuWalletAccountDto> accountList = huifuWalletAccountDao.getLastDayTradeHuifuWalletAccount(startDate+" 00:00:00",endDate+" 23:59:59",PaymentChannel.HUIFU.toString());

        List<HuifuWalletTranslog> detailList = Lists.newArrayList();
        List<HuifuWalletTranslog> updateDetailList = Lists.newArrayList();
        List<String> flowNoList = Lists.newArrayList();

        /*  需要剔除掉已经存在的，防止重复下载 */
        List<String> existsReqNoList = huifuWalletTranslogDao.selectReqNoByDate(startDate.replace("-",""), endDate.replace("-",""));
        /*  记录“处理中”状态的数据 */
        List<String> pReqNoList = huifuWalletTranslogDao.selectPReqNoByDate(startDate.replace("-",""), endDate.replace("-",""));

        for (HuifuWalletAccountDto account : accountList) {
            int pageNumber = 1;
            while (true) {
                try{
                    /* 调用支付平台接口获取账户交易明细 ***/
                    Map<String, Object> p = new HashMap<>();
                    p.put("huifuId", account.getWalletAccountNo());
//                    p.put("reqSeqId", SequenceTools.getReqSeqId32());
                    p.put("beginDate", startDate.replace("-",""));
                    p.put("endDate", endDate.replace("-",""));
                    p.put("pageNum", pageNumber);
                    p.put("pageSize", 50);
                    Map<String, Object> response;
                    HFBusiCode hFBusiCode;
                    try {
                        hFBusiCode = HFBusiCode.TXQUERY;
                        response = V2ApiRequest.api(hFBusiCode,p);
                    }catch (Exception e){
                        transactionLogService.save("huifuWalletAccountTranslogTask",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
                        throw new CrmebWalletException(e.getMessage());
                    }

                    if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
                        transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                        if (StringUtils.isEmpty(response.get("result_count").toString()) || Integer.parseInt(response.get("result_count").toString()) == 0) {
                            break;
                        }
                        /*** 解析返回的列表数据 ***/
                        ArrayList<Map> recordlist = JSON.parseObject(response.get("trans_log_result_list").toString(),
                                new TypeReference<ArrayList<Map>>() {
                                });
                        for (Map<String, Object> record : recordlist) {
                            HuifuWalletTranslog translog = new HuifuWalletTranslog();
                            translog.setUniId(account.getUniId());
                            translog.setCreateTime(new Date());
                            translog.setTransId(record.get("org_hf_seq_id").toString());
                            translog.setTransDate(record.get("org_req_date").toString());
                            translog.setTransAmt(record.get("cash_amt").toString());
                            String transStat = record.get("trans_status").toString();
                            transStat = transStat.equals("S")?"成功":transStat.equals("F")?"失败":"处理中";
                            translog.setTransStat(transStat);
                            translog.setCardNo(account.getCardNo());
                            translog.setCardName(account.getCardName());
                            translog.setBankCode(account.getBankCode());
                            translog.setFeeAmt(record.get("fee_amt").toString());
                            translog.setRemark(record.get("remark").toString());
                            translog.setTransDesc(record.get("trans_desc").toString());
                            translog.setPayChannel(PaymentChannel.HUIFU.toString());
                            String transType = "SURROGATE".equals(record.get("batch_trans_type").toString())?"银行卡代发":"取现";
                            translog.setTransType(transType);
                            String reqNo = translog.getTransDate()+translog.getTransId();
                            /* 记录不存在才允许进行添加 */
                            if (!existsReqNoList.contains(reqNo)) {
                                detailList.add(translog);
                            }
                            if (pReqNoList.contains(reqNo)) {
                                updateDetailList.add(translog);
                            }
                            if (!flowNoList.contains(reqNo)) {
                                flowNoList.add(reqNo);
                            }
                        }
                        /* 如果记录数小于100 说明没有下一页了*/
                        if (recordlist.size() < 100) {
                            break;
                        }
                        pageNumber++;
                    }else{
                        transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                        log.error(RET(response,2));
                        /* 如果返回数据异常，则直接循环下一个钱包数据 */
                        break;
                    }
                }catch (Exception e){
                    break;
                }
            }
        }
        //原处理中状态更新状态
        if (CollectionUtil.isNotEmpty(updateDetailList)) {
            for (HuifuWalletTranslog detail : updateDetailList) {
                if("处理中".equals(detail.getTransStat())){
                    continue;
                }
                huifuWalletTranslogDao.updateStatus(detail);
            }
        }
        /* 数据为空，则下面不需要执行了 */
        if (CollectionUtil.isEmpty(detailList)) {
            return "1";
        }
        /* 批量插入数据 */
        huifuWalletTranslogDao.insertBatch(detailList);
        return "1";
    }

    @Override
    public String huifuWalletAccountFeeFileApply(String stmtType, String startDate, String endDate) throws CrmebWalletException {
        return null;
    }

    @Override
    public Map<String, Object> huifuWalletAccountFeeFileQuery(String stmtType, String outRequestNo, String backOrderNo) throws CrmebWalletException {
        return null;
    }

    /**
     * <b> 获取企业钱包账户提现记录 </b>
     * @author ZXF
     * @create 2023/04/23 0023 10:37
     * @version
     * @注意事项 </b>
     */
    @Override
    public PageInfo<HuifuWalletTranslog> thisHuifuWalletTranslog(HuifuWalletTranslogDto dto) throws CrmebWalletException {
        if (StringUtils.isEmpty(dto.getUniId())) {
            throw new CrmebWalletException("企业ID不能为空");
        }
        if (dto.getPageNumber() == null) {
            throw new CrmebWalletException("第几页不能为空");
        }
        if (dto.getPageSize() == null) {
            throw new CrmebWalletException("每页多少行不能为空");
        }
        if (StringUtil.isEmpty(dto.getStartDate())) {
            throw new CrmebWalletException("开始日期不能为空");
        }
        if (StringUtil.isEmpty(dto.getEndDate())) {
            throw new CrmebWalletException("结束日期不能为空");
        }
        PageHelper.startPage(dto.getPageNumber(), dto.getPageSize());
        dto.setStartDate(dto.getStartDate().replace("-",""));
        dto.setEndDate(dto.getEndDate().replace("-",""));
        List<HuifuWalletTranslog> detailList = huifuWalletTranslogDao.selectByUniIdAndDate(dto);
        return new PageInfo(detailList);
    }

    /**
     * <b> C端转账接口 - 聚合正扫 </b>
     * @author ZXF
     * @create 2023/08/24 0024 11:31
     * @version
     * @注意事项 </b>
     */
    @Override
    public String huifuJspayTransfer(JsPayTransferDto dto) throws CrmebWalletException {
        Date date = new Date();
        logger.info(">>>>>>>>> C端转账接口huifuJspayTransfer："+dto.getBusinessPartnerSeq()+",开始");
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }

        boolean redisRepetition = redisUtil.getRedisRepetition(dto.getBusinessPartnerSeq());
        if (!redisRepetition) {
            logger.info(">>>>>>>>> C端转账接口huifuJspayTransfer："+dto.getBusinessPartnerSeq()+",交易已提交，请勿重复操作");
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }
        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(dto.getBusinessPartnerSeq(), dto.getTradeType());
        if (countTrade>0) {
            logger.info(">>>>>>>>> C端转账接口huifuJspayTransfer："+dto.getBusinessPartnerSeq()+",交易已完成，请勿重复操作");
            throw new CrmebWalletException("交易已完成，请勿重复操作");
        }
        if (StringUtil.isEmpty(dto.getGoodsDesc())) {
            throw new CrmebWalletException("商品描述不能为空");
        }
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto inAccount;//入账方 商家
        if(dto.getSellFeePriority()==0){
            // 买方 -> 平台 -> 商家
            // 订单100-平台10=分商家90
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
        }else{
            // 买方 -> 商家 -> 平台
            inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId(),PaymentChannel.HUIFU.toString());
        }
//        inAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(dto.getInId());
        //入账到平台，金额暂时设定为0.01元
//        inAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
//        dto.setAmount("0.02");
        if(inAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        p.put("huifuId", HFProfileCPayConstants.HUIFU_ID);
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("transAmt", dto.getAmount());
        p.put("isPlatAcct", "0");
        p.put("platAmount", "0.00");
        p.put("tradeType", dto.getTradeType());
        //计算入账方金额
        String inAmount = dto.getAmount();
        BigDecimal commissionAmount = new BigDecimal(inAmount).multiply(new BigDecimal("0.0063"));
        //如果手续费小于0.01元就扣0.01元
        if(commissionAmount.compareTo(new BigDecimal("0.01")) < 0){
            commissionAmount = new BigDecimal("0.01");
        }
        String cAmount = decimalFormat.format(commissionAmount);
        BigDecimal fee = new BigDecimal(inAmount).subtract(commissionAmount);
        inAmount = decimalFormat.format(fee);

        p.put("inAmount", inAmount);
        p.put("inWalletAccountNo", inAccount.getWalletAccountNo());
        p.put("commissionAmount", cAmount);//手续费
        String wxData = dto.getWxData()!=null?JSONObject.toJSONString(dto.getWxData()):"";
        String alipayData = dto.getAlipayData()!=null?JSONObject.toJSONString(dto.getAlipayData()):"";
        p.put("wxData", wxData);
        p.put("alipayData", alipayData);
        p.put("notifyUrl", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_HF_API_URL)+HFConstants.JSPAY_CALLBACK);
        p.put("remark", dto.getComment());
        p.put("goodDesc", dto.getGoodsDesc());
        logger.info(">>>>>>>>> C端转账接口huifuJspayTransfer，请求参数："+p.toString());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.JSPAY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("huifuJspayTransfer",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))||HFConstants.REQUEST_SUCC_XD_CODE.equals(RET(response,1))){
            final String ina = dto.getAmount();
            Boolean execute = transactionTemplate.execute(e -> {
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                JsPayTrade jsPayTrade = new JsPayTrade();
                jsPayTrade.setBusinessCode(dto.getBusinessCode());
                jsPayTrade.setBusinessPartnerSeq(dto.getBusinessPartnerSeq());
                jsPayTrade.setReqSeqId(response.get("req_seq_id").toString());
                jsPayTrade.setHfSeqId(response.get("hf_seq_id").toString());
                jsPayTrade.setCreateTime(date);
                jsPayTrade.setUpdateTime(new Date());
                jsPayTrade.setGoodDesc(dto.getGoodsDesc());
                if(dto.getWxData()!=null){
                    jsPayTrade.setWxData(JSON.toJSONString(dto.getWxData()));
                }
                if(dto.getAlipayData()!=null) {
                    jsPayTrade.setAlipayData(JSON.toJSONString(dto.getAlipayData()));
                }
                logger.info(">>>>>>>>> C端转账接口huifuJspayTransfer，pay_info转义："+response.get("pay_info").toString().replace("\"", "\\\""));
                jsPayTrade.setPayInfo(response.get("pay_info").toString());
                jsPayTrade.setIncomeAccountNo(inAccount.getWalletAccountNo());
                jsPayTrade.setInUniId(inAccount.getUniId());
                jsPayTrade.setRemark(dto.getComment());
                jsPayTrade.setUniId(dto.getUniId());
                jsPayTrade.setAmount(new BigDecimal(ina));
                jsPayTrade.setCommissionAmount(new BigDecimal(cAmount));
                jsPayTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                jsPayTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                jsPayTradeDao.insert(jsPayTrade);
//                if("1".equals(dto.getIsPlatAcct())){
//                    //平台分账也需要产生一条交易记录
//                    JsPayTrade platTrade = JSONObject.parseObject(JSON.toJSONString(jsPayTrade), JsPayTrade.class);;
//                    platTrade.setIncomeAccountNo(HFProfileConstants.HUIFU_ID);
//                    platTrade.setAmount(new BigDecimal(dto.getPlatAmount()));
//                    jsPayTradeDao.insertJsPayTrade(platTrade);
//                }
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new CrmebWalletException("企业钱包-交易支付-操作失败");
            }
            logger.info("===>C端转账接口huifuJspayTransfer.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> C端转账接口huifuJspayTransfer："+dto.getBusinessPartnerSeq()+",支付确认：succ");
            return response.get("pay_info").toString();
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    public static void main(String[] args) {
//        WxData w = new WxData();
//        Detail d = new Detail();
//        List<GoodsDetail> goods_detail = Lists.newArrayList();
//        GoodsDetail g = new GoodsDetail();
//        g.setGoods_name("风评商品");
//        g.setPrice(new BigDecimal("125"));
//        g.setQuantity(10);
//        g.setGoods_id("10001");
//        goods_detail.add(g);
//        d.setCost_price(new BigDecimal("1250.00"));
//        d.setGoods_detail(goods_detail);
//        w.setAttach("自定义参数");
//        w.setOpenid("123456");
//        w.setBody("商品描述");
//        w.setDetail(d);
//        System.out.println(JSONObject.toJSONString(w));
        String ret = "{\"bank_code\":\"\",\"org_req_date\":\"20231124\",\"trans_date\":\"20231124\",\"ord_amt\":\"0.02\",\"resp_desc\":\"交易处理中\",\"trans_stat\":\"P\",\"bank_accepted_flag\":\"Y\",\"org_hf_seq_id\":\"002900TOP1B231124132456P751ac139c0100000\",\"bank_message\":\"\",\"hf_seq_id\":\"003100TOP2B231124132638P979ac139cab00000\",\"remark\":\"风评商品微信退款\",\"trans_time\":\"132638\",\"org_req_seq_id\":\"20231124132456248hagarjtj92ewb5\",\"req_seq_id\":\"20231124132638632tz375otbxea5uq\",\"product_id\":\"KAZX\",\"req_date\":\"20231124\",\"resp_code\":\"00000100\",\"huifu_id\":\"6666000138624387\",\"acct_split_bunch\":\"{\\\"acct_infos\\\":[{\\\"div_amt\\\":\\\"0.01\\\",\\\"huifu_id\\\":\\\"6666000138624387\\\"},{\\\"div_amt\\\":\\\"0.01\\\",\\\"huifu_id\\\":\\\"6666000137445326\\\"}],\\\"fee_amt\\\":\\\"0.00\\\"}\"}";
        Map<String,Object> response = (Map<String,Object>)JSON.parseObject(ret,Map.class);
        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))||HFConstants.REQUEST_SUCC_XD_CODE.equals(RET(response,1))){
            response.get("req_seq_id").toString();
            response.get("hf_seq_id").toString();
//            response.get("wx_response").toString();//这里放的是 微信返回的响应报文
//            response.get("alipay_response").toString();//这里放的是 支付宝返回的响应报文
//            response.get("trans_finish_time").toString();//20211021163242
            response.get("acct_split_bunch").toString();//这里放的是 分账信息
            Constants.tradeStatus(response.get("trans_stat").toString()); // 交易成功
            System.out.println(1);
        }
        System.out.println(2);
    }

    /**
     * <b> C端聚合正扫记录加入交易详情表 </b>
     * @author ZXF
     * @create 2023/08/25 0025 16:43
     * @version
     * @注意事项 </b>
     */
    @Override
    public void jspayAddAccountDetail(JsPayTrade jsPayTrade) throws CrmebWalletException {
        HuifuWalletAccountDto dto = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(jsPayTrade.getIncomeAccountNo());
        HuifuWalletAccountDetail detail = huifuWalletAccountDetailDao.geAccountDetailByTradeFlowNo(jsPayTrade.getHfSeqId(), dto.getUniId());
        if(detail != null){
            return;
        }
        /* 调用支付平台接口获取账户交易明细 ***/
        Map<String, Object> p = new HashMap<>();
        p.put("huifuId", HFProfileCPayConstants.HUIFU_ID);
        p.put("orgHfSeqId", jsPayTrade.getHfSeqId());
        p.put("orgReqDate", DateUtils.formatDate(jsPayTrade.getCreateTime(),"yyyyMMdd"));
        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.SCANPAYQUERY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("jspayAddAccountDetail",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            detail = new HuifuWalletAccountDetail();
            detail.setTradeDate(response.get("trans_time").toString()); // 交易时间
            detail.setTradeFlowNo(jsPayTrade.getHfSeqId()); // 交易流水号
            detail.setFlowNo(response.get("out_trans_id").toString()); // 账务流水号（业务流水号）
            detail.setAccountsDealType("内部户处理"); //账务处理类型
            detail.setAccountsDealDate(response.get("acct_date").toString());// 账务处理时间
            detail.setAmount(response.get("trans_amt").toString()); // 交易金额
            detail.setBalance(""); // 交易后余额,工行没有交易后余额的数据
            detail.setDirection("入账"); // 资金流向
            String acctStat = response.get("acct_stat").toString();
            String tradeStatus = Constants.ACCTSTAT_CS.equals(acctStat)?"初始":Constants.ACCTSTAT_CLZ.equals(acctStat)?"处理中":Constants.ACCTSTAT_CG.equals(acctStat)?"成功":"失败";
            detail.setHandStatus(tradeStatus); // 处理状态
            detail.setTradeType(response.get("acct_trans_type").toString()); // 交易类型

            detail.setUniId(dto.getUniId());
            detail.setAccountIn(dto.getWalletAccountNo());
            detail.setPayChannel(PaymentChannel.HUIFU.toString());
            huifuWalletAccountDetailDao.insert(detail);
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            log.error(RET(response,2));
        }
    }

    /**
     * <b> C端退款接口 - 扫码交易退款 </b>
     * @author ZXF
     * @create 2023/08/24 0024 11:31
     * @version
     * @注意事项 </b>
     */
    @Override
    public String huifuJspayRefund(JsPayTransferDto dto) throws CrmebWalletException {
        Date date = new Date();
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getAmount())) {
            throw new CrmebWalletException("订单金额不能为空");
        }
        if (StringUtil.isEmpty(dto.getOldBusinessPartnerSeq())) {
            throw new CrmebWalletException("原业务交易流水号不能为空");
        }
        JsPayTrade jpt = jsPayTradeDao.getHfReqIdByReq(dto.getOldBusinessPartnerSeq());
        if (jpt == null) {
            throw new CrmebWalletException("原业务交易记录无效或不存在");
        }
        if (StringUtil.isEmpty(dto.getBusinessCode())) {
            throw new CrmebWalletException("业务编码不能为空");
        }
        if (StringUtil.isEmpty(dto.getBusinessPartnerSeq())) {
            throw new CrmebWalletException("业务交易流水号不能为空");
        }
        dto.setBusinessPartnerSeq(dto.getBusinessPartnerSeq()+"CT");
        logger.info(">>>>>>>>> C端退款接口huifuJspayRefund："+dto.getBusinessPartnerSeq()+",开始");
        boolean redisRepetition = redisUtil.getRedisRepetition(dto.getBusinessPartnerSeq());
        if (!redisRepetition) {
            logger.info(">>>>>>>>> C端退款接口huifuJspayRefund："+dto.getBusinessPartnerSeq()+",交易已提交，请勿重复操作");
            throw new CrmebWalletException("交易已提交，请勿重复操作");
        }
        int countTrade = huifuWalletTradeDao.getHuifuWalletTradeByReq(dto.getBusinessPartnerSeq(), dto.getTradeType());
        if (countTrade>0) {
            logger.info(">>>>>>>>> C端退款接口huifuJspayRefund："+dto.getBusinessPartnerSeq()+",交易已完成，请勿重复操作");
            throw new CrmebWalletException("交易已完成，请勿重复操作");
        }
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        outAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(jpt.getIncomeAccountNo());
        if(outAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        String platAmount = dto.getPlatAmount();
        String lockAmount = decimalFormat.format(jpt.getAmount().subtract(new BigDecimal(platAmount)));
        if(dto.getSellFeePriority()==0){
            // 先到平台的话直接拿记录的分账金额当冻结金额
            lockAmount = decimalFormat.format(new BigDecimal(platAmount));
        }

        String tradeType = StringUtils.isEmpty(dto.getTradeType())?"05":dto.getTradeType();
        //扣除手续费后才是实际要冻结的金额
        lockAmount = decimalFormat.format(new BigDecimal(lockAmount).subtract(jpt.getCommissionAmount()));
//        extractedLock(outAccount.getUniId(), tradeType, lockAmount);

        //临时设置退款0.02元
//        dto.setAmount("0.02");
        p.put("huifuId", HFProfileCPayConstants.HUIFU_ID);
        p.put("reqSeqId", SequenceTools.getReqSeqId32());
        p.put("ordAmt", dto.getAmount());
        p.put("orgHfSeqId", jpt.getHfSeqId());
        p.put("orgReqDate", DateUtils.formatDate(jpt.getCreateTime(),"yyyyMMdd"));
        p.put("notifyUrl", systemConfigService.getValueByKey(SysConfigConstants.CONFIG_HF_API_URL)+HFConstants.JSPAY_REFUND_CALLBACK);
        p.put("remark", dto.getComment());

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.SCANPAYREFUND;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("huifuJspayRefund",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        //冻结/解冻业务逻辑判断，计算记录冻结金额并入库 当前 TODO 解冻  业务待完善
//        BigDecimal frozenAmount = extractedLock(outAccount.getUniId(),"",dto.getBusinessCode(), "05", dto.getAmount());
        String lockAmountStr = lockAmount;
        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))||HFConstants.REQUEST_SUCC_XD_CODE.equals(RET(response,1))){//更新冻结金额

            Boolean execute = transactionTemplate.execute(e -> {
                syncUpdateSumFrozenAmount(outAccount.getUniId(),"04".equals(dto.getTradeType())?new BigDecimal(lockAmountStr):"05".equals(dto.getTradeType())?new BigDecimal("-"+lockAmountStr):BigDecimal.ZERO);

                logger.info(">>>>>>>>> C端退款接口huifuJspayRefund response：11133333");
                transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
                JsPayTrade jsPayTrade = new JsPayTrade();
                jsPayTrade.setBusinessCode(dto.getBusinessCode());
                jsPayTrade.setBusinessPartnerSeq(dto.getBusinessPartnerSeq());
                jsPayTrade.setOldBusinessPartnerSeq(jpt.getBusinessPartnerSeq());
                jsPayTrade.setReqSeqId(response.get("req_seq_id").toString());
                jsPayTrade.setHfSeqId(response.get("hf_seq_id").toString());
                jsPayTrade.setCreateTime(date);
                jsPayTrade.setUpdateTime(new Date());
                jsPayTrade.setGoodDesc("（退款）"+jpt.getGoodDesc());
                jsPayTrade.setTransFinishTime(response.get("trans_date")+""+response.get("trans_time"));//20211021163242
                jsPayTrade.setPayInfo(response.get("acct_split_bunch").toString());//这里放的是 分账信息
                jsPayTrade.setOutcomeAccountNo(outAccount.getWalletAccountNo());
                jsPayTrade.setInUniId(jpt.getUniId());
                jsPayTrade.setRemark(dto.getComment());
                jsPayTrade.setUniId(outAccount.getUniId());
                jsPayTrade.setAmount(new BigDecimal(dto.getAmount()));
                jsPayTrade.setTradeType(dto.getTradeType()); // 企业账户支付
                jsPayTrade.setTradeStatus(Constants.tradeStatus(response.get("trans_stat").toString())); // 交易成功
                jsPayTradeDao.insert(jsPayTrade);
                return Boolean.TRUE;
            });
            if (!execute) {
                throw new CrmebWalletException("企业钱包-交易支付-操作失败");
            }
            logger.info(">>>>>>>>> C端退款接口huifuJspayRefund response：222222");

            //平台分账业务退款
            if(Double.parseDouble(dto.getPlatAmount())>0){
                HuifuWalletAccountDto platAccount;
                if(dto.getSellFeePriority()==0){
                    // 买方 -> 平台 -> 商家
                    // 订单100-平台10=分商家90
                    dto.setPlatAmount((new BigDecimal(dto.getAmount())).subtract(new BigDecimal(dto.getPlatAmount())).toString());
                    platAccount = huifuWalletAccountDao.getHuifuWalletAccountByUniId(jpt.getInUniId(),PaymentChannel.HUIFU.toString());
                }else{
                    // 买方 -> 商家 -> 平台
                    platAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(HFProfileConstants.HUIFU_ID);
                }
                logger.info(">>>>>>>>> C端退款接口huifuJspayRefund：二级分账退款开始");
                HuifuWalletTransferDto dtoP = new HuifuWalletTransferDto();
                dtoP.setAmount(dto.getPlatAmount());
                dtoP.setOutId(platAccount.getUniId());
                dtoP.setInId(outAccount.getUniId());
                String comment = dto.getSellFeePriority()==0?"订单【"+dto.getBusinessPartnerSeq()+"】支付商品费退款："+dto.getPlatAmount()+"元":"订单【"+dto.getBusinessPartnerSeq()+"】支付平台服务费退款："+dto.getPlatAmount()+"元";
                dtoP.setComment(comment);
                dtoP.setBusinessPartnerSeq(dto.getBusinessPartnerSeq()+"-PT");
                dtoP.setTradeType(tradeType);
                dtoP.setBusinessCode(jpt.getBusinessCode());
                dtoP.setGoodsName(jpt.getGoodDesc());
                dtoP.setGoodsNumber("-");
                dtoP.setGoodsUnit("-");
                logger.info(">>>>>>>>> C端退款接口huifuJspayRefund：二级分账退款报文内容："+JSON.toJSONString(dtoP));
                //异步
                syncRefundToPlat(dtoP);
                logger.info(">>>>>>>>> C端退款接口huifuJspayRefund：二级分账退款任务生成");
            }

            logger.info("===>C端退款接口huifuJspayRefund.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> C端退款接口huifuJspayRefund："+dto.getBusinessPartnerSeq()+",支付确认：succ");
            return response.get("hf_seq_id").toString();
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    /**
     * <b> C端交易退款查询接口 </b>
     * @author ZXF
     * @create 2023/08/24 0024 11:31
     * @version
     * @注意事项 </b>
     */
    @Override
    public String huifuJspayRefundQuery(JsPayTransferDto dto) throws CrmebWalletException {
        Date date = new Date();
        logger.info(">>>>>>>>> C端交易退款查询接口huifuJspayRefundQuery："+dto.getBusinessPartnerSeq()+",开始");
        long a = System.currentTimeMillis();
        if (StringUtil.isEmpty(dto.getOldBusinessPartnerSeq())) {
            throw new CrmebWalletException("原业务交易流水号不能为空");
        }
        JsPayTrade jpt = jsPayTradeDao.getHfReqIdByReq(dto.getOldBusinessPartnerSeq());
        if (jpt == null) {
            throw new CrmebWalletException("原业务交易记录无效或不存在");
        }
        Map<String, Object> p = new HashMap<>();
        HuifuWalletAccountDto outAccount;
        outAccount = huifuWalletAccountDao.getHuifuWalletAccountByWalletNo(jpt.getIncomeAccountNo());
        if(outAccount == null){
            throw new CrmebWalletException("商户数据异常，请联系管理员");
        }
        p.put("huifuId", jpt.getOutcomeAccountNo());
        p.put("orgHfSeqId", jpt.getHfSeqId());
        p.put("orgReqDate", DateUtils.formatDate(jpt.getCreateTime(),"yyyyMMdd"));

        Map<String, Object> response;
        HFBusiCode hFBusiCode;
        try {
            hFBusiCode = HFBusiCode.REFUNDQUERY;
            response = V2ApiRequest.api(hFBusiCode,p);
        }catch (Exception e){
            transactionLogService.save("huifuJspayRefundQuery",Constants.N, JSONObject.toJSONString(p),e.getMessage(),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(e.getMessage());
        }

        if(HFConstants.REQUEST_SUCC_CODE.equals(RET(response,1))){
            transactionLogService.save(hFBusiCode.toString(),Constants.Y, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            logger.info("===>C端交易退款查询接口huifuJspayRefundQuery.本次转账耗时："+((System.currentTimeMillis()-a)/1000)+"秒");
            logger.info(">>>>>>>>> C端交易退款查询接口huifuJspayRefundQuery："+dto.getBusinessPartnerSeq()+",支付确认：succ");
            return response.toString();
        }else{
            transactionLogService.save(hFBusiCode.toString(),Constants.N, JSONObject.toJSONString(p),JSONObject.toJSONString(response),PaymentChannel.HUIFU.toString());
            throw new CrmebWalletException(RET(response,2));
        }
    }

    @Override
    public void testLock(String uniId, String tradeType, String amount) {
        //TODO 需要调整引用
//        BigDecimal frozenAmount = extractedLock(uniId, tradeType, amount);
        //更新冻结金额
        syncUpdateSumFrozenAmount(uniId,"04".equals(tradeType)?(new BigDecimal(amount)):"05".equals(tradeType)?(new BigDecimal("-"+amount)):BigDecimal.ZERO);
//        huifuWalletAccountDao.updateFrozenAmount(uniId,frozenAmount.toString());
    }
}

