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

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sunxung.factoring.component.enums.FinancingCurrentStageEnum;
import com.sunxung.factoring.component.enums.ProjectAndEnterpriseStatusEnums;
import com.sunxung.factoring.component.enums.SupplierStatusEnums;
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.BusinessStageDict;
import com.sunxung.factoring.dict.impl.ProjectInitiationStatusDict;
import com.sunxung.factoring.entity.GridPage;
import com.sunxung.factoring.entity.acceptance.AcceptanceApproval;
import com.sunxung.factoring.entity.acceptance.AcceptanceBasicInfo;
import com.sunxung.factoring.entity.biddingManagement.BiddingGuaranteeMethod;
import com.sunxung.factoring.entity.biddingManagement.CBiddingBasicInfo;
import com.sunxung.factoring.entity.creditresolution.CreditResolution;
import com.sunxung.factoring.entity.customerinformation.Customer;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.financing.apply.CFinancingBasicInfo;
import com.sunxung.factoring.entity.fundmanagement.FinancialCustomerExpenditureInfo;
import com.sunxung.factoring.entity.fundmanagement.FinancialCustomerInfo;
import com.sunxung.factoring.entity.invoicemanage.InvoiceBasicInfo;
import com.sunxung.factoring.entity.loanmanagement.ExemptionMatters;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.Project;
import com.sunxung.factoring.entity.project.ProjectCoreEnterprise;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.project.vo.BusinessHistoricDetailVo;
import com.sunxung.factoring.entity.project.vo.BusinessProcessingLogVo;
import com.sunxung.factoring.entity.project.vo.BusinessProcessingTaskVo;
import com.sunxung.factoring.entity.project.vo.SearchBusinessProcessingTask;
import com.sunxung.factoring.entity.purchcontractmanagement.PurchContractBasicInfo;
import com.sunxung.factoring.entity.purchcontractmanagement.PurchContractManagement;
import com.sunxung.factoring.entity.refundsManagement.RefundManagement;
import com.sunxung.factoring.entity.salescontractmanagement.CSalesContract;
import com.sunxung.factoring.entity.salescontractmanagement.CSalesContractBasicInfo;
import com.sunxung.factoring.entity.settlement.SettlementBasicInfo;
import com.sunxung.factoring.entity.signconfirmation.SignConfirmation;
import com.sunxung.factoring.entity.supplier.SupplierInfo;
import com.sunxung.factoring.entity.sys.*;
import com.sunxung.factoring.entity.sys.flowable.FlowActivityDefinition;
import com.sunxung.factoring.entity.underlying.UnderlyingBasicInfo;
import com.sunxung.factoring.service.acceptancesheet.AcceptanceBasicInfoService;
import com.sunxung.factoring.service.acceptancesheet.AcceptanceSheetLegalFlowService;
import com.sunxung.factoring.service.biddingManagement.IBiddingGuaranteeMethodService;
import com.sunxung.factoring.service.biddingManagement.ICBiddingBasicInfoService;
import com.sunxung.factoring.service.businessmanagement.BusinessBasicInfoService;
import com.sunxung.factoring.service.customerinformation.CustomerService;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.financing.apply.ICFinancingBasicInfoService;
import com.sunxung.factoring.service.fundmanagement.FinancialCustomerExpenditureService;
import com.sunxung.factoring.service.fundmanagement.FinancialCustomerInfoService;
import com.sunxung.factoring.service.invoicemanage.InvoiceBasicInfoService;
import com.sunxung.factoring.service.loanmanagement.IExemptionMattersService;
import com.sunxung.factoring.service.project.*;
import com.sunxung.factoring.service.purchcontractmanagement.PurchContractBasicInfoService;
import com.sunxung.factoring.service.purchcontractmanagement.PurchContractService;
import com.sunxung.factoring.service.refundsManagement.IRefundManagementService;
import com.sunxung.factoring.service.salescontractmanagement.ICSalesContractBasicInfoService;
import com.sunxung.factoring.service.salescontractmanagement.SalesContractService;
import com.sunxung.factoring.service.settlement.SettlementBasicInfoService;
import com.sunxung.factoring.service.signconfirmation.ISignConfirmationService;
import com.sunxung.factoring.service.supplier.ISupplierInfoService;
import com.sunxung.factoring.service.sys.*;
import com.sunxung.factoring.service.sys.flowable.FlowActivityDefinitionService;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import com.sunxung.factoring.service.underlying.UnderlyingBasicInfoService;
import org.apache.xpath.operations.Bool;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class BusinessProcessingTaskServiceImpl implements BusinessProcessingTaskService {

    @Autowired
    private FlowableService flowableService;
    @Autowired
    private UserService userService;
    @Autowired
    private FlowActivityDefinitionService flowActDefService;
    @Autowired
    private BusinessProcessingLogService processingLogService;
    @Autowired
    private DictionaryService dictService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private BusinessBasicInfoService businessBasicInfoService;
    @Autowired
    private SalesContractService salesContractService;
    @Autowired
    private PurchContractService purchContractService;
    @Autowired
    private PurchContractBasicInfoService purchContractBasicInfoService;
    @Autowired
    private AcceptanceBasicInfoService acceptanceBasicInfoService;
    @Autowired
    private InvoiceBasicInfoService invoiceBasicInfoService;
    @Autowired
    private SettlementBasicInfoService settlementBasicInfoService;
    @Autowired
    private UnderlyingBasicInfoService underlyingBasicInfoService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private OrgService orgService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private FinancialCustomerInfoService financialCustomerInfoService;
    @Autowired
    private FinancialCustomerExpenditureService financialCustomerExpenditureService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IBiddingGuaranteeMethodService biddingGuaranteeMethodService;
    @Autowired
    private ISignConfirmationService signConfirmationService;
    @Autowired
    private IExemptionMattersService exemptionMattersService;
    @Autowired
    private IRefundManagementService refundManagementService;
    @Autowired
    private AcceptanceSheetLegalFlowService acceptanceSheetLegalFlowService;
    @Autowired
    private ICSalesContractBasicInfoService salesContractBasicInfoService;
    @Autowired
    private BusinessAssigneeService assigneeService;
    @Autowired
    private ICBiddingBasicInfoService biddingBasicInfoService;
    @Autowired
    private IProjectCoreEnterpriseService projectCoreEnterpriseService;
    @Autowired
    private IProjectInformationService projectInformationService;
    @Autowired
    private ISupplierInfoService supplierInfoService;
    @Autowired
    private ICFinancingBasicInfoService financingBasicInfoService;
    @Autowired
    private RepositoryService repositoryService;


    @Override
    public GridPage<BusinessProcessingTaskVo> findMyPendingList(SearchBusinessProcessingTask search) {

        if (null == search || StringUtil.isEmpty(search.getSimpleClassName())) {
            throw new ValidatorException(CodeUtil.FAIL, "列表分页条件不能为空！");
        }
        if (StringUtil.isNotEmpty(search.getSourceBusinessId())) {
            search.setSourceBusinessId(
                    search.getSimpleClassName() + FlowableUtil.splitChar + search.getSourceBusinessId());
        }
        String simpleClassName = search.getSimpleClassName();
        List<Task> myTasks = flowableService.findMyPendingListPage(search, search.getSimpleClassName());
        //结算单处理
        if (simpleClassName.equals(ConstantUtil.BILL_BASIC_INFORMATION)) {
            List<Task> myPendingListPage = flowableService.findMyPendingListPage(search, ConstantUtil.BILL_UNIT_PRICE_ADJUST);
            if (CollectionUtil.isNotEmpty(myPendingListPage)) {
                myPendingListPage.forEach(r -> myTasks.add(r));
            }
        }
        List<BusinessProcessingTaskVo> rows = new ArrayList<>();
        if (null != myTasks && myTasks.size() > 0) {
            for (Task task : myTasks) {
                BusinessProcessingTaskVo businessProcessingTaskVo = autoPendingVo(task,
                        (Project) flowableService.getBusinessDataByProcessInst(task.getProcessInstanceId()));
                if (businessProcessingTaskVo != null) {
                    rows.add(autoPendingVo(task,
                            (Project) flowableService.getBusinessDataByProcessInst(task.getProcessInstanceId())));
                }
            }
            rows.sort(Comparator.comparing(BusinessProcessingTaskVo::getGmtModified).reversed());
        }
        long count = flowableService.countMyPendingListPage(search, search.getSimpleClassName());
        return new GridPage<>(search.getRows(), search.getPage(), count, rows);
    }

    /**
     * 待我处理：生成列表立项视图对象
     *
     * @param task    待我处理的任务
     * @param project 立项对象
     * @return
     */
    private BusinessProcessingTaskVo autoPendingVo(Task task, Project project) {
        if (null != project && null != task) {
            BusinessProcessingLog log = processingLogService.getLatestByTask(project.getId(),
                    project.getClass().getSimpleName(), task.getId(), ConstantConversionUtil.PROCESS_TASK);
            BusinessProcessingTaskVo taskVo = new BusinessProcessingTaskVo();
            taskVo.setId(project.getId());
            taskVo.setBusinessNumber(project.getBusinessNumber());
            taskVo.setModuleNumber(project.getModuleNumber());
            taskVo.setProjectName(project.getProjectName());
            taskVo.setCustomerName(project.getCustomerName());
            taskVo.setSupplierName(project.getSupplierName());
            taskVo.setGmtModified(project.getGmtModified());
            taskVo.setStatus(project.getStatusDictionary());
            taskVo.setTaskId(task.getId());
            taskVo.setTaskDefKey(task.getTaskDefinitionKey());
            taskVo.setTaskName(task.getName());
            if (task.getAssignee() != null) {
                taskVo.setAssignee(userService.get(Long.parseLong(task.getAssignee())));
            }
            if (project instanceof CBiddingBasicInfo) {
                CBiddingBasicInfo biddingBasicInfo = (CBiddingBasicInfo) project;
                taskVo.setBusinessName(biddingBasicInfo.getProjectName());
                taskVo.setCustomerName(biddingBasicInfo.getCustomerName());
                taskVo.setPlatformName(biddingBasicInfo.getTradingPlatformName());
                taskVo.setSupplierName(biddingBasicInfo.getOwnerName());
                BiddingGuaranteeMethod biddingGuaranteeMethod = biddingGuaranteeMethodService
                        .getOne(new LambdaQueryWrapper<BiddingGuaranteeMethod>()
                                .eq(BiddingGuaranteeMethod::getBiddingBasicInfoId, biddingBasicInfo.getId()));
                if (biddingGuaranteeMethod != null) {
                    if (biddingGuaranteeMethod.getBidGuaranteeMethod().equals(1)) {
                        taskVo.setMode("保函");
                    }
                    if (biddingGuaranteeMethod.getBidGuaranteeMethod().equals(0)) {
                        taskVo.setMode("保证金");
                        taskVo.setOpenAmount(biddingGuaranteeMethod.getDepositAmount());
                    }
                    if (biddingGuaranteeMethod.getBidGuaranteeMethod().equals(2)) {
                        taskVo.setMode("其他");
                    }
                }
                String stageName = biddingBasicInfo.getStage();
                Dictionary stage = dictService.getByNameAndParentCode(stageName, BusinessStageDict.CODE);
                taskVo.setStage(stage);

                if (stageName.equals(BusinessStageDict.ChildEnum.CREATE.getCode())) {
                    taskVo.setExecutor("供应商");
                }
                if (stageName.equals(BusinessStageDict.ChildEnum.GUARANTEE_MODE.getCode())
                        || stageName.equals(BusinessStageDict.ChildEnum.AWARD.getCode())) {
                    taskVo.setExecutor("业务经理");
                }
                if (stageName.equals(BusinessStageDict.ChildEnum.TEMPLATE_REVIEW.getCode())) {
                    taskVo.setExecutor("法务专员");
                }
                if (stageName.equals(BusinessStageDict.ChildEnum.BOND_COLLECTION.getCode()) ||
                        stageName.equals(BusinessStageDict.ChildEnum.REFUND_DEPOSIT.getCode())) {
                    taskVo.setExecutor("财务");
                }
                taskVo.setDelete(false);
                taskVo.setStatus(dictService.getByCode(biddingBasicInfo.getStatusCode()));
            }

            if (project instanceof CSalesContract) {
                CSalesContract salesContractManagement = (CSalesContract) project;
                CSalesContractBasicInfo contractBasicInfo = salesContractBasicInfoService
                        .lambdaQuery().eq(CSalesContractBasicInfo::getcSalesContractManagementId, salesContractManagement.getId()).one();
                if (contractBasicInfo != null) {
                    taskVo.setContractNumber(contractBasicInfo.getContractNumber());
                }
                taskVo.setPlatformName(salesContractManagement.getTradingPlatformName());
                taskVo.setStatus(salesContractManagement.getStatusDictionary());
                taskVo.setContractNumber(salesContractManagement.getContractNumber());
                BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.SALES_CONTRACT, project.getId());

                if (processingLog.getTaskName().contains("创建") || processingLog.getTaskName().contains("录入")
                        || processingLog.getTaskName().contains("签署确认")) {

                    taskVo.setExecutor("供应商");
                } else if (processingLog.getTaskName().contains("初审") || processingLog.getTaskName().contains("审核")) {
                    taskVo.setExecutor("法务专员");
                } else if (processingLog.getTaskName().equals("模板复审")) {
                    taskVo.setExecutor("法务经理");
                }
            }

            if (project instanceof PurchContractManagement) {
                PurchContractManagement purchContractManagement = (PurchContractManagement) project;

                PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.lambdaQuery()
                        .eq(PurchContractBasicInfo::getPurchContractManagementId, purchContractManagement.getId()).one();
                taskVo.setContractNumber(purchContractBasicInfo.getContractNumber());
                taskVo.setProjectName(purchContractBasicInfo.getProjectName());
                taskVo.setPlatformName(purchContractManagement.getTradingPlatformName());

                BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.PURCH_CONTRACT, project.getId());
                if (processingLog.getTaskName().contains("录入")
                        || processingLog.getTaskName().contains("采购合同签署")) {
                    taskVo.setExecutor("供应商");
                } else if (processingLog.getTaskName().contains("审核")) {
                    taskVo.setExecutor("法务专员");
                }
            }

            if (project instanceof AcceptanceBasicInfo) {
                AcceptanceBasicInfo acceptanceBasicInfo = (AcceptanceBasicInfo) project;
                taskVo.setStatusStr(acceptanceBasicInfo.getAcceptanceStatus());
                taskVo.setPlatformName(project.getTradingPlatformName());
                taskVo.setExpectedSettlementTime(((AcceptanceBasicInfo) project).getExpectedSettlementDate());
                if (!((AcceptanceBasicInfo) project).getAcceptanceStatus().equals(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode())) {
                    BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.ACCEPTANCE_SHEET, project.getId());
                    taskVo.setTaskName(processingLog.getTaskName());
                    if (processingLog.getTaskName().equals("法务审核") || processingLog.getTaskName().equals("单价变更审核")) {
                        taskVo.setAssigneeName("法务专员");
                    } else if(processingLog.getTaskName().equals("业务审核")){
                        taskVo.setAssigneeName("业务经理");
                    }else {
                        if (taskVo.getAssignee() != null) {
                            taskVo.setAssigneeName(taskVo.getAssignee().getName());
                        } else {
                            Long userId = assigneeService.getIdByBusiness(processingLog.getBusnessKey(), ConstantUtil.ACCEPTANCE_SHEET, ConstantUtil.ASSIGNEE_PROJECT_MANAGER);
                            taskVo.setAssigneeName(userService.get(userId).getName());
                        }
                    }
                }
            }

            if (project instanceof SettlementBasicInfo) {
                taskVo.setSettlementDate(((SettlementBasicInfo) project).getSettlementDate());
                taskVo.setSettlementAmount(((SettlementBasicInfo) project).getSettlementAmount());
                taskVo.setStatus(((SettlementBasicInfo) project).getStatus());
                taskVo.setPlatformName(((SettlementBasicInfo) project).getTradingPlatformName());
                taskVo.setProjectName(((SettlementBasicInfo) project).getBusinessName());
                taskVo.setBusinessName(project.getBusinessName());
                if (!((SettlementBasicInfo) project).getSettlementStatus().equals(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode())) {
                    BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.BILL_BASIC_INFORMATION, project.getId());
                    BusinessProcessingLog processingLog1 = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.BILL_UNIT_PRICE_ADJUST, project.getId());
                    processingLog = processingLog1 == null ?processingLog:processingLog1;
                    taskVo.setTaskName(processingLog.getTaskName());
                    if (processingLog.getTaskName().equals("法务审核")) {
                        taskVo.setAssigneeName("法务专员");
                    }else if (processingLog.getTaskName().equals("财务审核")) {
                        taskVo.setAssigneeName("财务人员");
                    }else {
                        if (taskVo.getAssignee() != null) {
                            taskVo.setAssigneeName(taskVo.getAssignee().getName());
                        } else {
                            Long userId = assigneeService.getIdByBusiness(processingLog.getBusnessKey(), ConstantUtil.BILL_BASIC_INFORMATION, ConstantUtil.ASSIGNEE_PROJECT_MANAGER);
                            taskVo.setAssigneeName(userService.get(userId).getName());
                        }
                    }
                }
            }

            if (project instanceof UnderlyingBasicInfo) {
                taskVo.setContractNumber(((UnderlyingBasicInfo) project).getContractNumber());
                taskVo.setContractName(((UnderlyingBasicInfo) project).getContractName());
                taskVo.setAccountsReceivableEndDate(((UnderlyingBasicInfo) project).getAccountsReceivableEndDate());
            }

            if (project instanceof InvoiceBasicInfo) {
                taskVo.setAmountKind(((InvoiceBasicInfo) project).getAmountKindDic());
                taskVo.setOpenAmount(((InvoiceBasicInfo) project).getOpenAmount());
                taskVo.setStatus(((InvoiceBasicInfo) project).getInvoiceStatusDic());
                taskVo.setPlatformName(((InvoiceBasicInfo) project).getTradingPlatformName());
                taskVo.setProjectName(((InvoiceBasicInfo) project).getBusinessName());
                taskVo.setBusinessName(project.getBusinessName());
            }

            if (project instanceof FinancialCustomerInfo) {
                taskVo.setInstitutionName(((FinancialCustomerInfo) project).getInstitutionName());
            }
            if (project instanceof FinancialCustomerExpenditureInfo) {
                taskVo.setInstitutionName(((FinancialCustomerExpenditureInfo) project).getInstitutionName());
                taskVo.setContractNumber(((FinancialCustomerExpenditureInfo) project).getContractNo());
                taskVo.setQuotaDisburseBatch(((FinancialCustomerExpenditureInfo) project).getQuotaDisburseBatch());
            }
            if (project instanceof SignConfirmation) {
                SignConfirmation signConfirmation = (SignConfirmation) project;
                Customer customer = customerService.getById(signConfirmation.getEnterpriseCustomerInfoId());
                taskVo.setCustomerName(customer.getEnterpriseName());
                taskVo.setComeFrom(signConfirmation.getComeFrom());
                taskVo.setStatus(dictService.get(signConfirmation.getStatusId()));
            }
            if (project instanceof SupplierInfo) {
                SupplierInfo supplierInfo = (SupplierInfo) project;
                Enterprise enterprise = enterpriseService.getById(supplierInfo.getcEnterpriseId());
                taskVo.setSupplierName(enterprise.getCorporateName());
                Dictionary dictionary = new Dictionary();
                dictionary.setName(SupplierStatusEnums.getByCode(supplierInfo.getStatusStr()).getDesc());
                taskVo.setStatusDictionary(dictionary);
                BusinessProcessingLog logServiceByBusinessTypeBusinessKey = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.SUPPLIER_INFO, supplierInfo.getId());
                User user;
                if (logServiceByBusinessTypeBusinessKey.getTaskName().equals("尽调分配")) {
                    user = userService.getByName("柳卓轩");
                } else {
                    user = userService.get(logServiceByBusinessTypeBusinessKey.getAssignee().getId());
                    if (user.getLoginName().equals("admin")) {
                        user = new User();
                        user.setName("C端客户");
                    }
                }
                taskVo.setAssigneeName(user.getName());
                taskVo.setConstructionIndustry(supplierInfo.getConstructionIndustry());
            }
            if (project instanceof ProjectInformation) {
                ProjectInformation projectInformation = (ProjectInformation) project;
                SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
                Enterprise ownerEnterprise = enterpriseService.getById(supplierInfo.getcEnterpriseId());
                ProjectCoreEnterprise coreEnterpriseServiceByProjectInfoId = projectCoreEnterpriseService.getByProjectInfoId(projectInformation.getId());
                Enterprise customerEnterprise = enterpriseService.getById(coreEnterpriseServiceByProjectInfoId.getcEnterpriseId());
                taskVo.setProjectName(projectInformation.getProjectName());
                taskVo.setBusinessNumber(projectInformation.getBusinessNumber());
                taskVo.setOwnerName(ownerEnterprise.getCorporateName());
                taskVo.setCustomerName(customerEnterprise.getCorporateName());
                String coreStatusStr = ProjectAndEnterpriseStatusEnums.getByCode(coreEnterpriseServiceByProjectInfoId.getStatusStr()).getDesc();
                taskVo.setCoreStatusStr(coreStatusStr);
                String projectStatusStr = ProjectAndEnterpriseStatusEnums.getByCode(projectInformation.getStatusStr()).getDesc();
                taskVo.setProjectStatusStr(projectStatusStr);
                BusinessProcessingLog logServiceByBusinessTypeBusinessKey = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.PROJECT_INFORMATION, projectInformation.getId());
                User user = userService.get(logServiceByBusinessTypeBusinessKey.getAssignee().getId());
                taskVo.setAssigneeName(user.getName());
            }
            if (project instanceof ProjectCoreEnterprise) {
                ProjectCoreEnterprise projectCoreEnterprise = (ProjectCoreEnterprise) project;
                ProjectInformation projectInformation = projectInformationService.get(projectCoreEnterprise.getcProjectInformationId());
                SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
                Enterprise ownerEnterprise = enterpriseService.getById(supplierInfo.getcEnterpriseId());
                Enterprise customerEnterprise = enterpriseService.getById(projectCoreEnterprise.getcEnterpriseId());
                taskVo.setProjectName(projectInformation.getProjectName());
                taskVo.setBusinessNumber(projectInformation.getBusinessNumber());
                taskVo.setOwnerName(ownerEnterprise.getCorporateName());
                taskVo.setCustomerName(customerEnterprise.getCorporateName());
                String coreStatusStr = ProjectAndEnterpriseStatusEnums.getByCode(projectCoreEnterprise.getStatusStr()).getDesc();
                taskVo.setCoreStatusStr(coreStatusStr);
                String projectStatusStr = ProjectAndEnterpriseStatusEnums.getByCode(projectInformation.getStatusStr()).getDesc();
                taskVo.setProjectStatusStr(projectStatusStr);
                BusinessProcessingLog logServiceByBusinessTypeBusinessKey = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.PROJECT_CORE_ENTERPRISE, projectCoreEnterprise.getId());
                User user = userService.get(logServiceByBusinessTypeBusinessKey.getAssignee().getId());
                taskVo.setAssigneeName(user.getName());
            }
            if (project instanceof CreditResolution) {
                CreditResolution creditResolution = (CreditResolution) project;
                ProjectInformation projectInformation = projectInformationService.get(creditResolution.getcProjectInformationId());
                ProjectCoreEnterprise projectCoreEnterprise = projectCoreEnterpriseService.getByProjectInfoId(projectInformation.getId());
                Enterprise coreEnterprise = enterpriseService.getById(projectCoreEnterprise.getcEnterpriseId());
                SupplierInfo supplierInfo = supplierInfoService.get(projectInformation.getcSupplierInfoId());
                Enterprise enterprise = enterpriseService.getById(supplierInfo.getcEnterpriseId());
                taskVo.setOwnerName(enterprise.getCorporateName());
                taskVo.setStatus(dictService.getByCode(creditResolution.getStatusStr()));
                BusinessProcessingLog logServiceByBusinessTypeBusinessKey = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.CREDIT_RESOLUTION, creditResolution.getId());
                User user = userService.get(logServiceByBusinessTypeBusinessKey.getAssignee().getId());
                taskVo.setCustomerName(coreEnterprise.getCorporateName());
                taskVo.setProjectName(projectInformation.getProjectName());
                taskVo.setBusinessNumber(projectInformation.getBusinessNumber());
                taskVo.setAssigneeName(user.getName());
            }
            if (project instanceof CFinancingBasicInfo) {
                CFinancingBasicInfo financingBasicInfo = (CFinancingBasicInfo) project;
                taskVo.setPlatformName(financingBasicInfo.getTradingPlatformName());
                taskVo.setContractNumber(financingBasicInfo.getContractNumber());
                taskVo.setFinancingAmount(financingBasicInfo.getFinancingAmount());
                taskVo.setStatusStr(financingBasicInfo.getFinancingStatus());
                taskVo.setStageStr(financingBasicInfo.getCurrentStage());
                if (taskVo.getStageStr().equals(FinancingCurrentStageEnum.REVIEW_QUOTA_DISBURSE.getDesc())
                        || taskVo.getStageStr().equals(FinancingCurrentStageEnum.PAYMENT_APPLY.getDesc())) {
                    //业务经理
                    taskVo.setExecutor(ConstantUtil.PROJECT_MANAGER);
                } else if (taskVo.getStageStr().equals(FinancingCurrentStageEnum.CONTRACT_MAKING.getDesc()) ||
                        taskVo.getStageStr().equals(FinancingCurrentStageEnum.CONTRACT_APPROVAL.getDesc()) ||
                        taskVo.getStageStr().equals(FinancingCurrentStageEnum.PAYMENT_APPROVAL.getDesc())) {
                    //合同制作-法务专员
                    taskVo.setExecutor(ConstantUtil.LEGAL_SPECIALIST);
                } else if (taskVo.getStageStr().equals(FinancingCurrentStageEnum.REVIEW_QUOTA_DISBURSE_APPROVAL.getDesc())) {
                    //风控经理
                    taskVo.setExecutor(ConstantUtil.RISK_CONTROL_MANAGER);
                }
            }

            if (project instanceof ExemptionMatters) {
                ExemptionMatters exemptionMatters = (ExemptionMatters) project;
                taskVo.setPaymentNo(exemptionMatters.getPaymentNo());
                taskVo.setQuotaDisburseBatch(exemptionMatters.getQuotaDisburseBatch());
                taskVo.setFinancingAmount(exemptionMatters.getFinancingAmount());
                taskVo.setPlatformName(exemptionMatters.getTradingPlatformName());
                taskVo.setContractNumber(exemptionMatters.getContractNo());
                BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.EXEMPTION_MATTERS, project.getId());
                if (processingLog.getTaskDefKey().equals(ConstantUtil.EXEMPTION_MATTER_ADD)) {
                    taskVo.setExecutor("业务经理");
                } else if (processingLog.getTaskDefKey().equals(ConstantUtil.EXEMPTION_MATTER_APPROVAL)) {
                    taskVo.setExecutor("法务专员");
                }
            }

            if (project instanceof RefundManagement) {
                RefundManagement refundManagement = (RefundManagement) project;
                taskVo.setPaymentNo(refundManagement.getRefundNumber());
                taskVo.setQuotaDisburseBatch(refundManagement.getQuotaDisburseBatch());
                taskVo.setFinancingAmount(refundManagement.getFinancingAmount());
                taskVo.setPlatformName(refundManagement.getTradingPlatformName());
                taskVo.setContractNumber(refundManagement.getContractNumber());
                taskVo.setPaymentCollectionPlanFactorings(refundManagement.getPaymentCollectionPlanFactorings());
                taskVo.setFinancingAmount(refundManagement.getFinancingAmount());
                taskVo.setStatusStr(refundManagement.getStatusDictionary().getName());
                taskVo.setCoreStatusStr(refundManagement.getCoreStatusStr());
                taskVo.setFinancingAmount(refundManagement.getFinancingAmount());

                BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.REFUND_MANAGEMENT, project.getId());
                if (processingLog.getTaskDefKey().equals(ConstantUtil.EXEMPTION_MATTER_ADD)) {
                    taskVo.setExecutor("业务经理");
                } else if (processingLog.getTaskDefKey().equals(ConstantUtil.EXEMPTION_MATTER_APPROVAL)) {
                    taskVo.setExecutor("法务专员");
                }
            }

            FlowActivityDefinition flowActDef = flowActDefService.getByProcActKey(task.getProcessDefinitionId(),
                    task.getTaskDefinitionKey());
            // 如果已分配，则按照分配的时间
            Date startTime = null;
            // 首先，确定该任务是待处理的任务，故直接获取其最新的处理日志，肯定为该任务办理人开始任务（或被分配任务）的记录。
            if (null != log) {
                startTime = log.getGmtCreate();// 若未分配，那么该时间为任务创建时间，若分配，那么该时间为办理人最新的任务分配时间
            }
            if (null != flowActDef) {
                Float deadline = null;
                if (flowActDef.getWorkingDay()) {
                    deadline = FlowableUtil.getBusinessDeadlineByWorkingDay(startTime, flowActDef.getTimeLimit(),
                            flowActDef.getWorkingDay());// 工作日时限
                } else {
                    deadline = FlowableUtil.getBusinessDeadlineByNatureDay(startTime, flowActDef.getTimeLimit(),
                            flowActDef.getWorkingDay());// 自然日时限
                }
                String deadlineStr = "";
                if (null != deadline) {
                    if (deadline < 0) {
                        deadlineStr = "逾期" + Math.abs(deadline) + (flowActDef.getWorkingDay() ? "个工作日" : "个自然日");
                    } else {
                        deadlineStr = deadline + (flowActDef.getWorkingDay() ? "个工作日" : "个自然日");
                    }
                }
                taskVo.setDeadline(deadlineStr);
            }
            return taskVo;
        }
        return null;
    }

    @Override
    public GridPage<BusinessProcessingTaskVo> findMyCompletedList(SearchBusinessProcessingTask search) {
        if (null == search || StringUtil.isEmpty(search.getSimpleClassName())) {
            throw new ValidatorException(CodeUtil.FAIL, "列表分页条件不能为空！");
        }
        search.setUserId(ThreadLocalUtil.getUserId());
        List<BusinessProcessingTaskVo> rows = new ArrayList<>();
        Page<BusinessProcessingTaskVo> page = PageHelper.startPage(search.getPage(), search.getRows());

        if (search.getSimpleClassName().equals(ConstantUtil.BUSINESS_MANAGEMENT)) {
            //业务管理
            rows = businessBasicInfoService.findMyCompletedList(search);
        }

        if (search.getSimpleClassName().equals(ConstantUtil.SALES_CONTRACT)) {
            //销售合同
            rows = salesContractService.findMyCompletedList(search);
        }

        //采购合同
        if (search.getSimpleClassName().equals(ConstantUtil.PURCH_CONTRACT)) {
            rows = purchContractService.findMyCompletedList(search);
        }

        //验收单
        if (search.getSimpleClassName().equals(ConstantUtil.ACCEPTANCE_SHEET)) {
            rows = acceptanceBasicInfoService.findMyCompletedList(search);
        }

        //结算单
        if (search.getSimpleClassName().equals(ConstantUtil.BILL_BASIC_INFORMATION)) {
            rows = settlementBasicInfoService.findMyCompletedList(search);
        }

        //底层
        if (search.getSimpleClassName().equals(ConstantUtil.UNDERLYING_MANAGE)) {
            rows = underlyingBasicInfoService.findMyCompletedList(search);
        }

        //发票
        if (search.getSimpleClassName().equals(ConstantUtil.INVOICE)) {
//            rows = invoiceBasicInfoService.findMyCompletedList(search);
        }
        //客户信息
        if (search.getSimpleClassName().equals(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS)) {
            rows = financialCustomerInfoService.findMyCompletedList(search);
        }

        if (search.getSimpleClassName().equals(ConstantUtil.SIGN_CONFIRMATION)) {
            rows = signConfirmationService.findMyCompletedList(search);
            for (BusinessProcessingTaskVo row : rows) {
                BusinessProcessingLog log = processingLogService.getByBusinessTypeBusinessKey(ConstantUtil.SIGN_CONFIRMATION, row.getId());
                if (log.getEndTime() == null) {
                    row.setTaskName(log.getTaskName());
                    if (log.getAssignee() != null) {
                        row.setAssignee(userService.get(log.getAssignee().getId()));
                    }
                }
            }
        }

        return new GridPage<>(search.getRows(), search.getPage(), page.getTotal(), rows);
    }

    /**
     * 已处理标签页：加载列表视图信息
     *
     * @param project  流程业务对象
     * @param historic 历史任务实例
     * @return
     */
    private BusinessProcessingTaskVo autoCompletedVo(Project project, HistoricTaskInstance historic) {
        if (null != project) {
            BusinessProcessingTaskVo taskVo = new BusinessProcessingTaskVo();
            taskVo.setId(project.getId());
            taskVo.setBusinessNumber(project.getBusinessNumber());
            taskVo.setStatus(project.getStatusDictionary());
            taskVo.setTaskId(historic.getId());
            taskVo.setTaskName(historic.getName());
            return taskVo;
        }
        return null;
    }

    /**
     * 全部标签页：加载列表视图信息
     *
     * @param project
     * @param procInstId
     * @return
     */
    private BusinessProcessingTaskVo autoStaticVo(Project project, String procInstId, Boolean buttonFlag) {
        if (null != project) {
            BusinessProcessingTaskVo taskVo = new BusinessProcessingTaskVo();
            taskVo.setId(project.getId());
            taskVo.setBusinessNumber(project.getBusinessNumber());
            if (null != buttonFlag) {
                taskVo.setButtonFlag(buttonFlag);
            }
            // 已终止或已完成的，不需要加载当前任务阶段、执行人、倒计时信息
            if (null != project.getStatusDictionary() && null != project.getStatusDictionary().getId()) {
                taskVo.setStatus(project.getStatusDictionary());
                Dictionary completed = dictService.getByCode(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode());
                if (null != completed && null != completed.getId()
                        && (long) completed.getId() == (long) project.getStatusDictionary().getId()) {
                    return taskVo;
                }
                Dictionary terminated = dictService
                        .getByCode(ProjectInitiationStatusDict.ChildEnum.TERMINATED.getCode());
                if (null != terminated && null != terminated.getId()
                        && (long) terminated.getId() == (long) project.getStatusDictionary().getId()) {
                    return taskVo;
                }
            }
            if (StringUtil.isNotEmpty(procInstId)) {
                List<Task> pendingTasks = flowableService.findRuntimeTaskByProcessInstId(procInstId);
                // 若该流程实例结束，则无当前阶段及倒计时信息
                if (null != pendingTasks && pendingTasks.size() > 0) {
                    if (pendingTasks.size() > 1) {
                        String split = "、";
                        String taskName = "";
                        String deadlineStr = "";
                        String assigneeName = "";
                        for (Task task : pendingTasks) {
                            if (StringUtil.isNotEmpty(task.getName())) {
                                taskName += task.getName() + split;
                            }
                            User assign = userService.get(Long.parseLong(task.getAssignee()));
                            if (null != assign && StringUtil.isNotEmpty(assign.getName())) {
                                assigneeName += assign.getName() + split;
                            }
                            FlowActivityDefinition flowActDef = flowActDefService
                                    .getByProcActKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
                            // 如果已分配，则按照分配的时间
                            Date startTime = null;
                            // 首先，确定该任务是待处理的任务，故直接获取其最新的处理日志，肯定为该任务办理人开始任务（或被分配任务）的记录。
                            BusinessProcessingLog log = processingLogService.getLatestByTask(project.getId(),
                                    project.getClass().getSimpleName(), task.getId(),
                                    ConstantConversionUtil.PROCESS_TASK);
                            if (null != log) {
                                startTime = log.getGmtCreate();// 若未分配，那么该时间为任务创建时间，若分配，那么该时间为办理人最新的任务分配时间
                            }
                            if (null != flowActDef) {
                                Float deadline = null;
                                if (flowActDef.getWorkingDay()) {
                                    deadline = FlowableUtil.getBusinessDeadlineByWorkingDay(startTime,
                                            flowActDef.getTimeLimit(), flowActDef.getWorkingDay());// 工作日时限
                                } else {
                                    deadline = FlowableUtil.getBusinessDeadlineByNatureDay(startTime,
                                            flowActDef.getTimeLimit(), flowActDef.getWorkingDay());// 自然日时限
                                }
                                if (null != deadline) {
                                    if (deadline < 0) {
                                        deadlineStr += "逾期" + Math.abs(deadline)
                                                + (flowActDef.getWorkingDay() ? "个工作日" : "个自然日") + split;
                                    } else {
                                        deadlineStr += deadline + (flowActDef.getWorkingDay() ? "个工作日" : "个自然日")
                                                + split;
                                    }
                                }
                            }
                        }
                        taskVo.setTaskName(taskName.substring(0, taskName.length() - 1));
                        taskVo.setAssigneeName(assigneeName.substring(0, assigneeName.length() - 1));
                        if (StringUtil.isNotEmpty(deadlineStr)) {// 无时限时
                            taskVo.setDeadline(deadlineStr.substring(0, deadlineStr.length() - 1));
                        }
                    } else {
                        Task task = pendingTasks.get(0);
                        taskVo.setTaskId(task.getId());
                        taskVo.setTaskDefKey(task.getTaskDefinitionKey());
                        taskVo.setTaskName(task.getName());
                        User assign = userService.get(Long.parseLong(task.getAssignee()));
                        if (null != assign) {
                            taskVo.setAssignee(assign);
                            taskVo.setAssigneeName(assign.getName());
                        }
                        FlowActivityDefinition flowActDef = flowActDefService
                                .getByProcActKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
                        // 如果已分配，则按照分配的时间
                        Date startTime = null;
                        // 首先，确定该任务是待处理的任务，故直接获取其最新的处理日志，肯定为该任务办理人开始任务（或被分配任务）的记录。
                        BusinessProcessingLog log = processingLogService.getLatestByTask(project.getId(),
                                project.getClass().getSimpleName(), task.getId(), ConstantConversionUtil.PROCESS_TASK);
                        if (null != log) {
                            startTime = log.getGmtCreate();// 若未分配，那么该时间为任务创建时间，若分配，那么该时间为办理人最新的任务分配时间
                        }
                        if (null != flowActDef) {
                            Float deadline = null;
                            if (flowActDef.getWorkingDay()) {
                                deadline = FlowableUtil.getBusinessDeadlineByWorkingDay(startTime,
                                        flowActDef.getTimeLimit(), flowActDef.getWorkingDay());// 工作日时限
                            } else {
                                deadline = FlowableUtil.getBusinessDeadlineByNatureDay(startTime,
                                        flowActDef.getTimeLimit(), flowActDef.getWorkingDay());// 自然日时限
                            }
                            String deadlineStr = "";
                            if (null != deadline) {
                                if (deadline < 0) {
                                    deadlineStr = "逾期" + Math.abs(deadline)
                                            + (flowActDef.getWorkingDay() ? "个工作日" : "个自然日");
                                } else {
                                    deadlineStr = deadline + (flowActDef.getWorkingDay() ? "个工作日" : "个自然日");
                                }
                            }
                            taskVo.setDeadline(deadlineStr);
                        }
                    }
                }
            }
            return taskVo;
        }
        return null;
    }

    /**
     * 过滤数据查看权限，仅业务数据执行者、知晓者、执行者同部门用户、执行者上级部门用户方可查看该条业务数据(包括各个节点信息查看)
     *
     * @param assigneeList 执行人ID集合
     * @param konwerList   知晓者ID集合
     * @return false表示无权限查看，true表示符合权限查看规则
     */
    public boolean filterDataView(List<Long> assigneeList, List<Long> konwerList) {
        if (null != assigneeList && assigneeList.size() > 0) {
            if (assigneeList.contains(ThreadLocalUtil.getUserId())) {
                return true;
            }
            for (Long assigneeId : assigneeList) {
                List<Long> parentOrgUserIds = userService.findCurrentAndParentOrgUserByUserId(assigneeId);
                if (null != parentOrgUserIds && parentOrgUserIds.size() > 0
                        && parentOrgUserIds.contains(ThreadLocalUtil.getUserId())) {
                    return true;
                }
            }
            if (null != konwerList && konwerList.size() > 0) {
                return konwerList.contains(ThreadLocalUtil.getUserId());
            }
        }
        return false;
    }

    @Override
    public GridPage<BusinessProcessingTaskVo> findAll(SearchBusinessProcessingTask search) {
        if (null == search || StringUtil.isEmpty(search.getSimpleClassName())) {
            throw new ValidatorException(CodeUtil.FAIL, "列表分页条件不能为空！");
        }
        Long currentUserId = ThreadLocalUtil.getUserId();
        List<UserOrgRel> userOrgRelList = userService.findOrgRelByUserId(currentUserId);


        Boolean flag = false;
        Boolean supplier = false;
        List<Long> userIdList = new ArrayList<>();
        String backName = "";
        List<UserRoleRel> userRoleRels = roleService.getUserRoleByUserId(ThreadLocalUtil.getUserId());
        Boolean riskManagerFlag = false;
        for (UserRoleRel userRoleRel : userRoleRels) {
            Role role = roleService.get(userRoleRel.getRoleId());
            if (ConstantUtil.RISK_CONTROL_MANAGER.equals(role.getName())){
                //如果包含风控经理的角色
                riskManagerFlag = true;

            }
        }

        if (!search.getSimpleClassName().equals(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS) && !search.getSimpleClassName().equals(ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS)) {
            for (UserOrgRel userOrgRel : userOrgRelList) {
                Org org = orgService.get(userOrgRel.getOrgId());
                if (org != null && org.getDeptNo().equals(ConstantConversionUtil.supplier_dept_no)) {
                    supplier = true;
                    User user = ThreadLocalUtil.getUser();
                    Customer customer = customerService.getOne(new QueryWrapper<Customer>()
                            .eq("enterprise_name", user.getName())
                            .eq("supplier", 1).last("LIMIT 1"));
                    search.setSupplierId(customer.getId());
                }
                if (org != null && org.getDeptNo().equals(ConstantConversionUtil.dept_no)) {
                    flag = true;
                    break;
                } else {
                    if (userOrgRel.isUserIdentity()) {
                        // 如果是部门负责人，获取部门下所有人员Id
                        List<Long> userIds = userService.findUserIdByOrgId(userOrgRel.getOrgId());
                        userIdList.addAll(userIds);
                    } else {
                        userIdList.add(currentUserId);
                    }
                }
            }
        } else {
            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 if (ConstantUtil.FINANCIAL_BACKER.equals(role.getName())) {
                        //如果角色为资方
                        User user = userService.get(ThreadLocalUtil.getUserId());
                        if (user != null) {
                            backName = user.getName();
                        }
                    }  else {
                        for (UserOrgRel userOrgRel : userOrgRelList) {
                            if (userOrgRel.isUserIdentity()) {
                                // 如果是部门负责人，获取部门下所有人员Id
                                List<Long> userIds = userService.findUserIdByOrgId(userOrgRel.getOrgId());
                                userIdList.addAll(userIds);
                            } else {
                                userIdList.add(currentUserId);
                            }
                        }
                    }
                }
            }
        }
        List<Long> pers = permissionService.getPermissionIdByUserId(ThreadLocalUtil.getUserId());
        Permission per = null;
        if (search.getSimpleClassName().equals(ConstantUtil.SALES_CONTRACT)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_SALES_CONTRACT_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.PURCH_CONTRACT)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_PURCH_CONTRACT_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.ACCEPTANCE_SHEET)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_ACCEPTANCE_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.BILL_BASIC_INFORMATION)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_BILL_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.UNDERLYING_MANAGE)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_MORTGAGE_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.INVOICE)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_INVOICE_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantConversionUtil.FINANCIAL_CUSTOMER)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_FINANCIAL_CUSTOMER);
        } else if (search.getSimpleClassName().equals(ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_FINANCIAL_INSTITUTION);
        } else if (search.getSimpleClassName().equals(ConstantUtil.BUSINESS_MANAGEMENT)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_BUSINESS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.BIDDING_MANAGEMENT)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_BIDDING);
        } else if (search.getSimpleClassName().equals(ConstantUtil.EXEMPTION_MATTERS)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_EXEMPTION_MATTERS);
        } else if (search.getSimpleClassName().equals(ConstantUtil.REFUND_MANAGEMENT)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_REFUND);
        } else if (search.getSimpleClassName().equals(ConstantUtil.FINANCING_APPLY)) {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_FINANCING_MANAGE);
        } else {
            per = permissionService.getByEname(ConstantConversionUtil.VIEW_ALL_SIGN_CONFIRMATION);
        }

        if (per == null) {
            throw new ValidatorException(CodeUtil.FAIL, "数据可见-查看全员权限不能为空");
        }
        if (pers.contains(per.getId())
                || ThreadLocalUtil.getUser().getLoginName().equals(ConstantConversionUtil.ADMINISTORIES)) {
            flag = true;
        }

        if (!flag) {
            if (riskManagerFlag){
                search.setRiskManagerId(ThreadLocalUtil.getUserId());
            }else {
                userIdList = userIdList.stream().distinct().collect(Collectors.toList());
                search.setUserIds(userIdList);
                search.setBackName(backName);
            }
        }

        List<BusinessProcessingTaskVo> rows = new ArrayList<>();
        Page<BusinessProcessingTaskVo> page = PageHelper.startPage(search.getPage(), search.getRows());
        if (search.getSimpleClassName().equals(ConstantUtil.SALES_CONTRACT)) {
            //销售合同
            rows = salesContractService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.PURCH_CONTRACT)) {
            //采购合同
            rows = purchContractService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.ACCEPTANCE_SHEET)) {
            //验收单
            if (supplier) {
                rows = acceptanceBasicInfoService.findAllListSupplier(search);
            } else {
                rows = acceptanceBasicInfoService.findAllList(search);
            }
        } else if (search.getSimpleClassName().equals(ConstantUtil.BILL_BASIC_INFORMATION)) {
            //结算单
            if (supplier) {
                rows = settlementBasicInfoService.findAllListSupplier(search);
            } else {
                rows = settlementBasicInfoService.findAllList(search);
            }
        } else if (search.getSimpleClassName().equals(ConstantUtil.UNDERLYING_MANAGE)) {
            //底层管理
            rows = underlyingBasicInfoService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.INVOICE)) {
            //发票
            rows = invoiceBasicInfoService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.FINANCIAL_CUSTOMER_PROCESS)) {
            //客户信息
            rows = financialCustomerInfoService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.FINANCIAL_CUSTOMER_EXPENDITURE_PROCESS)) {
            //客户支用信息
            rows = financialCustomerExpenditureService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.BIDDING_MANAGEMENT)) {
            //招投标信息
            rows = biddingBasicInfoService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.SIGN_CONFIRMATION)) {
            //签署确认
            rows = signConfirmationService.findAllList(search);
        } else if (search.getSimpleClassName().equals(ExemptionMatters.class.getSimpleName())) {
            //豁免事项跟进
            rows = exemptionMattersService.findBySearch(search);
        } else if (search.getSimpleClassName().equals(RefundManagement.class.getSimpleName())) {
            //退款管理
            rows = refundManagementService.findBySearch(search);
        } else if (search.getSimpleClassName().equals(ConstantUtil.FINANCING_APPLY)) {
            //融资管理
            rows = financingBasicInfoService.findAll(search);
        }
        for (BusinessProcessingTaskVo row : rows) {
            BusinessProcessingLog log = processingLogService.getByBusinessTypeBusinessKey(search.getSimpleClassName(), row.getId());
            if (log != null && log.getEndTime() == null) {
                row.setTaskName(log.getTaskName());
                row.setTaskId(log.getHistoricTaskId());
                if (log.getAssignee() != null) {
                    row.setAssignee(userService.get(log.getAssignee().getId()));
                }
            }
        }
        return new GridPage<>(search.getRows(), search.getPage(), page.getTotal(), rows);
    }

    @Override
    public List<BusinessHistoricDetailVo> getHistoricBusinessById(Long businessKey, String businessType) {
        List<BusinessHistoricDetailVo> list = new ArrayList<>();
        if (businessType.equals(ConstantUtil.SIGN_CONFIRMATION)) {
            SignConfirmation signConfirmation = signConfirmationService.getById(businessKey);
            if (signConfirmation.getComeFrom().equals("验收单")) {
                AcceptanceApproval acceptanceApproval = acceptanceSheetLegalFlowService.getView(signConfirmation.getApprovalId());
                BusinessProcessingLog processingLog =
                        processingLogService.getbyFormBusinessIdBusinessKeyTaskDefKeyBusinessType(acceptanceApproval.getId(), acceptanceApproval.getAcceptanceBasicInfoId(), "legal_review", ConstantUtil.ACCEPTANCE_SHEET);
                list.add(new BusinessHistoricDetailVo("验收单" + processingLog.getTaskName(), acceptanceApproval, transBusinessProcessingLog(processingLog)));
            }
        }
        if (businessType.equals(ConstantUtil.BILL_BASIC_INFORMATION)) {
            businessType = "Bill";
        }
        List<BusinessProcessingLog> logs = processingLogService.findCompletedByBusiness(businessKey, businessType);
        if (null != logs && logs.size() > 0) {
            for (BusinessProcessingLog log : logs) {
                if (log.getBusinessType().equals(ConstantUtil.PURCH_CONTRACT_CHANGE_PROCESS) || log.getBusinessType().equals(ConstantUtil.PURCH_CONTRACT)) {
                    list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                            .getFormBusinessDateById(log.getTaskDefKey(), log.getFormBusinessId()), transBusinessProcessingLog(log)));
                } else if (log.getBusinessType().equals(ConstantUtil.SUPPLIER_INFO)) {
                    SupplierInfo supplierInfo = supplierInfoService.get(log.getBusnessKey());
                    if (log.getTaskName().equals("供应商C端录入") && supplierInfo.getConstructionIndustry().equals(0)) {
                        list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                                .getNewFormBusinessDateById(log.getTaskDefKey(), log.getBusnessKey()), transBusinessProcessingLog(log)));
                    } else {
                        list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                                .getFormBusinessDateById(log.getTaskDefKey(), log.getFormBusinessId()), transBusinessProcessingLog(log)));
                    }
                } else {
                    list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                            .getFormBusinessDateById(log.getTaskDefKey(), log.getFormBusinessId()), transBusinessProcessingLog(log)));
                }
            }
        }
        return list;// 避免“返回结果为空”的错误提示信息
    }

    @Override
    public List<BusinessHistoricDetailVo> getCLogByBusinessKeyBusinessType(Long businessKey, String businessType) {
        List<BusinessHistoricDetailVo> list = new ArrayList<>();
        List<BusinessProcessingLog> logs = processingLogService.getCLogByBusinessKeyBusinessType(businessKey, businessType);
        if (null != logs && logs.size() > 0) {
            for (BusinessProcessingLog log : logs) {
                if (log.getBusinessType().equals(ConstantUtil.PURCH_CONTRACT_CHANGE_PROCESS) || log.getBusinessType().equals(ConstantUtil.PURCH_CONTRACT)) {
                    list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                            .getFormBusinessDateById(log.getTaskDefKey(), log.getFormBusinessId()), transBusinessProcessingLog(log)));
                } else if (log.getBusinessType().equals(ConstantUtil.SUPPLIER_INFO)) {
                    SupplierInfo supplierInfo = supplierInfoService.get(log.getBusnessKey());
                    if (log.getTaskName().equals("供应商C端录入") && supplierInfo.getConstructionIndustry().equals(0)) {
                        list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                                .getNewFormBusinessDateById(log.getTaskDefKey(), log.getBusnessKey()), transBusinessProcessingLog(log)));
                    } else {
                        list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                                .getFormBusinessDateById(log.getTaskDefKey(), log.getFormBusinessId()), transBusinessProcessingLog(log)));
                    }
                } else {
                    list.add(new BusinessHistoricDetailVo(log.getTaskName(), FlowableUtil
                            .getFormBusinessDateById(log.getTaskDefKey(), log.getFormBusinessId()), transBusinessProcessingLog(log)));
                }
            }
        }
        return list;
    }

    //将流程业务处理日志进行转换
    private BusinessProcessingLogVo transBusinessProcessingLog(BusinessProcessingLog businessProcessingLog) {
        BusinessProcessingLogVo vo = new BusinessProcessingLogVo();
        if (null != businessProcessingLog.getAssignee()) {
            User assign = userService.get(businessProcessingLog.getAssignee().getId());
            String assigneeName = assign != null ? assign.getName() : "";
            String adminName = "超级管理员";
            vo.setAssigneeName(adminName.equals(assigneeName) ? "供应商" : assigneeName);
        }
        vo.setAssigneeTypeName(ConstantConversionUtil.assigneeType.get(businessProcessingLog.getAssigneeType()));
        // 上午、下午开始时间换算
        String startTimeStr = DateUtil.getGeneralDateFormat(businessProcessingLog.getStartTime());
        String endTimeStr = DateUtil.getGeneralDateFormat(businessProcessingLog.getEndTime());
        vo.setStartTime(startTimeStr);
        vo.setEndTime(endTimeStr);
//        if (StringUtil.isNotEmpty(startTime)) {
//            if (ConstantUtil.AM_CNAME.equals(DateUtil.getCnameOfAMPM(businessProcessingLog.getStartTime()))) {
//                vo.setStartTime(startTime + " " + ConstantUtil.AM_CNAME);
//            } else {
//                vo.setStartTime(startTime + " " + ConstantUtil.PM_CNAME);
//            }
//        }
//        if (StringUtil.isNotEmpty(endTime)) {
//            if (ConstantUtil.AM_CNAME.equals(DateUtil.getCnameOfAMPM(businessProcessingLog.getEndTime()))) {
//                vo.setEndTime(endTime + " " + ConstantUtil.AM_CNAME);
//            } else {
//                vo.setEndTime(endTime + " " + ConstantUtil.PM_CNAME);
//            }
//        }
        if (StringUtil.isNotEmpty(businessProcessingLog.getStatus())) {
            vo.setStatus(businessProcessingLog.getStatus());
        }
        if (null != businessProcessingLog.getOverdueDays() && businessProcessingLog.getOverdueDays() > 0) {
            vo.setOverdue("逾期" + businessProcessingLog.getOverdueDays() + (businessProcessingLog.getWorkingDay() ? "个工作日" : "个自然日"));
        }
        return vo;
    }


    @Override
    public Boolean duplicateProcessingTask(String taskId) {
        Task task = flowableService.getByTaskQuery(taskId);
        if (task == null) {
            throw new ValidatorException(CodeUtil.FAIL, "操作失败，该业务可能已完成，请确认！");
        }

        if (StringUtil.isNotEmpty(task.getAssignee()) && !task.getAssignee().equals(ThreadLocalUtil.getUserId().toString())) {
            throw new ValidatorException(CodeUtil.FAIL, "无权操作，该业务可能已经分配，请确认！");
        }
        return true;
    }

    @Override
    public Boolean duplicateProcessingBusiness(Long businessId, String businessType, String msgType) {
        if (StringUtil.isEmpty(businessType) || null == businessId || StringUtil.isEmpty(msgType)) {
            throw new ValidatorException(CodeUtil.FAIL, "参数不正确，消息类型、业务类型及ID可能为空！");
        }
        Long processUser = null;
        String errorMsg = "";
        if (null == processUser) {
            throw new ValidatorException(CodeUtil.FAIL, errorMsg);
        }
        if ((long) processUser != ThreadLocalUtil.getUserId()) {
            throw new ValidatorException(CodeUtil.FAIL, "无权操作，该业务可能已经分配，请确认！");
        }
        return true;
    }

    @Override
    public Long terminate(String taskId, Long entityId, String businessType, String taskName, String taskDefKey) {
        BusinessProcessingLog processingLog = new BusinessProcessingLog();
        String procInstId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
        if (processInstance != null) {
            List<EndEvent> endNodes;
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
            if (bpmnModel != null) {
                Process mainProcess = bpmnModel.getMainProcess();
                endNodes = mainProcess.findFlowElementsOfType(EndEvent.class);
            } else {
                throw new BusinessException(CodeUtil.FAIL, "终止失败");
            }
            String endId = endNodes.get(0).getId();
            String processInstanceId = processInstance.getProcessInstanceId();
            //1、执行终止
            List<Execution> executions = runtimeService.createExecutionQuery().parentId(processInstanceId).list();
            List<String> executionIds = new ArrayList<>();
            executions.forEach(execution -> executionIds.add(execution.getId()));
            runtimeService.createChangeActivityStateBuilder().moveExecutionsToSingleActivityId(executionIds, endId).changeState();
            // 2.添加业务处理日志
            processingLog.setBusnessKey(entityId);
            processingLog.setBusinessType(businessType);
            processingLog.setHistoricTaskId(taskId);
            processingLog.setAssignee(ThreadLocalUtil.getUser());
            processingLog.setAssigneeType(ConstantConversionUtil.PROCESS_TASK);
            processingLog.setTaskDefKey(taskDefKey);
            processingLog.setTaskName(taskName);
            processingLog.setStatus(ConstantUtil.TERMINATE);
            processingLog.setFormBusinessId(entityId);
            processingLog.setStartTime(new Date());
            processingLog.setEndTime(new Date());
            processingLogService.add(processingLog);
        } else {
            throw new BusinessException(CodeUtil.FAIL, "不存在运行的流程实例,请确认!");
        }
        return processingLog.getId();
    }
}
