package com.hz.pm.api.gov.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hz.pm.api.common.helper.RegionCacheHelper;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.model.constant.RegionConst;
import com.hz.pm.api.gov.contants.BizProjectContant;
import com.hz.pm.api.gov.convert.ProjectConvert;
import com.hz.pm.api.gov.model.dto.*;
import com.hz.pm.api.gov.model.entity.*;
import com.hz.pm.api.gov.model.req.ProjectBaseInfoReq;
import com.hz.pm.api.gov.model.req.ProjectPushReq;
import com.hz.pm.api.gov.model.vo.*;
import com.hz.pm.api.gov.service.*;
import com.hz.pm.api.portrait.model.entity.ProjectTag;
import com.hz.pm.api.portrait.service.IProjectTagService;
import com.hz.pm.api.projectdeclared.model.entity.Operation;
import com.hz.pm.api.projectdeclared.model.entity.PreInsAcceptancePerson;
import com.hz.pm.api.projectdeclared.model.entity.Purchase;
import com.hz.pm.api.projectdeclared.service.IOperationService;
import com.hz.pm.api.projectdeclared.service.IPreInsAcceptancePersonService;
import com.hz.pm.api.projectdeclared.service.IPurchaseService;
import com.hz.pm.api.projectdeclared.utils.GenerateProjectCodeUtil;
import com.hz.pm.api.projectlib.model.entity.*;
import com.hz.pm.api.projectlib.model.enumeration.ProjectTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.ProjectTypeNewEnum;
import com.hz.pm.api.projectlib.model.req.ProjectListReq;
import com.hz.pm.api.projectlib.service.*;
import com.hz.pm.api.safety.model.entity.PersonSafetyInfo;
import com.hz.pm.api.safety.model.entity.SupplierSafetyQualification;
import com.hz.pm.api.safety.service.IPersonSafetyInfoService;
import com.hz.pm.api.safety.service.ISupplierSafetyQualificationService;
import com.hz.pm.api.staging.model.entity.ProjectStaging;
import com.hz.pm.api.staging.service.IProjectStagingService;
import com.hz.pm.api.user.security.model.UserInfoDetails;
import com.hz.pm.api.user.util.LoginUserUtil;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.file.service.FileService;
import com.wflow.bean.entity.WflowCcTasks;
import com.wflow.service.WflowCcTasksService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zpf
 * @since 2023/8/21 下午2:27
 */

@Component
@RequiredArgsConstructor
@Slf4j
public class GovProjectCollectionManage {

    private final IGovProjectDictionaryService dictionaryService;

    private final IGovBizProjectApplyService projectApplyService;

    private final IGovBizProjectBaseinfoService baseinfoService;

    private final IGovOperationProjectBaseinfoService operationProjectBaseinfoService;

    private final IGovBizProjectApproveService approveService;

    private final IGovBizProjectCimplementService cimplementService;

    private final IGovBizProjectMimplementService mimplementService;

    private final IGovBizProjectProcureService procureService;

    private final GenerateProjectCodeUtil generateProjectCodeUtil;

    private final IGovBizProjectDraftService draftService;

    private final IGovOperationProjectDraftService operationProjectDraftService;

    private final RestTemplate restTemplate;

    private final ThreadPoolTaskScheduler threadPoolTaskScheduler;

    private final FileService fileService;

    @Value("${project.push-url}")
    private String pushUrl;

    @Value("${project.no-effective-url}")
    private String noEffectiveUrl;

    @Value("${project.delete-all-url}")
    private String deleteAllUrl;

    @Value("${spring.profiles.active}")
    private String active;

    private final RegionCacheHelper regionCacheHelper;

    private final IProjectService projectService;
    private final IProjectApplicationService applicationService;

    private final IProjectInstService projectInstService;

    private final RuntimeService runtimeService;

    private final HistoryService historyService;

    private final WflowCcTasksService ccTasksService;

    private final IOperationService operationService;

    private final IProjectRenewalFundDeclarationService renewalFundDeclarationService;

    private final IProjectStagingService stagingService;

    private final INdProjectStatusChangeService statusChangeService;

    private final IPurchaseService purchaseService;

    private final IProjectTagService projectTagService;

    private final ISupplierSafetyQualificationService supplierSafetyQualificationService;
    private final IPreInsAcceptancePersonService preInsAcceptancePersonService;
    private final IPersonSafetyInfoService personService;

    public List<GovProjectDictionaryVO> dictionary(String type) {

        List<GovProjectDictionary> dictionaries = dictionaryService.list(Wrappers.lambdaQuery(GovProjectDictionary.class)
                .eq(StringUtils.isNotBlank(type), GovProjectDictionary::getType, type)
                .eq(GovProjectDictionary::getDeleted, Boolean.FALSE));

        if (CollUtil.isEmpty(dictionaries)) {
            return Collections.emptyList();
        }

        return dictionaries.stream().map(d -> BeanUtil.copyProperties(d, GovProjectDictionaryVO.class))
                .collect(Collectors.toList());
    }

    /**
     * 分页查 项目归集
     *
     * @param req \
     * @return \
     */
    public PageVo<GovBizProjectListVO> list(ProjectListReq req) {
        Page<GovBizProjectBaseinfo> page = req.page();
        LambdaQueryWrapper<GovBizProjectBaseinfo> wrapper = Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .like(StringUtils.isNotBlank(req.getProjectName()), GovBizProjectBaseinfo::getBaseProjName, req.getProjectName())
                .like(StringUtils.isNotBlank(req.getBuildOrg()), GovBizProjectBaseinfo::getBaseBuildDeprt, req.getBuildOrg())
                .gt(Objects.nonNull(req.getCreateOnMin()), GovBizProjectBaseinfo::getTongTime, req.getCreateOnMin())
                .le(Objects.nonNull(req.getCreateOnMax()), GovBizProjectBaseinfo::getTongTime, req.getCreateOnMax())
                .eq(StringUtils.isNotBlank(req.getProjectType()), GovBizProjectBaseinfo::getBaseProjType, req.getProjectType())
                .in(CollUtil.isNotEmpty(req.getProjectCodes()), GovBizProjectBaseinfo::getBaseProjId, req.getProjectCodes())
                .in(Objects.nonNull(req.getOldProjectType()) && ProjectTypeEnum.BUILD.getCode().equals(req.getOldProjectType()),
                        GovBizProjectBaseinfo::getBaseProjType, Lists.newArrayList(ProjectTypeNewEnum.FIRST_BUILD.getCode(),
                                ProjectTypeNewEnum.SJ_BUILD.getCode(), ProjectTypeNewEnum.SZ_BUILD.getCode()))
                .in(Objects.nonNull(req.getOldProjectType()) && ProjectTypeEnum.DEV_OPS.getCode().equals(req.getOldProjectType()),
                        GovBizProjectBaseinfo::getBaseProjType, Lists.newArrayList(ProjectTypeNewEnum.NEW_OPERA.getCode(),
                                ProjectTypeNewEnum.XU_OPERA.getCode()))
                .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                .orderByDesc(GovBizProjectBaseinfo::getBizTime);
        baseinfoService.page(page, wrapper);

        if (CollUtil.isEmpty(page.getRecords())) {
            return PageVo.empty();
        }

        List<String> projIds = page.getRecords().stream()
                .filter(p -> Objects.nonNull(p) && StringUtils.isNotBlank(p.getBaseProjId()))
                .map(GovBizProjectBaseinfo::getBaseProjId).collect(Collectors.toList());

        Map<String, GovBizProjectApply> applyMap = Maps.newHashMap();
        if (CollUtil.isNotEmpty(projIds)) {
            List<GovBizProjectApply> applies = projectApplyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                    .in(GovBizProjectApply::getBaseProjId, projIds)
                    .eq(GovBizProjectApply::getDeleted, Boolean.FALSE));
            applyMap = applies.stream().collect(Collectors.toMap(GovBizProjectApply::getBaseProjId, a -> a));
        }

        Map<String, GovBizProjectApply> finalApplyMap = applyMap;
        List<GovBizProjectListVO> res = page.getRecords().stream().map(p -> {
            GovBizProjectListVO vo = new GovBizProjectListVO();
            vo.setBaseAreaCode(p.getBaseAreaCode());
            vo.setBaseAreaName(p.getBaseAreaName());
            vo.setBaseBuildDeprt(p.getBaseBuildDeprt());
            vo.setBaseBuildDeprtDing(p.getBaseBuildDeprtDing());
            vo.setBaseProjId(p.getBaseProjId());
            vo.setBaseProjName(p.getBaseProjName());
            if (finalApplyMap.containsKey(p.getBaseProjId())) {
                GovBizProjectApply apply = finalApplyMap.get(p.getBaseProjId());
                vo.setBaseProjDeclAmount(apply.getBaseProjDeclAmount());
                vo.setBaseProjTotalAmount(apply.getBaseProjTotalAmount());
                vo.setBaseProjSetYear(apply.getBaseProjSetYear());
            }
            return vo;
        }).collect(Collectors.toList());

