package cn.cslg.report.service.business;

import cn.cslg.report.common.core.base.Constants;
import cn.cslg.report.common.model.dto.*;
import cn.cslg.report.common.model.vo.*;
import cn.cslg.report.common.utils.*;
import cn.cslg.report.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.report.common.utils.SecurityUtils.SecurityUtils;
import cn.cslg.report.entity.*;

import cn.cslg.report.entity.asso.AssoReportFile;
import cn.cslg.report.entity.asso.AssoReportPerson;
import cn.cslg.report.entity.invalidReReport.InvalidReReport;
import cn.cslg.report.entity.invalidReReport.InvalidReason;
import cn.cslg.report.exception.XiaoShiException;
import cn.cslg.report.mapper.ReportMapper;
import cn.cslg.report.service.*;
import cn.cslg.report.service.business.InvalidReReport.InvalidReReportService;
import cn.cslg.report.service.business.InvalidReReport.InvalidReasonService;
import cn.cslg.report.service.business.asso.AssoReportPersonService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
@SuppressWarnings({"all"})
public class ReportService extends ServiceImpl<ReportMapper, Report> {
    private final OutInterfaceService outInterfaceService;
    private final ReportMapper reportMapper;
    private final ReportFieldService reportFieldService;
    private final CacheUtils cacheUtils;
    private final LoginUtils loginUtils;
    private final AssoReportFileService assoReportFileService;
    private final ReportFileService reportFileService;
    private final AssoTaskPersonelService assoTaskPersonelService;
    private final TaskService taskService;
    private final FeatureService featureService;
    private final CompareScenariosService compareScenariosService;
    private final IProductService productService;
    private final IAvoidDesignDirectionService avoidDesignDirectionService;
    private final CompareFilesService compareFilesService;
    private final CompareMessageService compareMessageService;
    private final ImportTaskService importTaskService;
    private final InvalidRecordService invalidRecordService;
    private final ReportDocumentService reportDocumentService;
    private final ReportReferencesService reportReferencesService;
    private final CopyService copyService;
    private final SystemDictItemService systemDictItemService;
    private final AssoReportPersonService assoReportPersonService;
    private final IAssoEventReportService assoEventReportService;
    private final IFollowUpService followUpService;
    private final InvalidReReportService invalidReReportService;
    private final InvalidReasonService invalidReasonService;

    private Report loadReport(ReportDTO reportDto) {
        Report report = new Report();
        //装载基本信息
        //标的专利号
        report.setSignPatentNo(reportDto.getSignPatentNo());
        //名称
        report.setName(reportDto.getName());
        //产品/技术
        report.setProTec(reportDto.getProTec());
        if (reportDto.getCreatePersonId() == null) {
            PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
            //创建人
            report.setCreatePersonId(personnelVO.getId());
        } else {
            report.setCreatePersonId(reportDto.getCreatePersonId());
        }
        //负责人
        if (reportDto.getPersonId() != null) {
            report.setPersonId(reportDto.getPersonId());
        }
        //类型
        report.setType(reportDto.getType());
        //装载状态

        if (reportDto.getStatus() == null) {
            report.setStatus(1);
        } else {
            report.setStatus(reportDto.getStatus());
        }
        // 装载客户
        report.setClientId(reportDto.getClientId());
        //装载应用场景
        if (reportDto.getScenarioList() != null) {
            report.setScenarioId(StringUtils.join(reportDto.getScenarioList(), ","));
        }
        //装载核心论述
        report.setCronConclusion(reportDto.getCronConclusion());
        //装载核心结论
        if (reportDto.getConclusionIds() != null) {
            report.setConclusionId(StringUtils.join(reportDto.getConclusionIds(), ","));
        }
        //装载承担部门
        report.setDepartmentId(reportDto.getDepartmentId());
        //装载专题库
        report.setProjectId(reportDto.getProjectId());
        //调查类型
        report.setItFlag(reportDto.getItFlag());
        //卷号
        report.setVolumeNumber(reportDto.getVolumeNumber());
        //备注
        report.setRemark(reportDto.getRemark());
        return report;
    }

