/*
 * Copyright (c) 京北方信息技术股份有限公司 Corporation 2021 . All rights reserved.
 *
 */
package net.northking.cctp.testbug.api.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hzbank.testteam.autotest.dependencies.monsterDependency.dto.SystemDTO;
import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.cache.EntityNameCatalog;
import net.northking.cctp.common.db.BasicService;
import net.northking.cctp.common.db.DefaultPagination;
import net.northking.cctp.common.db.Pagination;
import net.northking.cctp.common.db.annotation.DatabaseReadOnly;
import net.northking.cctp.common.db.annotation.DatabaseWriteOnly;
import net.northking.cctp.common.db.excel.AbstractExcelService;
import net.northking.cctp.common.db.excel.ExcelHeader;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.http.QueryByPage;
import net.northking.cctp.common.http.ResultWrapper;
import net.northking.cctp.common.security.authentication.NKSecurityContext;
import net.northking.cctp.common.util.UUIDUtil;
import net.northking.cctp.common.util.excelUtil.ExcelToolUtil;
import net.northking.cctp.common.util.excelUtil.ExportExcel;
import net.northking.cctp.common.util.excelUtil.excelEntity.ExcelDataTemplate;
import net.northking.cctp.common.util.excelUtil.excelEntity.ExcelHead;
import net.northking.cctp.common.util.excelUtil.excelEntity.SheetHead;
import net.northking.cctp.common.util.excelUtil.excelEntity.SheetTemplate;
import net.northking.cctp.platform.db.entity.CltDictItem;
import net.northking.cctp.testbug.constants.TestBugConstants;
import net.northking.cctp.testbug.constants.TestBugError;
import net.northking.cctp.testbug.db.entity.*;
import net.northking.cctp.testbug.db.service.BugCorrelationLinkService;
import net.northking.cctp.testbug.db.service.BugManagementService;
import net.northking.cctp.testbug.dto.*;
import net.northking.cctp.testbug.dto.bug.BugManageQueryDto;
import net.northking.cctp.testbug.dto.bug.ResultResponse;
import net.northking.cctp.testbug.dto.bus.SynModule;
import net.northking.cctp.testbug.dto.bus.SynSystem;
import net.northking.cctp.testbug.dto.cases.MtProjectTemplateDetailDto;
import net.northking.cctp.testbug.dto.cases.MtProjectTemplateQueryDto;
import net.northking.cctp.testbug.dto.platform.CpNotice;
import net.northking.cctp.testbug.dto.platform.CpTemplatePropertiesDetailDto;
import net.northking.cctp.testbug.dto.platform.UserQueryDto;
import net.northking.cctp.testbug.dto.project.CpProjectDetailDto;
import net.northking.cctp.testbug.dto.project.CpProjectRuleQueryDto;
import net.northking.cctp.testbug.dto.project.RuleConfigValue;
import net.northking.cctp.testbug.dto.project.StatusRoleDto;
import net.northking.cctp.testbug.enums.BugFrom;
import net.northking.cctp.testbug.enums.TestBugStatus;
import net.northking.cctp.testbug.feign.client.HzBankFeignClient;
import net.northking.cctp.testbug.feign.client.PlatFormFeignClient;
import net.northking.cctp.testbug.feign.client.ProjectsFeignClient;
import net.northking.cctp.testbug.feign.client.UserInfoDto;
import net.northking.cctp.testbug.feign.server.CasesFeignServer;
import net.northking.cctp.testbug.feign.server.PlatFormFeignServer;
import net.northking.cctp.testbug.feign.server.ProjectsFeignServer;
import net.northking.cctp.testbug.util.BeanHelper;
import net.northking.cctp.testbug.util.CompareFieldsUtil;
import net.northking.cctp.testbug.util.ExcelUtil;
import net.northking.cctp.testbug.util.HttpClientUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 缺陷管理服务实现类
 *
 * @author maven-cctp-plugin
 * @since 1.0
 */

@Service
@RefreshScope
@ConditionalOnMissingBean(name = "BugManagementApiServiceImpl")
public class BugManagementApiServiceImpl extends AbstractExcelService<BugManagement> implements BugManagementApiService {
    /**
     * 日志
     */
    private final static Logger logger = LoggerFactory.getLogger(BugManagementApiServiceImpl.class);

    @Autowired
    private BugManagementService bugManagementService;

    @Autowired
    private BugRecordApiService bugRecordApiService;

    @Autowired
    private BugLogApiService bugLogApiService;

    @Autowired
    private EntityNameCache entityNameCache;

    @Autowired
    private BugCorrelationLinkApiService correlationLinkApiService;

    @Autowired
    private BugNoApiService bugNoApiService;

    @Autowired
    private CasesFeignServer casesFeignServer;

    @Autowired
    private ProjectsFeignServer projectsFeignServer;

    @Autowired
    private BugCorrelationLinkService bugCorrelationLinkService;

    @Autowired
    private PlatFormFeignServer platFormFeignServer;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private PlatFormFeignClient platFormFeignClient;

    @Autowired
    private ProjectsFeignClient projectsFeignClient;

    @Autowired
    private BugOverallTendencyChartApiService bugOverallTendencyChartApiService;

    @Autowired
    private BugManagementApiService bugManagementApiService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private EmailService emailService;


    @Value("${zmn.url}")
    private String zmnUrl;
    @Value("${zmn.ak}")
    private String ak;

    @Value("${zmn.hostStr}")
    private String hostStr;
    @Autowired
    private HzBankFeignClient hzBankFeign;

    //  关联类型：1、用例
    private final String linkType = TestBugConstants.STR_ONE;
    private final String bugStatus = "bugStatus";
    private final String bugType = "bugType";
    private final String bugGrade = "bugGrade";
    private final String bugFrom = "bugFrom";
    private final String isReappear = "isReappear";
    private final String emergency = "emergency";


    @Override
    public BasicService<BugManagement> getService() {
        return this.bugManagementService;
    }

    @Override
    public ExcelHeader[] excelHeaders() {
        ExcelHeader proName = new ExcelHeader("所属项目", "proName", String.class);
        ExcelHeader bugTitle = new ExcelHeader("缺陷标题", "bugTitle", String.class);
        ExcelHeader bugGrade = new ExcelHeader("严重程度", "bugGrade", String.class);
        ExcelHeader bugType = new ExcelHeader("缺陷分类", "bugType", String.class);
        ExcelHeader bugOrder = new ExcelHeader("缺陷编码", "bugOrder", String.class);
        ExcelHeader emergency = new ExcelHeader("紧急程度", "emergency", String.class);
        ExcelHeader isReappear = new ExcelHeader("是否重现", "isReappear", String.class);
        ExcelHeader status = new ExcelHeader("缺陷状态", "status", String.class);
        ExcelHeader createBy = new ExcelHeader("缺陷发现人", "createBy", String.class);
        ExcelHeader createTime = new ExcelHeader("缺陷发现时间", "createTime", Date.class);
        ExcelHeader receiver = new ExcelHeader("缺陷接收人", "receiver", String.class);
        ExcelHeader repairTime = new ExcelHeader("缺陷修复时间", "repairTime", Date.class);
        ExcelHeader closeTime = new ExcelHeader("缺陷关闭时间", "closeTime", Date.class);
        ExcelHeader moduleId = new ExcelHeader("所属模块", "moduleId", String.class);
        ExcelHeader errorMessage = new ExcelHeader("错误信息描述", "errorMessage", String.class);
        ExcelHeader systemName = new ExcelHeader("归属系统", "systemName", String.class);
        ExcelHeader message = new ExcelHeader("注释", "message", String.class);
        return new ExcelHeader[]{proName, bugOrder, bugTitle, bugGrade, emergency, bugType, isReappear, status,
                moduleId, createBy, receiver, createTime, repairTime, closeTime, errorMessage, systemName, message};
    }

