package cn.cslg.pas.service;

import cn.cslg.pas.common.core.base.Constants;
import cn.cslg.pas.common.model.BaseEntity;
import cn.cslg.pas.common.model.QueryPatentVO;
import cn.cslg.pas.common.model.dto.PatentDTO;
import cn.cslg.pas.common.model.dto.PatentQueryFieldSourceDTO;
import cn.cslg.pas.common.model.dto.TaskWebSocketDTO;
import cn.cslg.pas.domain.*;
import cn.cslg.pas.common.model.vo.PatentExportVO;
import cn.cslg.pas.common.model.vo.PatentQueryFieldSourceVO;
import cn.cslg.pas.common.model.vo.PatentVO;
import cn.cslg.pas.common.model.vo.TaskParams;
import cn.cslg.pas.common.utils.*;
import cn.cslg.pas.common.model.dto.CustomFieldDTO;
import cn.cslg.pas.common.model.params.PatentCustomFieldParams;
import cn.cslg.pas.common.utils.WebSocketServer;
import cn.cslg.pas.mapper.PatentMapper;
import cn.cslg.pas.common.utils.CacheUtils;
import cn.cslg.pas.common.utils.PatentUtils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.FileOutputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 专利信息表 服务实现类
 * </p>
 *
 * @author 王岩
 * @since 2021-12-26
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class PatentService extends ServiceImpl<PatentMapper, Patent> {
    private final PatentMapper patentMapper;
    private final PatentApplicantService patentApplicantService;
    private final PatentApplicantLinkService applicantAttributeService;
    private final ProjectPatentLinkService projectPatentLinkService;
    private final CustomAnalysisItemSourceService customAnalysisItemSourceService;
    private final CacheUtils cacheUtils;
    private final DataAnalysisService dataAnalysisService;
    private final PatentAffairService patentAffairService;
    private final ProjectFieldTreeService projectFieldTreeService;
    private final ProjectFieldOptionService projectFieldOptionService;
    private final PatentLabelService patentLabelService;
    private final ProjectFieldTextService projectFieldTextService;
    private final PatentFieldService patentFieldService;
    private final ProjectFieldService projectFieldService;
    private final TaskService taskService;
    private final FileUtils fileUtils;
    private final PatentImageService patentImageService;
    private final PatentInventorService patentInventorService;
    private final PatentAgencyService patentAgencyService;
    private final PatentAgentService patentAgentService;
    private final ProjectFolderPatentLinkService projectFolderPatentLinkService;
    private final PatentApplicantMergeLinkService patentApplicantMergeLinkService;
    private final AreaService areaService;
    private final PatentClassNumberService patentClassNumberService;
    private final PatentClassNumberLinkService patentClassNumberLinkService;
    private final ProjectFieldPatentLinkService projectFieldPatentLinkService;
    private final PatentInstructionService patentInstructionService;
    private final PatentSimpleFamilyService patentSimpleFamilyService;
    private final SystemDictService systemDictService;
    private final PatentSimpleFamilyLinkService patentSimpleFamilyLinkService;
    private final PatentRightService patentRightService;
    private final PatentInstructionTextService patentInstructionTextService;
    private final PatentLicensorService patentLicensorService;
    private final PatentPledgeService patentPledgeService;
    private final PatentInventorMergeService patentInventorMergeService;

    public List<Patent> getPatentListByIds(List<Integer> ids) {
        if (ids == null || ids.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Patent::getId, ids);
        return this.list(queryWrapper);
    }

    public List<Patent> getPatentListByPatentNo(List<String> patentNo) {
        if (patentNo == null || patentNo.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Patent::getPatentNo, patentNo);
        return this.list(queryWrapper);
    }

    public Patent getByPatentNo(String patentNo) {
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Patent::getPatentNo, patentNo);
        return this.getOne(queryWrapper);
    }

    public List<Patent> getPublicDateAndPatentNoByPatentNo(List<String> patentNo) {
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Patent::getPublicDate, Patent::getPatentNo, Patent::getId, Patent::getPublicNo
                , Patent::getSimpleFamily, Patent::getInpadocFamily, Patent::getPatSnapFamily);
        queryWrapper.in(Patent::getPatentNo, patentNo);
        queryWrapper.last(" order by appdate, patentno");
        return this.list(queryWrapper);
    }

    public List<Patent> getPatentIdAndPatentNoByIds(List<Integer> ids) {
        if (ids == null || ids.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Patent::getPatentNo, Patent::getId);
        queryWrapper.in(Patent::getId, ids);
        return this.list(queryWrapper);
    }

    public Date getDateTime(String ids, Integer fieldId, String type) {
        String column = "";
        switch (fieldId) {
            case 25:
                column = "appdate";
                break;
            case 26:
                column = "publicdate";
                break;
            case 27:
                column = "publictodate";
                break;
            default:
                return new Date(baseMapper.getDateTime2(ids, fieldId, type) * 1000L);
        }
        return new Date(baseMapper.getDateTime(ids, column, type) * 1000L);
    }

    public String getPatentNumberTypeCount(Integer projectId, String id, Integer field, CustomAnalysisItemSource source) {
        QueryWrapper<Patent> queryWrapper = new QueryWrapper<>();
        List<Integer> ids = StringUtils.changeStringToInteger(id, ",");
        String column = "";
        List<String> options = Arrays.asList(">", ">=", "<", "<=");
        if (ids.size() == 0) {
            return null;
        }
        Integer mino = source.getMin().getOperator();
        Integer maxo = source.getMax().getOperator();
        Integer minv = source.getMin().getValue();
        Integer maxv = source.getMax().getValue();
        queryWrapper.lambda().in(Patent::getId, ids);
        switch (field) {
            case 32:
                column = "quoteno";
                break;
            case 33:
                column = "quotedno";
                break;
            case 34:
                column = "inpadocfamilynum";
                break;
            case 35:
                column = "simplefamilynum";
                break;
            case 55:
                column = "patsnapfamilynum";
                break;
            case 38:
                column = "num2";
                break;
            case 39:
                column = "num3";
                break;
            default:
                List<Integer> patentIds = baseMapper.getCustomFieldCount(ids, field, options.get(mino), options.get(maxo), minv, maxv);
                return StringUtils.join(patentIds.stream().distinct().collect(Collectors.toList()), ",");
        }
        if (mino.equals(0)) {
            queryWrapper.gt(column, minv);
        } else {
            queryWrapper.ge(column, minv);
        }
        if (maxo.equals(2)) {
            queryWrapper.lt(column, maxv);
        } else {
            queryWrapper.le(column, maxv);
        }
        List<Patent> patentList = this.list(queryWrapper);
        return StringUtils.join(patentList.stream().map(Patent::getId).distinct().collect(Collectors.toList()), ",");
    }

    public String getPatentDateTime2(Integer projectId, Integer field, Long startDate, Long endDate, String id) {
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        List<Integer> ids = StringUtils.changeStringToInteger(id, ",");
        if (ids.size() == 0) {
            return null;
        }
        queryWrapper.in(Patent::getId, ids);
        switch (field) {
            case 25:
                queryWrapper.between(Patent::getApplicationDate, startDate, endDate);
                break;
            case 26:
                queryWrapper.between(Patent::getPublicDate, startDate, endDate);
                break;
            case 27:
                queryWrapper.between(Patent::getPublicAccreditDate, startDate, endDate);
                break;
            default:
                List<Integer> patentIds = baseMapper.getCustomFieldTime(ids, field, startDate, endDate);
                return StringUtils.join(patentIds.stream().distinct().collect(Collectors.toList()), ",");
        }
        List<Patent> patentList = this.list(queryWrapper);
        return StringUtils.join(patentList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList()), ",");
    }

    //装载专利查询数据
    private void setQueryPatentParams(PatentVO params) {
        params.setSelfField(new ArrayList<>());
        List<String> customIds = new ArrayList<>();
        List<String> notInIds = new ArrayList<>();
        params.setCids(new ArrayList<>());
        //设置专利名sql
        if (StringUtils.isNotEmpty(params.getName())) {
            params.setNameSql(PatentUtils.formatTextQuerySql(params.getName(), "a.name"));
        }
        //设置摘要sql
        if (StringUtils.isNotEmpty(params.getAbstractStr())) {
            params.setAbstractStrSql(PatentUtils.formatTextQuerySql(params.getAbstractStr(), "a.abstract"));
        }
        //设置公开号sql
        if (StringUtils.isNotEmpty(params.getPublicNo())) {
            params.setPublicNoSql(PatentUtils.formatTextQuerySql(params.getPublicNo(), "a.publicno"));
        }
        //设置申请号sql
        if (StringUtils.isNotEmpty(params.getApplicationNo())) {
            params.setApplicationNoSql(PatentUtils.formatTextQuerySql(params.getApplicationNo(), "a.applicationno"));
        }
        //设置权要sql
        if (StringUtils.isNotEmpty(params.getRightContent())) {
            params.setRightContentSql(PatentUtils.formatTextQuerySql(params.getRightContent(), "content"));
        }
        //遍历查询字段
        for (int i = 0; i < params.getField().size(); i++) {
            List<String> queryList = params.getField().get(i).getValue();
            String key = params.getField().get(i).getKey();
            List<Integer> field = StringUtils.changeStringToInteger(key, "-");
            if (queryList.size() == 0) {
                continue;
            }
            String fieldType = params.getField().get(i).getType();
            switch (key) {
                //分类号查询筛选
                case "13":
                case "15":
                case "16":
                case "17":
                    if (field.get(0) == 13) {
                        params.setQueryClassNumberIpc(true);
                        params.setWhereClassNumberIpc(queryList);
                        params.setQueryClassNumberIpcMethod(params.getField().get(i).getClassId());
                    }
                    if (field.get(0) == 15) {
                        params.setQueryClassNumberCpc(true);
                        params.setWhereClassNumberCpc(queryList);
                        params.setQueryClassNumberCpcMethod(params.getField().get(i).getClassId());
                    }
                    if (field.get(0) == 17) {
                        params.setQueryClassNumberUpc(true);
                        params.setWhereClassNumberUpc(queryList);
                        params.setQueryClassNumberUpcMethod(params.getField().get(i).getClassId());
                    }
                    if (field.get(0) == 16) {
                        params.setQueryClassNumberLoc(true);
                        params.setWhereClassNumberLoc(queryList);
                        params.setQueryClassNumberLocMethod(params.getField().get(i).getClassId());
                    }
                    break;
                //原始申请人筛选
                case "18-6":
                    params.setQueryApplicantOriginal(true);
                    params.setWhereApplicantOriginal(queryList);
                    break;
                //当前申请人筛选
                case "19-6":
                    params.setQueryApplicantCurrent(true);
                    params.setWhereApplicantCurrent(queryList);
                    break;
                case "20-0":
                    //发明人筛选
                    params.setQueryInventor(true);
                    params.setWhereInventor(queryList);
                    break;
                //合并发明人筛选
                case "20-1":
                    params.setQueryInventor(true);
                    params.setQueryInventorMerge(true);
                    params.setWhereInventorMerge(queryList);
                    break;
                //标准原始申请人筛选
                case "18-7":
                    params.setQueryApplicantOriginalStandard(true);
                    params.setWhereApplicantOriginalStandard(queryList);
                    break;
                //标准当前申请人筛选
                case "19-7":
                    params.setQueryApplicantCurrentStandard(true);
                    params.setWhereApplicantCurrentStandard(queryList);
                    break;
                //原始申请人筛选
                case "18-8":
                    params.setQueryApplicantOriginal(true);
                    params.setQueryApplicantOriginalMerge(true);
                    params.setWhereApplicantOriginalMerge(queryList);
                    break;
                //当前申请人筛选
                case "19-8":
                    params.setQueryApplicantCurrent(true);
                    params.setQueryApplicantCurrentMerge(true);
                    params.setWhereApplicantCurrentMerge(queryList);
                    break;
                case "28-0":
                    params.setQueryBureau(true);
                    params.setWhereBureau(queryList);
                    break;
                case "37-0":
                    params.setQueryType(true);
                    params.setWhereType(queryList);
                    break;
                case "36-0":
                    params.setQueryStatus(true);
                    params.setWhereStatus(queryList);
                    break;
                case "25-12":
                    params.setQueryAppDate(true);
                    params.setWhereAppDate(queryList);
                    break;
                case "26-12":
                    params.setQueryPublicDate(true);
                    params.setWherePublicDate(queryList);
                    break;
                case "29-17":
                    params.setQueryApplicantAddress(true);
                    params.setQueryCountry(true);
                    params.setWhereCountry(queryList);
                    break;
                case "29-18":
                    params.setQueryApplicantAddress(true);
                    params.setQueryApplicantProvince(true);
                    params.setWhereApplicantProvince(queryList);
                    break;
                case "40-0":
                    params.setQueryAffair(true);
                    StringBuilder str = new StringBuilder();
                    for (String s : queryList) {
                        str.append(s).append("|");
                    }
                    params.setWhereAffair(str.substring(0, str.length() - 1));
                    break;
                case "54-0":
                    params.setQueryLabel(true);
                    params.setWhereLabel(queryList);
                    break;
                //自定义字段筛选
                default:
                    //判断值里面是否含空
                    params.getField().get(i).setIsNull(queryList.stream().anyMatch(item -> item.equals("null")));
                    params.getSelfField().add(params.getField().get(i));
                    customIds.add(String.valueOf(field.get(0)));
                    if (params.getField().get(i).getIsNull() == null || !params.getField().get(i).getIsNull()) {
                        params.getCids().add(field.get(0));
                    } else if (params.getField().get(i).getIsNull() && queryList.size() == 1) {
                        notInIds.add(String.valueOf(field.get(0)));
                    }

            }
        }
        if (customIds.size() != 0) {
            params.setCustomIds(customIds);
        }
        params.getField().forEach(item -> {
            List<String> temIds = new ArrayList<>(notInIds);
            temIds.remove(item.getKey());
            item.setNotInIds(temIds);
        });
    }

    public List<Integer> getPatentListIds(PatentVO params) {
        this.setQueryFamilyParams(params);
        params.setSelected(new ArrayList<>());
        List<Integer> ids = this.getQueryPatentIds(params);
        return ids.stream().skip(params.getStartNumber() - 1).limit(params.getEndNumber() - params.getStartNumber() + 1).collect(Collectors.toList());
    }

    private void setQueryFamilyParams(PatentVO params) {
        switch (params.getFamily()) {
            //
            case 0:
                params.setQuerySimpleFamily(false);
                params.setQueryInpadocFamily(false);
                params.setQueryPatSnapFamily(false);
                break;
            case 1:
                params.setQuerySimpleFamily(true);
                params.setQueryInpadocFamily(false);
                params.setQueryPatSnapFamily(false);
                break;
            case 2:
                params.setQuerySimpleFamily(false);
                params.setQueryInpadocFamily(true);
                params.setQueryPatSnapFamily(false);
                break;
            case 3:
                params.setQuerySimpleFamily(false);
                params.setQueryInpadocFamily(false);
                params.setQueryPatSnapFamily(true);
                break;
        }
    }

    //获得专利列表
    public IPage<PatentDTO> getPageList(PatentVO params) {
        //根据同族类型装载需要查询的同族类型
        this.setQueryFamilyParams(params);
        //装载需要查询的字段
        this.setQueryPatentParams(params);
        //根据装载信息查询专利
        IPage<Patent> dataPage = baseMapper.getPageList(new Page<>(params.getCurrent(), params.getSize()), params);
        IPage<PatentDTO> pageList = new Page<>();
        List<PatentDTO> records = new ArrayList<>();
        List<Integer> patentIds = dataPage.getRecords().stream().map(Patent::getId).collect(Collectors.toList());
        List<PatentApplicant> patentApplicantList = patentApplicantService.getPatentApplicantByPatentIds(patentIds);
        List<PatentInventor> patentInventorList = patentInventorService.getPatentInventorByPatentIds(patentIds);
        List<PatentLabel> patentLabelList = patentLabelService.getPatentLabelByPatentIdsAndProjectId(patentIds, params.getProjectId());
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(patentIds);
        List<PatentAgent> patentAgentList = patentAgentService.getPatentAgentByPatentIds(patentIds);
        List<PatentAgency> patentAgencyList = patentAgencyService.getPatentAgencyByIds(dataPage.getRecords().stream().filter(item -> StringUtils.isNotEmpty(item.getAgencyId())).map(item -> Integer.parseInt(item.getAgencyId())).distinct().collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getSimpleFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentInpadocFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getInpadocFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentPatSnapFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getPatSnapFamily).collect(Collectors.toList()));
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS));
        //获得所有的自定义字段信息
        Map<Integer, List<PatentDTO.Field>> map = projectFieldService.getPatentFieldByPatentIdAndProjectId2(params.getProjectId(), patentIds);
        dataPage.getRecords().forEach(item -> {
            PatentDTO patentDTO = new PatentDTO();
            BeanUtils.copyProperties(item, patentDTO);
            patentDTO.setApplicationDate(DateUtils.formatDate(item.getApplicationDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPriorityDate(DateUtils.formatDate(item.getPriorityDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicDate(DateUtils.formatDate(item.getPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicAccreditDate(DateUtils.formatDate(item.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setFirstPublicDate(DateUtils.formatDate(item.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(item.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(item.getType()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setApplicant(patentApplicantList.stream().filter(patentApplicant -> patentApplicant.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setInventor(patentInventorList.stream().filter(patentInventor -> patentInventor.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setLabel(patentLabelList.stream().filter(patentLabel -> patentLabel.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            if (StringUtils.isNotEmpty(item.getAgencyId())) {
                patentDTO.setAgency(patentAgencyList.stream().filter(patentAgency -> patentAgency.getId().equals(Integer.parseInt(item.getAgencyId()))).findFirst().orElse(null));
            }
            PatentDTO.PatentFamily patentFamily = new PatentDTO.PatentFamily();
            patentFamily.setSimple(patentSimpleFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getSimpleFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setInpadoc(patentInpadocFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getInpadocFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setPatSnap(patentPatSnapFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getPatSnapFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentDTO.setFamily(patentFamily);
            patentDTO.setAgent(patentAgentList.stream().filter(patentAgent -> patentAgent.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            // TODO 性能优化
            patentDTO.setField(map.get(item.getId()));
            records.add(patentDTO);
        });
        pageList.setTotal(dataPage.getTotal());
        pageList.setRecords(records);
        pageList.setPages(dataPage.getPages());
        pageList.setSize(dataPage.getSize());
        pageList.setCurrent(dataPage.getCurrent());
        return pageList;
    }

    public IPage<PatentDTO> getPageListForRMS(QueryPatentVO params) {
        if (params.getObligeeName() != null) {
            String obligeeName = params.getObligeeName().replace("(", "\\(");
            obligeeName = obligeeName.replace(")", "\\)");
            params.setObligeeName(obligeeName);
        }
        if (params.getApplicationName() != null) {
            String applicationName = params.getApplicationName().replace("(", "\\(");
            applicationName = applicationName.replace(")", "\\)");
            params.setApplicationName(applicationName);
        }
        IPage<Patent> dataPage = baseMapper.getPageListForRMS2(new Page<>(params.getCurrent(), params.getSize()), params);

        IPage<PatentDTO> pageList = new Page<>();
        List<PatentDTO> records = new ArrayList<>();
        List<Integer> patentIds = dataPage.getRecords().stream().map(Patent::getId).collect(Collectors.toList());
        List<PatentApplicant> patentApplicantList = patentApplicantService.getPatentApplicantByPatentIds(patentIds);
        List<PatentInventor> patentInventorList = patentInventorService.getPatentInventorByPatentIds(patentIds);
        List<PatentLabel> patentLabelList = patentLabelService.getPatentLabelByPatentIdsAndProjectId(patentIds, params.getProjectId());
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(patentIds);
        List<PatentAgent> patentAgentList = patentAgentService.getPatentAgentByPatentIds(patentIds);
        List<PatentAgency> patentAgencyList = patentAgencyService.getPatentAgencyByIds(dataPage.getRecords().stream().filter(item -> StringUtils.isNotEmpty(item.getAgencyId())).map(item -> Integer.parseInt(item.getAgencyId())).distinct().collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getSimpleFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentInpadocFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getInpadocFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentPatSnapFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.getRecords().stream().map(Patent::getPatSnapFamily).collect(Collectors.toList()));
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS));
        dataPage.getRecords().forEach(item -> {
            PatentDTO patentDTO = new PatentDTO();
            BeanUtils.copyProperties(item, patentDTO);
            patentDTO.setApplicationDate(DateUtils.formatDate(item.getApplicationDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPriorityDate(DateUtils.formatDate(item.getPriorityDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicDate(DateUtils.formatDate(item.getPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicAccreditDate(DateUtils.formatDate(item.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setFirstPublicDate(DateUtils.formatDate(item.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(item.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(item.getType()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setApplicant(patentApplicantList.stream().filter(patentApplicant -> patentApplicant.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setInventor(patentInventorList.stream().filter(patentInventor -> patentInventor.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setLabel(patentLabelList.stream().filter(patentLabel -> patentLabel.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setAffair(patentAffairService.getPatentAffairByPatentId(item.getId()));
            if (StringUtils.isNotEmpty(item.getAgencyId())) {
                patentDTO.setAgency(patentAgencyList.stream().filter(patentAgency -> patentAgency.getId().equals(Integer.parseInt(item.getAgencyId()))).findFirst().orElse(null));
            }
            PatentDTO.PatentFamily patentFamily = new PatentDTO.PatentFamily();
            patentFamily.setSimple(patentSimpleFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getSimpleFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setInpadoc(patentInpadocFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getInpadocFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setPatSnap(patentPatSnapFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getPatSnapFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentDTO.setFamily(patentFamily);
            patentDTO.setAgent(patentAgentList.stream().filter(patentAgent -> patentAgent.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            // TODO 性能优化
            patentDTO.setField(projectFieldService.getPatentFieldByPatentIdAndProjectId(params.getProjectId(), item.getId()));
            records.add(patentDTO);
        });
        pageList.setTotal(dataPage.getTotal());
        pageList.setRecords(records);
        pageList.setPages(dataPage.getPages());
        pageList.setSize(dataPage.getSize());
        pageList.setCurrent(dataPage.getCurrent());
        return pageList;
    }

    public List<PatentDTO> getPatentDTOListForRMS(PatentVO params) {
        List<PatentDTO> records = new ArrayList<>();
        if (params.getPatentNos() == null || params.getPatentNos().size() == 0) {
            return records;
        }
        List<Patent> dataPage = baseMapper.getPatent(params.getPatentNos(), -1, -1);

        List<Integer> patentIds = dataPage.stream().map(Patent::getId).collect(Collectors.toList());
        List<PatentApplicant> patentApplicantList = patentApplicantService.getPatentApplicantByPatentIds(patentIds);
        List<PatentInventor> patentInventorList = patentInventorService.getPatentInventorByPatentIds(patentIds);
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(patentIds);
        List<PatentAgent> patentAgentList = patentAgentService.getPatentAgentByPatentIds(patentIds);
        List<PatentAgency> patentAgencyList = patentAgencyService.getPatentAgencyByIds(dataPage.stream().filter(item -> StringUtils.isNotEmpty(item.getAgencyId())).map(item -> Integer.parseInt(item.getAgencyId())).distinct().collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.stream().map(Patent::getSimpleFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentInpadocFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.stream().map(Patent::getInpadocFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentPatSnapFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.stream().map(Patent::getPatSnapFamily).collect(Collectors.toList()));
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS));
        dataPage.forEach(item -> {
            PatentDTO patentDTO = new PatentDTO();
            BeanUtils.copyProperties(item, patentDTO);
            patentDTO.setApplicationDate(DateUtils.formatDate(item.getApplicationDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPriorityDate(DateUtils.formatDate(item.getPriorityDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicDate(DateUtils.formatDate(item.getPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicAccreditDate(DateUtils.formatDate(item.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setFirstPublicDate(DateUtils.formatDate(item.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(item.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setSimpleStatusInt(item.getSimpleStatus());
            patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(item.getType()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setApplicant(patentApplicantList.stream().filter(patentApplicant -> patentApplicant.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setInventor(patentInventorList.stream().filter(patentInventor -> patentInventor.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            if (StringUtils.isNotEmpty(item.getAgencyId())) {
                patentDTO.setAgency(patentAgencyList.stream().filter(patentAgency -> patentAgency.getId().equals(Integer.parseInt(item.getAgencyId()))).findFirst().orElse(null));
            }
            PatentDTO.PatentFamily patentFamily = new PatentDTO.PatentFamily();
            patentFamily.setSimple(patentSimpleFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getSimpleFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setInpadoc(patentInpadocFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getInpadocFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setPatSnap(patentPatSnapFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getPatSnapFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentDTO.setFamily(patentFamily);
            patentDTO.setAffair(patentAffairService.getPatentAffairByPatentId(item.getId()));
            patentDTO.setAgent(patentAgentList.stream().filter(patentAgent -> patentAgent.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            // TODO 性能优化
            records.add(patentDTO);
        });
        return records;
    }

    //查询对比文件信息
    public List<PatentDTO> getRmsComparePatent(PatentVO params) {
        List<Patent> dataPage = baseMapper.getPatent(params.getPatentNos(), -1, -1);
        List<PatentDTO> records = new ArrayList<>();
        List<Integer> patentIds = dataPage.stream().map(Patent::getId).collect(Collectors.toList());
        List<PatentApplicant> patentApplicantList = patentApplicantService.getPatentApplicantByPatentIds(patentIds);
        List<PatentInventor> patentInventorList = patentInventorService.getPatentInventorByPatentIds(patentIds);
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(patentIds);
        List<PatentAgent> patentAgentList = patentAgentService.getPatentAgentByPatentIds(patentIds);
        List<PatentAgency> patentAgencyList = patentAgencyService.getPatentAgencyByIds(dataPage.stream().filter(item -> StringUtils.isNotEmpty(item.getAgencyId())).map(item -> Integer.parseInt(item.getAgencyId())).distinct().collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.stream().map(Patent::getSimpleFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentInpadocFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.stream().map(Patent::getInpadocFamily).collect(Collectors.toList()));
        List<PatentSimpleFamilyLink> patentPatSnapFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(dataPage.stream().map(Patent::getPatSnapFamily).collect(Collectors.toList()));
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS));
        dataPage.forEach(item -> {
            PatentDTO patentDTO = new PatentDTO();
            BeanUtils.copyProperties(item, patentDTO);
            patentDTO.setApplicationDate(DateUtils.formatDate(item.getApplicationDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPriorityDate(DateUtils.formatDate(item.getPriorityDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicDate(DateUtils.formatDate(item.getPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setPublicAccreditDate(DateUtils.formatDate(item.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setFirstPublicDate(DateUtils.formatDate(item.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
            patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(item.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setSimpleStatusInt(item.getSimpleStatus());
            patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(item.getType()))).findFirst().orElse(new SystemDict()).getLabel());
            patentDTO.setApplicant(patentApplicantList.stream().filter(patentApplicant -> patentApplicant.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setInventor(patentInventorList.stream().filter(patentInventor -> patentInventor.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getPatentId().equals(item.getId()) && patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
            if (StringUtils.isNotEmpty(item.getAgencyId())) {
                patentDTO.setAgency(patentAgencyList.stream().filter(patentAgency -> patentAgency.getId().equals(Integer.parseInt(item.getAgencyId()))).findFirst().orElse(null));
            }
            PatentDTO.PatentFamily patentFamily = new PatentDTO.PatentFamily();
            patentFamily.setSimple(patentSimpleFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getSimpleFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setInpadoc(patentInpadocFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getInpadocFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentFamily.setPatSnap(patentPatSnapFamilyLinkList.stream().filter(patentSimpleFamilyLink -> patentSimpleFamilyLink.getFamilyId().equals(item.getPatSnapFamily())).map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()));
            patentDTO.setFamily(patentFamily);
            patentDTO.setAffair(patentAffairService.getPatentAffairByPatentId(item.getId()));
            patentDTO.setAgent(patentAgentList.stream().filter(patentAgent -> patentAgent.getPatentId().equals(item.getId())).collect(Collectors.toList()));
            // TODO 性能优化
            records.add(patentDTO);
        });
        return records;
    }

    // 获得对比专利号
    public String getComPantentNos(QueryPatentVO params) {
        if (params.getObligeeName() != null) {
            String obligeeName = params.getObligeeName().replace("(", "\\(");
            obligeeName = obligeeName.replace(")", "\\)");
            params.setObligeeName(obligeeName);
        }
        if (params.getApplicationName() != null) {
            String applicationName = params.getApplicationName().replace("(", "\\(");
            applicationName = applicationName.replace(")", "\\)");
            params.setApplicationName(applicationName);
        }
        List<String> patents = baseMapper.getListForRMS(params);
        return Response.success(patents);
    }

    // 获得带筛选条件的对比专利号
    public String getConPantentNos(QueryPatentVO params) {
        List<String> patents = baseMapper.getConPantentNos(params);
        return Response.success(patents);
    }

    // 获得带筛选条件的专利
    public String getConPantents(QueryPatentVO params) {
        if (params.getStartNumber() != null && params.getEndNumber() != null) {
            params.setEndNumber(params.getEndNumber() - params.getStartNumber() + 1);
        }
        List<Patent> patents = baseMapper.getConPantents(params);
        return Response.success(patents);
    }

    public PatentDTO getPatentDTOById(Integer id, Integer projectId) {
        //根据id查询专利
        Patent patent = baseMapper.selectById(id);
        PatentDTO patentDTO = new PatentDTO();
        //将patent的属性复制到patentDTO里
        BeanUtils.copyProperties(patent, patentDTO);
        //从字典表里查询字典数据
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS, Constants.COUNTRIES));
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(Collections.singletonList(id));
        if (patent.getPriorityNo() != null) {
            patentDTO.setPriorityNo(patent.getPriorityNo());
        } else {
            patentDTO.setPriorityNo("");
        }

        if (patent.getPriorityCountry() != null) {
            if (patent.getPriorityCountry().contains("\\|")) {
                List<String> countryList = StringUtils.changeStringToString(patent.getPriorityCountry().replaceAll(" ", ""), "\\|");
                patentDTO.setPriorityCountry(countryList);
            } else if (patent.getPriorityCountry().contains(",")) {
                List<String> countryList = StringUtils.changeStringToString(patent.getPriorityCountry().replaceAll(" ", ""), ",");
                patentDTO.setPriorityCountry(countryList);
            } else if (patent.getPriorityCountry().contains(";")) {
                List<String> countryList = StringUtils.changeStringToString(patent.getPriorityCountry().replaceAll(" ", ""), ";");
                patentDTO.setPriorityCountry(countryList);
            }
        } else {
            patentDTO.setPriorityCountry(Collections.singletonList(""));
        }
        patentDTO.setApplicationDate(DateUtils.formatDate(patent.getApplicationDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setPriorityDate(DateUtils.formatDate(patent.getPriorityDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setPublicDate(DateUtils.formatDate(patent.getPublicDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setPublicAccreditDate(DateUtils.formatDate(patent.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setFirstPublicDate(DateUtils.formatDate(patent.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(patent.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
        patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(patent.getType()))).findFirst().orElse(new SystemDict()).getLabel());
        patentDTO.setLabel(patentLabelService.getPatentLabelByPatentIdAndProjectId(patent.getId(), projectId));
        patentDTO.setApplicant(patentApplicantService.getPatentApplicantByPatentId(patent.getId()));
        patentDTO.setInventor(patentInventorService.getPatentInventorByPatentId(patent.getId()));
        if (StringUtils.isNotEmpty(patent.getAgencyId())) {
            patentDTO.setAgency(patentAgencyService.getPatentAgencyById(Integer.parseInt(patent.getAgencyId())));
        } else {
            PatentAgency patentAgency = new PatentAgency();
            patentAgency.setName("");
            patentDTO.setAgency(patentAgency);
        }
        patentDTO.setAgent(patentAgentService.getPatentAgentByPatentId(patent.getId()));
        patentDTO.setAffair(patentAffairService.getPatentAffairByPatentId(patent.getId()));
        if (projectId != null) {
            patentDTO.setField(projectFieldService.getPatentFieldByPatentIdAndProjectId(projectId, patent.getId()));
        }
        if (StringUtils.isNotEmpty(patent.getPriorityCountry())) {
            List<String> priorityList = PatentUtils.formatValue(patent.getPriorityCountry());
            List<String> priorityCountryList = new ArrayList<>();
            for (String priorityCountry : priorityList) {
                priorityCountryList.add(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.COUNTRIES) && systemDict.getValue().equals(priorityCountry)).findFirst().orElse(new SystemDict()).getLabel());
            }
            patentDTO.setPriorityCountry(priorityCountryList);
        }
        patentDTO.setInstruction(patentInstructionTextService.getPatentInstructionTextByPatentId(patent.getId()));
        patentDTO.setRights(patentRightService.getPatentRightByPatentId(patent.getId()));
        patentDTO.setImage(patentImageService.getPatentImageByPatentId(patent.getId()));
        patentDTO.setPdf(patentInstructionService.getPatentInstructionByPatentNo(patent.getPatentNo()));
        patentDTO.setIpc(patentClassNumberLinkList.stream().filter(patentClassNumberLink -> patentClassNumberLink.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC) && patentClassNumberLink.getMain().equals(1)).findFirst().orElse(new PatentClassNumberLink()).getCode());
        patentDTO.setUpc(patentClassNumberLinkList.stream().filter(patentClassNumberLink -> patentClassNumberLink.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC) && patentClassNumberLink.getMain().equals(1)).findFirst().orElse(new PatentClassNumberLink()).getCode());
        patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        return patentDTO;
    }

    public PatentDTO getPatentDTOById(String patentNo, Integer projectId) {
        LambdaQueryWrapper<Patent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Patent::getPatentNo, patentNo);
        List<Patent> patents = this.list(wrapper);
        PatentDTO patentDTO = new PatentDTO();
        //如果未查出专利则返回为空
        if (patents == null || patents.size() == 0) {
            return patentDTO;
        }
        Patent patent = patents.get(0);


        BeanUtils.copyProperties(patent, patentDTO);
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.PATENT_TYPE, Constants.PATENT_SIMPLE_STATUS, Constants.COUNTRIES));
        List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(Collections.singletonList(patent.getId()));

        if (patent.getPriorityNo() != null) {
            patentDTO.setPriorityNo(patent.getPriorityNo());
        } else {
            patentDTO.setPriorityNo("");
        }

        if (patent.getPriorityCountry() != null) {
            if (patent.getPriorityCountry().contains("\\|")) {
                List<String> countryList = StringUtils.changeStringToString(patent.getPriorityCountry().replaceAll(" ", ""), "\\|");
                patentDTO.setPriorityCountry(countryList);
            } else if (patent.getPriorityCountry().contains(",")) {
                List<String> countryList = StringUtils.changeStringToString(patent.getPriorityCountry().replaceAll(" ", ""), ",");
                patentDTO.setPriorityCountry(countryList);
            } else if (patent.getPriorityCountry().contains(";")) {
                List<String> countryList = StringUtils.changeStringToString(patent.getPriorityCountry().replaceAll(" ", ""), ";");
                patentDTO.setPriorityCountry(countryList);
            }
        } else {
            patentDTO.setPriorityCountry(Collections.singletonList(""));
        }

        patentDTO.setQuote("");
        if (patent.getQuote() != null) {
            patentDTO.setQuote(patent.getQuote());
        }
        patentDTO.setQuoted("");
        if (patent.getQuoted() != null) {
            patentDTO.setQuoted(patent.getQuoted());
        }
        //根据同族号，获得所有同族专利（三种同族）
        List<Integer> familyIds = new ArrayList<>();
        if (patent.getSimpleFamily() != null) {
            familyIds.add(patent.getSimpleFamily());
        }
        if (patent.getInpadocFamily() != null) {

            familyIds.add(patent.getInpadocFamily());
        }
        if (patent.getPatSnapFamily() != null) {
            familyIds.add(patent.getPatSnapFamily());
        }
        if (familyIds.size() != 0) {
            LambdaQueryWrapper<PatentSimpleFamilyLink> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(PatentSimpleFamilyLink::getFamilyId, familyIds);
            List<PatentSimpleFamilyLink> patentSimpleFamilyLinks = patentSimpleFamilyLinkService.list(queryWrapper);
            List<String> familyPatentNos = patentSimpleFamilyLinks.stream().map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList());
            PatentDTO.PatentFamily patentFamily = new PatentDTO.PatentFamily();
            patentFamily.setSimple(familyPatentNos);
            patentDTO.setFamily(patentFamily);
        }
        patentDTO.setApplicationDate(DateUtils.formatDate(patent.getApplicationDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setPriorityDate(DateUtils.formatDate(patent.getPriorityDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setPublicDate(DateUtils.formatDate(patent.getPublicDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setPublicAccreditDate(DateUtils.formatDate(patent.getPublicAccreditDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setFirstPublicDate(DateUtils.formatDate(patent.getFirstPublicDate(), DateUtils.YYYY_MM_DD));
        patentDTO.setSimpleStatus(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getValue().equals(String.valueOf(patent.getSimpleStatus()))).findFirst().orElse(new SystemDict()).getLabel());
        patentDTO.setSimpleStatusInt(patent.getSimpleStatus());
        patentDTO.setType(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.PATENT_TYPE) && systemDict.getValue().equals(String.valueOf(patent.getType()))).findFirst().orElse(new SystemDict()).getLabel());
        patentDTO.setApplicant(patentApplicantService.getPatentApplicantByPatentId(patent.getId()));
        patentDTO.setInventor(patentInventorService.getPatentInventorByPatentId(patent.getId()));
        if (projectId != null) {
            patentDTO.setLabel(patentLabelService.getPatentLabelByPatentIdAndProjectId(patent.getId(), projectId));
        }
        if (StringUtils.isNotEmpty(patent.getAgencyId())) {
            patentDTO.setAgency(patentAgencyService.getPatentAgencyById(Integer.parseInt(patent.getAgencyId())));
        } else {
            PatentAgency patentAgency = new PatentAgency();
            patentAgency.setName("");
            patentDTO.setAgency(patentAgency);
        }
        patentDTO.setAgent(patentAgentService.getPatentAgentByPatentId(patent.getId()));
        patentDTO.setAffair(patentAffairService.getPatentAffairByPatentId(patent.getId()));
        if (StringUtils.isNotEmpty(patent.getPriorityCountry())) {
            List<String> priorityList = PatentUtils.formatValue(patent.getPriorityCountry());
            List<String> priorityCountryList = new ArrayList<>();
            for (String priorityCountry : priorityList) {
                priorityCountryList.add(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.COUNTRIES) && systemDict.getValue().equals(priorityCountry)).findFirst().orElse(new SystemDict()).getLabel());
            }
            patentDTO.setPriorityCountry(priorityCountryList);
        }
        patentDTO.setInstruction(patentInstructionTextService.getPatentInstructionTextByPatentId(patent.getId()));
        patentDTO.setRights(patentRightService.getPatentRightByPatentId(patent.getId()));
        patentDTO.setImage(patentImageService.getPatentImageByPatentId(patent.getId()));
        patentDTO.setPdf(patentInstructionService.getPatentInstructionByPatentNo(patent.getPatentNo()));
        patentDTO.setIpc(patentClassNumberLinkList.stream().filter(patentClassNumberLink -> patentClassNumberLink.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC) && patentClassNumberLink.getMain().equals(1)).findFirst().orElse(new PatentClassNumberLink()).getCode());
        patentDTO.setUpc(patentClassNumberLinkList.stream().filter(patentClassNumberLink -> patentClassNumberLink.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC) && patentClassNumberLink.getMain().equals(1)).findFirst().orElse(new PatentClassNumberLink()).getCode());
        patentDTO.setIpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_IPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        patentDTO.setCpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_CPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        patentDTO.setUpcList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_UPC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        patentDTO.setLocList(patentClassNumberLinkList.stream().filter(patentClassNumber -> patentClassNumber.getType().equals(Constants.PATENT_CLASS_NUMBER_LOC)).map(PatentClassNumberLink::getCode).distinct().collect(Collectors.toList()));
        return patentDTO;
    }


    public List<Integer> getQueryPatentIds(PatentVO params) {
        if (params.getSelected() != null && params.getSelected().size() != 0 && params.getSelectId() != null && params.getSelectId()) {
            return params.getSelected().stream().distinct().collect(Collectors.toList());
        }
        this.setQueryPatentParams(params);
        List<Patent> patentList = baseMapper.getPageList(params);
        return patentList.stream().map(Patent::getId).distinct().collect(Collectors.toList());
    }

    @Async
    public void exportPatent(TaskParams taskParams) {
        try {
            List<PatentExportVO> selected = JsonUtils.jsonToList(taskParams.getSelected(), PatentExportVO.class);
            List<Integer> ids = StringUtils.changeStringToInteger(taskParams.getIds(), ",");
            if (selected != null) {
                List<String> columns = selected.stream().filter(PatentExportVO::getSelected).map(PatentExportVO::getKey).distinct().collect(Collectors.toList());
                List<String> headers = selected.stream().filter(PatentExportVO::getSelected).map(PatentExportVO::getName).distinct().collect(Collectors.toList());
                String fileName = IdUtil.simpleUUID() + ".xls";
                String directoryName = fileUtils.createDirectory();
                String savePath = fileUtils.getSavePath(directoryName);
                HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
                HSSFSheet sheet = hssfWorkbook.createSheet();
                sheet.setDefaultColumnWidth(30);
                HSSFRow headerRow = sheet.createRow(0);
                headerRow.setHeight((short) 500);
                HSSFCellStyle headerCellStyle = hssfWorkbook.createCellStyle();
                HSSFCellStyle commonCellStyle = hssfWorkbook.createCellStyle();
                for (int i = 0; i < headers.size(); i++) {
                    HSSFCell cell = headerRow.createCell(i);
                    ExcelUtils.setExcelCellStyle(headerCellStyle);
                    headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
                    headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                    headerCellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.SKY_BLUE.getIndex());
                    headerCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                    headerCellStyle.setWrapText(true);
                    cell.setCellStyle(headerCellStyle);
                    cell.setCellValue(headers.get(i));
                }
                for (int i = 0; i < ids.size(); i++) {
                    Map<String, Object> map = new LinkedHashMap<>();
                    PatentDTO patent = this.getPatentDTOById(ids.get(i), taskParams.getProjectId());
                    if (patent == null) {
                        continue;
                    }
                    String country = PatentUtils.getPatentCountry(patent.getPatentNo());
                    for (int j = 0; j < columns.size(); j++) {
                        String column = columns.get(j);
                        PatentExportVO patentExportVO = selected.stream().filter(item -> item.getKey().equals(column)).findFirst().orElse(new PatentExportVO());
                        Object value = null;
                        switch (column) {
                            case "pname":
                                value = patent.getName();
                                break;
                            case "pname_out":
                                value = patent.getNameOut();
                                break;
                            case "patentno":
                                value = patent.getPatentNo();
                                break;
                            case "abstract":
                                value = patent.getAbstractStr();
                                break;
                            case "abstract_out":
                                value = patent.getAbstractOut();
                                break;
                            case "abstract_path":
                                break;
                            case "applicationno":
                                value = patent.getApplicationNo();
                                break;
                            case "appdate":
                                value = patent.getApplicationDate();
                                break;
                            case "publicno":
                                value = patent.getPublicNo();
                                break;
                            case "publicdate":
                                value = patent.getPublicDate();
                                break;
                            case "fpublicdate":
                                value = patent.getFirstPublicDate();
                                break;
                            case "publictono":
                                value = patent.getPublicAccreditNo();
                                break;
                            case "publictodate":
                                value = patent.getPublicAccreditDate();
                                break;
                            case "tags":
                                value = StringUtils.join(patent.getLabel().stream().map(PatentLabel::getName).distinct().collect(Collectors.toList()), "\n");
                                break;
                            case "bureau":
                                value = patent.getBureau();
                                break;
                            case "simplefamily":
                                List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(Collections.singletonList(patent.getSimpleFamily()));
                                value = StringUtils.join(patentSimpleFamilyLinkList.stream().map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "inpadocfamily":
                                List<PatentSimpleFamilyLink> patentInpadocFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(Collections.singletonList(patent.getInpadocFamily()));
                                value = StringUtils.join(patentInpadocFamilyLinkList.stream().map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "patsnapfamily":
                                List<PatentSimpleFamilyLink> patentPatSnapFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(Collections.singletonList(patent.getPatSnapFamily()));
                                value = StringUtils.join(patentPatSnapFamilyLinkList.stream().map(PatentSimpleFamilyLink::getPatentNo).collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "ipc":
                                value = StringUtils.join(patent.getIpcList(), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "upc":
                                value = StringUtils.join(patent.getUpcList(), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "intclassno":
                                value = patent.getIpc();
                                break;
                            case "intclasscpcno":
                                value = StringUtils.join(patent.getCpcList(), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "intclassupcno":
                                value = patent.getUpc();
                                break;
                            case "intclasslocno":
                                value = StringUtils.join(patent.getLocList(), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "pstatus":
                                value = patent.getSimpleStatus();
                                break;
                            case "ptype":
                                value = patent.getType();
                                break;
                            case "law_datetime":
                                value = PatentUtils.getPatentAffair(patent.getAffair(), 0);
                                break;
                            case "law_status":
                                value = PatentUtils.getPatentAffair(patent.getAffair(), 1);
                                break;
                            case "law_simplestatus":
                                value = PatentUtils.getPatentAffair(patent.getAffair(), 2);
                                break;
                            case "law_content":
                                value = PatentUtils.getPatentAffair(patent.getAffair(), 3);
                                break;
                            case "applicant":
                                value = StringUtils.join(patent.getApplicant().stream().filter(item -> item.getDataType().equals(2)).collect(Collectors.toList()).stream().map(PatentApplicant::getName).distinct().collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "applicant1":
                                value = StringUtils.join(patent.getApplicant().stream().filter(item -> item.getDataType().equals(2)).collect(Collectors.toList()).stream().map(PatentApplicant::getShortName).distinct().collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "rightholder":
                                value = StringUtils.join(patent.getApplicant().stream().filter(item -> item.getDataType().equals(1)).collect(Collectors.toList()).stream().map(PatentApplicant::getName).distinct().collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "rightholder1":
                                value = StringUtils.join(patent.getApplicant().stream().filter(item -> item.getDataType().equals(1)).collect(Collectors.toList()).stream().map(PatentApplicant::getShortName).distinct().collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "applicantcountry":
                                value = PatentUtils.getPeopleCountry(patent.getApplicant().stream().filter(item -> item.getDataType().equals(2)).collect(Collectors.toList()));
                                break;
                            case "rightholdercountry":
                                value = PatentUtils.getPeopleCountry(patent.getApplicant().stream().filter(item -> item.getDataType().equals(1)).collect(Collectors.toList()));
                                break;
                            case "applicantaddress":
                                value = PatentUtils.getPeopleAddress(patent.getApplicant().stream().filter(item -> item.getDataType().equals(2)).collect(Collectors.toList()));
                                break;
                            case "rightholderaddress":
                                value = PatentUtils.getPeopleAddress(patent.getApplicant().stream().filter(item -> item.getDataType().equals(1)).collect(Collectors.toList()));
                                break;
                            case "applicantaddr":
                                break;
                            case "rightholderaddr":
                                break;
                            case "firstapplicant":
                                PatentApplicant firstApplicant1 = patent.getApplicant().stream().filter(item -> item.getDataType().equals(2) && item.getOrder().equals(0)).findFirst().orElse(null);
                                if (firstApplicant1 != null) {
                                    value = firstApplicant1.getName();
                                }
                                break;
                            case "firstrightholder":
                                PatentApplicant firstApplicant3 = patent.getApplicant().stream().filter(item -> item.getDataType().equals(1) && item.getOrder().equals(0)).findFirst().orElse(null);
                                if (firstApplicant3 != null) {
                                    value = firstApplicant3.getName();
                                }
                                break;
                            case "firstapplicantaddr":
                                PatentApplicant firstApplicant2 = patent.getApplicant().stream().filter(item -> item.getDataType().equals(2) && item.getOrder().equals(0)).findFirst().orElse(null);
                                if (firstApplicant2 != null) {
                                    value = firstApplicant2.getAddressStr();
                                }
                                break;
                            case "firstrightholderaddr":
                                PatentApplicant firstApplicant4 = patent.getApplicant().stream().filter(item -> item.getDataType().equals(1) && item.getOrder().equals(0)).findFirst().orElse(null);
                                if (firstApplicant4 != null) {
                                    value = firstApplicant4.getAddressStr();
                                }
                                break;
                            case "firstapplicantnum":
                                value = patent.getApplicantNum();
                                break;
                            case "inventor":
                                value = StringUtils.join(patent.getInventor().stream().map(PatentInventor::getName).distinct().collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "firstnventoraddr":
                                value = patent.getInventor().stream().filter(PatentInventor::getFirst).findFirst().orElse(new PatentInventor()).getAddress();
                                break;
                            case "firstnventor":
                                value = patent.getInventor().stream().filter(PatentInventor::getFirst).findFirst().orElse(new PatentInventor()).getName();
                                break;
                            case "inventornum":
                                value = patent.getInventorNum();
                                break;
                            case "num2":
                                value = patent.getRightNum();
                                break;
                            case "content":
                            case "content_out":
                            case "selfcontent":
                                List<String> content = new ArrayList<>();
                                if (column.equals("content")) {
                                    content = patent.getRights().stream().map(PatentRight::getContent).collect(Collectors.toList());
                                }
                                if (column.equals("content_out")) {
                                    content = patent.getRights().stream().map(PatentRight::getContentOut).collect(Collectors.toList());
                                }
                                if (column.equals("selfcontent")) {
                                    content = patent.getRights().stream().filter(item -> item.getType().equals(1)).map(PatentRight::getContent).collect(Collectors.toList());
                                }
                                StringBuffer contentBuffer = new StringBuffer();
                                for (String s : content) {
                                    contentBuffer.append(s);
                                    switch (country) {
                                        case "JP":
                                        case "CN":
                                            contentBuffer.append("。\n");
                                            break;
                                        default:
                                            contentBuffer.append("\n");
                                    }
                                }
                                value = contentBuffer.toString();
                                break;
                            case "priorityno":
                                value = patent.getPriorityNo();
                                break;
                            case "prioritycountry":
                                value = patent.getPriorityCountry();
                                break;
                            case "prioritydate":
                                value = patent.getPriorityDate();
                                break;
                            case "page":
                                value = patent.getDocPage();
                                break;
                            case "code":
                                value = patent.getCode();
                                break;
                            case "manual":
                                if (patent.getInstruction() != null) {
                                    value = patent.getInstruction().getManual();
                                }
                                break;
                            case "simplefamilynum":
                                value = patent.getSimpleFamilyNum();
                                break;
                            case "inpadocfamilynum":
                                value = patent.getInpadocFamilyNum();
                                break;
                            case "patsnapfamilynum":
                                value = patent.getPatSnapFamilyNum();
                                break;
                            case "quoteno":
                                value = patent.getQuoteNum();
                                break;
                            case "quotedno":
                                value = patent.getQuotedNum();
                                break;
                            case "quotedno3":
                                value = patent.getQuotedNum3();
                                break;
                            case "quotedno5":
                                value = patent.getQuotedNum5();
                                break;
                            case "agency":
                                PatentAgency agency = patent.getAgency();
                                if (agency != null) {
                                    value = agency.getName();
                                }
                                break;
                            case "agent":
                                value = StringUtils.join(patent.getAgent().stream().map(PatentAgent::getName).distinct().collect(Collectors.toList()), Constants.SEPARATOR_VERTICAL_BAR);
                                break;
                            case "wonational":
                                value = patent.getWo();
                                break;
                            case "examiner":
                                value = patent.getExaminer();
                                break;
                            case "assexaminer":
                                value = patent.getAidExaminer();
                                break;
                            case "quote":
                                value = patent.getQuote();
                                break;
                            case "quoted":
                                value = patent.getQuoted();
                                break;
                            case "nonpatentquote":
                                value = patent.getNotPatentQuote();
                                break;
                            case "epcountry":
                                value = patent.getEpStatus();
                                break;
                            default:
                                PatentDTO.Field field = patent.getField().stream().filter(item -> item.getId().equals(Integer.parseInt(column))).findFirst().orElse(null);
                                if (field != null) {
                                    value = StringUtils.join(field.getSelected(), "\n");
                                }
                        }
                        map.put(patentExportVO.getName(), value);
                    }
                    HSSFRow row = sheet.createRow(i + 1);
                    row.setHeight((short) 800);
                    for (String key : map.keySet()) {
                        int index = headers.indexOf(key);
                        if (index != -1) {
                            HSSFCell cell = row.createCell(index);
                            ExcelUtils.setExcelCellStyle(commonCellStyle);
                            commonCellStyle.setVerticalAlignment(VerticalAlignment.TOP);
                            commonCellStyle.setWrapText(true);
                            cell.setCellStyle(commonCellStyle);
                            if (key.equals("摘要附图")) {
                                if (StringUtils.isNotEmpty(patent.getAbstractPath())) {
                                    try {
                                        byte[] pictureData = FileUtil.readBytes(fileUtils.getSystemPath(patent.getAbstractPath()));
                                        if (pictureData != null) {
                                            ExcelUtils.writePicture(sheet, index, i + 1, pictureData, HSSFWorkbook.PICTURE_TYPE_JPEG);
                                        }
                                        row.setHeight((short) 2500);
                                    } catch (Exception e) {

                                    }
                                }
                            } else if (StringUtils.isNotNull(map.get(key))) {
                                cell.setCellValue(String.valueOf(map.get(key)));
                            }
                        }
                    }
                    Integer total = ids.size();
                    WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                            .setTaskId(taskParams.getTaskId())
                            .setProjectId(taskParams.getProjectId())
                            .setComplete(false)
                            .setIndex(i)
                            .setTaskType(Constants.TASK_EXPORT_PATENT)
                            .setPercentage(total == 0 ? 0 : Math.round((total.equals(i) ? (i * 1D) : (i + 1D)) / total * 100D))
                            .setFileName("")
                            .setOldName("")
                            .setUrl("")
                            .setTotal(total), ResponseEnum.PATENT_EXPORT_TASK_SUCCESS), taskParams.getUserId());
                }
                FileOutputStream fos = new FileOutputStream(savePath + fileName);
                hssfWorkbook.write(fos);
                fos.flush();
                fos.close();
                String url = fileUtils.getDirectory(fileName);
                taskService.updateTime(taskParams.getTaskId(), 2, DateUtils.getDateTime(), url, fileName);
                WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                        .setTaskId(taskParams.getTaskId())
                        .setProjectId(taskParams.getProjectId())
                        .setComplete(true)
                        .setIndex(ids.size())
                        .setTaskType(Constants.TASK_EXPORT_PATENT)
                        .setPercentage(100L)
                        .setFileName(fileName)
                        .setOldName("")
                        .setUrl(url)
                        .setTotal(ids.size()), ResponseEnum.PATENT_EXPORT_TASK_SUCCESS), taskParams.getUserId());
            }
        } catch (Exception e) {
            e.printStackTrace();
            taskService.updateTime(taskParams.getTaskId(), 3, DateUtils.getDateTime(), null, null);
            WebSocketServer.sendInfo(Response.error(ResponseEnum.PATENT_EXPORT_TASK_ERROR), taskParams.getUserId());
        }
    }

    public IPage<PatentQueryFieldSourceDTO> getPatentQuerySourcePageList(PatentQueryFieldSourceVO params) {
        return this.getPatentAttributeSourcePageList(params);
    }

    public IPage<PatentQueryFieldSourceDTO> getPatentAttributeSourcePageList(PatentQueryFieldSourceVO params) {
        this.setPatentQuerySourceParams(params);
        if (params.getKey().equals("40-0")) {
            Integer projectId = params.getProjectId();
            List<PatentQueryFieldSourceDTO> dataList = baseMapper.getCountStatus(projectId);
            List<PatentQueryFieldSourceDTO> lstA = new ArrayList<>();
            List<PatentQueryFieldSourceDTO> lstB = new ArrayList<>();
            dataList.forEach(item -> {
                if (StringUtils.changeStringToString(item.getLabel(), "\\|").size() > 1) {
                    lstA.add(item);
                } else {
                    lstB.add(item);
                }
            });
            lstA.forEach(item -> {
                List<String> stringList = StringUtils.changeStringToString(item.getLabel(), "\\|");

                stringList.forEach(x -> {
                    List<PatentQueryFieldSourceDTO> lstC = new ArrayList<>();
                    for (PatentQueryFieldSourceDTO patentQueryFieldSourceDTO : lstB) {
                        if (!lstB.stream().map(PatentQueryFieldSourceDTO::getLabel).collect(Collectors.toList()).contains(x)) {
                            PatentQueryFieldSourceDTO a = new PatentQueryFieldSourceDTO();
                            a.setCount(item.getCount());
                            a.setLabel(x);
                            lstC.add(a);
                            break;
                        }
                        if (patentQueryFieldSourceDTO.getLabel().equals(x)) {
                            patentQueryFieldSourceDTO.setCount(patentQueryFieldSourceDTO.getCount() + item.getCount());
                        }
                    }
                    lstB.addAll(lstC);
                });
            });
            List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.PATENT_STATUS));
            lstB.forEach(b -> {
                Integer status = Integer.parseInt(systemDictList.stream()
                        .filter(systemDict -> systemDict.getType().equals(Constants.PATENT_STATUS) && systemDict.getLabel().equals(b.getLabel()))
                        .findFirst()
                        .orElse(new SystemDict()).getValue());
                b.setValue(String.valueOf(status));
            });
            IPage<PatentQueryFieldSourceDTO> pageList = baseMapper.getPatentQuerySourcePageList(new Page<>(params.getCurrent(), params.getSize()), params, new ArrayList<>());
            pageList.setRecords(lstB);
            return pageList;
        }
        IPage<PatentQueryFieldSourceDTO> pageList = baseMapper.getPatentQuerySourcePageList(new Page<>(params.getCurrent(), params.getSize()), params, new ArrayList<>());
        pageList.getRecords().forEach(item -> item.setIds(null));
        return pageList;
    }

    public List<PatentQueryFieldSourceDTO> getPatentAttributeSourceList(PatentQueryFieldSourceVO params, List<Integer> patentIds) {
        this.setPatentQuerySourceParams(params);
        List<PatentQueryFieldSourceDTO> dataList = baseMapper.getPatentQuerySourcePageList(params, patentIds);
        return dataList;
    }

    private void setPatentQuerySourceParams(PatentQueryFieldSourceVO params) {
        List<Integer> field = StringUtils.changeStringToInteger(params.getKey(), "-");
        Integer type = 0;
        Integer level = 0;
        Integer status = 0;
        switch (params.getKey()) {
            case "18-6":
            case "18-7":
            case "18-8":
            case "23-6":
            case "23-7":
            case "23-8":
                params.setApplicantType(2);
                break;
            case "19-6":
            case "19-7":
            case "19-8":
            case "24-6":
            case "24-7":
            case "24-8":
                params.setApplicantType(1);
                break;
            case "29-17":
            case "30-17":
            case "29-18":
            case "29-19":
            case "29-20":
            case "30-18":
            case "30-19":
            case "30-20":
                params.setApplicantType(field.get(0) == 29 ? 2 : 1);
                break;
            default:
                params.setCustomFieldId(field.get(0));
                if (params.getType().equals("6") && field.get(1).equals(0)) {
                    params.setCustomFieldTreeType(0);
                } else {
                    params.setCustomFieldTreeType(null);
                }
        }
    }

    public void updatePatentCustomField(PatentCustomFieldParams params) {
        List<CustomFieldDTO> dataList = new ArrayList<>();
        for (String key : params.keySet()) {
            List<String> fields = StringUtils.changeStringToString(key, ":");
            if (fields.size() == 2) {
                Object name = fields.get(0);
                Object selected = params.get(key);
                List<String> select = JsonUtils.jsonToList(JsonUtils.objectToJson(selected), String.class);
                if (StringUtils.isNull(select)) {
                    select = new ArrayList<>();
                }
                CustomFieldDTO data = new CustomFieldDTO();
                data.setName(name.toString());
                data.setSelected(select);
                data.setType(Integer.parseInt(fields.get(1)));
                dataList.add(data);
            }
        }
        for (CustomFieldDTO data : dataList) {
            ProjectField projectField = projectFieldService.getProjectFieldByNameAndType(data.getName(), data.getType(), params.getProjectId(), params.getUserId());
            projectFieldPatentLinkService.deleteByPatentIdAndProjectIdAndFieldId(params.getPatentId(), params.getProjectId(), projectField.getId());
            switch (projectField.getType()) {
                case 0:
                case 1:
                case 2:
                    for (String text : data.getSelected()) {
                        ProjectFieldText projectFieldText = projectFieldTextService.getProjectFieldTextByNameAndFieldId(text, projectField.getId());
                        if (projectFieldText == null) {
                            projectFieldText = new ProjectFieldText();
                            projectFieldText.setFieldId(projectField.getId());
                            projectFieldText.setText(text);
                            projectFieldText.insert();
                        }
                        projectFieldPatentLinkService.updateProjectPatentLink(params.getPatentId(), projectField.getType(), projectField.getId(), projectFieldText.getId(), params.getUserId(), params.getProjectId());
                    }
                    break;
                case 3:
                case 4:
                case 5:
                    for (String option : data.getSelected()) {
                        ProjectFieldOption projectFieldOption = projectFieldOptionService.getProjectFieldOptionByNameAndFieldId(option, projectField.getId());
                        if (projectFieldOption == null) {
                            projectFieldOption = new ProjectFieldOption();
                            projectFieldOption.setFieldId(projectField.getId());
                            projectFieldOption.setName(option);
                            projectFieldOption.insert();
                        }
                        projectFieldPatentLinkService.updateProjectPatentLink(params.getPatentId(), projectField.getType(), projectField.getId(), projectFieldOption.getId(), params.getUserId(), params.getProjectId());
                    }
                    break;
                case 6:
                    for (String tree : data.getSelected()) {
                        List<String> treeNode = StringUtils.changeStringToString(tree, "\\\\");
                        Integer treeNodeId = projectFieldTreeService.getTreeNodeIdByPathNameAndUpdateTreeData(treeNode, projectField);
                        if (treeNodeId != 0) {
                            projectFieldPatentLinkService.updateProjectPatentLink(params.getPatentId(), projectField.getType(), projectField.getId(), treeNodeId, params.getUserId(), params.getProjectId());
                        }
                    }
                    break;
            }
        }
    }

    public Map<String, Object> getBetweenPatentList(PatentVO params) {
        this.setQueryPatentParams(params);
        List<Patent> patentList = baseMapper.getPageList(params);
        int index = patentList.stream().map(Patent::getId).collect(Collectors.toList()).indexOf(params.getPatentId());
        Map<String, Object> map = new HashMap<>();
        if (index > 0) {
            Patent patent = patentList.get(index - 1);
            Map<String, Object> prev = new HashMap<>();
            prev.put("id", patent.getId());
            prev.put("patentNo", patent.getPatentNo());
            prev.put("total", index);
            map.put("prev", prev);
        }
        if (index < patentList.size() - 1) {
            Patent patent = patentList.get(index + 1);
            Map<String, Object> next = new HashMap<>();
            next.put("id", patent.getId());
            next.put("patentNo", patent.getPatentNo());
            next.put("total", patentList.size() - index - 1);
            map.put("next", next);
        }
        return map;
    }

    public void importPatent(Integer projectId, String patentJson, String patentAffairJson, String patentAgencyJson, String patentFamilyJson, String patentFamilyLinkJson, String patentInventorJson, String patentInventorLinkJson, String patentAgentJson, String patentAgentLinkJson, String patentApplicantJson, String patentApplicantLinkJson, String patentApplicantMergeLinkJson, String patentClassNumberJson, String patentInstructionTextJson, String patentRightJson, String patentLicensorJson, String patentPledgeJson, String patentInventorMergeJson) {
        List<Patent> importPatentList = JsonUtils.jsonToList(patentJson, Patent.class);
        List<PatentAffair> importPatentAffairList = JsonUtils.jsonToList(patentAffairJson, PatentAffair.class);
        List<PatentAgency> importPatentAgencyList = JsonUtils.jsonToList(patentAgencyJson, PatentAgency.class);
        List<PatentAgent> importPatentAgentList = JsonUtils.jsonToList(patentAgentJson, PatentAgent.class);
        List<PatentAgentLink> importPatentAgentLinkList = JsonUtils.jsonToList(patentAgentLinkJson, PatentAgentLink.class);
        List<PatentInventor> importPatentInventorList = JsonUtils.jsonToList(patentInventorJson, PatentInventor.class);
        List<PatentInventorMerge> importPatentInventorMergeList = JsonUtils.jsonToList(patentInventorMergeJson, PatentInventorMerge.class);
        List<PatentInventorLink> importPatentInventorLinkList = JsonUtils.jsonToList(patentInventorLinkJson, PatentInventorLink.class);
        List<PatentApplicant> importPatentApplicantList = JsonUtils.jsonToList(patentApplicantJson, PatentApplicant.class);
        List<PatentApplicantLink> importPatentApplicantLinkList = JsonUtils.jsonToList(patentApplicantLinkJson, PatentApplicantLink.class);
        List<PatentApplicantMergeLink> importPatentApplicantMergeLinkList = JsonUtils.jsonToList(patentApplicantMergeLinkJson, PatentApplicantMergeLink.class);
        List<PatentSimpleFamily> importPatentSimpleFamilyList = JsonUtils.jsonToList(patentFamilyJson, PatentSimpleFamily.class);
        List<PatentSimpleFamilyLink> importPatentSimpleFamilyLinkList = JsonUtils.jsonToList(patentFamilyLinkJson, PatentSimpleFamilyLink.class);
        List<PatentClassNumberLink> importPatentClassNumberLinkList = JsonUtils.jsonToList(patentClassNumberJson, PatentClassNumberLink.class);
        List<PatentInstructionText> importPatentInstructionTextList = JsonUtils.jsonToList(patentInstructionTextJson, PatentInstructionText.class);
        List<PatentRight> importPatentRightList = JsonUtils.jsonToList(patentRightJson, PatentRight.class);
        List<PatentLicensor> importPatentLicensorList = JsonUtils.jsonToList(patentLicensorJson, PatentLicensor.class);
        List<PatentPledge> importPatentPledgeList = JsonUtils.jsonToList(patentPledgeJson, PatentPledge.class);
        List<Patent> localPatentList = this.getPatentListByPatentNo(importPatentList.stream().map(Patent::getPatentNo).collect(Collectors.toList()));
        List<Patent> patentList = new ArrayList<>();
        for (Patent importPatent : importPatentList) {
            Patent localPatent = localPatentList.stream().filter(item -> item.getPatentNo().equals(importPatent.getPatentNo())).findFirst().orElse(null);
            Integer patentId;
            if (localPatent == null) {
                localPatent = new Patent();
                patentId = null;
            } else {
                patentId = localPatent.getId();
            }
            BeanUtils.copyProperties(importPatent, localPatent);
            localPatent.setId(patentId);
            if (StringUtils.isNotEmpty(importPatent.getAgencyId())) {
                PatentAgency importPatentAgency = importPatentAgencyList.stream().filter(item -> item.getId().equals(Integer.valueOf(importPatent.getAgencyId()))).findFirst().orElse(new PatentAgency());
                localPatent.setAgencyId(patentAgencyService.getAgencyStringIdByName(importPatentAgency.getName()));
            }
            localPatent.insertOrUpdate();
            patentList.add(localPatent);
        }
        for (Patent patent : patentList) {
            Patent importPatent = importPatentList.stream().filter(item -> item.getPatentNo().equals(patent.getPatentNo())).findFirst().orElse(new Patent());
            patentAffairService.importPatentAffair(patent, importPatentList, importPatentAffairList);
            patentAgentService.importPatentAgent(patent.getId(), importPatent.getId(), importPatentAgentList, importPatentAgentLinkList);
            patentSimpleFamilyService.importPatentSimpleFamily(patent, importPatentSimpleFamilyList, importPatentSimpleFamilyLinkList);
            patentInventorService.importPatentInventor(patent.getId(), importPatent.getId(), importPatentInventorList, importPatentInventorLinkList);
            patentApplicantService.importPatentApplicant(projectId, patent.getId(), importPatent.getId(), importPatentApplicantList, importPatentApplicantLinkList);
            patentClassNumberLinkService.importPatentClassNumberLink(patent.getId(), importPatent.getId(), importPatentClassNumberLinkList);
            patentInstructionTextService.importPatentInstructionText(patent.getId(), importPatent.getId(), importPatentInstructionTextList);
            patentRightService.importPatentRight(patent.getId(), importPatent.getId(), importPatentRightList);
            patentLicensorService.importPatentLicensor(patent.getId(), importPatent.getId(), importPatentLicensorList);
            patentPledgeService.importPatentPledge(patent.getId(), importPatent.getId(), importPatentPledgeList);
        }
        patentInventorMergeService.importPatentInventorMergeLink(projectId, importPatentInventorList, importPatentInventorMergeList);
        patentApplicantMergeLinkService.importPatentApplicantMergeLink(projectId, importPatentApplicantList, importPatentApplicantMergeLinkList);
    }

    public String getPatentNos(Integer projectId) {
        //根据专题库号获得专利id
        LambdaQueryWrapper<ProjectPatentLink> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(ProjectPatentLink::getPatentId).eq(ProjectPatentLink::getProjectId, projectId);
        List<ProjectPatentLink> projectPatentLinkList = projectPatentLinkService.list(wrapper);
        List<Integer> patentIds = projectPatentLinkList.stream().map(ProjectPatentLink::getPatentId).collect(Collectors.toList());
        //根据专利Id获得专利号
        LambdaQueryWrapper<Patent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Patent::getId, patentIds);
        List<Patent> patents = this.list(queryWrapper);
        List<String> patentNos = patents.stream().map(Patent::getPatentNo).collect(Collectors.toList());

        return Response.success(patentNos);
    }

    public String getPagination(List<String> list, int location) {
        Map map = new HashMap();
        LambdaQueryWrapper<Patent> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Patent::getPatentNo, list);
        Integer totalNumber = Math.toIntExact(this.count(wrapper));
        if (location >= totalNumber) {
            location = totalNumber;
            int a = location - 2;
            int b = 2;
            List<Patent> patent = patentMapper.getPatent(list, a, b);
            int front = location - 1;
            String str1 = patent.get(0).getPatentNo();
            String srr2 = patent.get(1).getPatentNo();
            int i = patent.get(0).getId();
            int j = patent.get(1).getId();
            map.put("frontID", i);
            map.put("currentID", j);
            map.put("behindPatentNo", null);
            map.put("frontNumber", front);
            map.put("behindNumber", 0);
            map.put("frontPatentNo", str1);
            map.put("currentPatentNo", srr2);
            map.put("totalNumber", totalNumber);
            return Response.success(map);

        }
        if (location == 1) {
            int a = 0;
            int p = 2;
            List<Patent> patent = patentMapper.getPatent(list, a, p);
            String str1 = patent.get(0).getPatentNo();
            String srr2 = patent.get(1).getPatentNo();
            int i = patent.get(0).getId();
            int j = patent.get(1).getId();
            map.put("currentID", i);
            map.put("behindID", j);
            map.put("currentPatentNo", str1);
            map.put("behindPatentNo", srr2);
            map.put("frontPatentNo", null);

            map.put("frontNumber", 0);
            int behindNumber = totalNumber - location;
            map.put("behindNumber", behindNumber);
            map.put("totalNumber", totalNumber);
            return Response.success(map);

        }

        int a = location - 2;
        int p = 3;
        List<Patent> patent = patentMapper.getPatent(list, a, p);
        String str1 = patent.get(0).getPatentNo();
        String str2 = patent.get(1).getPatentNo();
        String str3 = patent.get(2).getPatentNo();
        int i = patent.get(0).getId();
        int j = patent.get(1).getId();
        int k = patent.get(2).getId();
        map.put("frontID", i);
        map.put("currentID", j);
        map.put("behindID", k);
        map.put("frontPatentNo", str1);
        map.put("currentPatentNo", str2);
        map.put("behindPatentNo", str3);
        map.put("totalNumber", totalNumber);
        int behindNumber = totalNumber - location;
        int frontNumber = location - 1;
        map.put("behindNumber", behindNumber);
        map.put("frontNumber", frontNumber);
        return Response.success(map);
    }


}
