package com.sunxung.factoring.service.fundmanagement.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.dict.impl.FinancialCustomerStatusDict;
import com.sunxung.factoring.entity.GridPage;
import com.sunxung.factoring.entity.ResponseJson;
import com.sunxung.factoring.entity.ValidatorEntity;
import com.sunxung.factoring.entity.fundmanagement.*;
import com.sunxung.factoring.entity.fundmanagement.vo.*;
import com.sunxung.factoring.entity.project.BusinessAssignee;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.sys.*;
import com.sunxung.factoring.entity.sys.vo.SeachUser;
import com.sunxung.factoring.mapper.fundmanagement.FinancialInstitutionMapper;
import com.sunxung.factoring.service.fundmanagement.*;
import com.sunxung.factoring.service.invoicemanage.InvoiceGoodsInfoService;
import com.sunxung.factoring.service.project.BusinessAssigneeService;
import com.sunxung.factoring.service.project.BusinessProcessingLogService;
import com.sunxung.factoring.service.project.BusinessProcessingTaskService;
import com.sunxung.factoring.service.purchcontractmanagement.PurchContractBasicInfoService;
import com.sunxung.factoring.service.purchcontractmanagement.PurchContractService;
import com.sunxung.factoring.service.salescontractmanagement.ISalesContractBasicInfoHistoryService;
import com.sunxung.factoring.service.salescontractmanagement.ICSalesContractBasicInfoService;
import com.sunxung.factoring.service.salescontractmanagement.SalesContractService;
import com.sunxung.factoring.service.salescontractmanagement.SalesContractSettleInfoService;
import com.sunxung.factoring.service.settlement.SettlementGoodsInfoService;
import com.sunxung.factoring.service.sys.*;
import com.sunxung.factoring.service.sys.dto.AttachmentDto;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description :
 * @Author : L.Jia
 * @Date: 2023-02-13 20:13
 */