        return PageVo.of(res, page.getTotal());
    }

    /**
     * 运维项目归集列表
     *
     * @param req
     * @return
     */
    public PageVo<GovBizProjectListVO> operationList(ProjectListReq req) {
        Page<GovOperationProjectBaseinfo> page = req.page();
        LambdaQueryWrapper<GovOperationProjectBaseinfo> wrapper = Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                .like(StringUtils.isNotBlank(req.getProjectName()), GovOperationProjectBaseinfo::getBaseProjName, req.getProjectName())
                .like(StringUtils.isNotBlank(req.getBuildOrg()), GovOperationProjectBaseinfo::getBaseBuildDeprt, req.getBuildOrg())
                .gt(Objects.nonNull(req.getCreateOnMin()), GovOperationProjectBaseinfo::getTongTime, req.getCreateOnMin())
                .le(Objects.nonNull(req.getCreateOnMax()), GovOperationProjectBaseinfo::getTongTime, req.getCreateOnMax())
                .eq(StringUtils.isNotBlank(req.getProjectType()), GovOperationProjectBaseinfo::getBaseProjType, req.getProjectType())
                .in(CollUtil.isNotEmpty(req.getProjectCodes()), GovOperationProjectBaseinfo::getBaseProjId, req.getProjectCodes())
                .eq(GovOperationProjectBaseinfo::getDeleted, Boolean.FALSE)
                .orderByDesc(GovOperationProjectBaseinfo::getBizTime);
        operationProjectBaseinfoService.page(page, wrapper);

        if (CollUtil.isEmpty(page.getRecords())) {
            return PageVo.empty();
        }

        List<String> projIds = page.getRecords().stream()
                .filter(p -> Objects.nonNull(p) && StringUtils.isNotBlank(p.getBaseProjId()))
                .map(GovOperationProjectBaseinfo::getBaseProjId).collect(Collectors.toList());

        Map<String, GovBizProjectApply> applyMap = Maps.newHashMap();
        if (CollUtil.isNotEmpty(projIds)) {
            List<GovBizProjectApply> applys = projectApplyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                    .in(GovBizProjectApply::getBaseProjId, projIds)
                    .eq(GovBizProjectApply::getDeleted, Boolean.FALSE));
            applyMap = applys.stream().collect(Collectors.toMap(GovBizProjectApply::getBaseProjId, a -> a));
        }

        Map<String, GovBizProjectApply> finalApplyMap = applyMap;
        List<GovBizProjectListVO> res = page.getRecords().stream().map(p -> {
            GovBizProjectListVO vo = new GovBizProjectListVO();
            vo.setBaseAreaCode(p.getBaseAreaCode());
            vo.setBaseAreaName(p.getBaseAreaName());
            vo.setBaseBuildDeprt(p.getBaseBuildDeprt());
            vo.setBaseBuildDeprtDing(p.getBaseBuildDeprtDing());
            vo.setBaseProjId(p.getBaseProjId());
            vo.setBaseProjName(p.getBaseProjName());
            if (finalApplyMap.containsKey(p.getBaseProjId())) {
                GovBizProjectApply apply = finalApplyMap.get(p.getBaseProjId());
                vo.setBaseProjDeclAmount(apply.getBaseProjDeclAmount());
                vo.setBaseProjTotalAmount(apply.getBaseProjTotalAmount());
                vo.setBaseProjSetYear(apply.getBaseProjSetYear());
            }
            return vo;
        }).collect(Collectors.toList());

        return PageVo.of(res, page.getTotal());
    }

    /**
     * 草稿箱列表
     *
     * @param req
     * @return
     */
    public PageVo<GovBizProjectListVO> draftList(ProjectListReq req) {
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        Page<GovBizProjectDraft> page = req.page();
        LambdaQueryWrapper<GovBizProjectDraft> wrapper = Wrappers.lambdaQuery(GovBizProjectDraft.class)
                .like(StringUtils.isNotBlank(req.getProjectName()), GovBizProjectDraft::getBaseProjName, req.getProjectName())
                .like(StringUtils.isNotBlank(req.getBuildOrg()), GovBizProjectDraft::getBaseBuildDeprt, req.getBuildOrg())
                .gt(Objects.nonNull(req.getCreateOnMin()), GovBizProjectDraft::getTongTime, req.getCreateOnMin())
                .le(Objects.nonNull(req.getCreateOnMax()), GovBizProjectDraft::getTongTime, req.getCreateOnMax())
                .eq(StringUtils.isNotBlank(req.getProjectType()), GovBizProjectDraft::getBaseProjType, req.getProjectType())
                .in(Objects.nonNull(req.getOldProjectType()) && ProjectTypeEnum.BUILD.getCode().equals(req.getOldProjectType()),
                        GovBizProjectDraft::getBaseProjType, Lists.newArrayList(ProjectTypeNewEnum.FIRST_BUILD.getCode(),
                                ProjectTypeNewEnum.SJ_BUILD.getCode(), ProjectTypeNewEnum.SZ_BUILD.getCode()))
                .in(Objects.nonNull(req.getOldProjectType()) && ProjectTypeEnum.DEV_OPS.getCode().equals(req.getOldProjectType()),
                        GovBizProjectDraft::getBaseProjType, Lists.newArrayList(ProjectTypeNewEnum.NEW_OPERA.getCode(),
                                ProjectTypeNewEnum.XU_OPERA.getCode()))
                .eq(GovBizProjectDraft::getDeleted, Boolean.FALSE)
                .eq(GovBizProjectDraft::getCreateId, user.getUserId())
                .orderByDesc(GovBizProjectDraft::getBizTime);
        draftService.page(page, wrapper);

        if (CollUtil.isEmpty(page.getRecords())) {
            return PageVo.empty();
        }

        List<GovBizProjectListVO> res = page.getRecords().stream().map(p -> {
            GovBizProjectListVO vo = new GovBizProjectListVO();
            vo.setBaseAreaCode(p.getBaseAreaCode());
            vo.setBaseAreaName(p.getBaseAreaName());
            vo.setBaseBuildDeprt(p.getBaseBuildDeprt());
            vo.setBaseBuildDeprtDing(p.getBaseBuildDeprtDing());
            vo.setBaseProjId(p.getBaseProjId());
            vo.setBaseProjName(p.getBaseProjName());
            vo.setBaseProjDeclAmount(p.getBaseProjDeclAmount());
            vo.setBaseProjTotalAmount(p.getBaseProjTotalAmount());
            vo.setBaseProjSetYear(p.getBaseProjSetYear());
            vo.setDraftId(p.getId());
            return vo;
        }).collect(Collectors.toList());

        return PageVo.of(res, page.getTotal());
    }

    public PageVo<GovBizProjectListVO> operationDraftList(ProjectListReq req) {
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        Page<GovOperationProjectDraft> page = req.page();
        LambdaQueryWrapper<GovOperationProjectDraft> wrapper = Wrappers.lambdaQuery(GovOperationProjectDraft.class)
                .like(StringUtils.isNotBlank(req.getProjectName()), GovOperationProjectDraft::getBaseProjName, req.getProjectName())
                .like(StringUtils.isNotBlank(req.getBuildOrg()), GovOperationProjectDraft::getBaseBuildDeprt, req.getBuildOrg())
                .gt(Objects.nonNull(req.getCreateOnMin()), GovOperationProjectDraft::getTongTime, req.getCreateOnMin())
                .le(Objects.nonNull(req.getCreateOnMax()), GovOperationProjectDraft::getTongTime, req.getCreateOnMax())
                .eq(StringUtils.isNotBlank(req.getProjectType()), GovOperationProjectDraft::getBaseProjType, req.getProjectType())
                .eq(GovOperationProjectDraft::getDeleted, Boolean.FALSE)
                .eq(GovOperationProjectDraft::getCreateId, user.getUserId())
                .orderByDesc(GovOperationProjectDraft::getBizTime);
        operationProjectDraftService.page(page, wrapper);

        if (CollUtil.isEmpty(page.getRecords())) {
            return PageVo.empty();
        }

        List<GovBizProjectListVO> res = page.getRecords().stream().map(p -> {
            GovBizProjectListVO vo = new GovBizProjectListVO();
            vo.setBaseAreaCode(p.getBaseAreaCode());
            vo.setBaseAreaName(p.getBaseAreaName());
            vo.setBaseBuildDeprt(p.getBaseBuildDeprt());
            vo.setBaseBuildDeprtDing(p.getBaseBuildDeprtDing());
            vo.setBaseProjId(p.getBaseProjId());
            vo.setBaseProjName(p.getBaseProjName());
            vo.setBaseProjDeclAmount(p.getBaseProjDeclAmount());
            vo.setBaseProjTotalAmount(p.getBaseProjTotalAmount());
            vo.setBaseProjSetYear(p.getBaseProjSetYear());
            vo.setDraftId(p.getId());
            return vo;
        }).collect(Collectors.toList());

        return PageVo.of(res, page.getTotal());
    }

    public Long count(ProjectListReq req) {
        LambdaQueryWrapper<GovBizProjectBaseinfo> wrapper = Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .like(StringUtils.isNotBlank(req.getProjectName()), GovBizProjectBaseinfo::getBaseProjName, req.getProjectName())
                .like(StringUtils.isNotBlank(req.getBuildOrg()), GovBizProjectBaseinfo::getBaseBuildDeprt, req.getBuildOrg())
                .gt(Objects.nonNull(req.getCreateOnMin()), GovBizProjectBaseinfo::getTongTime, req.getCreateOnMin())
                .le(Objects.nonNull(req.getCreateOnMax()), GovBizProjectBaseinfo::getTongTime, req.getCreateOnMax())
                .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                .orderByDesc(GovBizProjectBaseinfo::getBizTime);
        return baseinfoService.count(wrapper);
    }

    public Long operationCount(ProjectListReq req) {
        LambdaQueryWrapper<GovOperationProjectBaseinfo> wrapper = Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                .like(StringUtils.isNotBlank(req.getProjectName()), GovOperationProjectBaseinfo::getBaseProjName, req.getProjectName())
                .like(StringUtils.isNotBlank(req.getBuildOrg()), GovOperationProjectBaseinfo::getBaseBuildDeprt, req.getBuildOrg())
                .gt(Objects.nonNull(req.getCreateOnMin()), GovOperationProjectBaseinfo::getTongTime, req.getCreateOnMin())
                .le(Objects.nonNull(req.getCreateOnMax()), GovOperationProjectBaseinfo::getTongTime, req.getCreateOnMax())
                .eq(GovOperationProjectBaseinfo::getDeleted, Boolean.FALSE)
                .orderByDesc(GovOperationProjectBaseinfo::getBizTime);
        return operationProjectBaseinfoService.count(wrapper);
    }

    /**
     * 项目归集详情
     *
     * @param projId
     * @return
     */
    public GovBizProjectDetailVO detail(String projId) {
        GovBizProjectDetailVO res = new GovBizProjectDetailVO();
        //1.先查 基本信息
        GovBizProjectBaseinfo baseinfo = baseinfoService.getOne(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .eq(GovBizProjectBaseinfo::getBaseProjId, projId)
                .orderByDesc(GovBizProjectBaseinfo::getBizTime)
                .last(BizConst.LIMIT_1));

        if (Objects.isNull(baseinfo)) {
            return res;
        }
        res.setBaseProjId(baseinfo.getBaseProjId());
        res.setBaseProjName(baseinfo.getBaseProjName());
        res.setBaseinfo(BeanUtil.copyProperties(baseinfo, GovBizProjectBaseinfoVO.class));

        //2.再查 申报信息
        GovBizProjectApply apply = projectApplyService.getOne(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .eq(GovBizProjectApply::getBaseProjId, projId)
                .orderByDesc(GovBizProjectApply::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(apply)) {
            res.setApply(BeanUtil.copyProperties(apply, GovBizProjectApplyVO.class));
        }

        //3.再查 审批信息
        GovBizProjectApprove approve = approveService.getOne(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                .eq(GovBizProjectApprove::getBaseProjId, projId)
                .orderByDesc(GovBizProjectApprove::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(approve)) {
            res.setApprove(BeanUtil.copyProperties(approve, GovBizProjectApproveVO.class));
        }

        //4 对应查询 实施项目还是运维项目
        GovBizProjectCimplement cimplement = cimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                .eq(GovBizProjectCimplement::getBaseProjId, projId)
                .orderByDesc(GovBizProjectCimplement::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(cimplement)) {
            res.setCimplement(BeanUtil.copyProperties(cimplement, GovBizProjectCimplementVO.class));
        }
        GovBizProjectMimplement mimplement = mimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectMimplement.class)
                .eq(GovBizProjectMimplement::getBaseProjId, projId)
                .orderByDesc(GovBizProjectMimplement::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(mimplement)) {
            res.setMimplement(BeanUtil.copyProperties(mimplement, GovBizProjectMimplementVO.class));
        }

        //5.最后查询采购信息
        List<GovBizProjectProcure> procures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                .eq(GovBizProjectProcure::getBaseProjId, projId)
                .orderByDesc(GovBizProjectProcure::getBizTime));
        if (CollUtil.isNotEmpty(procures)) {
            res.setProcures(procures.stream()
                    .map(p -> BeanUtil.copyProperties(p, GovBizProjectProcureVO.class))
                    .collect(Collectors.toList()));
        }

        return res;
    }

    public GovOperationProjectDetailVO operationDetail(String projId) {
        GovOperationProjectDetailVO res = new GovOperationProjectDetailVO();
        //1.先查 基本信息
        GovOperationProjectBaseinfo baseinfo = operationProjectBaseinfoService.getOne(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                .eq(GovOperationProjectBaseinfo::getBaseProjId, projId)
                .orderByDesc(GovOperationProjectBaseinfo::getBizTime)
                .last(BizConst.LIMIT_1));

        if (Objects.isNull(baseinfo)) {
            return res;
        }
        res.setBaseProjId(baseinfo.getBaseProjId());
        res.setBaseProjName(baseinfo.getBaseProjName());
        res.setBaseinfo(BeanUtil.copyProperties(baseinfo, GovOperationProjectBaseinfoVO.class));

        //2.再查 申报信息
        GovBizProjectApply apply = projectApplyService.getOne(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .eq(GovBizProjectApply::getBaseProjId, projId)
                .orderByDesc(GovBizProjectApply::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(apply)) {
            res.setApply(BeanUtil.copyProperties(apply, GovBizProjectApplyVO.class));
        }

        //3.再查 审批信息
        GovBizProjectApprove approve = approveService.getOne(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                .eq(GovBizProjectApprove::getBaseProjId, projId)
                .orderByDesc(GovBizProjectApprove::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(approve)) {
            res.setApprove(BeanUtil.copyProperties(approve, GovBizProjectApproveVO.class));
        }

        //4 对应查询 实施项目还是运维项目
        GovBizProjectCimplement cimplement = cimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                .eq(GovBizProjectCimplement::getBaseProjId, projId)
                .orderByDesc(GovBizProjectCimplement::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(cimplement)) {
            res.setCimplement(BeanUtil.copyProperties(cimplement, GovBizProjectCimplementVO.class));
        }
        GovBizProjectMimplement mimplement = mimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectMimplement.class)
                .eq(GovBizProjectMimplement::getBaseProjId, projId)
                .orderByDesc(GovBizProjectMimplement::getBizTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(mimplement)) {
            res.setMimplement(BeanUtil.copyProperties(mimplement, GovBizProjectMimplementVO.class));
        }

        //5.最后查询采购信息
        List<GovBizProjectProcure> procures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                .eq(GovBizProjectProcure::getBaseProjId, projId)
                .orderByDesc(GovBizProjectProcure::getBizTime));
        if (CollUtil.isNotEmpty(procures)) {
            res.setProcures(procures.stream()
                    .map(p -> BeanUtil.copyProperties(p, GovBizProjectProcureVO.class))
                    .collect(Collectors.toList()));
        }

        return res;
    }

    /**
     * 草稿箱详情
     *
     * @param draftId
     * @return
     */
    public GovBizProjectDetailVO draftDetail(Long draftId) {
        GovBizProjectDetailVO res = new GovBizProjectDetailVO();
        //查询草稿表
        GovBizProjectDraft draft = draftService.getById(draftId);

        if (Objects.isNull(draft)) {
            return null;
        }
        res.setDraftId(draftId);

        //1.基本信息
        res.setBaseProjId(draft.getBaseProjId());
        res.setBaseProjName(draft.getBaseProjName());
        res.setBaseinfo(BeanUtil.copyProperties(draft, GovBizProjectBaseinfoVO.class));

        //2.申报信息
        res.setApply(BeanUtil.copyProperties(draft, GovBizProjectApplyVO.class));

        //3.再查 审批信息
        res.setApprove(BeanUtil.copyProperties(draft, GovBizProjectApproveVO.class));

        //4 对应查询 实施项目还是运维项目
        GovBizProjectCimplementVO cimplementVo = BeanUtil.copyProperties(draft, GovBizProjectCimplementVO.class);
        cimplementVo.setBaseChanFile(draft.getBaseChanFileCimplement());
        cimplementVo.setBaseEstaSummFile(draft.getBaseEstaSummFileCimplement());
        cimplementVo.setBaseEngineerPostpoFile(draft.getBaseEngineerPostpoFileCimplement());
        cimplementVo.setBaseInforLevelFile(draft.getBaseInforLevelFileCimplement());
        cimplementVo.setBasePasswAssessFile(draft.getBasePasswAssessFileCimplement());
        cimplementVo.setBaseUserConsFile(draft.getBaseUserConsFileCimplement());
        cimplementVo.setBaseThirdAcceptFile(draft.getBaseThirdAcceptFileCimplement());
        cimplementVo.setBaseFinalExpertOpinionFile(draft.getBaseFinalExpertOpinionFileCimplement());
        cimplementVo.setBaseLogAggregation(draft.getBaseLogAggregationCimplement());
        cimplementVo.setBaseBusinessMetrics(draft.getBaseBusinessMetricsCimplement());
        res.setCimplement(cimplementVo);
        GovBizProjectMimplementVO mimplementVo = BeanUtil.copyProperties(draft, GovBizProjectMimplementVO.class);
        mimplementVo.setBaseChanFile(draft.getBaseChanFileMimplement());
        mimplementVo.setBaseEstaSummFile(draft.getBaseEstaSummFileMimplement());
        mimplementVo.setBaseEngineerPostpoFile(draft.getBaseEngineerPostpoFileMimplement());
        mimplementVo.setBaseInforLevelFile(draft.getBaseInforLevelFileMimplement());
        mimplementVo.setBasePasswAssessFile(draft.getBasePasswAssessFileMimplement());
        mimplementVo.setBaseUserConsFile(draft.getBaseUserConsFileMimplement());
        mimplementVo.setBaseThirdAcceptFile(draft.getBaseThirdAcceptFileMimplement());
        mimplementVo.setBaseFinalExpertOpinionFile(draft.getBaseFinalExpertOpinionFileMimplement());
        mimplementVo.setBaseLogAggregation(draft.getBaseLogAggregationMimplement());
        mimplementVo.setBaseBusinessMetrics(draft.getBaseBusinessMetricsMimplement());
        res.setMimplement(mimplementVo);

        //5.最后查询采购信息
        if (StringUtils.isNotBlank(draft.getProcure())) {
            try {
                res.setProcures(JSON.parseArray(draft.getProcure(), GovBizProjectProcureVO.class));
            } catch (Exception e) {
                log.error("草稿箱采购出错:" + e.getMessage());
            }
        }

        return res;
    }


    public GovOperationProjectDetailVO operationDraftDetail(Long draftId) {
        GovOperationProjectDetailVO res = new GovOperationProjectDetailVO();
        //查询草稿表
        GovOperationProjectDraft draft = operationProjectDraftService.getById(draftId);

        if (Objects.isNull(draft)) {
            return null;
        }
        res.setDraftId(draftId);

        //1.基本信息
        res.setBaseProjId(draft.getBaseProjId());
        res.setBaseProjName(draft.getBaseProjName());
        res.setBaseinfo(BeanUtil.copyProperties(draft, GovOperationProjectBaseinfoVO.class));

        //2.申报信息
        res.setApply(BeanUtil.copyProperties(draft, GovBizProjectApplyVO.class));

        //3.再查 审批信息
        res.setApprove(BeanUtil.copyProperties(draft, GovBizProjectApproveVO.class));

        //4 对应查询 实施项目还是运维项目
        GovBizProjectCimplementVO cimplementVo = BeanUtil.copyProperties(draft, GovBizProjectCimplementVO.class);
        cimplementVo.setBaseChanFile(draft.getBaseChanFileCimplement());
        cimplementVo.setBaseEstaSummFile(draft.getBaseEstaSummFileCimplement());
        cimplementVo.setBaseEngineerPostpoFile(draft.getBaseEngineerPostpoFileCimplement());
        cimplementVo.setBaseInforLevelFile(draft.getBaseInforLevelFileCimplement());
        cimplementVo.setBasePasswAssessFile(draft.getBasePasswAssessFileCimplement());
        cimplementVo.setBaseUserConsFile(draft.getBaseUserConsFileCimplement());
        cimplementVo.setBaseThirdAcceptFile(draft.getBaseThirdAcceptFileCimplement());
        cimplementVo.setBaseFinalExpertOpinionFile(draft.getBaseFinalExpertOpinionFileCimplement());
        cimplementVo.setBaseLogAggregation(draft.getBaseLogAggregationCimplement());
        cimplementVo.setBaseBusinessMetrics(draft.getBaseBusinessMetricsCimplement());
        res.setCimplement(cimplementVo);
        GovBizProjectMimplementVO mimplementVo = BeanUtil.copyProperties(draft, GovBizProjectMimplementVO.class);
        mimplementVo.setBaseChanFile(draft.getBaseChanFileMimplement());
        mimplementVo.setBaseEstaSummFile(draft.getBaseEstaSummFileMimplement());
        mimplementVo.setBaseEngineerPostpoFile(draft.getBaseEngineerPostpoFileMimplement());
        mimplementVo.setBaseInforLevelFile(draft.getBaseInforLevelFileMimplement());
        mimplementVo.setBasePasswAssessFile(draft.getBasePasswAssessFileMimplement());
        mimplementVo.setBaseUserConsFile(draft.getBaseUserConsFileMimplement());
        mimplementVo.setBaseThirdAcceptFile(draft.getBaseThirdAcceptFileMimplement());
        mimplementVo.setBaseFinalExpertOpinionFile(draft.getBaseFinalExpertOpinionFileMimplement());
        mimplementVo.setBaseLogAggregation(draft.getBaseLogAggregationMimplement());
        mimplementVo.setBaseBusinessMetrics(draft.getBaseBusinessMetricsMimplement());
        res.setMimplement(mimplementVo);

        //5.最后查询采购信息
        if (StringUtils.isNotBlank(draft.getProcure())) {
            try {
                res.setProcures(JSON.parseArray(draft.getProcure(), GovBizProjectProcureVO.class));
            } catch (Exception e) {
                log.error("草稿箱采购出错:" + e.getMessage());
            }
        }

        return res;
    }

    /**
     * 项目归集保存
     *
     * @param saveDTO
     * @return
     */
    @Transactional
    public String save(GovBizProjectSaveDTO saveDTO, UserInfoDetails user) {
        if (Objects.isNull(user)) {
            user = LoginUserUtil.loginUserDetail();
        }

        GovBizProjectBaseinfoDTO base = saveDTO.getBaseinfo();
        String baseProjId = saveDTO.getBaseProjId();
        String baseProjName = base.getBaseProjName();

        //1.保存基本信息
        GovBizProjectBaseinfoDTO baseinfo = saveDTO.getBaseinfo();
        baseinfo.setBaseProjId(baseProjId);
        baseinfo.setBaseProjName(baseProjName);
        baseinfo.setIsEffective(BizProjectContant.ProjectCollection.IS_EFFECTIVE);
        GovBizProjectBaseinfo oldBaseInfo = baseinfoService.getOne(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .eq(GovBizProjectBaseinfo::getBaseProjId, baseProjId)
                .last(BizConst.LIMIT_1));

        //项目名去重
        checkName(baseProjName, baseProjId);
        GovBizProjectBaseinfo saveBase = BeanUtil.copyProperties(baseinfo, GovBizProjectBaseinfo.class);
        saveBase.setBaseProjName(baseProjName);
        saveBase.setIsEffective(BizProjectContant.ProjectCollection.IS_EFFECTIVE);
        if (Objects.nonNull(oldBaseInfo)) {
            saveBase.setId(oldBaseInfo.getId());
            saveBase.setBaseAreaCode(null);
        } else {
            saveBase.setTongTime(LocalDateTime.now());
        }
        saveBase.setAreaCode(RegionConst.RC_HZ);
        saveBase.setBizTime(LocalDateTime.now());
        saveBase.setUpdateBy(user.getUsername());
        saveBase.setUpdateOn(LocalDateTime.now());

        //如果是新增的话 要生成 项目编号
        if (StringUtils.isBlank(baseProjId) || BizProjectContant.ProjectCollection.DRAFT.equals(baseProjId)) {
            baseProjId = generateProjectCodeUtil.generateProjectCode(saveDTO);
            saveBase.setBaseProjId(baseProjId);
        }

        baseinfoService.saveOrUpdate(saveBase);

        // 2.保存 申报信息
        GovBizProjectApplyDTO apply = saveDTO.getApply();
        if (Objects.nonNull(apply)) {
            apply.setBaseProjId(baseProjId);
            apply.setBaseProjName(baseProjName);
            GovBizProjectApply oldApply = projectApplyService.getOne(Wrappers.lambdaQuery(GovBizProjectApply.class)
                    .eq(GovBizProjectApply::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectApply saveApply = BeanUtil.copyProperties(apply, GovBizProjectApply.class);
            saveApply.setBaseProjId(baseProjId);
            if (Objects.nonNull(oldApply)) {
                saveApply.setId(oldApply.getId());
            } else {
                saveApply.setTongTime(LocalDateTime.now());
            }
            if (Objects.nonNull(saveApply.getBaseProjStartTime()) &&
                    Objects.nonNull(saveApply.getBaseProjEndTime())) {
                saveApply.setBaseProjDuration(convertMonth(saveApply.getBaseProjStartTime(),
                        saveApply.getBaseProjEndTime()));
            }
            saveApply.setAreaCode(RegionConst.RC_HZ);
            saveApply.setBizTime(LocalDateTime.now());
            saveApply.setUpdateBy(user.getUsername());
            saveApply.setUpdateOn(LocalDateTime.now());
            if (projectApplyService.saveOrUpdate(saveApply)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssApply(apply, oldApply, saveApply));
            }
        }

        // 3.保存 审批信息
        GovBizProjectApproveDTO approve = saveDTO.getApprove();
        if (Objects.nonNull(approve)) {
            approve.setBaseProjId(baseProjId);
            approve.setBaseProjName(baseProjName);
            GovBizProjectApprove oldApprove = approveService.getOne(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                    .eq(GovBizProjectApprove::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectApprove saveApprove = BeanUtil.copyProperties(approve, GovBizProjectApprove.class);
            saveApprove.setBaseProjId(baseProjId);
            if (Objects.nonNull(oldApprove)) {
                saveApprove.setId(oldApprove.getId());
            } else {
                saveApprove.setTongTime(LocalDateTime.now());
            }
            saveApprove.setBizTime(LocalDateTime.now());
            saveApprove.setAreaCode(RegionConst.RC_HZ);
            saveApprove.setUpdateBy(user.getUsername());
            saveApprove.setUpdateOn(LocalDateTime.now());
            if (approveService.saveOrUpdate(saveApprove)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssApprove(approve, oldApprove, saveApprove));
            }
        }

        // 4.保存 建设项目 实施信息
        GovBizProjectCimplementDTO cimplement = saveDTO.getCimplement();
        if (Objects.nonNull(cimplement)) {
            cimplement.setBaseProjId(baseProjId);
            cimplement.setBaseProjName(baseProjName);
            cimplement.setBaseBidCode(baseProjId);
            cimplement.setBaseBidName(baseProjName);
            GovBizProjectCimplement oldCimplement = cimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                    .eq(GovBizProjectCimplement::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectCimplement saveCimplement = BeanUtil.copyProperties(cimplement, GovBizProjectCimplement.class);
            saveCimplement.setBaseProjId(baseProjId);
            saveCimplement.setBaseBidCode(baseProjId);
            saveCimplement.setBaseBidName(baseProjName);
            if (Objects.nonNull(oldCimplement)) {
                saveCimplement.setId(oldCimplement.getId());
            } else {
                saveCimplement.setTongTime(LocalDateTime.now());
            }
            saveCimplement.setAreaCode(RegionConst.RC_HZ);
            saveCimplement.setBizTime(LocalDateTime.now());
            saveCimplement.setUpdateBy(user.getUsername());
            saveCimplement.setUpdateOn(LocalDateTime.now());
            if (cimplementService.saveOrUpdate(saveCimplement)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssCimplement(cimplement, oldCimplement, saveCimplement));
            }
        }

        // 5.保存 运维项目 实施信息
        GovBizProjectMimplementDTO mimplement = saveDTO.getMimplement();
        if (Objects.nonNull(mimplement)) {
            mimplement.setBaseProjId(baseProjId);
            mimplement.setBaseProjName(baseProjName);
            mimplement.setBaseBidCode(baseProjId);
            mimplement.setBaseBidName(baseProjName);
            GovBizProjectMimplement oldMimplement = mimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectMimplement.class)
                    .eq(GovBizProjectMimplement::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectMimplement saveMimplement = BeanUtil.copyProperties(mimplement, GovBizProjectMimplement.class);
            saveMimplement.setBaseProjId(baseProjId);
            saveMimplement.setBaseBidCode(baseProjId);
            saveMimplement.setBaseBidName(baseProjName);
            if (Objects.nonNull(oldMimplement)) {
                saveMimplement.setId(oldMimplement.getId());
            } else {
                saveMimplement.setTongTime(LocalDateTime.now());
            }
            if (Objects.nonNull(saveBase.getAreaCode())) {
                saveMimplement.setAreaCode(saveBase.getAreaCode());
            }
            saveMimplement.setAreaCode(RegionConst.RC_HZ);
            saveMimplement.setBizTime(LocalDateTime.now());
            saveMimplement.setUpdateBy(user.getUsername());
            saveMimplement.setUpdateOn(LocalDateTime.now());
            if (mimplementService.saveOrUpdate(saveMimplement)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssMimplement(mimplement, oldMimplement, saveMimplement));
            }
        }

        // 6.保存 采购信息
        List<GovBizProjectProcureDTO> procures = saveDTO.getProcures();

        if (Objects.nonNull(procures)) {
            procureService.remove(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                    .eq(GovBizProjectProcure::getBaseProjId, baseProjId));

            Integer index = 1;
            for (GovBizProjectProcureDTO procure : procures) {
                procure.setBaseProjId(baseProjId);
                procure.setBaseProjName(baseProjName);
                procure.setBaseBidCode(baseProjId + StrPool.DASH + String.format(StrPool.FORMAT_DATE_SINGLE_DIGITS, index));
                GovBizProjectProcure saveProcure = BeanUtil.copyProperties(procure, GovBizProjectProcure.class);
                saveProcure.setBaseProjId(baseProjId);
                saveProcure.setId(null);
                saveProcure.setAreaCode(RegionConst.RC_HZ);
                saveProcure.setTongTime(LocalDateTime.now());
                saveProcure.setBizTime(LocalDateTime.now());
                saveProcure.setUpdateBy(user.getUsername());
                saveProcure.setUpdateOn(LocalDateTime.now());
                if (procureService.save(saveProcure)) {
                    threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssProcure(procure, null, saveProcure));
                }
                index++;
            }

        }

        if (Objects.nonNull(saveDTO.getDraftId())) {
            draftService.removeById(saveDTO.getDraftId());
        }

        return BizConst.SAVE_SUCCESS;
    }

    /**
     * 运维项目保存
     *
     * @param saveDTO
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String operationSave(GovOperationProjectSaveDTO saveDTO, UserInfoDetails user) {
        if (Objects.isNull(user)) {
            user = LoginUserUtil.loginUserDetail();
        }

        GovOperationProjectBaseinfoDTO base = saveDTO.getBaseinfo();
        String baseProjId = saveDTO.getBaseProjId();
        String baseProjName = base.getBaseProjName();

        //1.保存基本信息
        GovOperationProjectBaseinfoDTO baseinfo = saveDTO.getBaseinfo();
        baseinfo.setBaseProjId(baseProjId);
        baseinfo.setBaseProjName(baseProjName);
        baseinfo.setIsEffective(BizProjectContant.ProjectCollection.IS_EFFECTIVE);
        GovOperationProjectBaseinfo oldBaseInfo = operationProjectBaseinfoService.getOne(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                .eq(GovOperationProjectBaseinfo::getBaseProjId, baseProjId)
                .last(BizConst.LIMIT_1));

        //项目名去重
        checkNameOperation(baseProjName, baseProjId);
        GovOperationProjectBaseinfo saveBase = BeanUtil.copyProperties(baseinfo, GovOperationProjectBaseinfo.class);
        saveBase.setBaseProjName(baseProjName);
        saveBase.setIsEffective(BizProjectContant.ProjectCollection.IS_EFFECTIVE);
        if (Objects.nonNull(oldBaseInfo)) {
            saveBase.setId(oldBaseInfo.getId());
            saveBase.setBaseAreaCode(null);
        } else {
            saveBase.setTongTime(LocalDateTime.now());
        }
        saveBase.setBizTime(LocalDateTime.now());
        saveBase.setUpdateBy(user.getUsername());
        saveBase.setUpdateOn(LocalDateTime.now());

        //如果是新增的话 要生成 项目编号
        if (StringUtils.isBlank(baseProjId) || BizProjectContant.ProjectCollection.DRAFT.equals(baseProjId)) {
            baseProjId = generateProjectCodeUtil.generateProjectCode(saveDTO);
            saveBase.setBaseProjId(baseProjId);
        }

        operationProjectBaseinfoService.saveOrUpdate(saveBase);

        // 2.保存 申报信息
        GovBizProjectApplyDTO apply = saveDTO.getApply();
        if (Objects.nonNull(apply)) {
            apply.setBaseProjId(baseProjId);
            apply.setBaseProjName(baseProjName);
            GovBizProjectApply oldApply = projectApplyService.getOne(Wrappers.lambdaQuery(GovBizProjectApply.class)
                    .eq(GovBizProjectApply::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectApply saveApply = BeanUtil.copyProperties(apply, GovBizProjectApply.class);
            saveApply.setBaseProjId(baseProjId);
            if (Objects.nonNull(oldApply)) {
                saveApply.setId(oldApply.getId());
            } else {
                saveApply.setTongTime(LocalDateTime.now());
            }
            if (Objects.nonNull(saveApply.getBaseProjStartTime()) &&
                    Objects.nonNull(saveApply.getBaseProjEndTime())) {
                saveApply.setBaseProjDuration(convertMonth(saveApply.getBaseProjStartTime(),
                        saveApply.getBaseProjEndTime()));
            }
            saveApply.setAreaCode(RegionConst.RC_HZ);
            saveApply.setBizTime(LocalDateTime.now());
            saveApply.setUpdateBy(user.getUsername());
            saveApply.setUpdateOn(LocalDateTime.now());
            if (projectApplyService.saveOrUpdate(saveApply)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssApply(apply, oldApply, saveApply));
            }
        }

        // 3.保存 审批信息
        GovBizProjectApproveDTO approve = saveDTO.getApprove();
        if (Objects.nonNull(approve)) {
            approve.setBaseProjId(baseProjId);
            approve.setBaseProjName(baseProjName);
            GovBizProjectApprove oldApprove = approveService.getOne(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                    .eq(GovBizProjectApprove::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectApprove saveApprove = BeanUtil.copyProperties(approve, GovBizProjectApprove.class);
            saveApprove.setBaseProjId(baseProjId);
            if (Objects.nonNull(oldApprove)) {
                saveApprove.setId(oldApprove.getId());
            } else {
                saveApprove.setTongTime(LocalDateTime.now());
            }
            saveApprove.setBizTime(LocalDateTime.now());
            saveApprove.setAreaCode(RegionConst.RC_HZ);
            saveApprove.setUpdateBy(user.getUsername());
            saveApprove.setUpdateOn(LocalDateTime.now());
            if (approveService.saveOrUpdate(saveApprove)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssApprove(approve, oldApprove, saveApprove));
            }
        }

        // 4.保存 建设项目 实施信息
        GovBizProjectCimplementDTO cimplement = saveDTO.getCimplement();
        if (Objects.nonNull(cimplement)) {
            cimplement.setBaseProjId(baseProjId);
            cimplement.setBaseProjName(baseProjName);
            cimplement.setBaseBidCode(baseProjId);
            cimplement.setBaseBidName(baseProjName);
            GovBizProjectCimplement oldCimplement = cimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                    .eq(GovBizProjectCimplement::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectCimplement saveCimplement = BeanUtil.copyProperties(cimplement, GovBizProjectCimplement.class);
            saveCimplement.setBaseProjId(baseProjId);
            saveCimplement.setBaseBidCode(baseProjId);
            saveCimplement.setBaseBidName(baseProjName);
            if (Objects.nonNull(oldCimplement)) {
                saveCimplement.setId(oldCimplement.getId());
            } else {
                saveCimplement.setTongTime(LocalDateTime.now());
            }
            saveCimplement.setAreaCode(RegionConst.RC_HZ);
            saveCimplement.setBizTime(LocalDateTime.now());
            saveCimplement.setUpdateBy(user.getUsername());
            saveCimplement.setUpdateOn(LocalDateTime.now());
            if (cimplementService.saveOrUpdate(saveCimplement)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssCimplement(cimplement, oldCimplement, saveCimplement));
            }
        }

        // 5.保存 运维项目 实施信息
        GovBizProjectMimplementDTO mimplement = saveDTO.getMimplement();
        if (Objects.nonNull(mimplement)) {
            mimplement.setBaseProjId(baseProjId);
            mimplement.setBaseProjName(baseProjName);
            mimplement.setBaseBidCode(baseProjId);
            mimplement.setBaseBidName(baseProjName);
            GovBizProjectMimplement oldMimplement = mimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectMimplement.class)
                    .eq(GovBizProjectMimplement::getBaseProjId, baseProjId)
                    .last(BizConst.LIMIT_1));

            GovBizProjectMimplement saveMimplement = BeanUtil.copyProperties(mimplement, GovBizProjectMimplement.class);
            saveMimplement.setBaseProjId(baseProjId);
            saveMimplement.setBaseBidCode(baseProjId);
            saveMimplement.setBaseBidName(baseProjName);
            if (Objects.nonNull(oldMimplement)) {
                saveMimplement.setId(oldMimplement.getId());
            } else {
                saveMimplement.setTongTime(LocalDateTime.now());
            }
            if (Objects.nonNull(saveBase.getAreaCode())) {
                saveMimplement.setAreaCode(saveBase.getAreaCode());
            }
            saveMimplement.setAreaCode(RegionConst.RC_HZ);
            saveMimplement.setBizTime(LocalDateTime.now());
            saveMimplement.setUpdateBy(user.getUsername());
            saveMimplement.setUpdateOn(LocalDateTime.now());
            if (mimplementService.saveOrUpdate(saveMimplement)) {
                threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssMimplement(mimplement, oldMimplement, saveMimplement));
            }
        }

        // 6.保存 采购信息
        List<GovBizProjectProcureDTO> procures = saveDTO.getProcures();

        if (Objects.nonNull(procures)) {
            procureService.remove(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                    .eq(GovBizProjectProcure::getBaseProjId, baseProjId));

            Integer index = 1;
            for (GovBizProjectProcureDTO procure : procures) {
                procure.setBaseProjId(baseProjId);
                procure.setBaseProjName(baseProjName);
                procure.setBaseBidCode(baseProjId + StrPool.DASH + String.format(StrPool.FORMAT_DATE_SINGLE_DIGITS, index));
                GovBizProjectProcure saveProcure = BeanUtil.copyProperties(procure, GovBizProjectProcure.class);
                saveProcure.setBaseProjId(baseProjId);
                saveProcure.setId(null);
                saveProcure.setAreaCode(RegionConst.RC_HZ);
                saveProcure.setTongTime(LocalDateTime.now());
                saveProcure.setBizTime(LocalDateTime.now());
                saveProcure.setUpdateBy(user.getUsername());
                saveProcure.setUpdateOn(LocalDateTime.now());
                if (procureService.save(saveProcure)) {
                    threadPoolTaskScheduler.execute(() -> uploadFileToProvincialOssProcure(procure, null, saveProcure));
                }
                index++;
            }

        }

        //如果是草稿箱来的 就要删除
        if (Objects.nonNull(saveDTO.getDraftId())) {
            operationProjectDraftService.removeById(saveDTO.getDraftId());
        }

        return BizConst.SAVE_SUCCESS;
    }

    /**
     * 计算2个时间的月份
     *
     * @param baseProjStartTime
     * @param baseProjEndTime
     * @return
     */
    public static String convertMonth(LocalDateTime baseProjStartTime, LocalDateTime baseProjEndTime) {
        String start = baseProjStartTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String end = baseProjEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Temporal temporal1 = LocalDate.parse(start);
        Temporal temporal2 = LocalDate.parse(end);
        // 方法返回为相差月份
        Long ll = ChronoUnit.MONTHS.between(temporal1, temporal2);
        return ll.toString();
    }

    /**
     * 暂存草稿箱
     *
     * @param saveDTO
     * @param user
     * @return
     */
    public String draft(GovBizProjectSaveDTO saveDTO, UserInfoDetails user) {
        if (Objects.isNull(user)) {
            user = LoginUserUtil.loginUserDetail();
        }

        GovBizProjectDraft draft = new GovBizProjectDraft();
        //草稿id
        Long draftId = saveDTO.getDraftId();
        if (Objects.nonNull(draftId)) {
            GovBizProjectDraft oldDraft = draftService.getById(draftId);
            VUtils.isTrue(Objects.isNull(oldDraft)).throwMessage("该草稿不存在!");
            draft.setId(draftId);
        } else {
            draft.setTongTime(LocalDateTime.now());
            draft.setCreateId(user.getUserId());
            draft.setTongTime(LocalDateTime.now());
        }

        //1.保存基本信息
        GovBizProjectBaseinfoDTO base = saveDTO.getBaseinfo();
        String baseProjId = base.getBaseProjId();
        String baseProjName = base.getBaseProjName();
        //要生成 草稿的项目编号
        if (StringUtils.isBlank(baseProjId)) {
            baseProjId = BizProjectContant.ProjectCollection.DRAFT;
        }

        // 2.保存 申报信息
        GovBizProjectApplyDTO apply = saveDTO.getApply();
        BeanUtil.copyProperties(apply, draft, CopyOptions.create()
                .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));

        // 3.保存 审批信息
        GovBizProjectApproveDTO approve = saveDTO.getApprove();
        BeanUtil.copyProperties(approve, draft, CopyOptions.create()
                .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));

        // 4.保存 建设项目 实施信息
        GovBizProjectCimplementDTO cimplement = saveDTO.getCimplement();
        if (Objects.nonNull(cimplement)) {
            BeanUtil.copyProperties(cimplement, draft, CopyOptions.create()
                    .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));
            draft.setBaseBidCode(baseProjId + "-1");
            draft.setBaseChanFileCimplement(cimplement.getBaseChanFile());
            draft.setBaseLogAggregationCimplement(cimplement.getBaseLogAggregation());
            draft.setBaseBusinessMetricsCimplement(cimplement.getBaseBusinessMetrics());
            draft.setBaseEstaSummFileCimplement(cimplement.getBaseEstaSummFile());
            draft.setBaseInforLevelFileCimplement(cimplement.getBaseInforLevelFile());
            draft.setBaseEngineerPostpoFileCimplement(cimplement.getBaseEngineerPostpoFile());
            draft.setBaseUserConsFileCimplement(cimplement.getBaseUserConsFile());
            draft.setBasePasswAssessFileCimplement(cimplement.getBasePasswAssessFile());
            draft.setBaseThirdAcceptFileCimplement(cimplement.getBaseThirdAcceptFile());
            draft.setBaseFinalExpertOpinionFileCimplement(cimplement.getBaseFinalExpertOpinionFile());
        }

        // 5.保存 运维项目 实施信息
        GovBizProjectMimplementDTO mimplement = saveDTO.getMimplement();
        if (Objects.nonNull(mimplement)) {
            BeanUtil.copyProperties(mimplement, draft, CopyOptions.create()
                    .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));
            draft.setBaseLogAggregationMimplement(mimplement.getBaseLogAggregation());
            draft.setBaseBusinessMetricsMimplement(mimplement.getBaseBusinessMetrics());
            draft.setBaseChanFileMimplement(mimplement.getBaseChanFile());
            draft.setBaseEstaSummFileMimplement(mimplement.getBaseEstaSummFile());
            draft.setBaseInforLevelFileMimplement(mimplement.getBaseInforLevelFile());
            draft.setBaseEngineerPostpoFileMimplement(mimplement.getBaseEngineerPostpoFile());
            draft.setBaseThirdAcceptFileMimplement(mimplement.getBaseThirdAcceptFile());
            draft.setBaseUserConsFileMimplement(mimplement.getBaseUserConsFile());
            draft.setBaseFinalExpertOpinionFileMimplement(mimplement.getBaseFinalExpertOpinionFile());
            draft.setBasePasswAssessFileMimplement(mimplement.getBasePasswAssessFile());
        }

        // 6.保存 采购信息
        List<GovBizProjectProcureDTO> procures = saveDTO.getProcures();
        if (Objects.nonNull(procures)) {
            draft.setProcure(JSON.toJSONString(procures));
        }

        //最后再保存 基本信息
        BeanUtil.copyProperties(base, draft, CopyOptions.create()
                .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));
        draft.setBaseProjId(baseProjId);
        draft.setBaseProjName(baseProjName);
        draft.setIsEffective(BizProjectContant.ProjectCollection.IS_EFFECTIVE);
        draft.setAreaCode(RegionConst.RC_HZ);
        draft.setBizTime(LocalDateTime.now());
        draft.setUpdateBy(user.getUsername());
        draft.setUpdateOn(LocalDateTime.now());
        draft.setOp(BizProjectContant.ProjectCollection.OP_INSERT);

        draftService.saveOrUpdate(draft);

        return BizConst.SAVE_SUCCESS;
    }

    public String operationDraft(GovOperationProjectSaveDTO saveDTO, UserInfoDetails user) {
        if (Objects.isNull(user)) {
            user = LoginUserUtil.loginUserDetail();
        }

        GovOperationProjectDraft draft = new GovOperationProjectDraft();
        //草稿id
        Long draftId = saveDTO.getDraftId();
        if (Objects.nonNull(draftId)) {
            GovOperationProjectDraft oldDraft = operationProjectDraftService.getById(draftId);
            VUtils.isTrue(Objects.isNull(oldDraft)).throwMessage("该草稿不存在!");
            draft.setId(draftId);
        } else {
            draft.setTongTime(LocalDateTime.now());
            draft.setCreateId(user.getUserId());
            draft.setTongTime(LocalDateTime.now());
        }

        //1.保存基本信息
        GovOperationProjectBaseinfoDTO base = saveDTO.getBaseinfo();
        String baseProjId = base.getBaseProjId();
        String baseProjName = base.getBaseProjName();
        //要生成 草稿的项目编号
        if (StringUtils.isBlank(baseProjId)) {
            baseProjId = BizProjectContant.ProjectCollection.DRAFT;
        }

        // 2.保存 申报信息
        GovBizProjectApplyDTO apply = saveDTO.getApply();
        BeanUtil.copyProperties(apply, draft, CopyOptions.create()
                .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));

        // 3.保存 审批信息
        GovBizProjectApproveDTO approve = saveDTO.getApprove();
        BeanUtil.copyProperties(approve, draft, CopyOptions.create()
                .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));

        // 4.保存 建设项目 实施信息
        GovBizProjectCimplementDTO cimplement = saveDTO.getCimplement();
        if (Objects.nonNull(cimplement)) {
            BeanUtil.copyProperties(cimplement, draft, CopyOptions.create()
                    .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));
            draft.setBaseBidCode(baseProjId + "-1");
            draft.setBaseChanFileCimplement(cimplement.getBaseChanFile());
            draft.setBaseLogAggregationCimplement(cimplement.getBaseLogAggregation());
            draft.setBaseBusinessMetricsCimplement(cimplement.getBaseBusinessMetrics());
            draft.setBaseEstaSummFileCimplement(cimplement.getBaseEstaSummFile());
            draft.setBaseInforLevelFileCimplement(cimplement.getBaseInforLevelFile());
            draft.setBaseEngineerPostpoFileCimplement(cimplement.getBaseEngineerPostpoFile());
            draft.setBaseUserConsFileCimplement(cimplement.getBaseUserConsFile());
            draft.setBasePasswAssessFileCimplement(cimplement.getBasePasswAssessFile());
            draft.setBaseThirdAcceptFileCimplement(cimplement.getBaseThirdAcceptFile());
            draft.setBaseFinalExpertOpinionFileCimplement(cimplement.getBaseFinalExpertOpinionFile());
        }

        // 5.保存 运维项目 实施信息
        GovBizProjectMimplementDTO mimplement = saveDTO.getMimplement();
        if (Objects.nonNull(mimplement)) {
            BeanUtil.copyProperties(mimplement, draft, CopyOptions.create()
                    .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));
            draft.setBaseLogAggregationMimplement(mimplement.getBaseLogAggregation());
            draft.setBaseBusinessMetricsMimplement(mimplement.getBaseBusinessMetrics());
            draft.setBaseChanFileMimplement(mimplement.getBaseChanFile());
            draft.setBaseEstaSummFileMimplement(mimplement.getBaseEstaSummFile());
            draft.setBaseInforLevelFileMimplement(mimplement.getBaseInforLevelFile());
            draft.setBaseEngineerPostpoFileMimplement(mimplement.getBaseEngineerPostpoFile());
            draft.setBaseThirdAcceptFileMimplement(mimplement.getBaseThirdAcceptFile());
            draft.setBaseUserConsFileMimplement(mimplement.getBaseUserConsFile());
            draft.setBaseFinalExpertOpinionFileMimplement(mimplement.getBaseFinalExpertOpinionFile());
            draft.setBasePasswAssessFileMimplement(mimplement.getBasePasswAssessFile());
        }

        // 6.保存 采购信息
        List<GovBizProjectProcureDTO> procures = saveDTO.getProcures();
        if (Objects.nonNull(procures)) {
            draft.setProcure(JSON.toJSONString(procures));
        }

        //最后再保存 基本信息
        BeanUtil.copyProperties(base, draft, CopyOptions.create()
                .setIgnoreError(Boolean.TRUE).setIgnoreNullValue(Boolean.TRUE));
        draft.setBaseProjId(baseProjId);
        draft.setBaseProjName(baseProjName);
        draft.setIsEffective(BizProjectContant.ProjectCollection.IS_EFFECTIVE);
        draft.setAreaCode(RegionConst.RC_HZ);
        draft.setBizTime(LocalDateTime.now());
        draft.setUpdateBy(user.getUsername());
        draft.setUpdateOn(LocalDateTime.now());
        draft.setOp(BizProjectContant.ProjectCollection.OP_INSERT);

        operationProjectDraftService.saveOrUpdate(draft);

        return BizConst.SAVE_SUCCESS;
    }

    /**
     * 删除项目归集
     *
     * @param projId
     * @return
     */
    public String remove(String projId) {
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        String username = user.getUsername();

        GovBizProjectBaseinfo baseinfo = baseinfoService.getOne(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .eq(GovBizProjectBaseinfo::getBaseProjId, projId)
                .last(BizConst.LIMIT_1));

        VUtils.isTrue(Objects.isNull(baseinfo)).throwMessage("项目不存在！");

        //改正逻辑删除
        baseinfo.setDeleted(Boolean.TRUE);
        baseinfo.setUpdateBy(username);
        baseinfo.setUpdateOn(LocalDateTime.now());
        baseinfoService.updateById(baseinfo);
        projectApplyService.update(Wrappers.lambdaUpdate(GovBizProjectApply.class)
                .eq(GovBizProjectApply::getBaseProjId, projId)
                .set(GovBizProjectApply::getDeleted, Boolean.TRUE)
                .set(GovBizProjectApply::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectApply::getUpdateBy, username));
        approveService.update(Wrappers.lambdaUpdate(GovBizProjectApprove.class)
                .eq(GovBizProjectApprove::getBaseProjId, projId)
                .set(GovBizProjectApprove::getDeleted, Boolean.TRUE)
                .set(GovBizProjectApprove::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectApprove::getUpdateBy, username));
        cimplementService.update(Wrappers.lambdaUpdate(GovBizProjectCimplement.class)
                .eq(GovBizProjectCimplement::getBaseProjId, projId)
                .set(GovBizProjectCimplement::getDeleted, Boolean.TRUE)
                .set(GovBizProjectCimplement::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectCimplement::getUpdateBy, username));
        mimplementService.update(Wrappers.lambdaUpdate(GovBizProjectMimplement.class)
                .eq(GovBizProjectMimplement::getBaseProjId, projId)
                .set(GovBizProjectMimplement::getDeleted, Boolean.TRUE)
                .set(GovBizProjectMimplement::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectMimplement::getUpdateBy, username));
        procureService.update(Wrappers.lambdaUpdate(GovBizProjectProcure.class)
                .eq(GovBizProjectProcure::getBaseProjId, projId)
                .set(GovBizProjectProcure::getDeleted, Boolean.TRUE)
                .set(GovBizProjectProcure::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectProcure::getUpdateBy, username));
        return BizConst.OP_SUCCESS;
    }

    public String operationRemove(String projId) {
        UserInfoDetails user = LoginUserUtil.loginUserDetail();
        String username = user.getUsername();

        GovOperationProjectBaseinfo baseinfo = operationProjectBaseinfoService.getOne(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                .eq(GovOperationProjectBaseinfo::getBaseProjId, projId)
                .last(BizConst.LIMIT_1));

        VUtils.isTrue(Objects.isNull(baseinfo)).throwMessage("运维项目不存在！");

        //改正逻辑删除
        baseinfo.setDeleted(Boolean.TRUE);
        baseinfo.setUpdateBy(username);
        baseinfo.setUpdateOn(LocalDateTime.now());
        operationProjectBaseinfoService.updateById(baseinfo);

        projectApplyService.update(Wrappers.lambdaUpdate(GovBizProjectApply.class)
                .eq(GovBizProjectApply::getBaseProjId, projId)
                .set(GovBizProjectApply::getDeleted, Boolean.TRUE)
                .set(GovBizProjectApply::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectApply::getUpdateBy, username));
        approveService.update(Wrappers.lambdaUpdate(GovBizProjectApprove.class)
                .eq(GovBizProjectApprove::getBaseProjId, projId)
                .set(GovBizProjectApprove::getDeleted, Boolean.TRUE)
                .set(GovBizProjectApprove::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectApprove::getUpdateBy, username));
        cimplementService.update(Wrappers.lambdaUpdate(GovBizProjectCimplement.class)
                .eq(GovBizProjectCimplement::getBaseProjId, projId)
                .set(GovBizProjectCimplement::getDeleted, Boolean.TRUE)
                .set(GovBizProjectCimplement::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectCimplement::getUpdateBy, username));
        mimplementService.update(Wrappers.lambdaUpdate(GovBizProjectMimplement.class)
                .eq(GovBizProjectMimplement::getBaseProjId, projId)
                .set(GovBizProjectMimplement::getDeleted, Boolean.TRUE)
                .set(GovBizProjectMimplement::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectMimplement::getUpdateBy, username));
        procureService.update(Wrappers.lambdaUpdate(GovBizProjectProcure.class)
                .eq(GovBizProjectProcure::getBaseProjId, projId)
                .set(GovBizProjectProcure::getDeleted, Boolean.TRUE)
                .set(GovBizProjectProcure::getUpdateOn, LocalDateTime.now())
                .set(GovBizProjectProcure::getUpdateBy, username));
        return BizConst.OP_SUCCESS;
    }

    /**
     * 项目归集 草稿箱删除
     *
     * @param draftId
     * @return
     */
    public String draftRemove(Long draftId) {
        if (draftService.removeById(draftId)) {
            return BizConst.OP_SUCCESS;
        }
        return BizConst.OP_FAIL;
    }

    public String operationDraftRemove(Long draftId) {
        if (operationProjectDraftService.removeById(draftId)) {
            return BizConst.OP_SUCCESS;
        }
        return BizConst.OP_FAIL;
    }

    private void checkName(String baseProjName, String baseProjId) {
        VUtils.isTrue(baseinfoService.count(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                        .eq(GovBizProjectBaseinfo::getBaseProjName, baseProjName)
                        .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                        .ne(GovBizProjectBaseinfo::getBaseProjId, baseProjId)) > 0L)
                .throwMessage("项目名重复");
    }

    private void checkNameOperation(String baseProjName, String baseProjId) {
        VUtils.isTrue(operationProjectBaseinfoService.count(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                        .eq(GovOperationProjectBaseinfo::getBaseProjName, baseProjName)
                        .eq(GovOperationProjectBaseinfo::getDeleted, Boolean.FALSE)
                        .ne(GovOperationProjectBaseinfo::getBaseProjId, baseProjId)) > 0L)
                .throwMessage("项目名重复");
    }

    /**
     * 推送项目
     *
     * @param saveDTO
     */
    public void pushProject(GovBizProjectSaveDTO saveDTO) {
        String url = pushUrl;
        ProjectPushReq req = ProjectConvert.convert(saveDTO);
        try {
            log.info("推送消息体  {} ,{},{}", saveDTO.getBaseProjId(), url, JSON.toJSONString(req));
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<ProjectPushReq> formEntity = new HttpEntity(req, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, formEntity, String.class);
            log.info("推送结果  {} :{}", saveDTO.getBaseProjId(), response);
        } catch (Exception e) {
            log.info("推送失败,{}", e.getMessage());
        }
    }

    public void pushProjectVo(GovBizProjectDetailVO vo) {
        String url = pushUrl;
        ProjectPushReq req = ProjectConvert.convertWithConvertPdf(vo);
        try {
            log.info("推送消息体  {} ,{},{}", vo.getBaseProjId(), url, JSON.toJSONString(req));
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<ProjectPushReq> formEntity = new HttpEntity<>(req, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, formEntity, String.class);
            log.info("推送结果  {} :{}", vo.getBaseProjId(), response);
        } catch (Exception e) {
            log.info("推送失败,{}", e.getMessage());
        }
    }

    public void pushProjectVo(GovOperationProjectDetailVO vo) {
        String url = pushUrl;
        ProjectPushReq req = ProjectConvert.convertWithConvertPdf(vo);
        try {
            log.info("推送消息体  {} ,{},{}", vo.getBaseProjId(), url, JSON.toJSONString(req));
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<ProjectPushReq> formEntity = new HttpEntity<>(req, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, formEntity, String.class);
            log.info("推送结果  {} :{}", vo.getBaseProjId(), response);
        } catch (Exception e) {
            log.info("推送失败,{}", e.getMessage());
        }
    }

    /**
     * 把项目置为无效
     *
     * @param baseinfo
     */
    private void notEffectiveProject(GovBizProjectBaseinfoDTO baseinfo) {
        String url = noEffectiveUrl;
        ProjectBaseInfoReq req = ProjectConvert.convertBase(baseinfo, BizProjectContant.NOT_EFFECTIVE_CODE);
        try {
            log.info("推送消息体  {},{},{}", baseinfo.getBaseProjId(), url, JSON.toJSONString(req));
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<ProjectBaseInfoReq> formEntity = new HttpEntity<>(req, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, formEntity, String.class);
            log.info("推送结果  {} :{}", baseinfo.getBaseProjId(), response);
        } catch (Exception e) {
            log.info("推送失败,{}", e.getMessage());
        }
    }

    public void deleteAll() {
        String url = deleteAllUrl;
        try {
            log.info("推送删除数据url  {}", url);
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<String> formEntity = new HttpEntity<>(null, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(url, formEntity, String.class);
            log.info("推送删除结果 :{}", response);
        } catch (Exception e) {
            log.info("推送删除失败,{}", e.getMessage());
        }
    }

    /**
     * 上传项目归集申报的文件到OSS 前提还要先转为PDF
     *
     * @param apply
     * @param oldApply
     */
    private void uploadFileToProvincialOssApply(GovBizProjectApplyDTO apply,
                                                GovBizProjectApply oldApply, GovBizProjectApply saveApply) {
        if (checkFieldNotPdf(apply.getBaseProjBasisFile(), oldApply, "baseProjBasisFile")) {
            StringJoiner sj = convertAndUpload(apply.getBaseProjBasisFile());
            saveApply.setBaseProjBasisFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(apply.getBaseProjApplyFile(), oldApply, "baseProjApplyFile")) {
            StringJoiner sj = convertAndUpload(apply.getBaseProjApplyFile());
            saveApply.setBaseProjApplyFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(apply.getBaseOperatMaintenFile(), oldApply, "baseOperatMaintenFile")) {
            StringJoiner sj = convertAndUpload(apply.getBaseOperatMaintenFile());
            saveApply.setBaseOperatMaintenFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(apply.getBaseResearchReportFile(), oldApply, "baseResearchReportFile")) {
            StringJoiner sj = convertAndUpload(apply.getBaseResearchReportFile());
            saveApply.setBaseResearchReportFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(apply.getBaseProjOtherFile(), oldApply, "baseProjOtherFile")) {
            StringJoiner sj = convertAndUpload(apply.getBaseProjOtherFile());
            saveApply.setBaseProjOtherFilePdf(sj.toString());
        }
        projectApplyService.updateById(saveApply);
    }

    private void uploadFileToProvincialOssApprove(GovBizProjectApproveDTO approve, GovBizProjectApprove oldApprove, GovBizProjectApprove saveApprove) {
        if (checkFieldNotPdf(approve.getApprovalFile(), oldApprove, "approvalFile")) {
            StringJoiner sj = convertAndUpload(approve.getApprovalFile());
            saveApprove.setApprovalFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(approve.getBaseReviewCommentsFile(), oldApprove, "baseReviewCommentsFile")) {
            StringJoiner sj = convertAndUpload(approve.getBaseReviewCommentsFile());
            saveApprove.setBaseReviewCommentsFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(approve.getPreliminaryDesignFile(), oldApprove, "preliminaryDesignFile")) {
            StringJoiner sj = convertAndUpload(approve.getPreliminaryDesignFile());
            saveApprove.setPreliminaryDesignFilePdf(sj.toString());
        }
        approveService.updateById(saveApprove);
    }

    private void uploadFileToProvincialOssCimplement(GovBizProjectCimplementDTO cimplement,
                                                     GovBizProjectCimplement oldCimplement, GovBizProjectCimplement saveCimplement) {
        if (checkFieldNotPdf(cimplement.getBaseChanFile(), oldCimplement, "baseChanFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseChanFile());
            saveCimplement.setBaseChanFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseCheckFile(), oldCimplement, "baseCheckFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseCheckFile());
            saveCimplement.setBaseCheckFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseInforLevelFile(), oldCimplement, "baseInforLevelFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseInforLevelFile());
            saveCimplement.setBaseInforLevelFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseChangeFormFile(), oldCimplement, "baseChangeFormFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseChangeFormFile());
            saveCimplement.setBaseChangeFormFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseEstaSummFile(), oldCimplement, "baseEstaSummFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseEstaSummFile());
            saveCimplement.setBaseEstaSummFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseEngineerPostpoFile(), oldCimplement, "baseEngineerPostpoFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseEngineerPostpoFile());
            saveCimplement.setBaseEngineerPostpoFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseFinalExpertOpinionFile(), oldCimplement, "baseFinalExpertOpinionFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseFinalExpertOpinionFile());
            saveCimplement.setBaseFinalExpertOpinionFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseThirdAcceptFile(), oldCimplement, "baseThirdAcceptFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseThirdAcceptFile());
            saveCimplement.setBaseThirdAcceptFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseUserConsFile(), oldCimplement, "baseUserConsFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseUserConsFile());
            saveCimplement.setBaseUserConsFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseFinanlAuditFile(), oldCimplement, "baseFinanlAuditFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseFinanlAuditFile());
            saveCimplement.setBaseFinanlAuditFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseEngineerPostpoFile(), oldCimplement, "baseEngineerPostpoFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseEngineerPostpoFile());
            saveCimplement.setBaseEngineerPostpoFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseInitialOpinionFile(), oldCimplement, "baseInitialOpinionFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseInitialOpinionFile());
            saveCimplement.setBaseInitialOpinionFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBasePasswAssessFile(), oldCimplement, "basePasswAssessFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBasePasswAssessFile());
            saveCimplement.setBasePasswAssessFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseSummReportFile(), oldCimplement, "baseSummReportFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseSummReportFile());
            saveCimplement.setBaseSummReportFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(cimplement.getBaseIrsTestRunFile(), oldCimplement, "baseIrsTestRunFile")) {
            StringJoiner sj = convertAndUpload(cimplement.getBaseIrsTestRunFile());
            saveCimplement.setBaseIrsTestRunFilePdf(sj.toString());
        }
        cimplementService.updateById(saveCimplement);
    }

    private void uploadFileToProvincialOssMimplement(GovBizProjectMimplementDTO mimplement, GovBizProjectMimplement oldMimplement, GovBizProjectMimplement saveMimplement) {
        if (checkFieldNotPdf(mimplement.getBaseChanFile(), oldMimplement, "baseChanFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseChanFile());
            saveMimplement.setBaseChanFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseInforLevelFile(), oldMimplement, "baseInforLevelFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseInforLevelFile());
            saveMimplement.setBaseInforLevelFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBasePasswAssessFile(), oldMimplement, "basePasswAssessFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBasePasswAssessFile());
            saveMimplement.setBasePasswAssessFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseThirdAcceptFile(), oldMimplement, "baseThirdAcceptFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseThirdAcceptFile());
            saveMimplement.setBaseThirdAcceptFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseEstaSummFile(), oldMimplement, "baseEstaSummFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseEstaSummFile());
            saveMimplement.setBaseEstaSummFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseUserConsFile(), oldMimplement, "baseUserConsFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseUserConsFile());
            saveMimplement.setBaseUserConsFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseOperatMaintenSummFile(), oldMimplement, "baseOperatMaintenSummFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseOperatMaintenSummFile());
            saveMimplement.setBaseOperatMaintenSummFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseFinalExpertOpinionFile(), oldMimplement, "baseFinalExpertOpinionFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseFinalExpertOpinionFile());
            saveMimplement.setBaseFinalExpertOpinionFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseEngineerPostpoFile(), oldMimplement, "baseEngineerPostpoFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseEngineerPostpoFile());
            saveMimplement.setBaseEngineerPostpoFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(mimplement.getBaseEngineerAlterFile(), oldMimplement, "baseEngineerAlterFile")) {
            StringJoiner sj = convertAndUpload(mimplement.getBaseEngineerAlterFile());
            saveMimplement.setBaseEngineerAlterFilePdf(sj.toString());
        }
        mimplementService.updateById(saveMimplement);
    }

    /**
     * 采购文件处理
     *
     * @param procure
     * @param o
     * @param saveProcure
     */
    private void uploadFileToProvincialOssProcure(GovBizProjectProcureDTO procure, Object o, GovBizProjectProcure saveProcure) {
        if (checkFieldNotPdf(procure.getPurchaseFile(), o, "purchaseFile")) {
            StringJoiner sj = convertAndUpload(procure.getPurchaseFile());
            saveProcure.setPurchaseFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(procure.getBiddingFile(), o, "biddingFile")) {
            StringJoiner sj = convertAndUpload(procure.getBiddingFile());
            saveProcure.setBiddingFilePdf(sj.toString());
        }
        if (checkFieldNotPdf(procure.getPurchaseContract(), o, "purchaseContract")) {
            StringJoiner sj = convertAndUpload(procure.getPurchaseContract());
            saveProcure.setPurchaseContractPdf(sj.toString());
        }
        procureService.updateById(saveProcure);
    }

    public StringJoiner convertAndUpload(String baseProjBasisFile) {
        throw BizException.wrap("pdf转换无效");
    }

    private boolean checkFieldNotPdf(String field, Object record, String fieldName) {
        if (StrUtil.isBlank(field)) {
            return Boolean.FALSE;
        }
        // 如果没有老值
        if (Objects.isNull(record)) {
            return Boolean.TRUE;
        }

        // 和老值做个对比 不一样则true
        Class<?> clazz = record.getClass();
        String oldFiled = StringUtils.EMPTY;
        try {
            Field fieldDeclared = clazz.getDeclaredField(fieldName);
            fieldDeclared.setAccessible(Boolean.TRUE);
            oldFiled = Objects.nonNull(fieldDeclared.get(record)) ? String.valueOf(fieldDeclared.get(record)) : null;
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error("转换PDF文件出错" + e);
        }

        if (StringUtils.isBlank(oldFiled)) {
            return Boolean.TRUE;
        }

        //如果一模一样 就不用上传了
        if (oldFiled.equals(field)) {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    /**
     * @param bytes     byte数组
     * @param fileRoute 文件路径
     * @param fileName  文件名
     */
    public static void upload(byte[] bytes, String fileRoute, String fileName) {
        File directory = new File(fileRoute);
        if (!directory.exists() && directory.mkdirs()) {
            log.info("文件夹创建：{}", directory.getAbsolutePath());
        }
        File file = new File(directory, fileName);
        try (FileOutputStream fos = new FileOutputStream(file);
             BufferedOutputStream bos = new BufferedOutputStream(fos)) {
            bos.write(bytes);
        } catch (IOException e) {
            log.error("文件上传异常", e);
        }
    }

    public String rebuildProjectCode(List<String> baseProjIds) {
        if (CollUtil.isEmpty(baseProjIds)) {
            throw new BizException("项目编号不能为空");
        }
        int successNum = 0;
        for (String baseProjId : baseProjIds) {
            //两种情况
            //1.项目归集
            GovBizProjectBaseinfo baseinfo = baseinfoService.getOne(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                    .eq(GovBizProjectBaseinfo::getBaseProjId, baseProjId)
                    .orderByDesc(GovBizProjectBaseinfo::getTongTime)
                    .last(BizConst.LIMIT_1));
            if (Objects.nonNull(baseinfo)) {
                rebuildGuiji(baseProjId);
                successNum++;
            }

            //2.运维备案
            GovOperationProjectBaseinfo operation = operationProjectBaseinfoService.getOne(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                    .eq(GovOperationProjectBaseinfo::getBaseProjId, baseProjId)
                    .orderByDesc(GovOperationProjectBaseinfo::getTongTime)
                    .last(BizConst.LIMIT_1));
            if (Objects.nonNull(operation)) {
                rebuildOperation(baseProjId);
                successNum++;
            }
        }
        return "运行成功 重新生成" + successNum + "个项目编号";
    }

    private void rebuildGuiji(String baseProjId) {
        GovBizProjectBaseinfo baseinfo = baseinfoService.getOne(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                .eq(GovBizProjectBaseinfo::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectBaseinfo::getTongTime)
                .last(BizConst.LIMIT_1));
        GovBizProjectApply apply = projectApplyService.getOne(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .eq(GovBizProjectApply::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectApply::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.isNull(baseinfo)) {
            log.warn("项目不存在跳过：{}", baseProjId);
            return;
        }
        GovBizProjectSaveDTO saveDTO = new GovBizProjectSaveDTO();
        saveDTO.setApply(BeanUtil.copyProperties(apply, GovBizProjectApplyDTO.class));
        saveDTO.setBaseinfo(BeanUtil.copyProperties(baseinfo, GovBizProjectBaseinfoDTO.class));
        String newProjId = generateProjectCodeUtil.generateProjectCode(saveDTO);

        baseinfo.setBaseProjId(newProjId);
        baseinfoService.updateById(baseinfo);
        apply.setBaseProjId(newProjId);
        projectApplyService.updateById(apply);

        GovBizProjectApprove approve = approveService.getOne(Wrappers.lambdaUpdate(GovBizProjectApprove.class)
                .eq(GovBizProjectApprove::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectApprove::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(approve)) {
            approve.setBaseProjId(newProjId);
            approveService.updateById(approve);
        }


        GovBizProjectCimplement cimplement = cimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                .eq(GovBizProjectCimplement::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectCimplement::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(cimplement)) {
            cimplement.setBaseProjId(newProjId);
            cimplement.setBaseBidCode(newProjId);
            cimplementService.updateById(cimplement);
        }

        GovBizProjectMimplement mimplement = mimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectMimplement.class)
                .eq(GovBizProjectMimplement::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectMimplement::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(mimplement)) {
            mimplement.setBaseProjId(newProjId);
            mimplement.setBaseBidCode(newProjId);
            mimplementService.updateById(mimplement);
        }

        List<GovBizProjectProcure> procures = procureService.list(Wrappers.lambdaUpdate(GovBizProjectProcure.class)
                .eq(GovBizProjectProcure::getBaseProjId, baseProjId));

        for (GovBizProjectProcure procure : procures) {
            procure.setBaseProjId(newProjId);
            procure.setBaseBidCode(newProjId + "-" + procure.getBaseBidCode().split("-")[1]);
            procureService.updateById(procure);
        }
    }

    private void rebuildOperation(String baseProjId) {
        GovOperationProjectBaseinfo operationBase = operationProjectBaseinfoService.getOne(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class)
                .eq(GovOperationProjectBaseinfo::getBaseProjId, baseProjId)
                .orderByDesc(GovOperationProjectBaseinfo::getTongTime)
                .last(BizConst.LIMIT_1));
        GovBizProjectApply apply = projectApplyService.getOne(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .eq(GovBizProjectApply::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectApply::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.isNull(operationBase)) {
            log.warn("运维备案项目不存在，跳过：{}", baseProjId);
            return;
        }
        GovOperationProjectSaveDTO saveDTO = new GovOperationProjectSaveDTO();
        saveDTO.setApply(BeanUtil.copyProperties(apply, GovBizProjectApplyDTO.class));
        saveDTO.setBaseinfo(BeanUtil.copyProperties(operationBase, GovOperationProjectBaseinfoDTO.class));
        String newProjId = generateProjectCodeUtil.generateProjectCode(saveDTO);

        operationBase.setBaseProjId(newProjId);
        operationProjectBaseinfoService.updateById(operationBase);
        apply.setBaseProjId(newProjId);
        projectApplyService.updateById(apply);

        GovBizProjectApprove approve = approveService.getOne(Wrappers.lambdaUpdate(GovBizProjectApprove.class)
                .eq(GovBizProjectApprove::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectApprove::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(approve)) {
            approve.setBaseProjId(newProjId);
            approveService.updateById(approve);
        }


        GovBizProjectCimplement cimplement = cimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                .eq(GovBizProjectCimplement::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectCimplement::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(cimplement)) {
            cimplement.setBaseProjId(newProjId);
            cimplement.setBaseBidCode(newProjId);
            cimplementService.updateById(cimplement);
        }

        GovBizProjectMimplement mimplement = mimplementService.getOne(Wrappers.lambdaQuery(GovBizProjectMimplement.class)
                .eq(GovBizProjectMimplement::getBaseProjId, baseProjId)
                .orderByDesc(GovBizProjectMimplement::getTongTime)
                .last(BizConst.LIMIT_1));
        if (Objects.nonNull(mimplement)) {
            mimplement.setBaseProjId(newProjId);
            mimplement.setBaseBidCode(newProjId);
            mimplementService.updateById(mimplement);
        }

        List<GovBizProjectProcure> procures = procureService.list(Wrappers.lambdaUpdate(GovBizProjectProcure.class)
                .eq(GovBizProjectProcure::getBaseProjId, baseProjId));

        for (GovBizProjectProcure procure : procures) {
            procure.setBaseProjId(newProjId);
            procure.setBaseBidCode(newProjId + "-" + procure.getBaseBidCode().split("-")[1]);
            procureService.updateById(procure);
        }
    }

    public String removeProject(List<String> projectCodes) {
        if (CollUtil.isEmpty(projectCodes)) {
            throw new BizException("项目编号不能为空!");
        }

        for (String projectCode : projectCodes) {
            //项目
            List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class)
                    .eq(Project::getProjectCode, projectCode));

            List<Long> projectIds = projects.stream().map(Project::getId).collect(Collectors.toList());

            //1.删除应用
            applicationService.remove(Wrappers.lambdaQuery(ProjectApplication.class)
                    .eq(ProjectApplication::getProjectCode, projectCode));

            //2.删除相关流程
            List<ProjectInst> projectInsts = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class)
                    .in(ProjectInst::getProjectId, projectIds));
            for (ProjectInst projectInst : projectInsts) {
                //实例
                try {
                    runtimeService.deleteProcessInstance(projectInst.getInstCode(), "删除");
                } catch (Exception e) {
                    log.error("删除流程实例信息失败：{}", projectInst, e);
                }
                try {
                    historyService.deleteHistoricProcessInstance(projectInst.getInstCode());
                } catch (Exception e) {
                    log.error("删除历史流程信息失败：{}", projectInst, e);
                }
                //抄送
                ccTasksService.remove(Wrappers.lambdaQuery(WflowCcTasks.class)
                        .eq(WflowCcTasks::getInstanceId, projectInst.getInstCode()));
            }
            projectInstService.removeByIds(projectInsts.stream().map(ProjectInst::getId).collect(Collectors.toList()));

            //3.删除实施表
            operationService.remove(Wrappers.lambdaQuery(Operation.class)
                    .eq(Operation::getProjectCode, projectCode));

            //4.删除续建项目资金表
            renewalFundDeclarationService.remove(Wrappers.lambdaQuery(ProjectRenewalFundDeclaration.class)
                    .eq(ProjectRenewalFundDeclaration::getProjectCode, projectCode));

            //5.暂存表
            stagingService.remove(Wrappers.lambdaQuery(ProjectStaging.class)
                    .in(ProjectStaging::getProjectId, projectIds));

            //6.状态变更表
            statusChangeService.remove(Wrappers.lambdaQuery(ProjectStatusChange.class)
                    .in(ProjectStatusChange::getProjectId, projectIds));

            //7.采购表
            purchaseService.remove(Wrappers.lambdaQuery(Purchase.class)
                    .in(Purchase::getProjectId, projectIds));

            //8.标签
            projectTagService.remove(Wrappers.lambdaQuery(ProjectTag.class)
                    .eq(ProjectTag::getProjectCode, projectCode));

            //9.初验人员
            preInsAcceptancePersonService.remove(Wrappers.lambdaQuery(PreInsAcceptancePerson.class)
                    .in(PreInsAcceptancePerson::getProjectId, projectIds));

            //10.供应商安全质量
            supplierSafetyQualificationService.remove(Wrappers.lambdaQuery(SupplierSafetyQualification.class)
                    .eq(SupplierSafetyQualification::getProjectCode, projectCode));

            //11.安全人员
            personService.remove(Wrappers.lambdaQuery(PersonSafetyInfo.class)
                    .eq(PersonSafetyInfo::getProjectCode, projectCode));

            //12.最后删除项目
            projectService.remove(Wrappers.lambdaQuery(Project.class)
                    .eq(Project::getProjectCode, projectCode));
        }
        return "删除成功";
    }

}