    /**
     * Excel导入，入库之前的处理
     *
     * @param records 从Excel读取到的记录
     * @return 待入库的记录
     */
    @Override
    protected List<BugManagement> beforeInsertBatch(List<BugManagement> records) {
        for (BugManagement record : records) {
            record.setBugId(UUIDUtil.create32UUID());
        }
        return records;
    }

    /**
     * 写入Excel之前的处理<br>
     * 数据的特殊处理在此处加工处理
     *
     * @param record 来自数据库记录
     * @return 待写入Excel的记录
     */
    @Override
    protected BugManagement beforeWriteExcel(BugManagement record) {
        return record;
    }

    //= Excel 导入导出相关代码 end =======================//

    //= 增删改查 相关代码 start ==================//
    @Override
    @DatabaseReadOnly
    public Pagination<BugManagementDetailDto> pagingQuery(QueryByPage<BugManagementQueryDto> queryByPage) {
        Pagination<BugManagementDetailDto> pagingQuery = null;
        BugManagementQueryDto query = queryByPage.getQuery();

        // 如果是缺陷库
        if (query.getProjectList() == null) {
            long l = System.currentTimeMillis();
            List<String> deletedProjectIds = projectsFeignServer.queryDeletedProjectId();
            if (deletedProjectIds != null && !deletedProjectIds.isEmpty()) {
                query.setDeletedProjectList(deletedProjectIds);
            }
        }

        //  若选择缺陷，则其他条件置空
        long l = System.currentTimeMillis();
        if (CollectionUtils.isNotEmpty(query.getBugIds())) {
            List<String> bugIds = query.getBugIds();
            query = new BugManagementQueryDto();
            query.setBugIds(bugIds);
            queryByPage.setQuery(query);
        }

        //  创建人模糊搜索
        l = System.currentTimeMillis();
        if (StringUtils.hasText(query.getCreatedBy())) {
            List<String> createdBys = getUserIds(query.getCreatedBy());
            query.setCreatedBys(createdBys);
            if (CollectionUtils.isEmpty(createdBys)) {
                return new DefaultPagination<>();
            }
        }

        //  分配给模糊搜索
        if (StringUtils.hasText(query.getReceiver())) {
            List<String> receivers = getUserIds(query.getReceiver());
            query.setReceivers(receivers);
            if (CollectionUtils.isEmpty(receivers)) {
                return new DefaultPagination<>();
            }
        }

        try {
            l = System.currentTimeMillis();
            pagingQuery = this.bugManagementService.pagingQueryNew(queryByPage);

            l = System.currentTimeMillis();

            setBugData(pagingQuery);


        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_INFO_FAILED);
        }

