package cn.ezhizao.project.business.order.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import cn.ezhizao.common.exception.ServiceException;
import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.StringUtils;
import cn.ezhizao.common.utils.uuid.SnowflakeIdWorker;
import cn.ezhizao.project.business.channel.domain.BizChannel;
import cn.ezhizao.project.business.channel.service.IBizChannelService;
import cn.ezhizao.project.business.company.domain.BizCompany;
import cn.ezhizao.project.business.company.domain.DictRegion;
import cn.ezhizao.project.business.company.service.IBizCompanyService;
import cn.ezhizao.project.business.company.service.IDictRegionService;
import cn.ezhizao.project.business.order.domain.*;
import cn.ezhizao.project.business.order.mapper.BizArchiveInputMapper;
import cn.ezhizao.project.business.order.service.IBizArchiveInputDetailProcessService;
import cn.ezhizao.project.business.order.service.IBizArchiveInputDetailService;
import cn.ezhizao.project.business.order.service.IBizArchiveInputService;
import cn.ezhizao.project.business.settings.domain.BizSource;
import cn.ezhizao.project.business.settings.service.IBizSourceService;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderDetail;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderRecord;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderDetailService;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderRecordService;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderService;
import cn.ezhizao.project.system.domain.SysDictData;
import cn.ezhizao.project.system.domain.SysFileStorage;
import cn.ezhizao.project.system.domain.SysUser;
import cn.ezhizao.project.system.service.ISysDictDataService;
import cn.ezhizao.project.system.service.ISysFileStorageService;
import cn.ezhizao.project.system.service.ISysUserService;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * 档案入库Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-16
 */
@Service
public class BizArchiveInputServiceImpl extends ServiceImpl<BizArchiveInputMapper, BizArchiveInput> implements IBizArchiveInputService {
    @Resource
    private BizArchiveInputMapper bizArchiveInputMapper;
    @Resource
    private IBizCompanyService companyService;
    @Resource
    private IDictRegionService regionService;
    @Resource
    private IBizArchiveInputDetailService archiveInputDetailService;
    @Resource
    private IBizArchiveInputDetailProcessService archiveInputDetailProcessService;
    @Resource
    private IBizWorkOrderService workOrderService;
    @Resource
    private IBizChannelService channelService;
    @Resource
    private IBizWorkOrderDetailService workOrderDetailService;
    @Resource
    private IBizWorkOrderRecordService workOrderRecordService;
    @Resource
    private ISysFileStorageService fileStorageService;
    @Resource
    private ISysDictDataService sysDictDataService;
    @Resource
    private ISysUserService userService;
    @Resource
    private IBizSourceService bizSourceService;
    @Resource
    SnowflakeIdWorker snowflakeIdWorker;

    final String[] reportTaskTableNames = {"biz_financial_individual_income_tax", "biz_financial_keep_account", "biz_financial_receive_ticket", "biz_financial_report_tax", "biz_financial_salary"};

    final String[] housingFundTaskTableNames = {"biz_housing_fund_confirm", "biz_housing_fund_declare"};

    final String[] socialSecurityTaskTableNames = {"biz_social_security_confirm", "biz_social_security_declare"};

    /**
     * 查询档案入库列表
     *
     * @param bizArchiveInput 档案入库
     * @return 档案入库
     */
    @Override
    public List<BizArchiveInput> getList(BizArchiveInput bizArchiveInput) {
        return bizArchiveInputMapper.getList(bizArchiveInput);
    }

    /**
     * 物理删除
     *
     * @param bizArchiveInput
     * @return 删除结果
     */
    @Override
    public int physicalDelete(BizArchiveInput bizArchiveInput) {
        return bizArchiveInputMapper.physicalDelete(bizArchiveInput);
    }

    @Override
    public boolean verify(BizArchiveInput bizArchiveInput) {
        super.updateById(bizArchiveInput);
        List<BizArchiveInputDetail> details = archiveInputDetailService.query().eq("contract_id", bizArchiveInput.getId()).list();
        List<BizArchiveInputDetailProcess> processes = archiveInputDetailProcessService.query().eq("contract_id", bizArchiveInput.getId()).list();
        List<BizWorkOrder> newWorkOrders = new ArrayList<>();
        List<BizWorkOrder> changeWorkOrders = new ArrayList<>();
        List<BizWorkOrderDetail> newWorkOrderDetails = new ArrayList<>();
        List<BizWorkOrderDetail> changeWorkOrderDetails = new ArrayList<>();
        if (bizArchiveInput.getVerifyStatus().equals(1)) {
            // 审核通过插入不存在的工单
            // 判断是循环还是单次
            if (bizArchiveInput.getServiceType().equals(1)) {
                // 假设是循环 判断是否已有该任务并没有签出
                details.forEach(l -> {
                    List<BizWorkOrder> workOrders = workOrderService.query().eq("company_id", bizArchiveInput.getCompanyId()).eq("task_type_id", l.getTaskTypeId()).eq("is_stop", 0).list();
                    List<BizWorkOrderDetail> workOrderDetails = workOrderDetailService.query().eq("contract_detail_id", l.getId()).list();
                    // 假设未有该任务 添加任务记录
                    if (workOrders.isEmpty()) {
                        BizWorkOrder workOrder = new BizWorkOrder();
                        workOrder.setCompanyId(bizArchiveInput.getCompanyId());
                        workOrder.setContractId(bizArchiveInput.getId());
                        workOrder.setNoContract(0);
                        workOrder.setContractDetailId(l.getId());
                        workOrder.setIsStop(0);
                        workOrder.setTenantId(l.getTenantId());
                        workOrder.setTaskTypeId(l.getTaskTypeId());
                        workOrder.setType(bizArchiveInput.getServiceType());
                        workOrder.setMonthNum(l.getFreeNum() + l.getServiceNum());
                        workOrder.setWorkOrderNo("workOrder_" + snowflakeIdWorker.nextId());
                        workOrder.setId(snowflakeIdWorker.nextId());
                        newWorkOrders.add(workOrder);
                        BizWorkOrderDetail bizWorkOrderDetail = new BizWorkOrderDetail();
                        bizWorkOrderDetail.setCompanyId(l.getCompanyId());
                        bizWorkOrderDetail.setWorkOrderId(workOrder.getId());
                        bizWorkOrderDetail.setContractDetailId(l.getId());
                        bizWorkOrderDetail.setServiceNum(l.getServiceNum());
                        bizWorkOrderDetail.setFreeNum(l.getFreeNum());
                        bizWorkOrderDetail.setTenantId(l.getTenantId());
                        bizWorkOrderDetail.setContractId(bizArchiveInput.getId());
                        newWorkOrderDetails.add(bizWorkOrderDetail);
//                        addLoopTasks(workOrder);
                    } else {
                        // 假设已有该任务 修改任务月数和结束月
                        // 判断是否有变更 是变更的先改下
                        workOrders.forEach(v -> {
                            Integer monthNum = v.getMonthNum();
                            BizWorkOrderDetail bizWorkOrderDetail = workOrderDetails.stream().filter(t -> t.getWorkOrderId().equals(v.getId())
                            ).findFirst().orElse(new BizWorkOrderDetail());
                            monthNum = monthNum - (bizWorkOrderDetail.getServiceNum() == null ? 0 : bizWorkOrderDetail.getServiceNum()) - (bizWorkOrderDetail.getFreeNum() == null ? 0 : bizWorkOrderDetail.getFreeNum()) + l.getFreeNum() + l.getServiceNum();
                            bizWorkOrderDetail.setCompanyId(l.getCompanyId());
                            bizWorkOrderDetail.setWorkOrderId(v.getId());
                            bizWorkOrderDetail.setContractDetailId(l.getId());
                            bizWorkOrderDetail.setServiceNum(l.getServiceNum());
                            bizWorkOrderDetail.setFreeNum(l.getFreeNum());
                            bizWorkOrderDetail.setTenantId(l.getTenantId());
                            bizWorkOrderDetail.setContractId(bizArchiveInput.getId());
                            if (bizWorkOrderDetail.getId() == null) {
                                newWorkOrderDetails.add(bizWorkOrderDetail);
                            } else {
                                changeWorkOrderDetails.add(bizWorkOrderDetail);
                            }
                            v.setMonthNum(monthNum);
                            DateTime startMonth = DateTime.of(v.getStartMonth());
                            v.setEndMonth(startMonth.offset(DateField.MONTH, monthNum - 1).toSqlDate());
                            changeWorkOrders.add(v);
                        });
                    }
                });


            } else if (bizArchiveInput.getServiceType().equals(2)) {
                List<BizWorkOrder> workOrders = workOrderService.query().eq("company_id", bizArchiveInput.getCompanyId()).eq("contract_id", bizArchiveInput.getId()).eq("is_stop", 0).list();
                // 假设是单次任务 添加该任务
                details.forEach(l -> {
                    processes.stream().filter(v -> v.getContractDetailId().equals(l.getId())).forEach(v -> {
                        BizWorkOrder workOrder = workOrders.stream().filter(e -> e.getContractDetailProcessId().equals(v.getId())).findFirst().orElse(new BizWorkOrder());
                        workOrder.setCity(l.getCity());
                        workOrder.setNoContract(0);
                        workOrder.setType(bizArchiveInput.getServiceType());
                        workOrder.setContractId(bizArchiveInput.getId());
                        workOrder.setContractDetailProcessId(v.getId());
                        workOrder.setContractDetailId(l.getId());
                        workOrder.setTenantId(l.getTenantId());
                        workOrder.setTaskTypeId(l.getTaskTypeId());
                        workOrder.setTaskTypeDetailId(v.getTaskTypeDetailId());
                        workOrder.setProvinceCode(l.getProvinceCode());
                        workOrder.setProvince(l.getProvince());
                        workOrder.setCityCode(l.getCityCode());
                        workOrder.setWorkOrderNo("workOrder_" + snowflakeIdWorker.nextId());
                        workOrder.setCompanyId(bizArchiveInput.getCompanyId());
                        workOrder.setDistrictCode(l.getDistrictCode());
                        workOrder.setDistrict(l.getDistrict());
                        if (workOrder.getId() == null) {
                            newWorkOrders.add(workOrder);
                        } else {
                            changeWorkOrders.add(workOrder);
                        }
                    });
                });
            }
        }
        boolean status = (newWorkOrderDetails.isEmpty() || workOrderDetailService.saveBatch(newWorkOrderDetails))
                && (newWorkOrders.isEmpty() || workOrderService.saveBatch(newWorkOrders))
                && (changeWorkOrders.isEmpty() || workOrderService.updateBatchById(changeWorkOrders))
                && (changeWorkOrderDetails.isEmpty() || workOrderDetailService.updateBatchById(changeWorkOrderDetails));
        newWorkOrders.forEach(this::addLoopTasks);
        return status;
    }