    /**
     * @param report 报告类
     * @author 沈永艺
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer addReport(ReportDTO reportDto, List<MultipartFile> files) throws IOException {
        //侵权/回避报告，若状态不是审核/完成，则直接将报告状态置为2(处理中)
        if (reportDto.getType().equals(4) || reportDto.getType().equals(5) || reportDto.getType().equals(7)) {
            if (reportDto.getStatus() != null && reportDto.getStatus() != 0 && reportDto.getStatus() != 3) {
                reportDto.setStatus(2);
            }
        }
        //新增报告
        Report report = this.loadReport(reportDto);
        if (reportDto.getTrack() != null && reportDto.getTrack()) {
            report.setCronConclusion(null);
            report.setConclusionId(null);
        }
        report.insert();
        //TODO 当是无效应对报告时，在无效应对报告里插入信息
        if (files != null && files.size() != 0) {
            //当
            if (report.getStatus() != 3) {
                //将文档上传并返回文件入库的Id
                List<Integer> fileIds = reportFileService.uploadFiles(files);
                assoReportFileService.addAsso(report.getId(), fileIds);
            } else {
                ReportReferences reportReferences = new ReportReferences();
                reportReferences.setReportID(report.getId());
                reportReferencesService.add(reportReferences, files);
            }
        }
        if (reportDto.getTrack() != null && reportDto.getTrack()) {
            //复制父报告自定义栏位
            LambdaQueryWrapper<ReportField> fieldWrapper = new LambdaQueryWrapper<>();
            fieldWrapper.eq(ReportField::getReportId, reportDto.getAssociateReportId());
            List<ReportField> fields = reportFieldService.list(fieldWrapper);
            String re = JSONObject.toJSON(fields).toString();
            List<ReportField> oldFields = JSONArray.parseArray(re, ReportField.class);
            if (fields.size() != 0) {
                for (ReportField reportField : fields) {
                    reportField.setId(null);
                    reportField.setReportId(report.getId());
                }
                reportFieldService.saveBatch(fields);
            }
            //复制
            if (reportDto.getCopyIds() != null) {
                //复制对比文件
                List<Integer> c1s = new ArrayList<>(Arrays.asList(0, 2, 4, 6));
                if (!Collections.disjoint(reportDto.getCopyIds(), c1s)) {
                    copyService.CopyComparePatents(reportDto.getAssociateReportId(), report.getId());
                }
                List<Integer> c2s = new ArrayList<>(Arrays.asList(1, 3, 5, 7));
                //复制标引信息
                if (!Collections.disjoint(reportDto.getCopyIds(), c2s)) {
                    copyService.CopyPatentLabels(oldFields, fields);
                }
            }
        } else {
            reportFieldService.addDefaultField(report.getId(), report.getType());
        }

        Integer reportId = report.getId();

        //新增事件
        List<EventAddNewDTO> eventAddNewDTOs = reportDto.getEventAddNewDTOs();
        if (eventAddNewDTOs != null && eventAddNewDTOs.size() > 0) {
            List<Integer> eventIds = new ArrayList<>();
            //过滤去除已有事件(已有事件无需新增，只做关联)
            List<EventAddNewDTO> oldEventAddNewDTOs = eventAddNewDTOs.stream().filter(item -> item.getId() != null).collect(Collectors.toList());
            eventAddNewDTOs.removeAll(oldEventAddNewDTOs);
            if (eventAddNewDTOs.size() > 0) {
                //调用分析系统新增事件接口
                String res = outInterfaceService.getEventIdsFromPAS(eventAddNewDTOs);
                JSONObject jsonObject = JSONObject.parseObject(res);
                List<Integer> newEventIds = JSONObject.parseObject(jsonObject.get("data").toString(), ArrayList.class);
                eventIds.addAll(newEventIds);
            }
            for (EventAddNewDTO oldEventAddNewDTO : oldEventAddNewDTOs) {
                eventIds.add(oldEventAddNewDTO.getId());
            }
            //新增事件和报告关联
            assoEventReportService.addNew(eventIds, reportId);
        }
        //新增后续事项
        List<FollowUpDTO> followUps = reportDto.getFollowUps();
        if (followUps != null && followUps.size() > 0) {
            for (FollowUpDTO followUp : followUps) {
                followUp.setReportId(reportId);
            }
            followUpService.add(followUps);
        }
        return report.getId();
    }

    //查询报告
    public String queryReport(ReportVO reportVO) throws IOException {
        Integer id = loginUtils.getId();
        List<Integer> departIds = outInterfaceService.getDutyDepartsFromPCS(id);
        LambdaQueryWrapper<Report> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(Report::getId, 0);
        if (reportVO.getName() != null) {
            queryWrapper.like(Report::getName, reportVO.getName());
        }
        if (reportVO.getReportId() != null) {
            queryWrapper.eq(Report::getId, reportVO.getReportId());
        }
        if (reportVO.getSignPatentNo() != null && reportVO.getSignPatentNo() != "") {
            queryWrapper.like(Report::getSignPatentNo, reportVO.getSignPatentNo());
        }
        if (reportVO.getTypes() != null && reportVO.getTypes().size() > 0) {
            queryWrapper.in(Report::getType, reportVO.getTypes());
        }
        //根据状态查询报告
        if (reportVO.getStatuses() != null && reportVO.getStatuses().size() > 0) {
            queryWrapper.in(Report::getStatus, reportVO.getStatuses());
        }
        if (reportVO.getCronIds() != null && reportVO.getCronIds().size() > 0) {
            StringBuilder strs = new StringBuilder();
            for (int i = 0; i < reportVO.getCronIds().size(); i++) {
                Integer item = reportVO.getCronIds().get(i);
                if (i == 0) {
                    strs.append("(FIND_IN_SET(" + item + ",CONCLUSION_ID)");
                } else {
                    strs.append("or FIND_IN_SET(" + item + ",CONCLUSION_ID)");
                }
            }
            strs.append(")");
            queryWrapper.apply(strs.toString());

        }

        queryWrapper.orderByDesc(Report::getCreateTime);
        //分页
        if (reportVO.getSize() != null && reportVO.getCurrent() != null) {
            SecurityUtils.startDataScope("/pcs/report/query");
            List<Report> reports = this.page(new Page<>(reportVO.getCurrent(), reportVO.getSize()), queryWrapper).getRecords();
            if (reports.size() > 0) {
                reports = this.reportData(reports);
            }
            SecurityUtils.startDataScope("/pcs/report/query");
            Long count = this.count(queryWrapper);
            return Response.success(reports, DataUtils.setPageColumn(reportVO.getSize(), reportVO.getCurrent(), Math.toIntExact(count)));
        } else {
            List<Report> reports = this.list(queryWrapper);
            long count = this.count(queryWrapper);
            reports = this.reportData(reports);
            return Response.success(reports, DataUtils.setPageColumn(0, 0, Math.toIntExact(count)));
        }
    }

    /**
     * @param reports
     * @return
     * @throws IOException
     * @function 查询报告
     */
    public List<Report> reportData(List<Report> reports) throws IOException {
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
        //根据登录人id获得登录人被分享的报告id
        LambdaQueryWrapper<AssoReportPerson> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AssoReportPerson::getReportId);
        wrapper.eq(AssoReportPerson::getPersonId, personnelVO.getId());
        Function<Object, Integer> f = (o -> Integer.parseInt(o.toString()));
        List<Integer> shareIds = assoReportPersonService.listObjs(wrapper, f);