        return pagingQuery;
    }

    private void setBugData(Pagination<BugManagementDetailDto> pagingQuery) {
        List<String> fileQuery = new ArrayList<>();
        fileQuery.add(TestBugConstants.STR_ZERO);
        //  设置中文人名

        for (BugManagementDetailDto b : pagingQuery.getRecords()) {
            b.setCreatedByName(getChnName(b.getCreatedBy()));
            b.setReceiverName(getChnName(b.getReceiver()));
            b.setProName(entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM, b.getProId()));
            fileQuery.add(b.getBugId());
        }
        //查询是否有文件和关联用例
        List<BugManagementDetailDto> detailDtos = pagingQuery.getRecords();
        Map<String, Integer> fileMap = platFormFeignClient.batchQueryCount(fileQuery).getData();

        if (fileMap == null) fileMap = new HashMap<>();
        for (BugManagementDetailDto record : pagingQuery.getRecords()) {
            record.setExistFile((fileMap.containsKey(record.getBugId()) && fileMap.get(record.getBugId()) > 0) ? TestBugConstants.STR_ONE : "0");
            record.setExistCase(record.getIsExit() == null
                    ? TestBugConstants.STR_ZERO : TestBugConstants.STR_ONE);
        }
    }

    @Override
    public void exportExcel(HttpServletResponse response, QueryByPage<?> queryByPage, String fileName) {
        super.exportExcel(response, queryByPage, fileName);
    }

    @Override
    @DatabaseWriteOnly
    @Transactional
    public String add(BugManagementAddDto dto) {
        BugManagement entity = new BugManagement();
        BeanUtils.copyProperties(dto, entity);
        if (StringUtils.isEmpty(entity.getBugId())) {
            entity.setBugId(UUIDUtil.create32UUID());
        }
        entity.setBugFrom(BugFrom.getBugFrom(dto.getCreateType()).getMsg());
        try {
            entity.setBugOrder(getBugOrder(dto));
            entity.setOrderSeq(Integer.parseInt(entity.getBugOrder().split("-")[2]));

            addBugRecord(dto.getBugId(), TestBugConstants.BUG_STATUS, dto.getBugStatus());

            //  添加缺陷注释信息
            addBugLog(dto.getMessage(), dto.getBugId());

            //  关联用例数
            int caseNum = 0;

            //  添加缺陷关联信息
            if (CollectionUtils.isNotEmpty(dto.getCorrelationLinkAddDtos())) {
                addCorrelationLink(dto.getCorrelationLinkAddDtos());
                List<BugCorrelationLinkAddDto> caseNums = dto.getCorrelationLinkAddDtos().stream().filter(l -> linkType.equals(l.getLinkType())).collect(Collectors.toList());
                caseNum = caseNums.size();
            }

            entity.setCaseNum(caseNum);
            this.bugManagementService.insert(entity);

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.ADD_BUG_INFO_FAILED);
        }
        return dto.getBugId();
    }

    @Override
    @DatabaseWriteOnly
    @Transactional
    public Integer updateByPK(BugManagementUpdateDto dto) throws IllegalAccessException {
        int count = 0;
        try {

            //  添加缺陷变更信息
            addBugRecord(dto);

            //  添加缺陷注释信息
            addBugLog(dto.getMessage(), dto.getBugId());

            //  判断是否快速操作,为null则不是
            if (Objects.isNull(dto.getFastOperate())) {
                //覆盖
                //删除
                //  关联用例数
                Long caseNum = 0L;
                BugCorrelationLink bugCorrelationLink = new BugCorrelationLink();
                bugCorrelationLink.setBugId(dto.getBugId());
                bugCorrelationLink.setLinkType(TestBugConstants.BUG_STATUS);//只重置类型为1的数据
                bugCorrelationLinkService.deleteByExample(bugCorrelationLink);

                //  新增缺陷关联信息
                if (CollectionUtils.isNotEmpty(dto.getCorrelationLinkAddDtos())) {

                    //添加
                    addCorrelationLink(dto.getCorrelationLinkAddDtos());

                    //  统计案例数
                    caseNum = dto.getCorrelationLinkAddDtos().stream().filter(l -> linkType.equals(l.getLinkType())).count();
                }

                dto.setCaseNum(caseNum.intValue());
            }

            //  获取缺陷终态
            List<String> endStatus = getBugEndStatus(dto.getProId());

            BugManagement bugManagement = this.bugManagementService.findByPrimaryKey(dto.getBugId());

            //  修改缺陷管理信息
            count = updateBugManagementInfo(dto, endStatus);

            //  发送缺陷同步信息
            SynBugInfoDto infoDto = BeanHelper.copyProperties(dto, SynBugInfoDto.class);
            infoDto.setCreatedBy(bugManagement.getCreatedBy());
            infoDto.setCreatedTime(bugManagement.getCreatedTime());
            infoDto.setTenantId(bugManagement.getTenantId());
            infoDto.setUpdatedTime(new Date());
            infoDto.setUpdatedBy(NKSecurityContext.getUserId());
        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.UPDATE_BUG_INFO_FAILED);
        }

        return count;
    }

    @Override
    @DatabaseReadOnly
    public BugManagementDetailDto findByPK(String uuid) {
        BugManagementDetailDto dto = null;
        try {
            //  根据bugId查询注释信息

            BugManagement entitys = this.bugManagementService.findByPrimaryKey(uuid);

            dto = new BugManagementDetailDto();
            BeanUtils.copyProperties(entitys, dto);

            dto.setReceiverName(getChnName(dto.getRepairUser()));

            //  根据bugId查询注释信息
            List<BugLogDetailDto> bugLogDetailDtos = bugLogApiService.queryByBugId(uuid);

            bugLogDetailDtos.forEach(b -> b.setUpdateByName(getChnName(b.getUpdatedBy())));
            if (CollectionUtils.isNotEmpty(bugLogDetailDtos)) {
                dto.setBugLogDetailDtos(bugLogDetailDtos);
            }
            //  查询缺陷变更记录
            List<BugRecordDetailDto> bugRecordDetailDtos = getBugRecordDetailDtos(uuid);

            //  根据bugId查询关联信息
            List<BugCorrelationLinkDetailDto> linkDetailDtos = correlationLinkApiService.queryByBugId(uuid);

            if (CollectionUtils.isNotEmpty(linkDetailDtos)) {
                dto.setCorrelationLinkDetailDtos(linkDetailDtos);
            }

            dto.setBugRecordDetailDtos(bugRecordDetailDtos);

            dto.setCreatedByName(getChnName(dto.getCreatedBy()));

            dto.setReceiverName(getChnName(dto.getReceiver()));

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_INFO_FAILED);
        }

        return dto;
    }

    private List<BugRecordDetailDto> getBugRecordDetailDtos(String uuid) {
        //  查询缺陷字典数据

        Map<String, Map<String, String>> dictData = queryDictData();
        Map<String, String> bugFields = getSysBugFields();

        //  根据bugId查询变更记录信息
        List<BugRecordDetailDto> bugRecordDetailDtos = bugRecordApiService.queryByBugId(uuid);


        bugRecordDetailDtos.forEach(r -> {
            r.setUpdatedByName(getChnName(r.getUpdatedBy()));

            //  设置字段属性值
            dictData.forEach((k, v) -> {
                if (k.equals(r.getRecordField())) {
                    r.setRecordValue(v.get(r.getRecordValue()));
                }
            });
            if (TestBugConstants.ERR_MSG.equals(r.getRecordField())) {
                r.setRecordField(TestBugConstants.RECORD_FIELD);
            }
            //  设置字段属性名
            bugFields.forEach((k, v) -> {
                if (k.equals(r.getRecordField())) {
                    r.setRecordField(v);
                }
            });
        });
        return bugRecordDetailDtos;
    }

    @Override
    @DatabaseWriteOnly
    public Integer deleteByPK(String uuid) {
        BugManagement entity = new BugManagement();
        entity.setBugId(uuid);
        return this.bugManagementService.deleteByExample(entity);
    }

    @Override
    public List<String> addBatch(List<BugManagementAddDto> batch) {
        List<String> result = new ArrayList<>();
        for (BugManagementAddDto dto : batch) {
            result.add(bugManagementApiService.add(dto));
        }
        return result;
    }

    @Override
    public Integer updateBatch(List<BugManagementUpdateDto> batch) throws IllegalAccessException {
        int sum = 0;
        for (BugManagementUpdateDto dto : batch) {
            sum = sum + bugManagementApiService.updateByPK(dto);
        }
        return sum;
    }

    @Override
    public Integer deleteBatch(List<Object> batch) {
        return this.bugManagementService.deleteByPrimaryKeys(batch);
    }

    /**
     * 查询缺陷创建人信息
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> queryBugCreatedBy(BugManagementQueryDto dto) {

        List<String> createdBys = new ArrayList<>();
        try {
            List<String> userNames = bugManagementService.queryBugCreatedBy(dto.getProjectList(),
                    NKSecurityContext.getTenantId());

            //  模糊查询
            userNames.forEach(u -> {
                String chnName = getChnName(u);
                if (StringUtils.isEmpty(dto.getCreatedBy()) || chnName.contains(dto.getCreatedBy())) {
                    createdBys.add(chnName);
                }
            });

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_CREATED_BY_FAILED);
        }

        return createdBys;
    }

    /**
     * 查询所有缺陷修复人
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> queryPubBugReceiver(BugManagementQueryDto dto) {
        List<String> receivers = new ArrayList<>();
        try {
            //加一个tenantId
            List<String> userNames = bugManagementService.queryBugReceiver(dto.getProjectList(),
                    null == dto.getTenantId() ? NKSecurityContext.getTenantId() : dto.getTenantId());
            if (userNames.size() != 0) {
                receivers.addAll(userNames);
            }
        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_RECEIVER_FAILED);
        }
        return receivers;
    }

    /**
     * 查询所有缺陷修复人
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> queryBugReceiver(BugManagementQueryDto dto) {
        List<String> receivers = new ArrayList<>();
        try {
            //加一个tenantId
            List<String> userNames = bugManagementService.queryBugReceiver(dto.getProjectList(),
                    null == dto.getTenantId() ? NKSecurityContext.getTenantId() : dto.getTenantId());

            //  模糊查询
            userNames.forEach(u -> {
                String chnName = getChnName(u);
                if (StringUtils.isEmpty(dto.getReceiver()) || chnName.contains(dto.getReceiver())) {
                    receivers.add(chnName);
                }
            });

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_RECEIVER_FAILED);
        }

        return receivers;
    }

    /**
     * 导出Excel：缺陷管理
     *
     * @param response
     * @param queryByPage
     */
    @Override
    public void exportBugExcel(HttpServletResponse response, QueryByPage<BugManagementQueryDto> queryByPage) {

        BugManagementQueryDto query = queryByPage.getQuery();
        List<String> projectList = query.getProjectList();

        //  查询自定义字段,仅缺陷管理导出自定义字段
        List<MtProjectTemplateDetailDto> expands = null;
        if (CollectionUtils.isNotEmpty(query.getProjectList())) {
            expands = getMtProjectTemplateDetailDtos(query);
        }

        //  获取缺陷模板系统属性
        Map<String, String> bugFields = getSysBugFields();

        // 每500页数据查询一次写入到Execl中
        queryByPage.setPageNo(1);
        queryByPage.setPageSize(500);
        query.setTenantId(NKSecurityContext.getTenantId());
        Pagination<BugManagementDetailDto> pagingQuery = pagingQuery(queryByPage);

        //  设置表头
        List<SheetTemplate> excel = new ArrayList<>();
        ExcelDataTemplate template = new ExcelDataTemplate();
        setTemplateExcel(excel, expands, template);
        SXSSFWorkbook workbook = ExportExcel.genExcelTemplateNoData(excel);

        try {
            String fileName = setExportFileName(projectList);
            exportBugExcel(response, queryByPage, bugFields, pagingQuery, template, workbook, fileName);
        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.EXPORT_BUG_INFO_FAILED);
        }
    }

    /**
     * 导出缺陷excel
     *
     * @param response
     * @param queryByPage
     * @param bugFields
     * @param pagingQuery
     * @param template
     * @param workbook
     * @param fileName
     * @throws Exception
     */
    private void exportBugExcel(HttpServletResponse response, QueryByPage<BugManagementQueryDto> queryByPage, Map<String, String> bugFields, Pagination<BugManagementDetailDto> pagingQuery, ExcelDataTemplate template, SXSSFWorkbook workbook, String fileName) throws Exception {
        int startRow = 2;
        if (pagingQuery.getPageCount() == 0) {
            //  处理数据
            setTemplateData(template, pagingQuery.getRecords(), startRow, bugFields);
            ExportExcel.excelWriterData(workbook, template, fileName, response);
        } else {

            int pageCount = pagingQuery.getPageCount();
            for (int i = 1; i <= pageCount; i++) {
                queryByPage.setPageNo(i);
                Pagination<BugManagementDetailDto> result = pagingQuery(queryByPage);
                //  处理数据
                setTemplateData(template, result.getRecords(), startRow, bugFields);

                startRow += 500;

                if (i == pageCount) {
                    ExportExcel.excelWriterData(workbook, template, fileName, response);
                } else {
                    ExportExcel.excelWriterData(workbook, template, null, null);
                }
            }
        }
    }

    /**
     * 设置缺陷导出文件名
     *
     * @param projectList
     * @return
     * @throws UnsupportedEncodingException
     */
    private String setExportFileName(List<String> projectList) throws UnsupportedEncodingException {
        String fileName;
        if (CollectionUtils.isNotEmpty(projectList)) {
            String proName = entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM, projectList.get(0));
            fileName = URLEncoder.encode(proName + TestBugConstants.PRO_BUG_FILE_NAME, TestBugConstants.URL_ENCODE);
        } else {
            fileName = URLEncoder.encode(TestBugConstants.BUG_FILE_NAME, TestBugConstants.URL_ENCODE);
        }
        return fileName;
    }

    /**
     * 获取缺陷系统属性
     *
     * @return
     */
    private Map<String, String> getSysBugFields() {
        List<CpTemplatePropertiesDetailDto> sysProperties = platFormFeignServer.getSysProperties(0);
        return sysProperties.stream().
                collect(Collectors.
                        toMap(CpTemplatePropertiesDetailDto::getTemplatePropName,
                                CpTemplatePropertiesDetailDto::getTemplatePropDisplay));
    }

    /**
     * 查询模块名
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> queryModule(BugManagementQueryDto dto) {

        List<String> moduleNames = null;
        try {
            dto.setTenantId(NKSecurityContext.getTenantId());
            List<BugManagement> bugManagements = bugManagementService.queryBugInfo(dto);

            moduleNames = bugManagements.stream().map(BugManagement::getModuleId).distinct().collect(Collectors.toList());
        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_MODULE_FAILED);
        }
        return moduleNames;
    }

    /**
     * 查询缺陷标题/编号
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> queryBugTitle(BugManagementQueryDto dto) {

        List<String> bugTitles = null;
        try {
            dto.setTenantId(NKSecurityContext.getTenantId());
            List<BugManagement> bugManagements = bugManagementService.queryBugInfo(dto);

            bugTitles = bugManagements.stream().map(BugManagement::getBugTitle).distinct().collect(Collectors.toList());
        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_TITLE_AND_ORDER_FAILED);
        }
        return bugTitles;
    }

    /**
     * 查询缺陷编号
     *
     * @param dto
     * @return
     */
    @Override
    public List<String> queryBugOrder(BugManagementQueryDto dto) {
        List<String> bugOrders = null;
        try {
            dto.setTenantId(NKSecurityContext.getTenantId());
            List<BugManagement> bugManagements = bugManagementService.queryBugInfo(dto);

            bugOrders = bugManagements.stream().map(BugManagement::getBugOrder).collect(Collectors.toList());
        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_TITLE_AND_ORDER_FAILED);
        }
        return bugOrders;
    }

    /**
     * 同步缺陷模块名
     *
     * @param data
     * @return
     */
    @Override
    @Transactional
    public Integer synchronizationModule(SynModule data) {
        //  查询变更数据,并新增至缺陷变更记录
        List<BugManagementDetailDto> dtoList = bugManagementService.findByLinkId(data.getCaseId());
        List<BugRecordAddDto> recordAddDtos = new ArrayList<>();
        //  模块名不同则新增缺陷变更记录
        if (dtoList == null || dtoList.size() == 0) return 0;
        dtoList.stream()
                .filter(d -> !data.getModuleName().equals(d.getModuleId()))
                .forEach(d -> {
                    BugRecordAddDto dto = new BugRecordAddDto();
                    dto.setBugId(d.getBugId());
                    dto.setRecordField(TestBugConstants.MODULE_ID);
                    dto.setRecordValue(data.getModuleName());
                    recordAddDtos.add(dto);
                });
        bugRecordApiService.addBatch(recordAddDtos);

        //  设置修改人为发送消息的人
        NKSecurityContext.setUserId(data.getUserId());

        return bugManagementService.synchronizationModule(data);
    }

    /**
     * 同步缺陷系统名
     *
     * @param data
     * @return
     */
    @Override
    @Transactional
    public Integer synchronizationSystem(SynSystem data) {
        //  查询变更数据,并新增至缺陷变更记录
        BugManagement bugManagement = new BugManagement();
        bugManagement.setProId(data.getId());
        List<BugManagement> bugManagements = bugManagementService.query(bugManagement);
        List<BugRecordAddDto> recordAddDtos = new ArrayList<>();
        //  系统名不同则新增缺陷变更记录
        bugManagements.stream()
                .filter(d -> !data.getOwningSystem().equals(d.getSystemId()))
                .forEach(d -> {
                    BugRecordAddDto dto = new BugRecordAddDto();
                    dto.setBugId(d.getBugId());
                    dto.setRecordField(TestBugConstants.SYSTEM_ID);
                    dto.setRecordValue(data.getOwningSystem());
                    dto.setTenantId(data.getTenantId());
                    recordAddDtos.add(dto);

                });
        bugRecordApiService.addBatch(recordAddDtos);

        //  设置修改人为发送消息的人
        NKSecurityContext.setUserId(data.getUpdatedBy());

        return bugManagementService.synchronizationSystem(data);
    }

    /**
     * 根据执行id或步骤id查询缺陷详情
     *
     * @param linkId
     * @return
     */
    @Override
    public List<BugManagementDetailDto> findByLinkId(String linkId) {
        List<BugManagementDetailDto> detailDtos = null;
        try {
            detailDtos = bugManagementService.findByLinkId(linkId);

            //查询是否有文件和关联用例
            List<String> bugIds = detailDtos.stream().map(BugManagementDetailDto::getBugId).distinct().collect(Collectors.toList());
            Map<String, Integer> data = platFormFeignClient.batchQueryCount(bugIds).getData();

            //  设置人名
            detailDtos.stream().distinct().forEach(d -> {
                d.setCreatedByName(getChnName(d.getCreatedBy()));
                d.setReceiverName(getChnName(d.getReceiver()));

                d.setExistFile((data.containsKey(d.getBugId()) && data.get(d.getBugId()) > 0) ? TestBugConstants.STR_ONE : TestBugConstants.STR_ZERO);

                d.setBugRecordDetailDtos(getBugRecordDetailDtos(d.getBugId()));

                d.getBugLogDetailDtos().forEach(l -> {
                    l.setUpdateByName(getChnName(l.getUpdatedBy()));
                });

                List<BugCorrelationLinkDetailDto> links = d.getCorrelationLinkDetailDtos().stream()
                        .filter(c -> !linkType.equals(c.getLinkType()) && linkId.equals(c.getLinkId()))
                        .collect(Collectors.toList());
                d.setCorrelationLinkDetailDtos(links);
            });

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_LINK_INFO_FAILED, e);
        }

        return detailDtos;
    }

    /**
     * 查询用户是否在项目创建缺陷
     *
     * @param projectId
     * @param userId
     * @return
     */
    @Override
    public boolean queryUserBugByProId(String projectId, String userId) {

        Integer count = bugManagementService.queryUserBugByProId(projectId, userId);
        return Objects.nonNull(count);
    }


    /**
     * 获取缺陷管理规则
     *
     * @param projectId
     * @param ruleCode
     * @return
     */
    private boolean queryRuleConfig(String projectId, String ruleCode) {
        CpProjectRuleQueryDto dto = new CpProjectRuleQueryDto();
        dto.setProjectId(projectId);
        dto.setRuleNo(ruleCode);
        RuleConfigValue ruleConfig = projectsFeignServer.queryRuleConfig(dto);
        return Objects.nonNull(ruleConfig) ? ruleConfig.getChecked() : false;
    }

    /**
     * 人名模糊搜索
     *
     * @param userName
     * @return
     */
    private List<String> getUserIds(String userName) {
        UserQueryDto example = new UserQueryDto();
        if (userName.contains(",") || userName.contains("，")) {
            userName = userName.replace(",", "|")
                    .replace("，", "|")
                    .replace("(", "\\(")
                    .replace(")", "\\)");
            String[] list = userName.split("\\|");
            String user = "";
            for (String one : list) {
                if (!StringUtils.isEmpty(one)) user = user + "|" + one;
            }
            example.setUserChnNames(user.substring(1));
        } else {
            example.setUserChnName(userName);
        }
        example.setTenantId(NKSecurityContext.getTenantId());
        return platFormFeignServer.findUserIdByName(example);
    }

    private void sendEmail(String receiver, List<CpNotice> list) {
        if (list == null || list.size() == 0) {
            return;
        }

        CpNotice notice = list.get(0);
        QueryByPage<UserQueryDto> query = new QueryByPage<>();
        UserQueryDto dto = new UserQueryDto();
        //接收人ID
        dto.setId(receiver);
        query.setQuery(dto);
        ResultWrapper<DefaultPagination<UserInfoDto>> userInfos = platFormFeignClient.queryUserInfo(query);
        List<UserInfoDto> records = userInfos.getData().getRecords();
        if (records.size() == 0) {
            logger.error("查询不到用户信息！");
            return;
        }

        //接受人email
        String mail = records.get(0).getMail();
        if (StringUtils.isEmpty(mail)) {
            logger.error("查询不到用户信息！");
            return;
        }

        try {
            emailService.sendMail(notice.getTitle(), notice.getContent(), Arrays.asList(mail));
        } catch (Exception e) {
            logger.error("发送邮件失败！", e);
        }
    }

    private List<MtProjectTemplateDetailDto> getMtProjectTemplateDetailDtos(BugManagementQueryDto query) {
        List<MtProjectTemplateDetailDto> expands;
        MtProjectTemplateQueryDto queryDto = new MtProjectTemplateQueryDto();
        queryDto.setTemplateType(0);
        queryDto.setTenantId(NKSecurityContext.getTenantId());
        queryDto.setPublics(false);
        queryDto.setProjectList(query.getProjectList());
        expands = projectsFeignServer.feignPagingQuery(queryDto);
        return expands;
    }

    /**
     * 处理数据
     *
     * @param template
     * @param records
     * @param startRow
     * @param bugFields
     */
    private void setTemplateData(ExcelDataTemplate template, List<BugManagementDetailDto> records, int startRow, Map<String, String> bugFields) {

        List<Map<String, Object>> dataSource = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(records)) {

            //  查询缺陷变更记录
            List<String> bugIds = records.stream().map(BugManagementDetailDto::getBugId).collect(Collectors.toList());
            List<BugRecordDetailDto> recordDetailDtos = bugRecordApiService.queryByBugIds(bugIds);

            //  查询缺陷字典数据
            Map<String, Map<String, String>> dictData = queryDictData();

            //  查询项目名称
            List<String> proIds = records.stream().distinct().map(BugManagement::getProId).collect(Collectors.toList());
            List<CpProjectDetailDto> listProject = projectsFeignServer.listProject(proIds);

            records.forEach(r -> {

                Map<String, Object> map = new HashMap<>();
                //处理自定义字段
                if (StringUtils.hasText(r.getExpands())) {
                    JSONObject object = JSONObject.parseObject(r.getExpands());
                    object.forEach(map::put);
                }

                //  设置项目名
                listProject.stream()
                        .filter(p -> r.getProId().equals(p.getId()))
                        .forEach(p -> r.setProName(p.getName()));

                //  设置字典类型数据
                dictData.forEach((k, v) -> {
                    switch (k) {
                        case bugStatus:
                            r.setBugStatus(v.get(r.getBugStatus()));
                            break;
                        case bugFrom:
                            r.setBugFrom(v.get(r.getBugFrom()));
                            break;
                        case bugType:
                            r.setBugType(v.get(r.getBugType()));
                            break;
                        case bugGrade:
                            r.setBugGrade(v.get(r.getBugGrade()));
                            break;
                        case isReappear:
                            r.setIsReappear(v.get(r.getIsReappear()));
                            break;
                        case emergency:
                            r.setEmergency(v.get(r.getEmergency()));
                            break;
                        default:
                    }
                });

                map.put(TestBugConstants.PRO_ID, r.getProName());
                map.put(TestBugConstants.BUG_ORDER, r.getBugOrder());
                map.put(TestBugConstants.BUG_TITLE, r.getBugTitle());
                map.put(TestBugConstants.BUG_GRADE, r.getBugGrade());
                map.put(TestBugConstants.EMERGENCY, r.getEmergency());
                map.put(TestBugConstants.BUG_TYPE, r.getBugType());
                map.put(TestBugConstants.IS_REAPPEAR, r.getIsReappear());
                map.put(TestBugConstants.BUG_STATUS, r.getBugStatus());
                map.put(TestBugConstants.MODULE_ID, r.getModuleId());
                map.put(TestBugConstants.CREATE_BY, getChnName(r.getCreatedBy()));
                map.put(TestBugConstants.RECEIVER, getChnName(r.getReceiver()));
                map.put(TestBugConstants.CREATED_TIME, r.getCreatedTime());
                map.put(TestBugConstants.REPAIR_TIME, Objects.isNull(r.getRepairTime()) ? "" : r.getRepairTime());
                map.put(TestBugConstants.CLOSE_TIME, r.getCloseTime());
                map.put(TestBugConstants.SYSTEM_ID, StringUtils.isEmpty(r.getSystemId()) ? "" : r.getSystemId());
                map.put(TestBugConstants.ROUND_ID, r.getRoundId());

                StringBuilder sb = new StringBuilder();
                //  标记创建人和时间去重
                Set<String> flag = new HashSet<>();
                //  行高
                AtomicInteger dataHeight = new AtomicInteger(2);

                SimpleDateFormat format = new SimpleDateFormat(TestBugConstants.SIMPLE_DATE_FORMAT);
                //  拼装变更记录
                recordDetailDtos.stream()
                        .filter(d -> r.getBugId().equals(d.getBugId()))
                        .forEach(d -> {
                            //  设置变更记录字段属性字典值
                            dictData.forEach((k, v) -> {
                                if (k.equals(d.getRecordField())) {
                                    d.setRecordValue(v.get(d.getRecordValue()));
                                }
                            });

                            //  设置变更记录字段名称
                            bugFields.forEach((k, v) -> {
                                if (k.equals(d.getRecordField())) {
                                    d.setRecordField(v);
                                }
                            });

                            if (TestBugConstants.ERR_MSG.equals(d.getRecordField())) {
                                d.setRecordField(TestBugConstants.RECORD_FIELD);
                            }

                            //  拼装修改人和时间
                            if (!flag.contains(d.getUpdatedBy() + d.getCreatedTime())) {
                                sb.append(getChnName(d.getUpdatedBy()))
                                        .append("   ")
                                        .append(format.format(d.getCreatedTime()))
                                        .append("\r\n");
                            }
                            flag.add(d.getUpdatedBy() + d.getCreatedTime());

                            sb.append(TestBugConstants.CHANGE_STR)
                                    .append(d.getRecordField())
                                    .append("\r\n")
                                    .append(TestBugConstants.CHANGE_VALUE)
                                    .append(d.getRecordValue())
                                    .append("\r\n");

                            dataHeight.getAndAdd(2);
                        });

                map.put(TestBugConstants.RECORDS, sb.toString());
                map.put(TestBugConstants.DATA_HEIGHT, dataHeight);
                dataSource.add(map);
            });
        }

        template.setDataSource(dataSource);
        template.setSheetAt(0);
        template.setStartRow(startRow);

    }

    /**
     * 查询缺陷所有字典数据
     *
     * @return
     */
    private Map<String, Map<String, String>> queryDictData() {
        String[] dictCodes = {bugStatus, bugFrom, bugGrade, bugType, isReappear, emergency};
        return platFormFeignServer.queryDictData(Arrays.asList(dictCodes));
    }

    /**
     * 设置excel表头
     *
     * @param excel
     * @param expands
     * @param template
     */
    private void setTemplateExcel(List<SheetTemplate> excel, List<MtProjectTemplateDetailDto> expands, ExcelDataTemplate template) {
        SheetTemplate sheet = new SheetTemplate();
        sheet.setSheetName(TestBugConstants.BUG_LIST_EXECL_EXPORT);
        List<SheetHead> heads = new ArrayList<>();
        List<ExcelHead> head1s = new ArrayList<>();

        String[] name = TestBugConstants.TEST_BUG_NAME;
        String[] key = TestBugConstants.TEST_BUG_KEY;

        for (int i = 0; i < name.length; i++) {
            SheetHead head = new SheetHead();
            head.setStartRow(1);
            head.setEndRow(1);
            head.setStartCol(ExcelToolUtil.getExcelColumnLabel(i));
            head.setEndCol(ExcelToolUtil.getExcelColumnLabel(i));
            head.setName(name[i]);
            heads.add(head);

            ExcelHead head1 = new ExcelHead();
            head1.setIsMerge(TestBugConstants.STR_ZERO);
            head1.setTemplatePropDisplay(name[i]);
            head1.setTemplatePropName(key[i]);
            head1s.add(head1);
        }

        //  处理自定义字段
        ExcelUtil.handleExpands(heads, head1s, expands);

        sheet.setHeadList(heads);
        excel.add(sheet);

        template.setSheetAt(0);
        template.setStartColumn(TestBugConstants.STR_A);
        template.setEndColumn(ExcelToolUtil.getExcelColumnLabel(heads.size() - 1));
        template.setHeadList(head1s);
    }

    /**
     * 拼接缺陷编码
     *
     * @param dto
     * @return
     */
    private String getBugOrder(BugManagementAddDto dto) {

        BugNo bugNo = new BugNo();
        bugNo.setNoType(TestBugConstants.DEFECT);
        bugNo.setNoValue(1L);

        Long order = bugNoApiService.genBugNo(bugNo);
        return String.format(TestBugConstants.DEFECT_STR,dto.getCreateType(),order);
    }

    /**
     * 拼接缺陷编码
     *
     * @param dto
     * @return
     */
    private String getPubBugOrder(BugManagementAddDto dto, String tenantId) {

        BugNo bugNo = new BugNo();
        bugNo.setNoType(TestBugConstants.DEFECT);
        bugNo.setNoValue(1L);

        Long order = bugNoApiService.genPubBugNo(bugNo, tenantId);
        return String.format(TestBugConstants.DEFECT_STR,dto.getCreateType(),order);
    }

    /**
     * 添加缺陷变更记录信息
     *
     * @param bugId
     * @param recordField
     * @param recordValue
     */
    private void addPubBugRecord(String bugId, String recordField, String recordValue, String createdBy, String tenantId) {
        BugRecord bugRecordAddDto = new BugRecord();
        bugRecordAddDto.setRecordId(UUIDUtil.create32UUID());
        bugRecordAddDto.setBugId(bugId);
        bugRecordAddDto.setRecordField(recordField);
        bugRecordAddDto.setRecordValue(recordValue);
        bugRecordAddDto.setTenantId(tenantId);
        bugRecordAddDto.setCreatedBy(createdBy);
        bugRecordAddDto.setUpdatedBy(createdBy);
        Date date = new Date();
        bugRecordAddDto.setCreatedTime(date);
        bugRecordAddDto.setUpdatedTime(date);
        bugRecordApiService.pubAdd(bugRecordAddDto);
    }

    /**
     * 添加缺陷变更记录信息
     *
     * @param bugId
     * @param recordField
     * @param recordValue
     */
    private void addBugRecord(String bugId, String recordField, String recordValue) {
        BugRecordAddDto bugRecordAddDto = new BugRecordAddDto();
        bugRecordAddDto.setBugId(bugId);
        bugRecordAddDto.setRecordField(recordField);
        bugRecordAddDto.setRecordValue(recordValue);
        bugRecordApiService.add(bugRecordAddDto);
    }


    /**
     * 添加缺陷变更记录信息
     *
     * @param dto
     */
    private void addBugRecord(BugManagementUpdateDto dto) {
        //  定义不添加的属性
        final String ignoreArr = TestBugConstants.BUG_MGR_IGNORE_ADDR;

        BugManagement bug = bugManagementService.findByPrimaryKey(dto.getBugId());
        BugManagementUpdateDto sourceDto = BeanHelper.copyProperties(bug, BugManagementUpdateDto.class);

        Map<String, Object> map = CompareFieldsUtil.compareFields(dto, sourceDto, ignoreArr);

        String bugId = dto.getBugId();
        if (!org.springframework.util.CollectionUtils.isEmpty(map)) {
            map.forEach((k, v) -> {
                switch (k) {
                    case TestBugConstants.RECEIVER:
                        addBugRecord(bugId, k, getChnName(v.toString()));
                        break;
                    case TestBugConstants.BUG_TITLE:
                    case TestBugConstants.ROUND_ID:
                    case TestBugConstants.ERR_MSG:
                        addBugRecord(bugId, k, "已变更");
                        break;
                    default:
                        addBugRecord(bugId, k, v.toString());
                }
            });
        }

    }

    /**
     * 添加缺陷注释信息
     *
     * @param message
     * @param bugId
     */
    private void addPubBugLog(String message, String bugId, String createdBy, String tenantId) {
        if (StringUtils.hasText(message)) {
            BugLog bugLogAddDto = new BugLog();
            bugLogAddDto.setBugLogId(UUIDUtil.create32UUID());
            bugLogAddDto.setBugId(bugId);
            bugLogAddDto.setMessage(message);
            bugLogAddDto.setTenantId(tenantId);
            bugLogAddDto.setCreatedBy(createdBy);
            bugLogAddDto.setUpdatedBy(createdBy);
            Date date = new Date();
            bugLogAddDto.setUpdatedTime(date);
            bugLogAddDto.setCreatedTime(date);
            bugLogApiService.pubAdd(bugLogAddDto);
        }
    }

    /**
     * 添加缺陷注释信息
     *
     * @param message
     * @param bugId
     */
    private void addBugLog(String message, String bugId) {
        if (StringUtils.hasText(message)) {
            BugLogAddDto bugLogAddDto = new BugLogAddDto();
            bugLogAddDto.setBugId(bugId);
            bugLogAddDto.setMessage(message);
            bugLogApiService.add(bugLogAddDto);
        }
    }

    /**
     * 添加缺陷关联信息
     *
     * @param correlationLinkAddDtos
     */
    private void addCorrelationLink(List<BugCorrelationLinkAddDto> correlationLinkAddDtos) {
        correlationLinkApiService.addBatch(correlationLinkAddDtos);
    }

    /**
     * 根据用户id，获取用户中文名
     *
     * @param userId
     * @return
     */
    public String getChnName(String userId) {
        return entityNameCache.translateById(EntityNameCatalog.MONSTER_USER, userId);
    }

    /**
     * 修改缺陷管理信息
     *
     * @param dto
     * @return
     */
    private int updateBugManagementInfo(BugManagementUpdateDto dto, List<String> endStatus) {
        String status = dto.getBugStatus();
        Date date = new Date();
        if (TestBugStatus.REPAIRED.getCode().equals(status)) {
            dto.setRepairUser(NKSecurityContext.getUserId());
            dto.setRepairTime(date);
        }
        if (CollectionUtils.isNotEmpty(endStatus) && endStatus.contains(status)) {
            dto.setCloseTime(date);
        }

        int count = 0;
        try {
            BugManagement bugManagement = BeanHelper.copyProperties(dto, BugManagement.class);
            count = bugManagementService.updateByPrimaryKey(bugManagement);

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.UPDATE_BUG_INFO_FAILED);
        }

        return count;
    }

    /**
     * 获取缺陷终态
     *
     * @param projectId
     * @return
     */
    private List<String> getBugEndStatus(String projectId) {
        StatusRoleDto statusRoleDto = new StatusRoleDto();
        statusRoleDto.setFinishedState(true);
        statusRoleDto.setProjectId(projectId);
        return projectsFeignServer.queryBugEndStatus(statusRoleDto);
    }

    @Override
    public List<BugTendencyChartDetailDto> queryBugByStatus(BugTendencyChartQueryDto bugTendencyChartQueryDto) {
        List<BugTendencyChartDetailDto> bugTendencyChartDetailDtos = new ArrayList<>();
        bugTendencyChartQueryDto.getProjectIdList().forEach(proId -> {
            StatusRoleDto s = new StatusRoleDto();
            s.setFinishedState(true);
            s.setProjectId(proId);
            //根据项目id获取终态
            List<String> statusList = projectsFeignServer.queryBugEndStatus(s);
            //逐一获取每个项目的缺陷趋势信息
            bugTendencyChartDetailDtos.addAll(bugManagementService.queryBugByStatus(proId, statusList, bugTendencyChartQueryDto.getTenantId(), bugTendencyChartQueryDto.getStartTime(), bugTendencyChartQueryDto.getEndTime()));
        });
        //处理求和
        List<BugOverallTendencyChartAddDto> bugOverallTendencyChartAddDtoList = new ArrayList<>();
        bugTendencyChartDetailDtos.forEach(bugTendencyChartDetailDto -> {
            BugOverallTendencyChartAddDto bugOverallTendencyChartAddDto = BeanHelper.copyProperties(bugTendencyChartDetailDto, BugOverallTendencyChartAddDto.class);
            bugOverallTendencyChartAddDto.setAll(bugTendencyChartDetailDto.getAllAmount());
            bugOverallTendencyChartAddDtoList.add(bugOverallTendencyChartAddDto);
        });
        bugOverallTendencyChartApiService.deleteAll();
        bugOverallTendencyChartApiService.addBatch(bugOverallTendencyChartAddDtoList);
        List<BugOverallTendencyChartDetailDto> bugOverallTendencyChartDetailDtos = bugOverallTendencyChartApiService.selectGroupByTime();

        return BeanHelper.copyWithCollection(bugOverallTendencyChartDetailDtos, BugTendencyChartDetailDto.class);
    }

    @Override
    public DefaultPagination<BugManagementDetailDto> pagingQueryFilter(QueryByPage<BugManagementQueryDto> queryByPage) {
        DefaultPagination<BugManagementDetailDto> pagingQuery = null;
        try {
            List<String> createdBys = new ArrayList<>();
            BugManagementQueryDto query = queryByPage.getQuery();
            if (StringUtils.hasText(query.getCreatedBy())) {
                UserQueryDto example = new UserQueryDto();
                example.setUserChnName(query.getCreatedBy());
                example.setTenantId(NKSecurityContext.getTenantId());
                createdBys = platFormFeignServer.findUserIdByName(example);
            }

            List<String> receivers = new ArrayList<>();
            if (StringUtils.hasText(query.getReceiver())) {
                UserQueryDto example = new UserQueryDto();
                example.setUserChnName(query.getReceiver());
                example.setTenantId(NKSecurityContext.getTenantId());
                receivers = platFormFeignServer.findUserIdByName(example);
            }

            query.setCreatedBys(createdBys);
            query.setReceivers(receivers);

            pagingQuery = this.bugManagementService.pagingQueryFilter(queryByPage);

            //  查询缺陷字典数据
            Map<String, Map<String, String>> dictData = queryDictData();

            Map<String, String> bugFields = getSysBugFields();

            //  设置中文人名
            pagingQuery.getRecords().forEach(p -> {
                p.setCreatedByName(getChnName(p.getCreatedBy()));
                p.setReceiverName(getChnName(p.getReceiver()));
                p.getBugRecordDetailDtos().forEach(r -> {
                    r.setUpdatedByName(getChnName(r.getUpdatedBy()));

                    //  设置字段属性值
                    dictData.forEach((k, v) -> {
                        if (k.equals(r.getRecordField())) {
                            r.setRecordValue(v.get(r.getRecordValue()));
                        }
                    });

                    //  设置字段属性名
                    bugFields.forEach((k, v) -> {
                        if (k.equals(r.getRecordField())) {
                            r.setRecordField(v);
                        }

                        if (k.equals(TestBugConstants.ERR_MSG)) {
                            r.setRecordField(TestBugConstants.RECORD_FIELD);
                        }
                    });
                });
            });

        } catch (Exception e) {
            throw new PlatformRuntimeException(TestBugError.QUERY_BUG_INFO_FAILED);
        }

        return pagingQuery;
    }

    @Override
    public List<BugStatisticsChartAddDto> queryBugByDicItems(List<CltDictItem> dictItems, String tenantId) {
        return bugManagementService.queryBugByDicItems(dictItems, tenantId);
    }

    @Override
    public List<IsCommitBugDetailDto> findByLinkIdList(List<String> linkIdList) {
        return bugManagementService.findByLinkIdList(linkIdList);
    }

    @Override
    public List<String> findTenantIdList() {
        return bugManagementService.findTenantIdList();
    }

    @Override
    public DefaultPagination<BugHighDegreeChartDetailDto> pagingQueryHighDegree(QueryByPage<BugHighDegreeChartQueryDto> queryByPage) {
        if ("2".equals(queryByPage.getQuery().getFindType())) {
            //调feign查询出子项目列表
            List<String> data = projectsFeignClient.listLeafProject(queryByPage.getQuery().getProjectIdList()).getData();
            if (null != data && data.size() != 0) {
                queryByPage.getQuery().setProjectIdList(data);
            }
        }
        DefaultPagination<BugHighDegreeChartDetailDto> page = bugManagementService.pagingQueryHighDegree(queryByPage);
        //根据项目id去获取项目名称
        //获取中文名
        if (null != page.getRecords()) {
            List<CltDictItem> cltDictItems = JSON.parseArray(JSON.toJSONString(
                    redisTemplate.opsForValue().get(TestBugConstants.DICT_KEY + NKSecurityContext.getTenantId() + TestBugConstants.DICT_BUG_STATUS)), CltDictItem.class);
            page.getRecords().forEach(bugHighDegreeChartDetailDto -> {
                bugHighDegreeChartDetailDto.setProName(null == projectsFeignServer.listProject(Collections.singletonList(bugHighDegreeChartDetailDto.getProId())) ? null :
                        projectsFeignServer.listProject(Collections.singletonList(bugHighDegreeChartDetailDto.getProId())).get(0).getName());
                if (null != bugHighDegreeChartDetailDto.getReceiver()) {
                    bugHighDegreeChartDetailDto.setReceiver(entityNameCache.translateById(EntityNameCatalog.MONSTER_USER, bugHighDegreeChartDetailDto.getReceiver()));
                }
                if (null != bugHighDegreeChartDetailDto.getCreatedBy()) {
                    bugHighDegreeChartDetailDto.setCreatedBy(entityNameCache.translateById(EntityNameCatalog.MONSTER_USER, bugHighDegreeChartDetailDto.getCreatedBy()));
                }
                //获取缺陷状态映射值
                if (null != bugHighDegreeChartDetailDto.getBugStatus() && null != cltDictItems) {
                    cltDictItems.forEach(cltDictItem -> {
                        if (bugHighDegreeChartDetailDto.getBugStatus().equals(cltDictItem.getItemCode())) {
                            bugHighDegreeChartDetailDto.setBugStatus(cltDictItem.getItemName());
                        }
                    });
                }
                //获取紧急程度映射值
                if (null != bugHighDegreeChartDetailDto.getEmergency()) {
                    if (TestBugConstants.STR_ONE.equals(bugHighDegreeChartDetailDto.getEmergency()))
                        bugHighDegreeChartDetailDto.setEmergency(TestBugConstants.STR_HIGH);
                    else if (TestBugConstants.STR_TWO.equals(bugHighDegreeChartDetailDto.getEmergency()))
                        bugHighDegreeChartDetailDto.setEmergency(TestBugConstants.STR_MID);
                    else if (TestBugConstants.STR_THREE.equals(bugHighDegreeChartDetailDto.getEmergency()))
                        bugHighDegreeChartDetailDto.setEmergency(TestBugConstants.STR_LOW);
                }
                //获取严重程度映射值
                if (null != bugHighDegreeChartDetailDto.getBugGrade()) {
                    if (TestBugConstants.STR_A.equals(bugHighDegreeChartDetailDto.getBugGrade()))
                        bugHighDegreeChartDetailDto.setBugGrade(TestBugConstants.BUG_STATUS_A);
                    else if (TestBugConstants.STR_B.equals(bugHighDegreeChartDetailDto.getBugGrade()))
                        bugHighDegreeChartDetailDto.setBugGrade(TestBugConstants.BUG_STATUS_B);
                    else if (TestBugConstants.STR_C.equals(bugHighDegreeChartDetailDto.getBugGrade()))
                        bugHighDegreeChartDetailDto.setBugGrade(TestBugConstants.BUG_STATUS_C);
                    else if (TestBugConstants.STR_D.equals(bugHighDegreeChartDetailDto.getBugGrade()))
                        bugHighDegreeChartDetailDto.setBugGrade(TestBugConstants.BUG_STATUS_D);
                    else if (TestBugConstants.STR_E.equals(bugHighDegreeChartDetailDto.getBugGrade()))
                        bugHighDegreeChartDetailDto.setBugGrade(TestBugConstants.BUG_STATUS_E);
                }
            });
        }
        return page;
    }

    @Override
    public CountBugDetailDto countBugAmount(String projectId) {
        return bugManagementService.countBugAmount(projectId, getBugEndStatus(projectId));
    }

    @Override
    public List<BugManagementDetailDto> pageQ(BugManagementQueryDto query) {
        return bugManagementService.pageQ(query);
    }

    @Override
    public ResultResponse getBugList(BugManageQueryDto queryByPage) {
        SystemDTO systemDTO = hzBankFeign.selectOneByMap(Long.parseLong(queryByPage.getUiProjectId()));
        if (systemDTO != null) {
            queryByPage.setUiProjectNo(systemDTO.getSysCode());
            logger.info("ProjectCode:---------------->"+systemDTO.getSysCode());
        }
        queryByPage.setAk(ak);
        cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(queryByPage);
        String doPost = HttpClientUtil.doPost(zmnUrl + TestBugConstants.PICUS_MQ_URL, jsonObject.toString());

        com.alibaba.fastjson.JSONObject parseObject = JSON.parseObject(doPost);
        ResultResponse resultResponse = parseObject.toJavaObject(ResultResponse.class);
        resultResponse.setHostStr(hostStr);
        return resultResponse;
    }

}