@Service
public class FinancialInstitutionServiceImpl extends ServiceImpl<FinancialInstitutionMapper, FinancialInstitutionInfo>
        implements FinancialInstitutionService {

    @Autowired
    private FinancialInstitutionMapper financialInstitutionMapper;

    @Autowired
    private FinancialRelationCustomerService financialRelationCustomerService;

    @Autowired
    private FinancialRelationCustomerDisburseService financialRelationCustomerDisburseService;

    @Autowired
    private FinancialCustomerInfoService financialCustomerInfoService;

    @Autowired
    private FinancialCustomerExpenditureInfoService financialCustomerExpenditureInfoService;

    @Autowired
    private PurchContractService purchContractService;

    @Autowired
    private PurchContractBasicInfoService purchContractBasicInfoService;

    @Autowired
    private SalesContractService salesContractService;

    @Autowired
    private ICSalesContractBasicInfoService salesContractBasicInfoService;

    @Autowired
    private SalesContractSettleInfoService salesContractSettleInfoService;

    @Autowired
    private ISalesContractBasicInfoHistoryService salesContractBasicInfoHistoryService;

    @Autowired
    private SettlementGoodsInfoService settlementGoodsInfoService;

    @Autowired
    private ISysAttachmentRefService sysAttachmentRefService;

    @Autowired
    private InvoiceGoodsInfoService invoiceGoodsInfoService;

    @Autowired
    private FinancialCustomerExpenditureContractInfoService financialCustomerExpenditureContractInfoService;

    @Autowired
    private DictionaryService dictService;

    @Value("${config.financial.findRecordList.url}")
    private String findRecordListUrl;

    @Value("${config.judge.enterprise.review.url}")
    private String judgeEnterpriseReviewUrl;

    @Value("${config.review.getProjectManager.url}")
    private String getProjectManagerUrl;

    @Value("${config.review.getQuotaDisburse.url}")
    private String getQuotaDisburseUrl;

    @Value("${config.review.getReviewAccountsReceivable.url}")
    private String getReviewAccountsReceivableUrl;

    @Value("${config.fileStorage.getFile.url}")
    private String getFileUrl;

    @Value("${config.contract.getContractFile.url}")
    private String getContractFileUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private BusinessAssigneeService assigneeService;

    @Autowired
    private FlowableService flowableService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private UserOrgRelService userOrgRelService;

    @Autowired
    private BusinessProcessingTaskService businessProcessingTaskService;

    @Autowired
    private BusinessProcessingLogService businessProcessingLogService;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private PermissionService permissionService;

    @Override
    public GridPage<FinancialInstitutionInfo> findBySearch(SeachUser search) {

        List<UserRoleRel> userRoleRels = roleService.getUserRoleByUserId(ThreadLocalUtil.getUserId());
        List<Long> userIdList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userRoleRels)) {
            for (UserRoleRel userRoleRel : userRoleRels) {
                Role role = roleService.get(userRoleRel.getRoleId());
                if (ConstantUtil.REFINANCING_OPERATION_OWNER.equals(role.getName())) {
                    //如果角色为再融资操作岗位，获取当前用户部门下的所有用户Id
                    List<UserOrgRel> userOrgRels = userService.findOrgRelByUserId(ThreadLocalUtil.getUserId());
                    if (CollectionUtil.isNotEmpty(userOrgRels)) {
                        for (UserOrgRel userOrgRel : userOrgRels) {
                            List<Long> userIds = userService.findUserIdByOrgId(userOrgRel.getOrgId());
                            userIdList.addAll(userIds);
                        }
                    }
                } else {
                    List<UserOrgRel> userOrgRelList = userService.findOrgRelByUserId(ThreadLocalUtil.getUserId());
                    for (UserOrgRel userOrgRel : userOrgRelList) {
                        if (userOrgRel.isUserIdentity()) {
                            // 如果是部门负责人，获取部门下所有人员Id
                            List<Long> userIds = userService.findUserIdByOrgId(userOrgRel.getOrgId());
                            userIdList.addAll(userIds);
                        } else {
                            userIdList.add(ThreadLocalUtil.getUserId());
                        }
                    }
                }
            }
        }

        List<Long> pers = permissionService.getPermissionIdByUserId(ThreadLocalUtil.getUserId());
        Permission per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_RELATION_DISBURSE);
        if (per == null) {
            throw new ValidatorException(CodeUtil.FAIL, "数据可见-查看全员权限不能为空");
        }

        Boolean flag = false;
        if (pers.contains(per.getId())
                || ThreadLocalUtil.getUser().getLoginName().equals(ConstantConversionUtil.ADMINISTORIES)) {
            flag = true;
        }
        if (!flag) {
            userIdList = userIdList.stream().distinct().collect(Collectors.toList());
            search.setUserIds(userIdList);
        }

        Page<FinancialInstitutionInfo> page = PageHelper.startPage(search.getPage(), search.getRows());
        List<FinancialInstitutionInfo> result = financialInstitutionMapper.findBySearch(search);
        return new GridPage<>(search.getRows(), search.getPage(), page.getTotal(), result);
    }

    @Override
    public GridPage<FinancialInstitutionDetailVo> getDetailList(FinancialInstitutionSearch search) {
        Page<FinancialInstitutionInfo> page = PageHelper.startPage(search.getPage(), search.getRows());
        List<FinancialInstitutionDetailVo> result = financialInstitutionMapper.getDetailList(search);
        if (CollectionUtil.isNotEmpty(result)) {
            result.stream().forEach(r -> {
                LoanInfoVo loanInfoVo = getLoanInfoVo(r.getBusinessNo(), r.getContractNo(), r.getQuotaDisburseBatch());
                if (loanInfoVo != null) {
                    r.setLoanInfoVo(loanInfoVo);
                }
            });
        }
        return new GridPage<>(search.getRows(), search.getPage(), page.getTotal(), result);
    }

    private LoanInfoVo getLoanInfoVo(String businessNo, String contractNo, Integer quotaDisburseBatch) {
        LoanInfoVo loanInfoVo = new LoanInfoVo();
        if (businessNo != null && contractNo != null && quotaDisburseBatch != null) {
            //调用sop查询业务放款信息
            LoanInfoSearch loanInfoSearch = new LoanInfoSearch(businessNo, contractNo, quotaDisburseBatch);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(findRecordListUrl, loanInfoSearch, String.class);
            ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
            if (responseEntity.getStatusCode().value() == HttpStatus.OK.value() && responseJson.isSuccess()) {
                JSONObject jsonObject = (JSONObject) responseJson.getData();
                if (jsonObject != null) {
                    loanInfoVo = jsonObject.toBean(LoanInfoVo.class);
                }
            }
        }
        return loanInfoVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEnterpriseList(EnterpriseVo enterpriseVo) {
        if (enterpriseVo != null) {
            List<String> enterpriseNameList = enterpriseVo.getEnterpriseName();
            if (enterpriseNameList == null || enterpriseNameList.isEmpty()) {
                throw new ValidatorException(CodeUtil.FAIL, "企业不能为空");
            }
            //查询资方信息
            FinancialInstitutionInfo institutionInfo = getById(enterpriseVo.getFinancialInstitutionInfoId());
            if (institutionInfo == null) {
                throw new ValidatorException(CodeUtil.FAIL, "资方信息不能为空");
            }
            for (String enterpriseName : enterpriseNameList) {
                addEnterprise(institutionInfo, enterpriseName);
            }
        }
    }

    /**
     * 新增客户信息并开启流程
     *
     * @param institutionInfo
     * @param enterpriseName
     */
    private FinancialRelationCustomer addEnterprise(FinancialInstitutionInfo institutionInfo, String enterpriseName) {
        //判断该企业是否被同一个资方关联
        FinancialRelationCustomer latestRelationCustomer = financialRelationCustomerService.getOne(new QueryWrapper<FinancialRelationCustomer>()
                .eq("financial_institution_info_id", institutionInfo.getId())
                .eq("credit_subject_name", enterpriseName));
        if (latestRelationCustomer != null) {
            throw new ValidatorException(CodeUtil.FAIL, "该企业-" + enterpriseName + "-已被同一个资方关联、不能重复关联");
        }
        //判断该企业是否评审决议确认已完成
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(judgeEnterpriseReviewUrl + "?enterpriseName=" + enterpriseName, String.class);
        ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
        if (responseEntity.getStatusCode().value() == HttpStatus.OK.value() && responseJson.isSuccess()) {
            Boolean b = (Boolean) responseJson.getData();
            if (!b) {
                throw new ValidatorException(CodeUtil.FAIL, "该企业-" + enterpriseName + "-评审决议确认未完成，请重新选择其它企业");
            }
        }
        //保存关联企业信息
        FinancialRelationCustomer relationCustomer = new FinancialRelationCustomer();
        relationCustomer.setCreditSubjectName(enterpriseName);
        relationCustomer.setFinancialInstitutionInfoId(institutionInfo.getId());
        //调用sop查询该企业的业务经理
        List<String> managerStrList = getProjectManager(enterpriseName);
        relationCustomer.setProjectManager(StringUtils.join(managerStrList, ","));
        financialRelationCustomerService.save(relationCustomer);

        //开启关联企业审批流程
        //1.新增客户信息数据
        FinancialCustomerInfo financialCustomerInfo = new FinancialCustomerInfo();
        financialCustomerInfo.setFinancialRelationCustomerId(relationCustomer.getId());
        financialCustomerInfo.setCustomerStatus(dictService.getByCode(FinancialCustomerStatusDict.ChildEnum.FINANCIAL_CUSTOMER_TO_BE_EDIT.getCode()).getId());
        financialCustomerInfoService.save(financialCustomerInfo);

        //2.新增处理人
        //客户信息编辑人员为--融资经理（所有）+项目经理（对应企业）+项目经理所在部门的对应的再融资操作岗人员
        BusinessAssignee projectManager = new BusinessAssignee(financialCustomerInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_PROCESS);
        // List<Long> candidateIdList = getOperatorLit(managerStrList);
        List<Long> candidateIdList = getOperatorLit(Arrays.asList(institutionInfo.getCustomerManager()));
        projectManager.setCandidateId(StringUtils.join(candidateIdList, ","));
        projectManager.setAssigneeType(ConstantUtil.ASSIGNEE_REFINANCIAL_OPERATOR);
        assigneeService.add(projectManager);

        //获取对应的资方的id
        User backerUser = userService.getByName(institutionInfo.getInstitutionName());
        BusinessAssignee financialAssignee = new BusinessAssignee(financialCustomerInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_PROCESS);
        financialAssignee.setAssigneeId(backerUser.getId());
        financialAssignee.setAssigneeType(ConstantUtil.ASSIGNEE_FINANCIAL_BACKER);
        assigneeService.add(financialAssignee);


        //3.开启流程实例
        Map<String, Object> procVariables = new HashMap<>();
        procVariables.put(ConstantUtil.FINANCIAL_CUSTOMER_COMMIT_CANDIDATE,
                assigneeService.getCandidateByBusiness(financialCustomerInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_PROCESS, ConstantUtil.ASSIGNEE_REFINANCIAL_OPERATOR));
        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, institutionInfo.getInstitutionName() + "--" + enterpriseName);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "资方名称为“" + institutionInfo.getInstitutionName() + "---客户名称为" + enterpriseName + "”的项目已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS) + "—formBusiness”阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        //查询条件：资方名称/客户名称
        String queryBusiness = institutionInfo.getInstitutionName() + FlowableUtil.splitChar + enterpriseName;
        ProcessInstance processInst = flowableService.startProcessInstance(financialCustomerInfo, procVariables,
                FlowableUtil.generateBusinessKey(financialCustomerInfo, ConstantUtil.FINANCIAL_CUSTOMER_PROCESS, queryBusiness), msgVariables, ConstantUtil.FINANCIAL_CUSTOMER_PROCESS);
        if (processInst == null) {
            throw new BusinessException(CodeUtil.FAIL, "流程启动失败");
        }
        return relationCustomer;
    }

    /**
     * 调用sop获取对应企业的项目经理
     *
     * @param enterpriseName 企业名称
     * @return
     */
    private List<String> getProjectManager(String enterpriseName) {
        ResponseEntity<String> managerResponse = restTemplate.getForEntity(getProjectManagerUrl + "?enterpriseName=" + enterpriseName, String.class);
        ResponseJson managerResponseJson = JSONUtil.toBean(managerResponse.getBody(), ResponseJson.class);
        List<String> managerStrList = new ArrayList<>();
        if (managerResponse.getStatusCode().value() == HttpStatus.OK.value() && managerResponseJson.isSuccess()) {
            JSONArray jsonArray = (JSONArray) managerResponseJson.getData();
            if (jsonArray != null && !jsonArray.isEmpty()) {
                managerStrList = jsonArray.toList(String.class);
            }
        }
        return managerStrList;
    }

    /**
     * 获取客户信息和客户支用信息的处理人(融资经理（所有）+项目经理（对应企业）+项目经理所在部门的对应的再融资操作岗人员)
     *
     * @param managerStrList
     * @return
     */
    private List<Long> getOperatorLit(List<String> managerStrList) {
        //获取角色为融资经理的所有人员
        List<User> refinancingManagerList = userService.findUserByRoleName(ConstantUtil.FINANCIAL_MANAGER);

        //获取对应客户的再融资操作岗的所有人员
        //获取角色为再融资操作岗的所有人员
        List<User> refinancingOperatorList = userService.findUserByRoleName(ConstantUtil.REFINANCING_OPERATION_OWNER);
        //获取企业业务经理所属部门
        List<Long> orgIdList = getOrgIdList(managerStrList);
        if (CollectionUtil.isNotEmpty(refinancingOperatorList)) {
            refinancingOperatorList = refinancingOperatorList.stream().filter(u -> {

                for (Long orgId : orgIdList) {
                    UserOrgRel userOrgRel = userService.getByUserIdAndOrgId(u.getId(), orgId);
                    if (userOrgRel != null) {
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
        }

        //获取对应客户的业务经理
        List<User> managerList = getUserList(managerStrList);

        //获取办理组
        return getCandidate(refinancingManagerList, refinancingOperatorList, managerList);
    }

    @Override
    public List<CreditSubjectsVo> getQuotaDisburseList(Long institutionId) {

        //调用sop获取对应资方支用信息
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(getQuotaDisburseUrl + "?institutionId=" + institutionId, String.class);
        ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);

        List<QuotaDisburseVo> quotaDisburseVoList = new ArrayList<>();
        if (responseEntity.getStatusCode().value() == HttpStatus.OK.value() && responseJson.isSuccess()) {
            JSONArray jsonArray = (JSONArray) responseJson.getData();
            if (jsonArray != null && !jsonArray.isEmpty()) {
                quotaDisburseVoList = jsonArray.toList(QuotaDisburseVo.class);
            }
        } else {
            throw new BusinessException(CodeUtil.FAIL, "调用sop获取对应资方支用信息失败:" + responseJson.getMsg());
        }

        //对返回结果进行分组处理
        Map<String, Map<String, Map<String, List<QuotaDisburseVo>>>> map = quotaDisburseVoList.stream()
                .collect(Collectors.groupingBy(QuotaDisburseVo::getCreditSubjectName,
                        Collectors.groupingBy(QuotaDisburseVo::getBusinessNo,
                                Collectors.groupingBy(QuotaDisburseVo::getContractNo))));

        List<CreditSubjectsVo> result = new ArrayList<>();
        for (String creditSubjectName : map.keySet()) {
            CreditSubjectsVo creditSubjectsVo = new CreditSubjectsVo();
            creditSubjectsVo.setCreditSubjectName(creditSubjectName);

            Map<String, Map<String, List<QuotaDisburseVo>>> businessNumberMap = map.get(creditSubjectName);
            List<BusinessNumbersVo> businessNumbersVoList = new ArrayList<>();
            for (String businessNumber : businessNumberMap.keySet()) {
                BusinessNumbersVo businessNumbersVo = new BusinessNumbersVo();
                businessNumbersVo.setBusinessNo(businessNumber);

                Map<String, List<QuotaDisburseVo>> contractMap = businessNumberMap.get(businessNumber);
                List<ContractNumbersVo> contractNumbersVoList = new ArrayList<>();
                for (String contractNumber : contractMap.keySet()) {
                    ContractNumbersVo contractNumbersVo = new ContractNumbersVo();
                    contractNumbersVo.setContractNo(contractNumber);
                    List<QuotaDisburseVo> quotaDisburseVos = contractMap.get(contractNumber);

                    List<QuotaDisburseBatchVo> quotaDisburseBatchVoList = quotaDisburseVos.stream().map(quotaDisburseVo -> {
                        QuotaDisburseBatchVo quotaDisburseBatchVo = new QuotaDisburseBatchVo();
                        quotaDisburseBatchVo.setQuotaDisburseBatch(quotaDisburseVo.getQuotaDisburseBatch());
                        return quotaDisburseBatchVo;
                    }).collect(Collectors.toList());
                    contractNumbersVo.setQuotaDisburseBatchs(quotaDisburseBatchVoList);
                    contractNumbersVoList.add(contractNumbersVo);
                }
                businessNumbersVo.setContractNumbersVos(contractNumbersVoList);
                businessNumbersVoList.add(businessNumbersVo);
            }
            creditSubjectsVo.setBusinessNumbers(businessNumbersVoList);
            result.add(creditSubjectsVo);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEnterpriseDisburseList(EnterpriseDisburseVo enterpriseDisburseVo) {
        if (enterpriseDisburseVo != null) {
            //查询资方信息
            FinancialInstitutionInfo institutionInfo = getById(enterpriseDisburseVo.getFinancialInstitutionInfoId());
            Long financialInstitutionInfoId = enterpriseDisburseVo.getFinancialInstitutionInfoId();

            List<QuotaDisburseVo> quotaDisburseVoList = enterpriseDisburseVo.getQuotaDisburseVoList();
            if (CollectionUtil.isNotEmpty(quotaDisburseVoList)) {
                for (QuotaDisburseVo quotaDisburseVo : quotaDisburseVoList) {
                    String creditSubjectName = quotaDisburseVo.getCreditSubjectName();
                    if (creditSubjectName == null) {
                        throw new ValidatorException(CodeUtil.FAIL, "授信主体不能为空");
                    }
                    //判断资方对应的企业是否已经已经审批，是的话只发起支用流程，否的话同时发起客户流程和支用流程
                    FinancialRelationCustomer relationCustomer = financialRelationCustomerService.getOne(new QueryWrapper<FinancialRelationCustomer>()
                            .eq("financial_institution_info_id", financialInstitutionInfoId)
                            .eq("credit_subject_name", quotaDisburseVo.getCreditSubjectName()));
                    if (relationCustomer == null) {
                        //发起客户信息流程
                        relationCustomer = addEnterprise(institutionInfo, creditSubjectName);
                    }

                    //判断对应支用是否已经审批
                    FinancialRelationCustomerDisburse exist = financialRelationCustomerDisburseService.getOne(new QueryWrapper<FinancialRelationCustomerDisburse>()
                            .eq("business_no", quotaDisburseVo.getBusinessNo())
                            .eq("contract_no", quotaDisburseVo.getContractNo())
                            .eq("quota_disburse_batch", quotaDisburseVo.getQuotaDisburseBatch()));
                    if (exist != null) {
                        throw new ValidatorException(CodeUtil.FAIL, "业务编号--" + quotaDisburseVo.getBusinessNo()
                                + ",合同编号--" + quotaDisburseVo.getContractNo()
                                + ",批次号--" + quotaDisburseVo.getQuotaDisburseBatch() + "的支用已经提交过客户支用，不能重复提交！");
                    }

                    //发起客户支用信息流程
                    //1.保存关联企业支用信息
                    FinancialRelationCustomerDisburse relationCustomerDisburse = new FinancialRelationCustomerDisburse();
                    relationCustomerDisburse.setBusinessNo(quotaDisburseVo.getBusinessNo());
                    relationCustomerDisburse.setContractNo(quotaDisburseVo.getContractNo());
                    relationCustomerDisburse.setQuotaDisburseBatch(quotaDisburseVo.getQuotaDisburseBatch());
                    relationCustomerDisburse.setFinancialRelationCustomerId(relationCustomer.getId());
                    //调用sop查询到期日
                    LoanInfoVo loanInfoVo = getLoanInfoVo(quotaDisburseVo.getBusinessNo(), quotaDisburseVo.getContractNo(), quotaDisburseVo.getQuotaDisburseBatch());
                    if (loanInfoVo != null && loanInfoVo.getExpireDate() != null) {
                        relationCustomerDisburse.setExpireDate(loanInfoVo.getExpireDate());
                    }
                    financialRelationCustomerDisburseService.save(relationCustomerDisburse);

                    //2.新增客户支用信息数据
                    FinancialCustomerExpenditureInfo customerExpenditureInfo = new FinancialCustomerExpenditureInfo();
                    customerExpenditureInfo.setFinancialRelationCustomerDisburseId(relationCustomerDisburse.getId());
                    customerExpenditureInfo.setDisburseStatus(dictService.getByCode(FinancialCustomerStatusDict.ChildEnum.FINANCIAL_CUSTOMER_TO_BE_EDIT.getCode()).getId());
                    financialCustomerExpenditureInfoService.save(customerExpenditureInfo);

                    //3.新增处理人
                    //客户信息编辑人员为--融资经理（所有）+项目经理（对应企业）+项目经理所在部门的对应的再融资操作岗人员
                    BusinessAssignee projectManager = new BusinessAssignee(customerExpenditureInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS);

                    //List<String> managerStrList = getProjectManager(creditSubjectName);
                    List<Long> candidateIdList = getOperatorLit(Arrays.asList(institutionInfo.getCustomerManager()));
                    projectManager.setCandidateId(StringUtils.join(candidateIdList, ","));
                    projectManager.setAssigneeType(ConstantUtil.ASSIGNEE_REFINANCIAL_OPERATOR);
                    assigneeService.add(projectManager);
                    //获取对应的资方的id
                    User backerUser = userService.getByName(institutionInfo.getInstitutionName());
                    BusinessAssignee financialAssignee = new BusinessAssignee(customerExpenditureInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS);
                    financialAssignee.setAssigneeId(backerUser.getId());
                    financialAssignee.setAssigneeType(ConstantUtil.ASSIGNEE_FINANCIAL_BACKER);
                    assigneeService.add(financialAssignee);


                    //4.开启流程实例
                    Map<String, Object> procVariables = new HashMap<>();
                    procVariables.put(ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_EDIT,
                            assigneeService.getCandidateByBusiness(customerExpenditureInfo.getId(), ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS, ConstantUtil.ASSIGNEE_REFINANCIAL_OPERATOR));
                    Map<String, Object> msgVariables = new HashMap<>(2);
                    msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, creditSubjectName + "--" + quotaDisburseVo.getBusinessNo() + "--" + quotaDisburseVo.getContractNo());
                    msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                            "客户名称为“" + creditSubjectName + "--业务编号为" + quotaDisburseVo.getBusinessNo()
                                    + "--合同编号为" + quotaDisburseVo.getContractNo()
                                    + "--批次号为" + quotaDisburseVo.getQuotaDisburseBatch() + "”的项目已进入“"
                                    + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS) + "—formBusiness”阶段，"
                                    + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
                    //查询条件：资方名称/客户名称
                    String queryBusiness = institutionInfo.getInstitutionName() + FlowableUtil.splitChar + creditSubjectName;
                    ProcessInstance processInst = flowableService.startProcessInstance(customerExpenditureInfo, procVariables,
                            FlowableUtil.generateBusinessKey(customerExpenditureInfo, ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS, queryBusiness), msgVariables, ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS);
                    if (processInst == null) {
                        throw new BusinessException(CodeUtil.FAIL, "流程启动失败");
                    }

                    //判断对应业务是sop底层还是贸理通底层
                    LoanInfoSearch loanInfoSearch = new LoanInfoSearch(relationCustomerDisburse);
                    ResponseEntity<String> responseEntity = restTemplate.postForEntity(getReviewAccountsReceivableUrl, loanInfoSearch, String.class);
                    ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
                    if (responseEntity.getStatusCode().value() == HttpStatus.OK.value() && responseJson.isSuccess()) {
                        JSONObject jsonObject = (JSONObject) responseJson.getData();
                        if (jsonObject != null) {
                            ReviewAccountsReceivableVo reviewAccountsReceivableVo = jsonObject.toBean(ReviewAccountsReceivableVo.class);
                            if (reviewAccountsReceivableVo == null) {
                                throw new ValidatorException(CodeUtil.FAIL, "从sop获取不到支用对应的底层信息");
                            }
                            if (reviewAccountsReceivableVo.getTradeFactoring()) {
                                //生成贸理通支用数据
                                List<String> tradeReceivablesNumbers = reviewAccountsReceivableVo.getTradeReceivablesNumberList();
//                                generateTradeDisburse(tradeReceivablesNumbers, customerExpenditureInfo);
                            } else {
                                //生成非贸理通业务支用数据
                                List<DomesticAccountsReceivableVo> sopAccountsReceivables = reviewAccountsReceivableVo.getSopAccountsReceivables();
                                generateNoTradeDisburse(sopAccountsReceivables, customerExpenditureInfo);
                            }
                        }
                    }
                    //从贸理通抓取保理合同附件
                    ResponseEntity<String> contractFileResponse = restTemplate.postForEntity(getContractFileUrl, loanInfoSearch, String.class);
                    ResponseJson contractFileResponseJson = JSONUtil.toBean(contractFileResponse.getBody(), ResponseJson.class);
                    if (contractFileResponse.getStatusCode().value() == HttpStatus.OK.value() && contractFileResponseJson.isSuccess()) {
                        JSONObject jsonObject = (JSONObject) contractFileResponseJson.getData();
                        if (jsonObject != null) {
                            ContractFileVo contractFileVo = jsonObject.toBean(ContractFileVo.class);
                            if (contractFileVo != null) {
                                List<FileStorage> contractFileList = contractFileVo.getContractFileList();
                                if (CollectionUtil.isNotEmpty(contractFileList)) {
                                    FileModuleDict.ChildEnum childEnum = FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_ATTACHMENT_FILE;
                                    for (FileStorage fileStorage : contractFileList) {
                                        //从sop获取文件
                                        String fileName = fileStorage.getName().substring(0, fileStorage.getName().lastIndexOf("."));
                                        String localFilePath = FileUtil.getAbsolutePath(fileName, fileStorage.getFileType(), childEnum);
                                        File destFile = new File(localFilePath);
                                        if (!destFile.getParentFile().exists()) {
                                            destFile.getParentFile().mkdirs();
                                        }
                                        getFileBySop(fileStorage, destFile);
                                        //新建FileStorage
                                        FileStorage newFileStorage = new FileStorage(fileStorage, localFilePath, childEnum);
                                        fileStorageService.add(newFileStorage);
                                        //新建关联关系
                                        AttachmentDto attachmentDto = AttachmentDto.builder().setEntityId(customerExpenditureInfo.getId()).setChildEnum(childEnum).build();
                                        sysAttachmentRefService.saveRef(Arrays.asList(newFileStorage.getId()), attachmentDto);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 生成客户支用-合同信息(非贸理通业务)
     *
     * @param sopAccountsReceivables
     * @param customerExpenditureInfo
     */
    private void generateNoTradeDisburse(List<DomesticAccountsReceivableVo> sopAccountsReceivables, FinancialCustomerExpenditureInfo customerExpenditureInfo) {

        if (CollectionUtil.isNotEmpty(sopAccountsReceivables)) {
            for (DomesticAccountsReceivableVo domesticAccountsReceivableVo : sopAccountsReceivables) {
                FinancialCustomerExpenditureContractInfo customerExpenditureContractInfo = new FinancialCustomerExpenditureContractInfo();

                customerExpenditureContractInfo.setFinancialCustomerExpenditureInfoId(customerExpenditureInfo.getId());
                //下游合同编号
                customerExpenditureContractInfo.setDownstreamContractNo(domesticAccountsReceivableVo.getContractNo());
                //下游合同金额
                customerExpenditureContractInfo.setDownstreamContractAmount(domesticAccountsReceivableVo.getContractAmount());
                //下游合同账期
                customerExpenditureContractInfo.setDownstreamContractPaymentDays(domesticAccountsReceivableVo.getTerm());
                //下游应收账款金额
                customerExpenditureContractInfo.setDownstreamAccountsReceivableAmount(domesticAccountsReceivableVo.getAccountsReceivableAmount());
                financialCustomerExpenditureContractInfoService.save(customerExpenditureContractInfo);

                List<FileStorage> fileStorageList = domesticAccountsReceivableVo.getDomesticAccountsReceivableFileList();
                if (CollectionUtil.isNotEmpty(fileStorageList)) {
                    List<FileModuleDict.ChildEnum> fileModuleList =
                            Arrays.asList(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_SETTLEMENT_FILE
                                    , FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_SALES_FILE
                                    , FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_INVOICE_FILE);
                    for (FileStorage fileStorage : fileStorageList) {
                        for (FileModuleDict.ChildEnum childEnum : fileModuleList) {
                            //从sop获取文件
                            String fileName = fileStorage.getName().substring(0, fileStorage.getName().lastIndexOf("."));
                            String localFilePath = FileUtil.getAbsolutePath(fileName, fileStorage.getFileType(), childEnum);
                            File destFile = new File(localFilePath);
                            if (!destFile.getParentFile().exists()) {
                                destFile.getParentFile().mkdirs();
                            }
                            getFileBySop(fileStorage, destFile);
                            //新建FileStorage
                            FileStorage newFileStorage = new FileStorage(fileStorage, localFilePath, childEnum);
                            fileStorageService.add(newFileStorage);
                            //新建关联关系
                            AttachmentDto attachmentDto = AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).setChildEnum(childEnum).build();
                            sysAttachmentRefService.saveRef(Arrays.asList(newFileStorage.getId()), attachmentDto);
                        }
                    }
                }
            }
        }
    }

    /**
     * 使用RestTemplate从sop下载文件
     *
     * @param fileStorage
     */
    private void getFileBySop(FileStorage fileStorage, File destFile) {
        //CloseableHttpClient httpclient = HttpClients.createDefault();

        CloseableHttpClient httpclient = CloseableHttpClientUtils.getHttpClient();

        HttpPost request = new HttpPost(getFileUrl + "?fileId=" + fileStorage.getId());
        HttpResponse response;
        try {
            response = httpclient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
                InputStream input = response.getEntity().getContent();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                IOUtils.copy(input, baos);
                FileUtils.writeByteArrayToFile(destFile, baos.toByteArray());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 生成客户支用-合同信息(贸理通业务)
     *
     * @param tradeReceivablesNumbers
     * @param customerExpenditureInfo
     */
//    private void generateTradeDisburse(List<String> tradeReceivablesNumbers, FinancialCustomerExpenditureInfo
//            customerExpenditureInfo) {
//        if (CollectionUtil.isNotEmpty(tradeReceivablesNumbers)) {
//            for (String tradeReceivablesNumber : tradeReceivablesNumbers) {
//                UnderlyingBasicInfo underlyingBasicInfo = underlyingBasicInfoService.getOne
//                        (new QueryWrapper<UnderlyingBasicInfo>().eq("receivables_number", tradeReceivablesNumber));
//                if (underlyingBasicInfo != null) {
//                    FinancialCustomerExpenditureContractInfo customerExpenditureContractInfo = new FinancialCustomerExpenditureContractInfo();
//                    customerExpenditureContractInfo.setFinancialCustomerExpenditureInfoId(customerExpenditureInfo.getId());
//                    //上游合同编号
//                    customerExpenditureContractInfo.setUpstreamContractNo(underlyingBasicInfo.getContractNumber());
//                    //上游合同金额
//                    customerExpenditureContractInfo.setUpstreamContractAmount(underlyingBasicInfo.getContractAmount());
//                    //上游合同账期
//                    customerExpenditureContractInfo.setUpstreamContractPaymentDays(underlyingBasicInfo.getAccountReceivablePeriod().toString());
//                    //上游应收账款金额
//                    List<UnderlyingAccountsReceivableInfo> accountsReceivableInfoList = underlyingAccountsReceivableInfoService.list(new QueryWrapper<UnderlyingAccountsReceivableInfo>()
//                            .eq("underlying_basic_info_id", underlyingBasicInfo.getId()));
//                    if (CollectionUtil.isNotEmpty(accountsReceivableInfoList)) {
//                        BigDecimal accountsReceivableAmountTotal = accountsReceivableInfoList.stream().filter(a -> a.getAccountsReceivableAmount() != null)
//                                .map(UnderlyingAccountsReceivableInfo::getAccountsReceivableAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//                        customerExpenditureContractInfo.setUpstreamAccountsReceivableAmount(accountsReceivableAmountTotal);
//                    }
//
//                    //下游应收账款金额
//                    List<UnderlyingGoodsInfo> underlyingGoodsInfoList = underlyingGoodsInfoService.list(new QueryWrapper<UnderlyingGoodsInfo>()
//                            .eq("underlying_basic_info_id", underlyingBasicInfo.getId()));
//                    if (CollectionUtil.isNotEmpty(underlyingGoodsInfoList)) {
//                        BigDecimal accountsReceivableAmountTotal = underlyingGoodsInfoList.stream().filter(a -> a.getSalesTotalPrice() != null)
//                                .map(UnderlyingGoodsInfo::getSalesTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
//                        customerExpenditureContractInfo.setDownstreamAccountsReceivableAmount(accountsReceivableAmountTotal);
//                    }
//
//                    CSalesContract salesContractManagement = salesContractService.getByBusinessNumber(underlyingBasicInfo.getBusinessNumber());
//                    SalesContractBasicInfo salesContractBasicInfo;
//                    if (salesContractManagement != null) {
//                        salesContractBasicInfo = salesContractBasicInfoService.getLatestBasicInfo(salesContractManagement.getId(), ConstantConversionUtil.APPROVAL_RESULT_PASS);
//                        if (salesContractBasicInfo != null) {
//                            //下游合同编号
//                            customerExpenditureContractInfo.setDownstreamContractNo(salesContractBasicInfo.getContractNumber());
//                            //下游合同金额
//                            customerExpenditureContractInfo.setDownstreamContractAmount(salesContractBasicInfo.getContractPlanAmount());
//                            //下游合同账期
//                            SalesContractSettleInfo salesContractSettleInfo = salesContractSettleInfoService.findByBasicInfoId(salesContractBasicInfo.getId());
//
//                            String downstreamContractPaymentDays = "";
//                            if (salesContractSettleInfo != null && salesContractSettleInfo.getPlanPaybackDays() != null) {
//                                downstreamContractPaymentDays = "结算后" + salesContractSettleInfo.getPlanPaybackDays() + "天";
//                            }
//                            customerExpenditureContractInfo.setDownstreamContractPaymentDays(downstreamContractPaymentDays);
//                        }
//                    }
//                    financialCustomerExpenditureContractInfoService.save(customerExpenditureContractInfo);
//
//                    //采购合同
//                    //根据业务编号和供应商Id获取对应的采购合同编号
//                    PurchContractManagement purchContractManagement = purchContractService.getOne(new QueryWrapper<PurchContractManagement>().
//                            eq("business_number", underlyingBasicInfo.getBusinessNumber())
//                            .eq("supplier_id", underlyingBasicInfo.getSupplierId()));
//                    if (purchContractManagement != null) {
//                        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.getLatestBasicInfo(purchContractManagement.getId(), ConstantConversionUtil.APPROVAL_RESULT_PASS);
//                        List<FileStorage> purchaseContractFileList = sysAttachmentRefService.getFiles(AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.PURCHASE_CONTRACT_FILE)
//                                .setEntityId(purchContractBasicInfo.getId()).build());
//                        if (CollectionUtil.isNotEmpty(purchaseContractFileList)) {
//                            purchaseContractFileList.stream().forEach(p -> {
//                                sysAttachmentRefService.copyFile(p, FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_UPSTREAM_PURCH_FILE,
//                                        AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).build());
//                            });
//                        }
//                    }
//
//                    List<Long> settlementBasicInfoIds = new ArrayList<>();
//                    if (CollectionUtil.isNotEmpty(underlyingGoodsInfoList)) {
//                        List<Long> acceptanceBasicInfoIds = underlyingGoodsInfoList.stream().map(UnderlyingGoodsInfo::getAcceptanceBasicInfoId).distinct().collect(Collectors.toList());
//                        if (CollectionUtil.isNotEmpty(acceptanceBasicInfoIds)) {
//                            List<SettlementGoodsInfo> settlementGoodsInfoList = settlementGoodsInfoService.list(new QueryWrapper<SettlementGoodsInfo>().in("acceptance_basic_info_id", acceptanceBasicInfoIds));
//                            if (CollectionUtil.isNotEmpty(settlementGoodsInfoList)) {
//                                settlementBasicInfoIds = settlementGoodsInfoList.stream().map(SettlementGoodsInfo::getSettlementBasicInfoId).distinct().collect(Collectors.toList());
//                            }
//                        }
//                    }
//                    if (CollectionUtil.isNotEmpty(settlementBasicInfoIds)) {
//                        for (Long settlementBasicInfoId : settlementBasicInfoIds) {
//                            //上游结算单
//                            List<FileStorage> upstreamFileList = sysAttachmentRefService.getFiles(AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.SETTLEMENT_UPSTREAM_UNSIGNED_FILE)
//                                    .setEntityId(settlementBasicInfoId).build());
//                            if (CollectionUtil.isNotEmpty(upstreamFileList)) {
//                                upstreamFileList.stream().forEach(u -> {
//                                    sysAttachmentRefService.copyFile(u, FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_UPSTREAM_SETTLEMENT_FILE,
//                                            AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).build());
//                                });
//                            }
//                            //下游结算单
//                            List<FileStorage> settlementFileList = sysAttachmentRefService.getFiles(AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.SETTLEMENT_FILE)
//                                    .setEntityId(settlementBasicInfoId).build());
//                            if (CollectionUtil.isNotEmpty(settlementFileList)) {
//                                settlementFileList.stream().forEach(s -> {
//                                    sysAttachmentRefService.copyFile(s, FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_SETTLEMENT_FILE,
//                                            AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).build());
//                                });
//                            }
//                        }
//                        List<InvoiceGoodsInfo> invoiceGoodsInfoList = invoiceGoodsInfoService.list(new QueryWrapper<InvoiceGoodsInfo>()
//                                .in("settlement_basic_info_id", settlementBasicInfoIds));
//                        if (CollectionUtil.isNotEmpty(invoiceGoodsInfoList)) {
//                            List<Long> InvoiceBasicInfoIdList = invoiceGoodsInfoList.stream().map(InvoiceGoodsInfo::getInvoiceBasicInfoId).distinct().collect(Collectors.toList());
//                            for (Long invoiceBasicInfoId : InvoiceBasicInfoIdList) {
//                                //采购发票
//                                List<FileStorage> purchaseFileList = sysAttachmentRefService.getFiles(AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.INVOICE_PURCHASE_FILE)
//                                        .setEntityId(invoiceBasicInfoId).build());
//                                if (CollectionUtil.isNotEmpty(purchaseFileList)) {
//                                    purchaseFileList.stream().forEach(p -> {
//                                        sysAttachmentRefService.copyFile(p, FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_UPSTREAM_INVOICE_FILE,
//                                                AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).build());
//                                    });
//                                }
//                                //销售待开发票
////                                List<FileStorage> salesFileList = sysAttachmentRefService.getFiles(AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.INVOICE_SALES_FILE)
////                                        .setEntityId(invoiceBasicInfoId).build());
////                                if (CollectionUtil.isNotEmpty(salesFileList)) {
////                                    salesFileList.stream().forEach(p -> {
////                                        sysAttachmentRefService.copyFile(p, FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_INVOICE_FILE,
////                                                AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).build());
////                                    });
////                                }
//                            }
//                        }
//                    }
//                    if (salesContractManagement != null) {
//                        //销售合同
//                        SalesContractBasicInfoHistory salesContractBasicInfoHistory = salesContractBasicInfoHistoryService.getOne(new QueryWrapper<SalesContractBasicInfoHistory>()
//                                .eq("sales_contract_management_id", salesContractManagement.getId()).orderByDesc("id").last("LIMIT 1"));
//                        List<FileStorage> salesFileList = sysAttachmentRefService.getFiles(AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.SALES_CONTRACT_HIS_FILE)
//                                .setEntityId(salesContractBasicInfoHistory.getId()).build());
//                        if (CollectionUtil.isNotEmpty(salesFileList)) {
//                            salesFileList.stream().forEach(s -> {
//                                sysAttachmentRefService.copyFile(s, FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_SALES_FILE,
//                                        AttachmentDto.builder().setEntityId(customerExpenditureContractInfo.getId()).build());
//                            });
//                        }
//                    }
//                }
//            }
//        }
//    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEnterprise(FinancialInstitutionDetailVo financialInstitutionDetailVo) {

        if (financialInstitutionDetailVo.getRelationCustomerDisburseId() != null) {
            //如果删除的是关联支用 判断当前支用是否为编辑态 才满足删除条件
            FinancialCustomerExpenditureInfo customerExpenditureInfo = financialCustomerExpenditureInfoService
                    .getOne(new QueryWrapper<FinancialCustomerExpenditureInfo>().eq("financial_relation_customer_disburse_id", financialInstitutionDetailVo.getRelationCustomerDisburseId()));
            FinancialRelationCustomerDisburse customerDisburse = financialRelationCustomerDisburseService.getById(customerExpenditureInfo.getFinancialRelationCustomerDisburseId());
            FinancialCustomerInfo financialCustomer = financialCustomerInfoService.getOne(new QueryWrapper<FinancialCustomerInfo>().eq("financial_relation_customer_id", customerDisburse.getFinancialRelationCustomerId()));
            if (!dictService.get(customerExpenditureInfo.getDisburseStatus()).getCode().equals(FinancialCustomerStatusDict.ChildEnum.FINANCIAL_CUSTOMER_TO_BE_EDIT.getCode())) {
                throw new ValidatorException(CodeUtil.FAIL, "已存在流程数据，不可删除！");
            }
            BusinessProcessingLog expenditureLog = businessProcessingLogService.getByBusinessTypeBusinessKey(ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS, customerExpenditureInfo.getId());
            //终止支用流程
            businessProcessingTaskService.terminate(expenditureLog.getHistoricTaskId(), customerExpenditureInfo.getId(), expenditureLog.getBusinessType(),
                    expenditureLog.getTaskName(), expenditureLog.getTaskDefKey());

            //删除客户支用合同信息
            List<FinancialCustomerExpenditureContractInfo> customerExpenditureContractInfoList = financialCustomerExpenditureContractInfoService.list(new QueryWrapper<FinancialCustomerExpenditureContractInfo>()
                    .eq("financial_customer_expenditure_info_id", customerExpenditureInfo.getId()));
            if (CollectionUtil.isNotEmpty(customerExpenditureContractInfoList)) {
                List<Long> idList = customerExpenditureContractInfoList.stream().map(FinancialCustomerExpenditureContractInfo::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(idList)) {
                    for (Long id : idList) {
                        //上游采购合同
                        AttachmentDto upstreamPurchDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_UPSTREAM_PURCH_FILE).setEntityId(id).build();
                        sysAttachmentRefService.removeFileAndRef(upstreamPurchDto);
                        //上游结算单
                        AttachmentDto upstreamSettleDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_UPSTREAM_SETTLEMENT_FILE).setEntityId(id).build();
                        sysAttachmentRefService.removeFileAndRef(upstreamSettleDto);
                        //上游采购发票
                        AttachmentDto upstreamInvoiceDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_UPSTREAM_INVOICE_FILE).setEntityId(id).build();
                        sysAttachmentRefService.removeFileAndRef(upstreamInvoiceDto);
                        //下游销售合同
                        AttachmentDto downstreamSalesDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_SALES_FILE).setEntityId(id).build();
                        sysAttachmentRefService.removeFileAndRef(downstreamSalesDto);
                        //下游结算单
                        AttachmentDto downstreamSettleDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_SETTLEMENT_FILE).setEntityId(id).build();
                        sysAttachmentRefService.removeFileAndRef(downstreamSettleDto);
                        //下游发票
                        AttachmentDto downstreamInvoiceDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_DOWNSTREAM_INVOICE_FILE).setEntityId(id).build();
                        sysAttachmentRefService.removeFileAndRef(downstreamInvoiceDto);
                    }
                }
                financialCustomerExpenditureContractInfoService.removeByIds(idList);
            }
            //删除保理合同附件
            AttachmentDto attachmentDto = AttachmentDto.builder().setChildEnum(FileModuleDict.ChildEnum.FINANCIAL_EXPENDITURE_ATTACHMENT_FILE).setEntityId(customerExpenditureInfo.getId()).build();
            sysAttachmentRefService.removeFileAndRef(attachmentDto);

            //删除客户支用
            financialCustomerExpenditureInfoService.removeById(customerExpenditureInfo);

            //删除数据
            financialRelationCustomerDisburseService.removeById(customerDisburse);

            List<FinancialRelationCustomerDisburse> customerDisburses = financialRelationCustomerDisburseService.list(new QueryWrapper<FinancialRelationCustomerDisburse>()
                    .eq("financial_relation_customer_id", financialInstitutionDetailVo.getRelationCustomerId()));
            if (customerDisburses.isEmpty()) {
                //如果客户对应的支用信息都为空 删除客户信息
                if (dictService.get(financialCustomer.getCustomerStatus()).getCode().equals(FinancialCustomerStatusDict.ChildEnum.FINANCIAL_CUSTOMER_TO_BE_EDIT.getCode())) {
                    BusinessProcessingLog customerLog = businessProcessingLogService.getByBusinessTypeBusinessKey(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS, financialCustomer.getId());
                    //终止客户信息流程
                    businessProcessingTaskService.terminate(customerLog.getHistoricTaskId(), financialCustomer.getId(), customerLog.getBusinessType(),
                            customerLog.getTaskName(), customerLog.getTaskDefKey());
                    //删除客户信息
                    financialCustomerInfoService.removeById(financialCustomer);
                    //删除关联客户信息
                    FinancialRelationCustomer relationCustomer = financialRelationCustomerService.getById(financialInstitutionDetailVo.getRelationCustomerId());
                    financialRelationCustomerService.removeById(relationCustomer);
                }
            }
        } else {
            //删除客户信息
            FinancialCustomerInfo financialCustomer = financialCustomerInfoService.getOne(new QueryWrapper<FinancialCustomerInfo>()
                    .eq("financial_relation_customer_id", financialInstitutionDetailVo.getRelationCustomerId()));
            if (financialCustomer != null) {
                financialCustomer.setStatusDictionary(dictService.get(financialCustomer.getCustomerStatus()));
                if (financialCustomer.getStatusDictionary().getCode().equals(FinancialCustomerStatusDict.ChildEnum.FINANCIAL_CUSTOMER_TO_BE_EDIT.getCode())) {
                    BusinessProcessingLog customerLog = businessProcessingLogService.getByBusinessTypeBusinessKey(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS, financialCustomer.getId());
                    //终止客户信息流程
                    businessProcessingTaskService.terminate(customerLog.getHistoricTaskId(), financialCustomer.getId(), customerLog.getBusinessType(),
                            customerLog.getTaskName(), customerLog.getTaskDefKey());
                    //删除客户信息
                    financialCustomerInfoService.removeById(financialCustomer);
                    //删除关联客户信息
                    FinancialRelationCustomer relationCustomer = financialRelationCustomerService.getById(financialInstitutionDetailVo.getRelationCustomerId());
                    financialRelationCustomerService.removeById(relationCustomer);
                } else {
                    throw new ValidatorException(CodeUtil.FAIL, "该数据存在审批流程，不可删除！");
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBackerUser() {
        List<FinancialInstitutionInfo> institutionInfoList = list();
        institutionInfoList.stream().forEach(institutionInfo -> {
            if (userService.getByName(institutionInfo.getInstitutionName()) == null) {
                String loginName = getLoginName(userService.findAllLoginName(), ChinesePinYinUtil.getPinYinFirstChar(institutionInfo.getInstitutionName()));
                //新增资方账号
                User financialBacker = new User();
                financialBacker.setName(institutionInfo.getInstitutionName());
                financialBacker.setPassword(ConstantUtil.PASSWORD);
                financialBacker.setLoginName(loginName);
                financialBacker.setEnabled(true);
                userService.addCustomerUser(financialBacker);
                Role role = roleService.getByRoleName(ConstantUtil.FINANCIAL_BACKER);
                if (role != null) {
                    UserRoleRel userRoleRel = new UserRoleRel();
                    userRoleRel.setRoleId(role.getId());
                    userRoleRel.setUserId(financialBacker.getId());
                    userService.addUserRoleRel(userRoleRel);
                } else {
                    throw new BusinessException(CodeUtil.FAIL, "没有资方角色！");
                }
                Org financialOrg = orgService.getByCode(ConstantUtil.FINANCIAL_BACKER_ORG);
                if (financialOrg != null) {
                    UserOrgRel userOrgRel = new UserOrgRel();
                    userOrgRel.setUserId(financialBacker.getId());
                    userOrgRel.setOrgCode(financialOrg.getInternalCode());
                    userOrgRel.setOrgId(financialOrg.getId());
                    userOrgRelService.save(userOrgRel);
                } else {
                    throw new BusinessException(CodeUtil.FAIL, "没有资方对应的组织机构！");
                }
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyPassword(String institutionName) {
        User user = userService.getByName(institutionName);
        user.setPassword(ConstantUtil.PASSWORD);
        userService.updateCustomerUser(user);
    }


    /**
     * 获取客户信息、客户支用信息办理人组
     *
     * @param refinancingManagerList  融资经理
     * @param refinancingOperatorList 再融资操作岗人员
     * @param managerList             业务经理
     * @return
     */
    private List<Long> getCandidate
    (List<User> refinancingManagerList, List<User> refinancingOperatorList, List<User> managerList) {
        List<Long> candidateIdList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(refinancingManagerList)) {
            List<Long> refinancingManagerIdList = refinancingManagerList.stream().map(User::getId).collect(Collectors.toList());
            candidateIdList.addAll(refinancingManagerIdList);
        }
        if (CollectionUtil.isNotEmpty(refinancingOperatorList)) {
            List<Long> refinancingOperatorIdList = refinancingOperatorList.stream().map(User::getId).collect(Collectors.toList());
            candidateIdList.addAll(refinancingOperatorIdList);
        }
        if (CollectionUtil.isNotEmpty(managerList)) {
            List<Long> managerIdList = managerList.stream().map(User::getId).collect(Collectors.toList());
            candidateIdList.addAll(managerIdList);
        }
        candidateIdList = candidateIdList.stream().distinct().collect(Collectors.toList());
        return candidateIdList;
    }

    /**
     * 根据名称获取企业业务经理
     *
     * @param managerStrList
     * @return
     */
    private List<User> getUserList(List<String> managerStrList) {
        List<User> userList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(managerStrList)) {
            for (String managerStr : managerStrList) {
                User user = userService.getByName(managerStr);
                if (user != null) {
                    userList.add(user);
                }
            }
        }
        return userList;
    }

    /**
     * 获取企业业务经理所属部门
     *
     * @param managerStrList
     * @return
     */
    private List<Long> getOrgIdList(List<String> managerStrList) {
        List<Long> orgIdList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(managerStrList)) {
            for (String managerStr : managerStrList) {
                User user = userService.getByName(managerStr);
                if (user != null) {
                    List<UserOrgRel> orgRelByUserId = userService.findOrgRelByUserId(user.getId());
                    if (CollectionUtil.isNotEmpty(orgRelByUserId)) {
                        for (UserOrgRel userOrgRel : orgRelByUserId) {
                            orgIdList.add(userOrgRel.getOrgId());
                        }
                    }
                }
            }
            orgIdList = orgIdList.stream().distinct().collect(Collectors.toList());
        }
        return orgIdList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addFinancialInstitution(FinancialInstitutionInfo institutionInfo) {
        ValidatorUtil.validator(ValidatorEntity.ValidatorType.ADD, institutionInfo);
        //判断是否已有该资方
        if (getOne(new QueryWrapper<FinancialInstitutionInfo>().eq("institution_name", institutionInfo.getInstitutionName()).eq("customer_manager", institutionInfo.getCustomerManager())) != null) {
            return true;
        }
        int count = financialInstitutionMapper.insert(institutionInfo);
        if (userService.getByName(institutionInfo.getInstitutionName()) != null) {
            return true;
        }
        String loginName = getLoginName(userService.findAllLoginName(), ChinesePinYinUtil.getPinYinFirstChar(institutionInfo.getInstitutionName()));
        //新增资方账号
        User financialBacker = new User();
        financialBacker.setName(institutionInfo.getInstitutionName());
        financialBacker.setPassword(ConstantUtil.PASSWORD);
        financialBacker.setLoginName(loginName);
        financialBacker.setEnabled(true);
        userService.addCustomerUser(financialBacker);
        Role role = roleService.getByRoleName(ConstantUtil.FINANCIAL_BACKER);
        if (role != null) {
            UserRoleRel userRoleRel = new UserRoleRel();
            userRoleRel.setRoleId(role.getId());
            userRoleRel.setUserId(financialBacker.getId());
            userService.addUserRoleRel(userRoleRel);
        } else {
            throw new BusinessException(CodeUtil.FAIL, "没有资方角色！");
        }
        Org financialOrg = orgService.getByCode(ConstantUtil.FINANCIAL_BACKER_ORG);
        if (financialOrg != null) {
            UserOrgRel userOrgRel = new UserOrgRel();
            userOrgRel.setUserId(financialBacker.getId());
            userOrgRel.setOrgCode(financialOrg.getInternalCode());
            userOrgRel.setOrgId(financialOrg.getId());
            userOrgRelService.save(userOrgRel);
        } else {
            throw new BusinessException(CodeUtil.FAIL, "没有资方对应的组织机构！");
        }
        if (count == 1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFinancialUser(User user) {
        User oldUser = userService.getByName(user.getName());
        //校验相同登录名
        if (userService.validatorLoginName(user.getLoginName(), oldUser.getId()) != null) {
            throw new ValidatorException(CodeUtil.FAIL, "登录名重复，请修改后提交!");
        } else {
            oldUser.setLoginName(user.getLoginName());
            oldUser.setEnabled(true);
            userService.update(oldUser);
        }
    }

    String getLoginName(List<String> names, String name) {
        int m = 1;
        String newName = name;
        while (true) {
            if (names.contains(newName)) {
                newName = name + m;
                m++;
                continue;
            } else {
                break;
            }
        }
        return newName;
    }
}