        //提出报告Id
        List<Integer> reportIds = reports.stream().map(Report::getId).collect(Collectors.toList());
        // 提出客户Id
        List<Integer> clientIds = reports.stream().map(Report::getClientId).collect(Collectors.toList());
        //提出部门Id
        List<Integer> departIds = reports.stream().map(Report::getDepartmentId).collect(Collectors.toList());
        //提出人员Id
        List<Integer> personIds = reports.stream().map(Report::getPersonId).collect(Collectors.toList());
        //提出创建人Id
        List<Integer> createIds = reports.stream().map(Report::getCreatePersonId).collect(Collectors.toList());
        personIds.addAll(createIds);
        //根据报告类型
        List<Map<String, Object>> conclusions = systemDictItemService.getCronConClusions(new ArrayList<Integer>());
        //根据报告ID查询报告文件关联信息
        List<AssoReportFile> assoReportFiles = assoReportFileService.queryFileByReportId(reportIds);
        List<ReportFiles> reportFilesList = new ArrayList<>();
        if (assoReportFiles.size() != 0) {
            List<Integer> fileIds = assoReportFiles.stream().map(AssoReportFile::getFileId).collect(Collectors.toList());
            reportFilesList = reportFileService.getFiles(fileIds);
        }
        String res = outInterfaceService.getDictsFromPAS();
        JSONObject jsonObject = JSONObject.parseObject(res);
        List<SystemDictVO> list = JSONArray.parseArray(jsonObject.getString("data"), SystemDictVO.class);
        List<ReportFiles> temList = reportFilesList;
        //根据人员Id获得人员信息
        String res1 = outInterfaceService.getPersonnelByIdsFromPCS(personIds);
        JSONObject jsonObject1 = JSONObject.parseObject(res1);
        //解析jason获得标的专利的权要
        List<Personnel> personnels = JSON.parseArray(jsonObject1.getString("data"), Personnel.class);
        //根据部门Id 获得部门信息
        List<Map<String, Object>> mapDeparts = new ArrayList<>();
        if (departIds.size() != 0) {
            String res2 = outInterfaceService.getDeparts(departIds);
            mapDeparts = JSONObject.parseArray(res2);
        }
        //根据客户Id 获得客户信息
        List<ClientVO> mapClients = new ArrayList<>();
        if (clientIds.size() != 0) {
            String res3 = outInterfaceService.getClientNameFromPCS(clientIds);
            mapClients = JSONObject.parseArray(res3, ClientVO.class);
        }
        //过滤报告
        for (Report item : reports) {
            //装载登录人在报告中的角色
            List<Integer> roles = new ArrayList<>();
            if (item.getCreatePersonId().equals(personnelVO.getId())) {
                roles.add(0);
            }
            if (item.getPersonId() != null && item.getPersonId().equals(personnelVO.getId())) {
                roles.add(1);
            }
            if (shareIds.contains(item.getId())) {
                roles.add(2);
            }
            item.setLoginRole(roles);
            //装载创建人名和负责人名
            List<Personnel> mapCre = personnels.stream().filter(tem -> tem.getId().equals(item.getCreatePersonId())).collect(Collectors.toList());
            List<Personnel> mapDuty = personnels.stream().filter(tem -> tem.getId().equals(item.getPersonId())).collect(Collectors.toList());
            if (mapDuty.size() != 0)
                item.setPersonName(mapDuty.get(0).getPersonnelName());
            if (mapCre.size() != 0)
                item.setCreatePersonName(mapCre.get(0).getPersonnelName());
            //装载部门名
            if (item.getDepartmentId() != null) {
                List<Map<String, Object>> mapDeaprt = mapDeparts.stream().filter(tem -> tem.get("departId").toString().equals(item.getDepartmentId().toString())).collect(Collectors.toList());
                if (mapDeaprt.size() != 0) {
                    item.setDepartmentName(mapDeaprt.get(0).get("departName").toString());
                }
            }
            if (item.getClientId() == null) {
                item.setClientId(0);
            }
            //装载客户
            for (ClientVO clientVO : mapClients) {
                if (clientVO.getId().equals(item.getClientId())) {
                    item.setClientName(clientVO.getName());
                }
            }
            //装载报告应用场景
            if (StringUtils.isNotEmpty(item.getScenarioId())) {
                item.setScenarioList(StringUtils.changeStringToString(item.getScenarioId(), ","));
                item.setScenarioNames(list.stream().filter(systemDict -> systemDict.getType().equals(Constants.ENTERPRISE_APPLICATION_SCENARIO) && item.getScenarioList().contains(systemDict.getValue())).map(SystemDictVO::getLabel).collect(Collectors.toList()));
                item.setScenarioId(null);
            }
            //装载核心结论
            if (StringUtils.isNotEmpty(item.getConclusionId())) {
                List<String> ids = StringUtils.changeStringToString(item.getConclusionId(), ",");
                item.setConclusionIds(ids);
                List<String> names = new ArrayList<>();
                for (Map<String, Object> temMap : conclusions) {
                    if (ids.contains(temMap.get("cType").toString())) {
                        names.add(temMap.get("cTypeName").toString());
                    }
                }
                item.setConclusions(names);

            }
            //装载报告文件
            List<AssoReportFile> partReportFiles = assoReportFiles.stream().filter(tem -> tem.getReportId().equals(item.getId())).collect(Collectors.toList());
            if (partReportFiles.size() == 0) {
                item.setReportFiles(null);
            } else {
                List<Integer> partFileIds = partReportFiles.stream().map(AssoReportFile::getFileId).collect(Collectors.toList());
                List<ReportFiles> partFiles = temList.stream().filter(tem -> partFileIds.contains(tem.getId())).collect(Collectors.toList());
                item.setReportFiles(partFiles);
            }
        }
        return reports;
    }

    /**
     * @param id(报告id)
     * @return
     * @throws IOException
     * @function 修改报告
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateReport(ReportDTO reportDto, List<MultipartFile> files) throws IOException {
        Report report = this.loadReport(reportDto);
        report.setId(reportDto.getId());
        // 根据报告Id查询对应的附件Id
        LambdaQueryWrapper<AssoReportFile> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AssoReportFile::getReportId, reportDto.getId());
        List<AssoReportFile> assoReportFiles = assoReportFileService.list(wrapper);
        List<Integer> fileIds = assoReportFiles.stream().map(AssoReportFile::getFileId).collect(Collectors.toList());
        // 获得报告更新后的附件Id
        List<Integer> updateFileId = new ArrayList<>();
        if (reportDto.getReportFiles() != null) {
            updateFileId = reportDto.getReportFiles().stream().map(ReportFiles::getId).collect(Collectors.toList());
            fileIds.removeAll(updateFileId);
        }
        //做差获得被删除的文件Id
        if (fileIds.size() != 0) {
            //根据文件Id删除报告文件关联表记录
            LambdaQueryWrapper<AssoReportFile> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.in(AssoReportFile::getFileId, fileIds);
            assoReportFileService.remove(deleteWrapper);
            //根据文件Id删除文件表记录
            reportFileService.removeByIds(fileIds);
        }
//添加附件
        if (files != null && files.size() != 0) {
            //将文档上传并返回文件入库的Id
            List<Integer> fileIdList = reportFileService.uploadFiles(files);
            assoReportFileService.addAsso(reportDto.getId(), fileIdList);
        }
        return report.updateById();

    }

    /**
     * @param id(报告id)
     * @return
     * @throws IOException
     * @function 删除报告
     */
    @Transactional(rollbackFor = Exception.class)
    public String reportDele(int id) throws IOException {
        //删除所有和报告有关的任务
        taskService.deleteTaskByreportId(id);
        //删除所有和报告有关的特征
        featureService.delByReportId(id);
        //删除所有和报告有关的自定义字段
        reportFieldService.deleteByReportId(id);
        //删除所有和报告有关的对比方案
        compareScenariosService.deleteByReportId(id);
        //删除任务人员关联信息表
        assoTaskPersonelService.deleAssoTaskPersonel(id);
        //陈宇 ↓ 删除和报告有关的产品相关数据
        productService.deleteProduct(id);
        //陈宇 ↓ 删除和报告有关的回避设计方案相关数据
        avoidDesignDirectionService.deleteAvoidDesignDirection(id);
        //删除对比文件
        compareFilesService.delete(id);
        //导入删除导入任务
        importTaskService.deleteByRortID(id);

        //删除报告文件导出
        reportDocumentService.deleteByReportId(id);
        //删除报告参考资料
        reportReferencesService.deleteByReportId(id);
        //删除对比信息
        compareMessageService.deleteByreportID(id);
        //TODO 当时无效应对报告时

        //删除与报告关联的表数据
        //删除无效理由表数据
        invalidReasonService.remove(new LambdaQueryWrapper<InvalidReason>().eq(InvalidReason::getReportId, id));

        Boolean dele = this.removeById(id);
        if (dele == true) {
            return Response.success();
        }
        return Response.error("没有数据");
    }

    /**
     * @param id(报告id)
     * @return
     * @throws IOException
     * @function 查询报告
     */

    public String getName(int id) throws IOException {
        LambdaQueryWrapper<Report> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Report::getId, id);
        List<Report> list = this.list(wrapper);
        if (list.size() > 0) {
            Report report = list.get(0);
            return report.getName();
        }
        return null;
    }

    /**
     * 修改报告的状态
     *
     * @param reportId 报告id
     * @param status   状态
     */
    @Transactional
    public void updateStatus(Integer reportId, Integer status) {
        LambdaQueryWrapper<Report> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Report::getId, reportId);
        Report report = this.list(wrapper).get(0);
        report.setStatus(status);
        report.updateById();

    }

    @Transactional
    public List<VisualReportVO> reportVisual(ReportVO reportVO) throws IOException {
        Integer id = loginUtils.getId();
        LambdaQueryWrapper<Report> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(Report::getId, 0);
        if (reportVO.getName() != null) {
            queryWrapper.like(Report::getName, reportVO.getName());
        }
        if (reportVO.getReportId() != null) {
            queryWrapper.eq(Report::getId, reportVO.getReportId());
        }
        if (reportVO.getSignPatentNo() != null && reportVO.getSignPatentNo() != "") {
            queryWrapper.like(Report::getSignPatentNo, reportVO.getSignPatentNo());
        }
        if (reportVO.getTypes() != null && reportVO.getTypes().size() > 0) {
            queryWrapper.in(Report::getType, reportVO.getTypes());
        }
        if (reportVO.getCronIds() != null && reportVO.getCronIds().size() > 0) {
            StringBuilder strs = new StringBuilder();
            for (int i = 0; i < reportVO.getCronIds().size(); i++) {
                Integer item = reportVO.getCronIds().get(i);
                if (i == 0) {
                    strs.append("(FIND_IN_SET(" + item + ",REPLACE(CONCLUSION_ID, '/', ','))");
                } else {
                    strs.append("or FIND_IN_SET(" + item + ",REPLACE(CONCLUSION_ID, '/', ','))");
                }
            }
            strs.append(")");
            queryWrapper.apply(strs.toString());
        }
        SecurityUtils.startDataScope("/pcs/report/query");
        List<Report> reports = this.list(queryWrapper);
        List<Map<String, Object>> map = new ArrayList<>();
        List<VisualReportVO> reportVOS = this.loadVisualReport();
        for (Report report : reports) {
            VisualReportVO reportDTO = reportVOS.stream().filter(item -> item.getTypeValue().equals(report.getType() + "")).findFirst().orElse(null);
            if (reportDTO != null) {
                reportDTO.setReportNum(reportDTO.getReportNum() + 1);
                //获得核心结论值
                if (report.getConclusionId() == null) {
                    report.setConclusionId("");
                }
                List<String> ids = StringUtils.changeStringToString(report.getConclusionId(), "/");
                List<VisualReportVO.Conclusions> conclusions = reportDTO.getConclusions().stream().filter(item -> ids.contains(item.getValue())).collect(Collectors.toList());
                conclusions.forEach(item -> {
                    item.setNum(item.getNum() + 1);
                });
                //获得未完成的结论
                VisualReportVO.Conclusions noComplate = reportDTO.getConclusions().stream().filter(item -> item.getValue().equals("-1")).findFirst().orElse(null);
                if (noComplate != null) {
                    List<Integer> status = new ArrayList<>(Arrays.asList(0, 1, 2));
                    if (status.contains(report.getStatus())) {
                        noComplate.setNum(noComplate.getNum() + 1);
                    }
                }

            }
        }
        return reportVOS;
    }

    private List<VisualReportVO> loadVisualReport() {
        List<VisualReportVO> reportVOS = new ArrayList<>();
        //获得所有报告的分类
        LambdaQueryWrapper<SysDictItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictItem::getDictParentKey, "REPORT_TYPE");
        List<SysDictItem> reportTypes = systemDictItemService.list(wrapper);
        //获得所有报告的核心结论
        List<Integer> ids = reportTypes.stream().map(SysDictItem::getId).collect(Collectors.toList());
        List<SysDictItem> conclusions = new ArrayList<>();
        if (ids.size() != 0) {
            LambdaQueryWrapper<SysDictItem> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.in(SysDictItem::getParentId, ids)
                    .eq(SysDictItem::getGroupId, 1);
            conclusions = systemDictItemService.list(wrapper1);
        }
        for (SysDictItem item : reportTypes) {
            VisualReportVO reportVO = new VisualReportVO();
            reportVO.setReportType(item.getDictChildLabel());
            reportVO.setTypeValue(item.getDictChildValue());
            reportVO.setReportNum(0);
            //获得不同报告类别的核心结论字典
            List<SysDictItem> sysDictItems = conclusions.stream().filter(tem -> tem.getParentId().equals(item.getId() + "")).collect(Collectors.toList());
            List<VisualReportVO.Conclusions> conclusions1 = new ArrayList<>();
            VisualReportVO.Conclusions noComplate = new VisualReportVO.Conclusions();
            noComplate.setName("未完成");
            noComplate.setValue("-1");
            noComplate.setNum(0);
            conclusions1.add(noComplate);
            sysDictItems.forEach(
                    tem -> {
                        VisualReportVO.Conclusions conclusion = new VisualReportVO.Conclusions();
                        conclusion.setName(tem.getDictChildLabel());
                        conclusion.setValue(tem.getDictChildValue());
                        conclusion.setNum(0);
                        conclusions1.add(conclusion);
                    }
            );
            reportVO.setConclusions(conclusions1);
            reportVOS.add(reportVO);
        }
        return reportVOS;
    }


    public Map<Integer, List<Integer>> getPermession() {
        Map<Integer, List<Integer>> map = new HashMap<>();
        Integer id = loginUtils.getId();
        //查询登录人创建的报告
        LambdaQueryWrapper<Report> createWrapper = new LambdaQueryWrapper<>();
        createWrapper.select(Report::getId);
        createWrapper.eq(Report::getCreatePersonId, id);
        List<Report> creates = this.list(createWrapper);
        creates.forEach(
                item -> {
                    if (map.get(item.getId()) == null) {
                        List<Integer> roles = new ArrayList<>();
                        roles.add(0);
                        map.put(item.getId(), roles);
                    } else {
                        List<Integer> roles = map.get(item.getId());
                        if (!roles.contains(0)) {
                            roles.add(0);
                            map.put(item.getId(), roles);
                        }
                    }
                }
        );
        //查询登录人负责的报告
        LambdaQueryWrapper<Report> dutyWrapper = new LambdaQueryWrapper<>();
        dutyWrapper.select(Report::getId);
        dutyWrapper.eq(Report::getPersonId, id);
        List<Report> dutys = this.list(dutyWrapper);
        dutys.forEach(
                item -> {
                    if (map.get(item.getId()) == null) {
                        List<Integer> roles = new ArrayList<>();
                        roles.add(1);
                        map.put(item.getId(), roles);
                    } else {
                        List<Integer> roles = map.get(item.getId());
                        if (!roles.contains(1)) {
                            roles.add(1);
                            map.put(item.getId(), roles);
                        }
                    }
                }
        );
        //查询登录人被分享的报告
        LambdaQueryWrapper<AssoReportPerson> shareWrapper = new LambdaQueryWrapper<>();
        shareWrapper.select(AssoReportPerson::getReportId);
        shareWrapper.eq(AssoReportPerson::getPersonId, id);
        List<AssoReportPerson> shares = assoReportPersonService.list(shareWrapper);
        shares.forEach(
                item -> {
                    if (map.get(item.getReportId()) == null) {
                        List<Integer> roles = new ArrayList<>();
                        roles.add(2);
                        map.put(item.getReportId(), roles);
                    } else {
                        List<Integer> roles = map.get(item.getReportId());
                        if (!roles.contains(2)) {
                            roles.add(2);
                            map.put(item.getReportId(), roles);
                        }
                    }
                }
        );
        return map;
    }

    public Boolean addConclusions(ConclusionDTO conclusionDTO) {
        Report report = this.getById(conclusionDTO.getReportId());
        report.setCronConclusion(conclusionDTO.getCronConclusion());
        if (conclusionDTO.getConclusionIds() != null) {
            report.setConclusionId(StringUtils.join(conclusionDTO.getConclusionIds(), ","));
        }

        //调新增后续事项业务
        List<FollowUpDTO> followUps = conclusionDTO.getFollowUps();
        if (followUps != null && followUps.size() > 0) {
            for (FollowUpDTO followUp : followUps) {
                followUp.setReportId(conclusionDTO.getReportId());
            }
            followUpService.add(followUps);
        }

        return report.updateById();

    }

    /**
     * @param ReportId
     * @return
     * @autor 谢翔
     */
    public ReportDeVO reReportDetail(Integer reportId) {
        ReportDeVO reportDeVO = new ReportDeVO();
        //检测传入参数合法性
        if (reportId == null && reportId <= 0) {
            throw new XiaoShiException("传入参数异常");
        }
        //根据报告id获得报告
        Report report = this.getById(reportId);
        //若根据报告id未获取到报告返回空
        if (report == null) {
            return null;
        }
        List<Report> reports = new ArrayList<>();
        reports.add(report);
        try {
            //调用this.reportData装载报告
            List<Report> reports1 = this.reportData(reports);
            Report report1 = reports1.get(0);
            //若报告为无效应对报告则从无效应对报告表中获得无效对应报告拓展信息
            if (report1.getType().equals(7)) {
                LambdaQueryWrapper<InvalidReReport> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(InvalidReReport::getReportId, report1.getId());
                InvalidReReport invalidReReport = invalidReReportService.getOne(queryWrapper);
                if (invalidReReport == null) {
                    throw new XiaoShiException("未查询到无效应对报告信息");
                }
                //装载报告信息，无效对应报告拓展信息到ReportDeDTO并返回
                BeanUtils.copyProperties(report1, reportDeVO);
                BeanUtils.copyProperties(invalidReReport, reportDeVO);
            } else {
                BeanUtils.copyProperties(report1, reportDeVO);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return reportDeVO;
    }
}