    @Override
    public boolean save(BizArchiveInput bizArchiveInput) {
        boolean saveStatus = super.save(bizArchiveInput);
        List<BizArchiveInputDetail> bizArchiveInputDetails = bizArchiveInput.getDetails();
        List<BizArchiveInputDetailProcess> bizArchiveInputDetailProcesses = new ArrayList<>();
        List<SysFileStorage> files = bizArchiveInput.getFiles();
        bizArchiveInputDetails.forEach(l -> {
            l.setCompanyId(bizArchiveInput.getCompanyId());
            l.setContractId(bizArchiveInput.getId());
            l.setTenantId(bizArchiveInput.getTenantId());
        });
        files.forEach(l -> {
            l.setMasterId(bizArchiveInput.getId());
            l.setMasterTableName("biz_archive_input");
        });
        saveStatus = saveStatus && (files.isEmpty() || fileStorageService.saveBatch(files));
        saveStatus = saveStatus && (bizArchiveInputDetails.isEmpty() || archiveInputDetailService.saveBatch(bizArchiveInputDetails));
        bizArchiveInputDetails.forEach(l -> {
            l.getProcesses().forEach(v -> {
                v.setCompanyId(bizArchiveInput.getCompanyId());
                v.setContractId(bizArchiveInput.getId());
                v.setContractDetailId(l.getId());
                v.setTenantId(bizArchiveInput.getTenantId());
            });
            bizArchiveInputDetailProcesses.addAll(l.getProcesses());
        });

        return saveStatus && (bizArchiveInputDetailProcesses.isEmpty() || archiveInputDetailProcessService.saveBatch(bizArchiveInputDetailProcesses));
    }

    @Override
    public boolean updateById(BizArchiveInput bizArchiveInput) {
        boolean saveStatus = super.updateById(bizArchiveInput);
        List<BizArchiveInputDetail> bizArchiveInputDetails = bizArchiveInput.getDetails();
        List<BizArchiveInputDetailProcess> bizArchiveInputDetailProcesses = new ArrayList<>();
        BizArchiveInputDetail delDetail = new BizArchiveInputDetail();
        delDetail.setContractId(bizArchiveInput.getId());
        archiveInputDetailService.physicalDelete(delDetail);
        BizArchiveInputDetailProcess delProcess = new BizArchiveInputDetailProcess();
        delProcess.setContractId(bizArchiveInput.getId());
        archiveInputDetailProcessService.physicalDelete(delProcess);
        SysFileStorage fileStorage = new SysFileStorage();
        fileStorage.setMasterTableName("biz_archive_input");
        fileStorage.setMasterId(bizArchiveInput.getId());
        fileStorageService.physicalDelete(fileStorage);

        List<SysFileStorage> files = bizArchiveInput.getFiles();
        files.forEach(l -> {
            l.setMasterId(bizArchiveInput.getId());
            l.setMasterTableName("biz_archive_input");
        });
        fileStorageService.saveBatch(files);
        bizArchiveInputDetails.forEach(l -> {
            l.setCompanyId(bizArchiveInput.getCompanyId());
            l.setContractId(bizArchiveInput.getId());
            l.setTenantId(bizArchiveInput.getTenantId());
        });
        saveStatus = saveStatus && archiveInputDetailService.saveBatch(bizArchiveInputDetails);
        bizArchiveInputDetails.forEach(l -> {
            l.getProcesses().forEach(v -> {
                v.setCompanyId(bizArchiveInput.getCompanyId());
                v.setContractId(bizArchiveInput.getId());
                v.setContractDetailId(l.getId());
                v.setTenantId(bizArchiveInput.getTenantId());
            });
            bizArchiveInputDetailProcesses.addAll(l.getProcesses());
        });
        return saveStatus && (bizArchiveInputDetailProcesses.isEmpty() || archiveInputDetailProcessService.saveBatch(bizArchiveInputDetailProcesses));
    }

    // 创建循环任务
    public boolean addLoopTasks(BizWorkOrder workOrder) {
        if (workOrder.getTaskTypeId() == 1L) {
            return addReportTask(workOrder);
        } else if (workOrder.getTaskTypeId() == 2L) {
            return addSocialSecurity(workOrder);
        } else if (workOrder.getTaskTypeId() == 3L) {
            return addHousingFund(workOrder);
        }
        return true;
    }

    // 停止循环任务
    public boolean stopLoopTasks(BizWorkOrder workOrder) {
        if (workOrder.getTaskTypeId() == 1L) {
            return stopReportTask(workOrder);
        } else if (workOrder.getTaskTypeId() == 2L) {
            return stopSocialSecurity(workOrder);
        } else if (workOrder.getTaskTypeId() == 3L) {
            return stopHousingFund(workOrder);
        }
        return true;
    }

    private boolean stopHousingFund(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(housingFundTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("workOrderId", workOrder.getId());
            return map;
        }).collect(Collectors.toList());
        workOrderService.stopTasks(maps);
        return true;
    }

    private boolean stopSocialSecurity(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(socialSecurityTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("workOrderId", workOrder.getId());
            return map;
        }).collect(Collectors.toList());
        workOrderService.stopTasks(maps);
        return true;
    }

    private boolean stopReportTask(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(reportTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("workOrderId", workOrder.getId());
            return map;
        }).collect(Collectors.toList());
        workOrderService.stopTasks(maps);
        return true;
    }

    public boolean addReportTask(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(reportTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("id", snowflakeIdWorker.nextId());
            map.put("workOrderId", workOrder.getId());
            map.put("creatorId", SecurityUtils.getUserId());
            map.put("companyId", workOrder.getCompanyId());
            map.put("tenantId", workOrder.getTenantId());
            return map;
        }).collect(Collectors.toList());
        workOrderService.insertTasks(maps);
        return true;
    }


    public boolean addHousingFund(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(housingFundTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("id", snowflakeIdWorker.nextId());
            map.put("workOrderId", workOrder.getId());
            map.put("creatorId", SecurityUtils.getUserId());
            map.put("companyId", workOrder.getCompanyId());
            map.put("tenantId", workOrder.getTenantId());
            return map;
        }).collect(Collectors.toList());
        workOrderService.insertTasks(maps);
        return true;
    }

    public boolean addSocialSecurity(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(socialSecurityTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("id", snowflakeIdWorker.nextId());
            map.put("workOrderId", workOrder.getId());
            map.put("creatorId", SecurityUtils.getUserId());
            map.put("companyId", workOrder.getCompanyId());
            map.put("tenantId", workOrder.getTenantId());
            return map;
        }).collect(Collectors.toList());
        workOrderService.insertTasks(maps);
        return true;
    }

    @Override
    public boolean removeBatchByIds(List<Long> ids) {
        // 判断是否已审核
        if (this.query().in("id", ids).eq("verify_status", 1).count() > 0) {
            throw new ServiceException("已审核合同不能删除。");
        } else if (this.query().in("id", ids).eq("status", 8).count() > 0) {
            throw new ServiceException("合同变更不能删除");
        } else if (this.query().in("id", ids).eq("status", 9).count() > 0) {
            throw new ServiceException("合同已解除不能删除");
        } else {
            // 未审核的删掉 合同信息和对应明细信息
            super.removeBatchByIds(ids);
            QueryWrapper<BizArchiveInputDetail> detailQueryWrapper = new QueryWrapper<>();
            detailQueryWrapper.in("contract_id", ids);
            archiveInputDetailService.remove(detailQueryWrapper);
            QueryWrapper<BizArchiveInputDetailProcess> processQueryWrapper = new QueryWrapper<>();
            processQueryWrapper.in("contract_id", ids);
            archiveInputDetailProcessService.remove(processQueryWrapper);
        }
        return true;
    }

    @Override
    public boolean stopWorkOrder(BizArchiveInput bizArchiveInput) {
        if (bizArchiveInput.getServiceType().equals(2)) {
            // 假设是单次任务
            List<BizWorkOrder> bizWorkOrders = workOrderService.query().eq("contract_id", bizArchiveInput.getId()).list();
            bizWorkOrders.forEach(v -> {
                v.setIsStop(1);
            });
            return bizWorkOrders.isEmpty() || workOrderService.updateBatchById(bizWorkOrders);
        } else if (bizArchiveInput.getServiceType().equals(1)) {
            // 假设是循环任务
            // 判断是否是最后一个合同 是否有未完成
            // 假设有未完成 不停止
            List<BizWorkOrderDetail> details = workOrderDetailService.query().eq("contract_id", bizArchiveInput.getId()).list();
            List<BizWorkOrder> workOrders = new ArrayList<>();
            if (!details.isEmpty()) {
                workOrders = workOrderService.query().in("id", details.stream().map(BizWorkOrderDetail::getWorkOrderId).collect(Collectors.toList())).list();
                List<BizWorkOrderDetail> otherDetails = workOrderDetailService.query().eq("is_stop", 0).in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).notIn("id", details.stream().map(BizWorkOrderDetail::getId).collect(Collectors.toList())).list();
                List<BizWorkOrderRecord> records = workOrderRecordService.query().in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).list();
                workOrders.forEach(l -> {
                    l.setDetails(otherDetails.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).collect(Collectors.toList()));
                    l.setRecords(records.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).collect(Collectors.toList()));
//                l.setMonthNum(l.getDetails().stream().mapToInt(v -> v.getServiceNum() + v.getFreeNum()).sum());
                    if (l.getStartMonth() != null) {
                        Integer monthNun = l.getDetails().stream().mapToInt(v -> v.getServiceNum() + v.getFreeNum()).sum();
                        DateTime startDate = DateTime.of(l.getStartMonth());
                        DateTime endDate = startDate.offsetNew(DateField.MONTH, monthNun - 1);
                        // 假设结束月小于完成月
                        if (records.stream().noneMatch(v -> (v.getYear() + v.getMonth()).compareTo(endDate.toString("yyyyMM")) >= 0)) {
                            // 停止工单
                            l.setIsStop(1);
                        } else {
                            // 不停止工单 只修改工单完成时间
                            l.setMonthNum(monthNun);
                            l.setEndMonth(endDate);
                            // 旧任务明细 停止
                            details.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).forEach(v -> v.setIsStop(1));
                        }
                    } else {
                        l.setIsStop(1);
                    }
                });
            }
            workOrders.stream().filter(v -> v.getIsStop().equals(1)).forEach(this::stopLoopTasks);
            return (workOrders.isEmpty() || workOrderService.updateBatchById(workOrders)) && (details.isEmpty() || workOrderDetailService.updateBatchById(details));
        } else {
            return true;
        }
    }


    @Override
    public boolean checkWorkOrderStatusProcess(List<BizArchiveInputDetailProcess> delProcess) {
        // 判断是否任务已完成
        List<BizWorkOrder> workOrders = workOrderService.query().in("contract_detail_process_id", delProcess.stream().map(BizArchiveInputDetailProcess::getId).collect(Collectors.toList())).list();
        if (workOrderRecordService.query().in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).count() > 0) {
            // 存在已经在做的任务不能未完成
            return false;
        }
        return true;
    }

    @Override
    public boolean checkWorkOrderStatus(List<BizArchiveInputDetail> delList) {
        List<BizWorkOrderDetail> details = workOrderDetailService.query().in("contract_detail_id", delList.stream().map(BizArchiveInputDetail::getId).collect(Collectors.toList())).list();
        List<BizWorkOrder> workOrders = workOrderService.query().in("id", details.stream().map(BizWorkOrderDetail::getWorkOrderId).collect(Collectors.toList())).list();
        List<BizWorkOrderDetail> otherDetails = workOrderDetailService.query().eq("is_stop", 0).in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).notIn("id", details.stream().map(BizWorkOrderDetail::getId).collect(Collectors.toList())).list();
        List<BizWorkOrderRecord> records = workOrderRecordService.query().in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).list();
        AtomicBoolean status = new AtomicBoolean(true);
        workOrders.forEach(l -> {
            // 除了删除的工单明细之外的工单
            l.setDetails(otherDetails.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).collect(Collectors.toList()));
            // 完成的部分
            l.setRecords(records.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).collect(Collectors.toList()));
            if (l.getStartMonth() != null) {
                // 余下明细的结束月
                Integer monthNun = l.getDetails().stream().mapToInt(v -> v.getServiceNum() + v.getFreeNum()).sum();
                DateTime startDate = DateTime.of(l.getStartMonth());
                DateTime endDate = startDate.offsetNew(DateField.MONTH, monthNun - 1);
                if (records.stream().noneMatch(v -> (v.getYear() + v.getMonth()).compareTo(endDate.toString("yyyyMM")) >= 0)) {
                    status.set(false);
                } else {
                    status.set(status.get());
                }
            } else {
                status.set(status.get());
            }
        });
        return status.get();
    }

    @Override
    public boolean checkWorkOrderChangeStatus(List<BizArchiveInputDetail> changeList) {
        List<BizWorkOrderDetail> details = workOrderDetailService.query().in("contract_detail_id", changeList.stream().map(BizArchiveInputDetail::getId).collect(Collectors.toList())).list();
        List<BizWorkOrder> workOrders = workOrderService.query().in("id", details.stream().map(BizWorkOrderDetail::getWorkOrderId).collect(Collectors.toList())).list();
        List<BizWorkOrderDetail> otherDetails = workOrderDetailService.query().eq("is_stop", 0).in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).notIn("id", details.stream().map(BizWorkOrderDetail::getId).collect(Collectors.toList())).list();
        List<BizWorkOrderRecord> records = workOrderRecordService.query().in("work_order_id", workOrders.stream().map(BizWorkOrder::getId).collect(Collectors.toList())).list();
        AtomicBoolean status = new AtomicBoolean(true);
        workOrders.forEach(l -> {
            // 除了删除的工单明细之外的工单
            l.setDetails(otherDetails.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).collect(Collectors.toList()));
            BizWorkOrderDetail item = details.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).findFirst().orElse(new BizWorkOrderDetail());
            BizArchiveInputDetail itemDetail = changeList.stream().filter(v -> v.getId().equals(item.getContractDetailId())).findFirst().orElse(new BizArchiveInputDetail());

            // 完成的部分
            l.setRecords(records.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).collect(Collectors.toList()));
            if (l.getStartMonth() != null) {
                // 余下明细的结束月
                int monthNun = l.getDetails().stream().mapToInt(v -> v.getServiceNum() + v.getFreeNum()).sum() + (itemDetail.getServiceNum() == null ? 0 : itemDetail.getServiceNum()) + (itemDetail.getFreeNum() == null ? 0 : itemDetail.getFreeNum());
                DateTime startDate = DateTime.of(l.getStartMonth());
                DateTime endDate = startDate.offsetNew(DateField.MONTH, monthNun - 1);
                if (records.stream().noneMatch(v -> (v.getYear() + v.getMonth()).compareTo(endDate.toString("yyyyMM")) >= 0)) {
                    status.set(false);
                } else {
                    status.set(status.get());
                }
            } else {
                status.set(status.get());
            }
        });
        return status.get();
    }

    @Override
    public String importLoop(List<OrderExcelImportLoopModel> orderList, Long userId, long tenantId) {
        if (StringUtils.isNull(orderList) || orderList.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        List<BizArchiveInput> archiveInputs = new ArrayList<>();
        List<BizWorkOrder> bizWorkOrders = new ArrayList<>();
        List<BizWorkOrderDetail> bizWorkOrderDetails = new ArrayList<>();
        List<BizArchiveInputDetail> archiveInputDetails = new ArrayList<>();
        List<BizCompany> companies = companyService.query().eq("tenant_id", tenantId).list();
        BizSource sourceCondition = new BizSource();
        sourceCondition.setTenantId(tenantId);
        List<BizSource> sources = bizSourceService.getList(sourceCondition);
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (OrderExcelImportLoopModel item : orderList) {
            BizArchiveInput archiveInput = new BizArchiveInput();
            BizCompany company = companies.stream().filter(v -> v.getName().equals(item.getCompanyName())).findFirst().orElse(null);
            if (company == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、客户 ").append(item.getCompanyName()).append(" 不存在");
                continue;
            }
            archiveInput.setCompanyId(company.getId());
            archiveInput.setArchiveCode(String.valueOf(snowflakeIdWorker.nextId()));
            archiveInput.setAmount(item.getAmount());
            archiveInput.setDiscountAmount(item.getDiscountAmount());
            archiveInput.setTrueAmount(item.getTrueAmount());
            archiveInput.setFormDate(item.getFormDate());
            archiveInput.setContractNo(item.getContractNo());
            SysUser user = userService.selectUserByUserNameAndTenantId(item.getSignerName(), String.valueOf(tenantId));
//            if (user == null) {
//                failureNum++;
//                failureMsg.append("<br/>").append(failureNum).append("、员工 ").append(item.getSignerName()).append(" 不存在");
//                continue;
//            }
            // 判断下订单总价单价是否和录入相符
            // 假设 amount - discountAmount != trueAmount 跳过该订单
            if(item.getAmount().subtract(item.getDiscountAmount() == null ? BigDecimal.ZERO : item.getDiscountAmount()).compareTo(item.getTrueAmount()) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 实际付款金额出错");
                continue;
            }
            if (item.getTrueAmount().compareTo(BigDecimal.ZERO) < 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 实际付款金额小于0");
                continue;
            }
            // 假设子表金额不等于订单总金额
            BigDecimal keepAccount = item.getKeepAccountAmount() == null ? BigDecimal.ZERO : item.getKeepAccountAmount();
            BigDecimal security = item.getSocialSecurityAmount() == null ? BigDecimal.ZERO : item.getSocialSecurityAmount();
            BigDecimal housingFund = item.getHousingFundAmount() == null ? BigDecimal.ZERO : item.getHousingFundAmount();
            BigDecimal returnTax = item.getReturnTaxAmount() == null ? BigDecimal.ZERO : item.getReturnTaxAmount();
            if (item.getAmount().compareTo(keepAccount.add(security).add(housingFund).add(returnTax)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 总金额不等于实际任务金额的和。");
                continue;
            }

            BigDecimal keepAccountPrice = item.getKeepAccountPrice() == null ? BigDecimal.ZERO : item.getKeepAccountPrice();
            BigDecimal securityPrice = item.getSocialSecurityPrice() == null ? BigDecimal.ZERO : item.getSocialSecurityPrice();
            BigDecimal housingFundPrice = item.getHousingFundPrice() == null ? BigDecimal.ZERO : item.getHousingFundPrice();
            BigDecimal returnTaxPrice = item.getReturnTaxPrice() == null ? BigDecimal.ZERO : item.getReturnTaxPrice();
            BigDecimal keepAccountMonth = item.getKeepAccountMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(item.getKeepAccountMonth());
            BigDecimal securityMonth = item.getSocialSecurityMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(item.getSocialSecurityMonth());
            BigDecimal housingFundMonth = item.getHousingFundMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(item.getHousingFundMonth());
            BigDecimal returnTaxMonth = item.getReturnTaxMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(item.getReturnTaxMonth());
            if (keepAccount.compareTo(keepAccountPrice.multiply(keepAccountMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 记账总金额计算值与记账单价不符。");
                continue;
            }
            if (security.compareTo(securityPrice.multiply(securityMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 社保总金额计算值与社保单价不符。");
                continue;
            }
            if (housingFund.compareTo(housingFundPrice.multiply(housingFundMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 公积金总金额计算值与公积金单价不符。");
                continue;
            }
            if (returnTax.compareTo(returnTaxMonth.multiply(returnTaxPrice)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 返税总金额计算值与返税单价不符。");
                continue;
            }

            archiveInput.setSignerId(user != null ? user.getUserId() : null);
            archiveInput.setContractType("新签".equals(item.getOrderType()) ? 0 : "续签".equals(item.getOrderType()) ? 1 : 3);
            archiveInput.setServiceType(1);
            archiveInput.setTenantId(tenantId);
            archiveInput.setId(snowflakeIdWorker.nextId());
            archiveInput.setStatus(1);
            archiveInput.setVerifyStatus(1);
            archiveInput.setRemark(item.getRemark());
            String sourceName = item.getSourceName();
            String sourceCategory = item.getSourceCategoryName();
            BizSource source = sources.stream().filter(v -> v.getTitle().equals(sourceCategory)).findFirst().orElse(null);
            if (source != null) {
                archiveInput.setSourceCategoryId(source.getId());
                switch (source.getReferrerDataSource()) {
                    case "company":
                        QueryWrapper<BizCompany> companyWrapper = new QueryWrapper<>();
                        companyWrapper.eq("name", sourceName);
                        BizCompany sourceCompany = companyService.getOne(companyWrapper);
                        archiveInput.setSourceId(sourceCompany.getId());
                        break;
                    case "employee":
                        SysUser sourceUser = userService.selectUserByUserName(sourceName);
                        archiveInput.setSourceId(sourceUser != null ? sourceUser.getId() : null);
                        break;
                    case "channel":
                        QueryWrapper<BizChannel> channelWrapper = new QueryWrapper<>();
                        channelWrapper.eq("name", sourceName);
                        BizChannel sourceChannel = channelService.getOne(channelWrapper);
                        archiveInput.setSourceId(sourceChannel.getId());
                        break;
                    default:
                        break;
                }
            }
            archiveInputs.add(archiveInput);
            if ("是".equals(item.getKeepAccount())) {
                BizArchiveInputDetail detail = new BizArchiveInputDetail();
                detail.setTaskTypeId(1L);
                detail.setAmount(item.getKeepAccountAmount());
                detail.setPrice(item.getKeepAccountPrice());
                detail.setServiceNum(item.getKeepAccountMonth());
                detail.setFreeNum(item.getKeepAccountFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                archiveInputDetails.add(detail);
                BizWorkOrder workOrder =  bizWorkOrders.stream().filter(v -> v.getCompanyId().equals(detail.getCompanyId()) && v.getTaskTypeId().equals(1L)).findFirst().orElse(null);
                if (workOrder == null) {
                    workOrder = new BizWorkOrder();
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setType(1);
                    workOrder.setTaskTypeId(1L);
                    workOrder.setId(snowflakeIdWorker.nextId());
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setContractDetailId(detail.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setStartMonth(item.getKeepAccountStartMonth());
                    workOrder.setEndMonth(item.getKeepAccountEndMonth());
                    workOrder.setTenantId(tenantId);
                    int monthNum = (item.getKeepAccountMonth() == null ? 0 : item.getKeepAccountMonth()) + (item.getKeepAccountFreeMonth() == null ? 0 : item.getKeepAccountFreeMonth());
                    workOrder.setMonthNum(monthNum);
                } else {
                    int monthNum = (item.getKeepAccountMonth() == null ? 0 : item.getKeepAccountMonth()) + (item.getKeepAccountFreeMonth() == null ? 0 : item.getKeepAccountFreeMonth());
                    workOrder.setMonthNum(workOrder.getMonthNum() + monthNum);
                    workOrder.setEndMonth(workOrder.getEndMonth().compareTo(item.getKeepAccountEndMonth()) > 0 ? workOrder.getEndMonth() : item.getKeepAccountEndMonth());
                    workOrder.setStartMonth(workOrder.getStartMonth().compareTo(item.getKeepAccountStartMonth()) > 0 ? item.getKeepAccountStartMonth() : workOrder.getStartMonth());
                }
                BizWorkOrderDetail workOrderDetail = new BizWorkOrderDetail();
                workOrderDetail.setCompanyId(archiveInput.getCompanyId());
                workOrderDetail.setContractDetailId(detail.getId());
                workOrderDetail.setContractId(archiveInput.getId());
                workOrderDetail.setWorkOrderId(workOrder.getId());
                workOrderDetail.setFreeNum(detail.getFreeNum());
                workOrderDetail.setServiceNum(detail.getServiceNum());
                workOrderDetail.setTenantId(tenantId);
                bizWorkOrderDetails.add(workOrderDetail);
            }
            if ("是".equals(item.getSocialSecurity())) {
                BizArchiveInputDetail detail = new BizArchiveInputDetail();
                detail.setTaskTypeId(2L);
                detail.setAmount(item.getSocialSecurityAmount());
                detail.setPrice(item.getSocialSecurityPrice());
                detail.setServiceNum(item.getSocialSecurityMonth());
                detail.setFreeNum(item.getSocialSecurityFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                archiveInputDetails.add(detail);
                BizWorkOrder workOrder =  bizWorkOrders.stream().filter(v -> v.getCompanyId().equals(detail.getCompanyId()) && v.getTaskTypeId().equals(2L)).findFirst().orElse(null);
                if (workOrder == null) {
                    workOrder = new BizWorkOrder();
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setType(1);
                    workOrder.setTaskTypeId(2L);
                    workOrder.setId(snowflakeIdWorker.nextId());
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setContractDetailId(detail.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setStartMonth(item.getSocialSecurityStartMonth());
                    workOrder.setEndMonth(item.getSocialSecurityEndMonth());
                    workOrder.setTenantId(tenantId);
                    int monthNum = (item.getSocialSecurityMonth() == null ? 0 : item.getSocialSecurityMonth()) + (item.getSocialSecurityFreeMonth() == null ? 0 : item.getSocialSecurityFreeMonth());
                    workOrder.setMonthNum(monthNum);
                    bizWorkOrders.add(workOrder);
                } else {
                    int monthNum = (item.getSocialSecurityMonth() == null ? 0 : item.getSocialSecurityMonth()) + (item.getSocialSecurityFreeMonth() == null ? 0 : item.getSocialSecurityFreeMonth());
                    workOrder.setMonthNum(workOrder.getMonthNum() + monthNum);
                    workOrder.setEndMonth(workOrder.getEndMonth().compareTo(item.getSocialSecurityEndMonth()) > 0 ? workOrder.getEndMonth() : item.getSocialSecurityEndMonth());
                    workOrder.setStartMonth(workOrder.getStartMonth().compareTo(item.getSocialSecurityStartMonth()) > 0 ? item.getSocialSecurityStartMonth() : workOrder.getStartMonth());
                }
                BizWorkOrderDetail workOrderDetail = new BizWorkOrderDetail();
                workOrderDetail.setCompanyId(archiveInput.getCompanyId());
                workOrderDetail.setContractDetailId(detail.getId());
                workOrderDetail.setContractId(archiveInput.getId());
                workOrderDetail.setWorkOrderId(workOrder.getId());
                workOrderDetail.setFreeNum(detail.getFreeNum());
                workOrderDetail.setServiceNum(detail.getServiceNum());
                workOrderDetail.setTenantId(tenantId);
                bizWorkOrderDetails.add(workOrderDetail);
            }
            if ("是".equals(item.getHousingFund())) {
                BizArchiveInputDetail detail = new BizArchiveInputDetail();
                detail.setTaskTypeId(3L);
                detail.setAmount(item.getHousingFundAmount());
                detail.setPrice(item.getHousingFundPrice());
                detail.setServiceNum(item.getHousingFundMonth());
                detail.setFreeNum(item.getHousingFundFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                archiveInputDetails.add(detail);
                BizWorkOrder workOrder =  bizWorkOrders.stream().filter(v -> v.getCompanyId().equals(detail.getCompanyId()) && v.getTaskTypeId().equals(3L)).findFirst().orElse(null);
                if (workOrder == null) {
                    workOrder = new BizWorkOrder();
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setType(1);
                    workOrder.setTaskTypeId(3L);
                    workOrder.setId(snowflakeIdWorker.nextId());
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setContractDetailId(detail.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setStartMonth(item.getHousingFundStartMonth());
                    workOrder.setEndMonth(item.getHousingFundEndMonth());
                    workOrder.setTenantId(tenantId);
                    int monthNum = (item.getHousingFundMonth() == null ? 0 : item.getHousingFundMonth()) + (item.getHousingFundFreeMonth() == null ? 0 : item.getHousingFundFreeMonth());
                    workOrder.setMonthNum(monthNum);
                    bizWorkOrders.add(workOrder);
                } else {
                    int monthNum = (item.getHousingFundMonth() == null ? 0 : item.getHousingFundMonth()) + (item.getHousingFundFreeMonth() == null ? 0 : item.getHousingFundFreeMonth());
                    workOrder.setMonthNum(workOrder.getMonthNum() + monthNum);
                    workOrder.setEndMonth(workOrder.getEndMonth().compareTo(item.getHousingFundEndMonth()) > 0 ? workOrder.getEndMonth() : item.getHousingFundEndMonth());
                    workOrder.setStartMonth(workOrder.getStartMonth().compareTo(item.getHousingFundStartMonth()) > 0 ? item.getHousingFundStartMonth() : workOrder.getStartMonth());
                }
                BizWorkOrderDetail workOrderDetail = new BizWorkOrderDetail();
                workOrderDetail.setCompanyId(archiveInput.getCompanyId());
                workOrderDetail.setContractDetailId(detail.getId());
                workOrderDetail.setContractId(archiveInput.getId());
                workOrderDetail.setWorkOrderId(workOrder.getId());
                workOrderDetail.setFreeNum(detail.getFreeNum());
                workOrderDetail.setServiceNum(detail.getServiceNum());
                workOrderDetail.setTenantId(tenantId);
                bizWorkOrderDetails.add(workOrderDetail);
            }
            if ("是".equals(item.getReturnTax())) {
                BizArchiveInputDetail detail = new BizArchiveInputDetail();
                detail.setTaskTypeId(4L);
                detail.setAmount(item.getReturnTaxAmount());
                detail.setPrice(item.getReturnTaxPrice());
                detail.setServiceNum(item.getReturnTaxMonth());
                detail.setFreeNum(item.getReturnTaxFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                archiveInputDetails.add(detail);
                BizWorkOrder workOrder =  bizWorkOrders.stream().filter(v -> v.getCompanyId().equals(detail.getCompanyId()) && v.getTaskTypeId().equals(4L)).findFirst().orElse(null);
                if (workOrder == null) {
                    workOrder = new BizWorkOrder();
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setType(1);
                    workOrder.setTaskTypeId(4L);
                    workOrder.setId(snowflakeIdWorker.nextId());
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setContractDetailId(detail.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setStartMonth(item.getReturnTaxStartMonth());
                    workOrder.setEndMonth(item.getReturnTaxEndMonth());
                    workOrder.setTenantId(tenantId);
                    int monthNum = (item.getReturnTaxMonth() == null ? 0 : item.getReturnTaxMonth()) + (item.getReturnTaxFreeMonth() == null ? 0 : item.getReturnTaxFreeMonth());
                    workOrder.setMonthNum(monthNum);
                    bizWorkOrders.add(workOrder);
                } else {
                    int monthNum = (item.getReturnTaxMonth() == null ? 0 : item.getReturnTaxMonth()) + (item.getReturnTaxFreeMonth() == null ? 0 : item.getReturnTaxFreeMonth());
                    workOrder.setMonthNum(workOrder.getMonthNum() + monthNum);
                    workOrder.setEndMonth(workOrder.getEndMonth().compareTo(item.getReturnTaxEndMonth()) > 0 ? workOrder.getEndMonth() : item.getReturnTaxEndMonth());
                    workOrder.setStartMonth(workOrder.getStartMonth().compareTo(item.getReturnTaxStartMonth()) > 0 ? item.getReturnTaxStartMonth() : workOrder.getStartMonth());
                }
                BizWorkOrderDetail workOrderDetail = new BizWorkOrderDetail();
                workOrderDetail.setCompanyId(archiveInput.getCompanyId());
                workOrderDetail.setContractDetailId(detail.getId());
                workOrderDetail.setContractId(archiveInput.getId());
                workOrderDetail.setWorkOrderId(workOrder.getId());
                workOrderDetail.setFreeNum(detail.getFreeNum());
                workOrderDetail.setServiceNum(detail.getServiceNum());
                workOrderDetail.setTenantId(tenantId);
                bizWorkOrderDetails.add(workOrderDetail);
            }
            successNum++;
            successMsg.append("<br/>").append(successNum).append("、订单 ").append(item.getContractNo()).append(" 导入成功");
        }
        super.saveBatch(archiveInputs);
        archiveInputDetailService.saveBatch(archiveInputDetails);
        workOrderService.saveBatch(bizWorkOrders);
        workOrderDetailService.saveBatch(bizWorkOrderDetails);
        bizWorkOrders.forEach(this::addLoopTasks);
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public String importOnce(List<OrderExcelImportOnceModel> orderList, Long userId, long tenantId) {
        if (StringUtils.isNull(orderList) || orderList.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        List<BizArchiveInput> archiveInputs = new ArrayList<>();
        List<BizWorkOrder> bizWorkOrders = new ArrayList<>();
        List<BizArchiveInputDetail> archiveInputDetails = new ArrayList<>();
        List<BizArchiveInputDetailProcess> archiveInputDetailProcesses = new ArrayList<>();
        List<BizCompany> companies = companyService.query().eq("tenant_id", tenantId).list();
        BizSource sourceCondition = new BizSource();
        sourceCondition.setTenantId(tenantId);
        List<BizSource> sources = bizSourceService.getList(sourceCondition);
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (OrderExcelImportOnceModel item : orderList) {
            BizArchiveInput archiveInput = new BizArchiveInput();
            BizCompany company = companies.stream().filter(v -> v.getName().equals(item.getCompanyName())).findFirst().orElse(null);
            if (company == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、客户 ").append(item.getCompanyName()).append(" 不存在");
                continue;
            }
            SysUser user = userService.selectUserByUserNameAndTenantId(item.getSignerName(), String.valueOf(tenantId));
//            if (user == null) {
//                failureNum++;
//                failureMsg.append("<br/>").append(failureNum).append("、员工 ").append(item.getSignerName()).append(" 不存在");
//                continue;
//            }
            // 金额验证
            // 假设 amount - discountAmount != trueAmount 跳过该订单
            if(item.getAmount().subtract(item.getDiscountAmount() == null ? BigDecimal.ZERO : item.getDiscountAmount()).compareTo(item.getTrueAmount()) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 实际付款金额出错");
                continue;
            }
            if (item.getTrueAmount().compareTo(BigDecimal.ZERO) < 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 实际付款金额小于0");
                continue;
            }
            // 假设子表金额不等于订单总金额
            BigDecimal registerAmount = item.getRegisterAmount() == null ? BigDecimal.ZERO : item.getRegisterAmount();
            BigDecimal alterAmount = item.getAlterAmount() == null ? BigDecimal.ZERO : item.getAlterAmount();
            BigDecimal logoutAmount = item.getLogoutAmount() == null ? BigDecimal.ZERO : item.getLogoutAmount();
            BigDecimal qualifiedAmount = item.getQualifiedAmount() == null ? BigDecimal.ZERO : item.getQualifiedAmount();
            BigDecimal otherAmount = item.getOtherAmount() == null ? BigDecimal.ZERO : item.getOtherAmount();
            if (item.getAmount().compareTo(registerAmount.add(alterAmount).add(logoutAmount).add(qualifiedAmount).add(otherAmount)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(item.getContractNo()).append(" 总金额不等于实际任务金额的和。");
                continue;
            }

            archiveInput.setSignerId(user != null ? user.getUserId() : null);
            archiveInput.setCompanyId(company.getId());
            archiveInput.setArchiveCode(String.valueOf(snowflakeIdWorker.nextId()));
            archiveInput.setAmount(item.getAmount());
            archiveInput.setDiscountAmount(item.getDiscountAmount());
            archiveInput.setTrueAmount(item.getTrueAmount());
            archiveInput.setFormDate(item.getFormDate());
            archiveInput.setContractNo(item.getContractNo());
            archiveInput.setContractType(0);
            archiveInput.setServiceType(2);
            archiveInput.setStatus(1);
            archiveInput.setVerifyStatus(1);
            archiveInput.setRemark(item.getRemark());
            archiveInput.setTenantId(tenantId);
            archiveInput.setId(snowflakeIdWorker.nextId());
            String sourceName = item.getSourceName();
            String sourceCategory = item.getSourceCategoryName();
            BizSource source = sources.stream().filter(v -> v.getTitle().equals(sourceCategory)).findFirst().orElse(null);
            if (source != null) {
                archiveInput.setSourceCategoryId(source.getId());
                switch (source.getReferrerDataSource()) {
                    case "company":
                        QueryWrapper<BizCompany> companyWrapper = new QueryWrapper<>();
                        companyWrapper.eq("name", sourceName);
                        BizCompany sourceCompany = companyService.getOne(companyWrapper);
                        archiveInput.setSourceId(sourceCompany.getId());
                        break;
                    case "employee":
                        SysUser sourceUser = userService.selectUserByUserName(sourceName);
                        archiveInput.setSourceId(sourceUser != null ? sourceUser.getId() : null);
                        break;
                    case "channel":
                        QueryWrapper<BizChannel> channelWrapper = new QueryWrapper<>();
                        channelWrapper.eq("name", sourceName);
                        BizChannel sourceChannel = channelService.getOne(channelWrapper);
                        archiveInput.setSourceId(sourceChannel.getId());
                        break;
                    default:
                        break;
                }
            }
            archiveInputs.add(archiveInput);
            if ("是".equals(item.getRegister())) {
                BizArchiveInputDetail register = new BizArchiveInputDetail();
                register.setTaskTypeId(5L);
                register.setTenantId(tenantId);
                register.setCompanyId(archiveInput.getCompanyId());
                register.setContractId(archiveInput.getId());
                register.setAmount(item.getRegisterAmount());
                register.setId(snowflakeIdWorker.nextId());
                if ("是".equals(item.getPrivateAddress())) {
                    register.setAddressStyle(1);
                    register.setProvince(item.getRegisterProvince());
                    register.setCity(item.getRegisterCity());
                    register.setDistrict(item.getRegisterDistrict());
                    DictRegion province = regionService.query().eq("name", item.getRegisterProvince()).eq("substr(code, 3, 4) = '0000'", "0000").one();
                    register.setProvinceCode(province != null ? province.getCode() : null);

                    DictRegion city = regionService.query().eq("substr(code, 1, 2)", province != null ? province.getCode().substring(0, 2) : null).eq("name", item.getRegisterCity()).one();
                    register.setCityCode(province != null && city != null ? city.getCode() : null);
                    DictRegion district = regionService.query().eq("substr(code, 1, 4)", city != null ? city.getCode().substring(0, 4) : null).eq("name", item.getRegisterCity()).one();
                    register.setDistrictCode(province != null && city != null && district != null ? district.getCode() : null);
                }
                if ("是".equals(item.getFictionAddress())) {
                    register.setAddressStyle(2);
                    register.setAddressAmount(item.getFictionAddressAmount());
                    register.setAddress(item.getFictionAddressPosition());
                    SysDictData conditions = new SysDictData();
                    conditions.setDictType("virtual_address");
                    conditions.setDictLabel(item.getFictionAddressPosition());
                    conditions.setTenantId(tenantId);
                    SysDictData dictData = sysDictDataService.selectDictDataList(conditions).stream().findFirst().orElse(null);

                    register.setFictionAddressId(dictData != null ? dictData.getDictCode() : null);
                }
                if ("是".equals(item.getRegisterLicense())) {
                    // 执照注册
                    BizArchiveInputDetailProcess registerLicense = new BizArchiveInputDetailProcess();
                    registerLicense.setTaskTypeId(5L);
                    registerLicense.setTaskTypeDetailId(1L);
                    registerLicense.setContractId(archiveInput.getId());
                    registerLicense.setContractDetailId(register.getId());
                    registerLicense.setCompanyId(archiveInput.getCompanyId());
                    registerLicense.setAmount(item.getRegisterLicenseAmount());
                    archiveInputDetailProcesses.add(registerLicense);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    registerLicense.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(register.getId());
                    workOrder.setContractDetailProcessId(registerLicense.getId());
                    workOrder.setCity(register.getCity());
                    workOrder.setProvince(register.getProvince());
                    workOrder.setDistrict(register.getDistrict());
                    workOrder.setTaskTypeId(5L);
                    workOrder.setTaskTypeDetailId(1L);
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getRegisterSeal())) {
                    // 注册刻印
                    BizArchiveInputDetailProcess registerSeal = new BizArchiveInputDetailProcess();
                    registerSeal.setTaskTypeId(5L);
                    registerSeal.setTaskTypeDetailId(2L);
                    registerSeal.setContractId(archiveInput.getId());
                    registerSeal.setContractDetailId(register.getId());
                    registerSeal.setCompanyId(archiveInput.getCompanyId());
                    registerSeal.setAmount(item.getRegisterSealAmount());
                    archiveInputDetailProcesses.add(registerSeal);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    registerSeal.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(register.getId());
                    workOrder.setContractDetailProcessId(registerSeal.getId());
                    workOrder.setCity(register.getCity());
                    workOrder.setProvince(register.getProvince());
                    workOrder.setDistrict(register.getDistrict());
                    workOrder.setTaskTypeId(5L);
                    workOrder.setTaskTypeDetailId(2L);
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getRegisterBank())) {
                    // 注册银行
                    BizArchiveInputDetailProcess registerBank = new BizArchiveInputDetailProcess();
                    registerBank.setTaskTypeId(5L);
                    registerBank.setTaskTypeDetailId(3L);
                    registerBank.setContractId(archiveInput.getId());
                    registerBank.setContractDetailId(register.getId());
                    registerBank.setCompanyId(archiveInput.getCompanyId());
                    registerBank.setAmount(item.getRegisterBankAmount());
                    archiveInputDetailProcesses.add(registerBank);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    registerBank.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(register.getId());
                    workOrder.setContractDetailProcessId(registerBank.getId());
                    workOrder.setCity(register.getCity());
                    workOrder.setProvince(register.getProvince());
                    workOrder.setDistrict(register.getDistrict());
                    workOrder.setTaskTypeId(5L);
                    workOrder.setTaskTypeDetailId(3L);
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getRegisterTax())) {
                    // 注册税务
                    BizArchiveInputDetailProcess registerTax = new BizArchiveInputDetailProcess();
                    registerTax.setTaskTypeId(5L);
                    registerTax.setTaskTypeDetailId(4L);
                    registerTax.setContractId(archiveInput.getId());
                    registerTax.setContractDetailId(register.getId());
                    registerTax.setCompanyId(archiveInput.getCompanyId());
                    registerTax.setAmount(item.getRegisterTaxAmount());
                    archiveInputDetailProcesses.add(registerTax);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    registerTax.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(register.getId());
                    workOrder.setContractDetailProcessId(registerTax.getId());
                    workOrder.setCity(register.getCity());
                    workOrder.setProvince(register.getProvince());
                    workOrder.setDistrict(register.getDistrict());
                    workOrder.setTaskTypeId(5L);
                    workOrder.setTaskTypeDetailId(4L);
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getRegisterSecurity())) {
                    // 注册社保
                    BizArchiveInputDetailProcess registerSecurity = new BizArchiveInputDetailProcess();
                    registerSecurity.setTaskTypeId(5L);
                    registerSecurity.setTaskTypeDetailId(5L);
                    registerSecurity.setContractId(archiveInput.getId());
                    registerSecurity.setContractDetailId(register.getId());
                    registerSecurity.setCompanyId(archiveInput.getCompanyId());
                    registerSecurity.setAmount(item.getRegisterSecurityAmount());
                    archiveInputDetailProcesses.add(registerSecurity);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    registerSecurity.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(register.getId());
                    workOrder.setContractDetailProcessId(registerSecurity.getId());
                    workOrder.setCity(register.getCity());
                    workOrder.setProvince(register.getProvince());
                    workOrder.setDistrict(register.getDistrict());
                    workOrder.setTaskTypeId(5L);
                    workOrder.setTaskTypeDetailId(5L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getRegisterHousingFund())) {
                    // 注册公积金
                    BizArchiveInputDetailProcess registerHousingFund = new BizArchiveInputDetailProcess();
                    registerHousingFund.setTaskTypeId(5L);
                    registerHousingFund.setTaskTypeDetailId(6L);
                    registerHousingFund.setContractId(archiveInput.getId());
                    registerHousingFund.setContractDetailId(register.getId());
                    registerHousingFund.setCompanyId(archiveInput.getCompanyId());
                    registerHousingFund.setAmount(item.getRegisterHousingFundAmount());
                    archiveInputDetailProcesses.add(registerHousingFund);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    registerHousingFund.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(register.getId());
                    workOrder.setContractDetailProcessId(registerHousingFund.getId());
                    workOrder.setCity(register.getCity());
                    workOrder.setProvince(register.getProvince());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setDistrict(register.getDistrict());
                    workOrder.setTaskTypeId(5L);
                    workOrder.setTaskTypeDetailId(6L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                archiveInputDetails.add(register);
            }
            if ("是".equals(item.getAlter())) {
                BizArchiveInputDetail alter = new BizArchiveInputDetail();
                alter.setTaskTypeId(6L);
                alter.setTenantId(tenantId);
                alter.setCompanyId(archiveInput.getCompanyId());
                alter.setContractId(archiveInput.getId());
                alter.setAmount(item.getAlterAmount());
                alter.setId(snowflakeIdWorker.nextId());
                alter.setProvince(item.getAlterProvince());
                alter.setCity(item.getAlterCity());
                alter.setDistrict(item.getAlterDistrict());
                DictRegion province = regionService.query().eq("name", item.getAlterProvince()).eq("substr(code, 3, 4) = '0000'", "0000").one();
                alter.setProvinceCode(province != null ? province.getCode() : null);

                DictRegion city = regionService.query().eq("substr(code, 1, 2)", province != null ? province.getCode().substring(0, 2) : null).eq("name", item.getAlterCity()).one();
                alter.setCityCode(province != null && city != null ? city.getCode() : null);
                DictRegion district = regionService.query().eq("substr(code, 1, 4)", city != null ? city.getCode().substring(0, 4) : null).eq("name", item.getAlterDistrict()).one();
                alter.setDistrictCode(province != null && city != null && district != null ? district.getCode() : null);
                if ("是".equals(item.getAlterLicense())) {
                    // 执照变更
                    BizArchiveInputDetailProcess alterLicense = new BizArchiveInputDetailProcess();
                    alterLicense.setTaskTypeId(6L);
                    alterLicense.setTaskTypeDetailId(7L);
                    alterLicense.setContractId(archiveInput.getId());
                    alterLicense.setContractDetailId(alter.getId());
                    alterLicense.setCompanyId(archiveInput.getCompanyId());
                    alterLicense.setAmount(item.getAlterLicenseAmount());
                    archiveInputDetailProcesses.add(alterLicense);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    alterLicense.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(alter.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(alterLicense.getId());
                    workOrder.setCity(alter.getCity());
                    workOrder.setProvince(alter.getProvince());
                    workOrder.setDistrict(alter.getDistrict());
                    workOrder.setTaskTypeId(6L);
                    workOrder.setTaskTypeDetailId(7L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getAlterSeal())) {
                    // 注册刻印
                    BizArchiveInputDetailProcess alterSeal = new BizArchiveInputDetailProcess();
                    alterSeal.setTaskTypeId(6L);
                    alterSeal.setTaskTypeDetailId(8L);
                    alterSeal.setContractId(archiveInput.getId());
                    alterSeal.setContractDetailId(alter.getId());
                    alterSeal.setCompanyId(archiveInput.getCompanyId());
                    alterSeal.setAmount(item.getAlterSealAmount());
                    archiveInputDetailProcesses.add(alterSeal);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    alterSeal.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(alter.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(alterSeal.getId());
                    workOrder.setCity(alter.getCity());
                    workOrder.setProvince(alter.getProvince());
                    workOrder.setDistrict(alter.getDistrict());
                    workOrder.setTaskTypeId(6L);
                    workOrder.setTaskTypeDetailId(8L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getAlterBank())) {
                    // 注册银行
                    BizArchiveInputDetailProcess alterBank = new BizArchiveInputDetailProcess();
                    alterBank.setTaskTypeId(6L);
                    alterBank.setTaskTypeDetailId(9L);
                    alterBank.setContractId(archiveInput.getId());
                    alterBank.setContractDetailId(alter.getId());
                    alterBank.setCompanyId(archiveInput.getCompanyId());
                    alterBank.setAmount(item.getAlterBankAmount());
                    archiveInputDetailProcesses.add(alterBank);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    alterBank.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(alter.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(alterBank.getId());
                    workOrder.setCity(alter.getCity());
                    workOrder.setProvince(alter.getProvince());
                    workOrder.setDistrict(alter.getDistrict());
                    workOrder.setTaskTypeId(6L);
                    workOrder.setTaskTypeDetailId(9L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getAlterTax())) {
                    // 注册税务
                    BizArchiveInputDetailProcess alterTax = new BizArchiveInputDetailProcess();
                    alterTax.setTaskTypeId(6L);
                    alterTax.setTaskTypeDetailId(10L);
                    alterTax.setContractId(archiveInput.getId());
                    alterTax.setContractDetailId(alter.getId());
                    alterTax.setCompanyId(archiveInput.getCompanyId());
                    alterTax.setAmount(item.getAlterTaxAmount());
                    archiveInputDetailProcesses.add(alterTax);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    alterTax.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(alter.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(alterTax.getId());
                    workOrder.setCity(alter.getCity());
                    workOrder.setProvince(alter.getProvince());
                    workOrder.setDistrict(alter.getDistrict());
                    workOrder.setTaskTypeId(6L);
                    workOrder.setTaskTypeDetailId(10L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getAlterSecurity())) {
                    // 注册社保
                    BizArchiveInputDetailProcess alterSecurity = new BizArchiveInputDetailProcess();
                    alterSecurity.setTaskTypeId(6L);
                    alterSecurity.setTaskTypeDetailId(11L);
                    alterSecurity.setContractId(archiveInput.getId());
                    alterSecurity.setContractDetailId(alter.getId());
                    alterSecurity.setCompanyId(archiveInput.getCompanyId());
                    alterSecurity.setAmount(item.getAlterSecurityAmount());
                    archiveInputDetailProcesses.add(alterSecurity);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    alterSecurity.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(alter.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(alterSecurity.getId());
                    workOrder.setCity(alter.getCity());
                    workOrder.setProvince(alter.getProvince());
                    workOrder.setDistrict(alter.getDistrict());
                    workOrder.setTaskTypeId(6L);
                    workOrder.setTaskTypeDetailId(11L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getAlterHousingFund())) {
                    // 注册公积金
                    BizArchiveInputDetailProcess alterHousingFund = new BizArchiveInputDetailProcess();
                    alterHousingFund.setTaskTypeId(6L);
                    alterHousingFund.setTaskTypeDetailId(12L);
                    alterHousingFund.setContractId(archiveInput.getId());
                    alterHousingFund.setContractDetailId(alter.getId());
                    alterHousingFund.setCompanyId(archiveInput.getCompanyId());
                    alterHousingFund.setAmount(item.getAlterHousingFundAmount());
                    archiveInputDetailProcesses.add(alterHousingFund);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    alterHousingFund.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(alter.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(alterHousingFund.getId());
                    workOrder.setCity(alter.getCity());
                    workOrder.setProvince(alter.getProvince());
                    workOrder.setDistrict(alter.getDistrict());
                    workOrder.setTaskTypeId(6L);
                    workOrder.setTaskTypeDetailId(12L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                archiveInputDetails.add(alter);
            }
            if ("是".equals(item.getLogout())) {
                BizArchiveInputDetail logout = new BizArchiveInputDetail();
                logout.setTaskTypeId(7L);
                logout.setTenantId(tenantId);
                logout.setCompanyId(archiveInput.getCompanyId());
                logout.setContractId(archiveInput.getId());
                logout.setAmount(item.getLogoutAmount());
                logout.setId(snowflakeIdWorker.nextId());
                logout.setProvince(item.getLogoutProvince());
                logout.setCity(item.getLogoutCity());
                logout.setDistrict(item.getLogoutDistrict());
                DictRegion province = regionService.query().eq("name", item.getLogoutProvince()).eq("substr(code, 3, 4) = '0000'", "0000").one();
                logout.setProvinceCode(province != null ? province.getCode() : null);

                DictRegion city = regionService.query().eq("substr(code, 1, 2)", province != null ? province.getCode().substring(0, 2) : null).eq("name", item.getLogoutCity()).one();
                logout.setCityCode(province != null && city != null ? city.getCode() : null);
                DictRegion district = regionService.query().eq("substr(code, 1, 4)", city != null ? city.getCode().substring(0, 4) : null).eq("name", item.getLogoutDistrict()).one();
                logout.setDistrictCode(province != null && city != null && district != null ? district.getCode() : null);
                if ("是".equals(item.getLogoutLicense())) {
                    // 执照变更
                    BizArchiveInputDetailProcess logoutLicense = new BizArchiveInputDetailProcess();
                    logoutLicense.setTaskTypeId(7L);
                    logoutLicense.setTaskTypeDetailId(13L);
                    logoutLicense.setContractId(archiveInput.getId());
                    logoutLicense.setContractDetailId(logout.getId());
                    logoutLicense.setCompanyId(archiveInput.getCompanyId());
                    logoutLicense.setAmount(item.getLogoutLicenseAmount());
                    archiveInputDetailProcesses.add(logoutLicense);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    logoutLicense.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(logout.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(logoutLicense.getId());
                    workOrder.setCity(logout.getCity());
                    workOrder.setProvince(logout.getProvince());
                    workOrder.setDistrict(logout.getDistrict());
                    workOrder.setTaskTypeId(7L);
                    workOrder.setTaskTypeDetailId(13L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getLogoutBank())) {
                    // 注册银行
                    BizArchiveInputDetailProcess logoutBank = new BizArchiveInputDetailProcess();
                    logoutBank.setTaskTypeId(7L);
                    logoutBank.setTaskTypeDetailId(14L);
                    logoutBank.setContractId(archiveInput.getId());
                    logoutBank.setContractDetailId(logout.getId());
                    logoutBank.setCompanyId(archiveInput.getCompanyId());
                    logoutBank.setAmount(item.getLogoutBankAmount());
                    archiveInputDetailProcesses.add(logoutBank);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    logoutBank.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(logout.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(logoutBank.getId());
                    workOrder.setCity(logout.getCity());
                    workOrder.setProvince(logout.getProvince());
                    workOrder.setDistrict(logout.getDistrict());
                    workOrder.setTaskTypeId(7L);
                    workOrder.setTaskTypeDetailId(14L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getLogoutTax())) {
                    // 注册税务
                    BizArchiveInputDetailProcess logoutTax = new BizArchiveInputDetailProcess();
                    logoutTax.setTaskTypeId(7L);
                    logoutTax.setTaskTypeDetailId(15L);
                    logoutTax.setContractId(archiveInput.getId());
                    logoutTax.setContractDetailId(logout.getId());
                    logoutTax.setCompanyId(archiveInput.getCompanyId());
                    logoutTax.setAmount(item.getLogoutTaxAmount());
                    archiveInputDetailProcesses.add(logoutTax);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    logoutTax.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(logout.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(logoutTax.getId());
                    workOrder.setCity(logout.getCity());
                    workOrder.setProvince(logout.getProvince());
                    workOrder.setDistrict(logout.getDistrict());
                    workOrder.setTaskTypeId(7L);
                    workOrder.setTaskTypeDetailId(15L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getLogoutSecurity())) {
                    // 注册社保
                    BizArchiveInputDetailProcess logoutSecurity = new BizArchiveInputDetailProcess();
                    logoutSecurity.setTaskTypeId(7L);
                    logoutSecurity.setTaskTypeDetailId(16L);
                    logoutSecurity.setContractId(archiveInput.getId());
                    logoutSecurity.setContractDetailId(logout.getId());
                    logoutSecurity.setCompanyId(archiveInput.getCompanyId());
                    logoutSecurity.setAmount(item.getLogoutSecurityAmount());
                    archiveInputDetailProcesses.add(logoutSecurity);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    logoutSecurity.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(logout.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(logoutSecurity.getId());
                    workOrder.setCity(logout.getCity());
                    workOrder.setProvince(logout.getProvince());
                    workOrder.setDistrict(logout.getDistrict());
                    workOrder.setTaskTypeId(7L);
                    workOrder.setTaskTypeDetailId(16L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getLogoutHousingFund())) {
                    // 注册公积金
                    BizArchiveInputDetailProcess logoutHousingFund = new BizArchiveInputDetailProcess();
                    logoutHousingFund.setTaskTypeId(7L);
                    logoutHousingFund.setTaskTypeDetailId(17L);
                    logoutHousingFund.setContractId(archiveInput.getId());
                    logoutHousingFund.setContractDetailId(logout.getId());
                    logoutHousingFund.setCompanyId(archiveInput.getCompanyId());
                    logoutHousingFund.setAmount(item.getLogoutHousingFundAmount());
                    archiveInputDetailProcesses.add(logoutHousingFund);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    logoutHousingFund.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(logout.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(logoutHousingFund.getId());
                    workOrder.setCity(logout.getCity());
                    workOrder.setProvince(logout.getProvince());
                    workOrder.setDistrict(logout.getDistrict());
                    workOrder.setTaskTypeId(7L);
                    workOrder.setTaskTypeDetailId(17L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                if ("是".equals(item.getLogoutQualified())) {
                    // 注册公积金
                    BizArchiveInputDetailProcess logoutQualified = new BizArchiveInputDetailProcess();
                    logoutQualified.setTaskTypeId(7L);
                    logoutQualified.setTaskTypeDetailId(18L);
                    logoutQualified.setContractId(archiveInput.getId());
                    logoutQualified.setContractDetailId(logout.getId());
                    logoutQualified.setCompanyId(archiveInput.getCompanyId());
                    logoutQualified.setAmount(item.getLogoutQualifiedAmount());
                    archiveInputDetailProcesses.add(logoutQualified);
                    BizWorkOrder workOrder = new BizWorkOrder();
                    logoutQualified.setId(snowflakeIdWorker.nextId());
                    workOrder.setContractId(archiveInput.getId());
                    workOrder.setContractDetailId(logout.getId());
                    workOrder.setCompanyId(archiveInput.getCompanyId());
                    workOrder.setContractDetailProcessId(logoutQualified.getId());
                    workOrder.setCity(logout.getCity());
                    workOrder.setProvince(logout.getProvince());
                    workOrder.setDistrict(logout.getDistrict());
                    workOrder.setTaskTypeId(7L);
                    workOrder.setTaskTypeDetailId(18L);
                    workOrder.setTenantId(tenantId);
                    workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                    workOrder.setType(2);
                    bizWorkOrders.add(workOrder);
                }
                archiveInputDetails.add(logout);
            }
            if ("是".equals(item.getQualified())) {
                BizArchiveInputDetail qualified = new BizArchiveInputDetail();
                qualified.setTaskTypeId(8L);
                qualified.setTenantId(tenantId);
                qualified.setCompanyId(archiveInput.getCompanyId());
                qualified.setContractId(archiveInput.getId());
                qualified.setAmount(item.getQualifiedAmount());
                qualified.setId(snowflakeIdWorker.nextId());
                qualified.setProvince(item.getQualifiedProvince());
                qualified.setCity(item.getQualifiedCity());
                qualified.setDistrict(item.getQualifiedDistrict());
                DictRegion province = regionService.query().eq("name", item.getQualifiedProvince()).eq("substr(code, 3, 4) = '0000'", "0000").one();
                qualified.setProvinceCode(province != null ? province.getCode() : null);

                DictRegion city = regionService.query().eq("substr(code, 1, 2)", province != null ? province.getCode().substring(0, 2) : null).eq("name", item.getQualifiedCity()).one();
                qualified.setCityCode(province != null && city != null ? city.getCode() : null);
                DictRegion district = regionService.query().eq("substr(code, 1, 4)", city != null ? city.getCode().substring(0, 4) : null).eq("name", item.getQualifiedDistrict()).one();
                qualified.setDistrictCode(province != null && city != null && district != null ? district.getCode() : null);
                // 资质申请
                BizArchiveInputDetailProcess qualifiedProcess = new BizArchiveInputDetailProcess();
                qualifiedProcess.setTaskTypeId(8L);
                qualifiedProcess.setTaskTypeDetailId(19L);
                qualifiedProcess.setContractId(archiveInput.getId());
                qualifiedProcess.setContractDetailId(qualified.getId());
                qualifiedProcess.setCompanyId(archiveInput.getCompanyId());
                qualifiedProcess.setAmount(item.getQualifiedAmount());
                archiveInputDetailProcesses.add(qualifiedProcess);
                archiveInputDetails.add(qualified);
                BizWorkOrder workOrder = new BizWorkOrder();
                qualifiedProcess.setId(snowflakeIdWorker.nextId());
                workOrder.setContractId(archiveInput.getId());
                workOrder.setContractDetailId(qualified.getId());
                workOrder.setCompanyId(archiveInput.getCompanyId());
                workOrder.setContractDetailProcessId(qualifiedProcess.getId());
                workOrder.setCity(qualified.getCity());
                workOrder.setProvince(qualified.getProvince());
                workOrder.setDistrict(qualified.getDistrict());
                workOrder.setTaskTypeId(8L);
                workOrder.setTaskTypeDetailId(19L);
                workOrder.setTenantId(tenantId);
                workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                workOrder.setType(2);
                bizWorkOrders.add(workOrder);
            }
            if ("是".equals(item.getOther())) {
                BizArchiveInputDetail other = new BizArchiveInputDetail();
                other.setTaskTypeId(9L);
                other.setTenantId(tenantId);
                other.setCompanyId(archiveInput.getCompanyId());
                other.setContractId(archiveInput.getId());
                other.setAmount(item.getOtherAmount());
                other.setId(snowflakeIdWorker.nextId());
                other.setProvince(item.getOtherProvince());
                other.setCity(item.getOtherCity());
                other.setDistrict(item.getOtherDistrict());
                DictRegion province = regionService.query().eq("name", item.getOtherProvince()).eq("substr(code, 3, 4) = '0000'", "0000").one();
                other.setProvinceCode(province != null ? province.getCode() : null);

                DictRegion city = regionService.query().eq("substr(code, 1, 2)", province != null ? province.getCode().substring(0, 2) : null).eq("name", item.getOtherCity()).one();
                other.setCityCode(province != null && city != null ? city.getCode() : null);
                DictRegion district = regionService.query().eq("substr(code, 1, 4)", city != null ? city.getCode().substring(0, 4) : null).eq("name", item.getOtherDistrict()).one();
                other.setDistrictCode(province != null && city != null && district != null ? district.getCode() : null);
                // 资质申请
                BizArchiveInputDetailProcess otherProcess = new BizArchiveInputDetailProcess();
                otherProcess.setTaskTypeId(9L);
                otherProcess.setTaskTypeDetailId(20L);
                otherProcess.setContractId(archiveInput.getId());
                otherProcess.setContractDetailId(other.getId());
                otherProcess.setCompanyId(archiveInput.getCompanyId());
                otherProcess.setAmount(item.getOtherAmount());
                archiveInputDetailProcesses.add(otherProcess);
                archiveInputDetails.add(other);
                BizWorkOrder workOrder = new BizWorkOrder();
                otherProcess.setId(snowflakeIdWorker.nextId());
                workOrder.setContractId(archiveInput.getId());
                workOrder.setContractDetailId(other.getId());
                workOrder.setCompanyId(archiveInput.getCompanyId());
                workOrder.setContractDetailProcessId(otherProcess.getId());
                workOrder.setCity(other.getCity());
                workOrder.setProvince(other.getProvince());
                workOrder.setDistrict(other.getDistrict());
                workOrder.setTaskTypeId(8L);
                workOrder.setTaskTypeDetailId(20L);
                workOrder.setTenantId(tenantId);
                workOrder.setWorkOrderNo(String.valueOf(snowflakeIdWorker.nextId()));
                workOrder.setType(2);
                bizWorkOrders.add(workOrder);
            }
            successNum++;
            successMsg.append("<br/>").append(successNum).append("、订单 ").append(item.getContractNo()).append(" 导入成功");
        }
        super.saveBatch(archiveInputs);
        archiveInputDetailService.saveBatch(archiveInputDetails);
        archiveInputDetailProcessService.saveBatch(archiveInputDetailProcesses);
        workOrderService.saveBatch(bizWorkOrders);
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
