package cn.cslg.pas.service;

import cn.cslg.pas.common.core.base.Constants;
import cn.cslg.pas.common.model.PatentCell;
import cn.cslg.pas.common.model.dto.TaskWebSocketDTO;
import cn.cslg.pas.common.model.params.*;
import cn.cslg.pas.common.model.vo.ProjectImportPatentVO;
import cn.cslg.pas.common.model.vo.TaskParams;
import cn.cslg.pas.common.model.vo.UploadParamsVO;
import cn.cslg.pas.common.model.vo.UploadSettingVO;
import cn.cslg.pas.common.utils.*;
import cn.cslg.pas.domain.*;
import cn.cslg.pas.mapper.ImportErrorLogMapper;
import cn.cslg.pas.mapper.WebTaskMapper;
import cn.cslg.pas.service.asso.AssoProductPatentService;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.PictureData;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class UploadPatentBatchService {
    private final FileUtils fileUtils;
    private final SystemDictService systemDictService;
    private final PatentImageService patentImageService;
    private final PatentService patentService;
    private final PatentAgencyService patentAgencyService;
    private final PatentInstructionTextService patentInstructionTextService;
    private final PatentRightService patentRightService;
    private final PatentAgentService patentAgentService;
    private final PatentPledgeService patentPledgeService;
    private final PatentLicensorService patentLicensorService;
    private final PatentSimpleFamilyService patentSimpleFamilyService;
    private final PatentInventorService patentInventorService;
    private final ProjectPatentLinkService projectPatentLinkService;
    private final ProjectFieldPatentLinkService projectFieldPatentLinkService;
    private final ProjectFolderPatentLinkService projectFolderPatentLinkService;
    private final PatentApplicantLinkService patentApplicantLinkService;
    private final PatentApplicantService patentApplicantService;
    private final PatentLabelService patentLabelService;
    private final PatentClassNumberLinkService patentClassNumberLinkService;
    private final PatentAffairService patentAffairService;
    private final ImportErrorLogMapper importErrorLogMapper;
    private final AssoProductPatentService assoProductPatentService;
    private final PatentInstructionService patentInstructionService;
    private static int FLAG = 0;

    @Async("singleThreadAsyncTaskExecutor")
    public void uploadPatentBatch(TaskParams params, ProjectImportPatentVO projectImportPatentVO) {
        //获得专利总数量
        Integer total = params.getRowList().size();
        try {
            //拿到存放在服务器的专利数据来源配置文件uploadSetting.json并按行读取文件字符流，返回整个文件字符串
            String getSettingJson = fileUtils.analysisJsonFile();
            //查找并装载本次导入的专利需要的数据源（如智慧芽）的对应配置（如前台传来的数据来源id是1，即“智慧芽”，那么jsonData装载的就是智慧芽的数据源配置）
            List<UploadSettingVO.Column> jsonData = UploadPatentBatchUtil.parsingConfigurationFiles(projectImportPatentVO, getSettingJson);

            //装载所有专利的摘要附图（key：专利行数  value：专利行数对应的专利的摘要附图图片数据）
            Map<String, PictureData> pictureDataMap = ExcelUtils.getDataFromExcel(params.getPath());
            //遍历所有专利（专利总数量），将数据进行装配并进行数据库操作
            for (int i = 0; i < params.getRowList().size(); i++) {
                //获取每一行的数据
                Map<Object, Object> row = params.getRowList().get(i);
                //专利基础数据装配（此步与数据源配置文件对象相关）
                UploadParamsVO uploadParamsVO = UploadPatentBatchUtil.processData(row, jsonData);
                //专利基础数据入库（专利表"os_patent"）：专利基础数据根据UploadParamsVO中patent对象装载的专利号patentNo查询专利表“os_patent”，如果存在就将表中专利的Id装载到patent的id属性上，如果不存在就先将该专利数据入表后再装载Id
                getOneOrInsertOne(uploadParamsVO);

                //摘要附图数据装配及入库（摘要附图表"os_patent_img"）
                PictureData pictureData = pictureDataMap.get(String.valueOf(i + 1));
                if (uploadParamsVO.getPatent() != null) {
                    if (uploadParamsVO.getPatent().getId() != null && pictureData != null) {
                        uploadParamsVO.getPatent().setAbstractPath(patentImageService.updatePatentImage(uploadParamsVO.getPatent().getId(), pictureData));
                    }
                }
                //代理机构数据装配及入库（代理机构表"os_patent_agency"）
                if (uploadParamsVO.getPatent() != null) {
                    if (uploadParamsVO.getPatent().getAgencyId() != null) {
                        uploadParamsVO.getPatent().setAgencyId(patentAgencyService.getAgencyStringIdByName(uploadParamsVO.getPatent().getAgencyId()));
                    }

                }

                //将装配对象中的数据保存到数据库
                dataToDB(params, uploadParamsVO, projectImportPatentVO);

                //通过WebSocket 在每一次循环结束后 向前端发送完成进度
                WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                        .setTaskId(params.getTaskId())
                        .setProjectId(projectImportPatentVO.getProjectId())
                        .setComplete(false)
                        .setIndex(i)
                        .setTaskType(Constants.TASK_IMPORT_PATENT)
                        .setPercentage(total == 0 ? 0 : Math.round((total.equals(i) ? (i * 1D) : (i + 1D)) / total * 100D))
                        .setFileName("")
                        .setOldName(params.getOldName())
                        .setUrl("")
                        .setTotal(total), ResponseEnum.PATENT_IMPORT_TASK_SUCCESS), params.getUserId());
            }

            SpringUtil.getBean(ProjectService.class).setImportPatentTaskStatus(2, params.getTaskId());
            WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                    .setTaskId(params.getTaskId())
                    .setProjectId(projectImportPatentVO.getProjectId())
                    .setComplete(true)
                    .setIndex(total)
                    .setTaskType(Constants.TASK_IMPORT_PATENT)
                    .setPercentage(100L)
                    .setFileName("")
                    .setOldName(params.getOldName())
                    .setUrl("")
                    .setTotal(total), ResponseEnum.PATENT_IMPORT_TASK_SUCCESS), params.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            SpringUtil.getBean(ProjectService.class).setImportPatentTaskStatus(3, params.getTaskId());
            if (FLAG > 0) {
                int successCount = total - FLAG;
                WebSocketServer.sendInfo(Response.error("部分数据上传成功" + "\n" + "成功条数:" + successCount + "失败条数:" + FLAG), params.getUserId());
            }
            FLAG = 0;
        }
    }

    /**
     * @return uploadParamsVO 返回一个由processData方法填充完数据的Pojo类
     * @date 2022/7/7
     * @name 解析配置文件
     * @description uploadPatentBatch的兄弟方法
     */
//    @Async("singleThreadAsyncTaskExecutor")
    public String uploadPatentBatchBro(TaskParams params) {
        Integer total = params.getTotal();
        Integer index = params.getIndex();
        try {
            //先解析Json文件 获得配置文件的Json串
            String getSettingJson = fileUtils.analysisJsonFile();
            //查找需求数据源的对应配置
            List<UploadSettingVO.Column> jsonData = UploadPatentBatchUtil.parsingConfigurationFilesBro(getSettingJson);
            Map<String, PictureData> pictureDataMap = ExcelUtils.getDataFromExcel(params.getPath());
            //将数据进行装配并进行数据库操作
            //获取每一行的数据
            Map<Object, Object> row = params.getRowList().get(0);
            //基础数据装配
            UploadParamsVO uploadParamsVO = UploadPatentBatchUtil.processData(row, jsonData);
            //查询数据是否存在 如果存在 返回该条数据 如果不存在 新增一条数据
            getOneOrInsertOne(uploadParamsVO);
            //专利信息需要特殊处理部分
            //专利信息(摘要附图)数据装配
            PictureData pictureData = pictureDataMap.get(String.valueOf(index + 1));
            if (uploadParamsVO.getPatent() != null) {
                if (uploadParamsVO.getPatent().getId() != null && pictureData != null) {
                    uploadParamsVO.getPatent().setAbstractPath(patentImageService.updatePatentImage(uploadParamsVO.getPatent().getId(), pictureData));
                }
            }
            //专利信息(代理机构)数据装配
            if (uploadParamsVO.getPatent() != null) {
                if (uploadParamsVO.getPatent().getAgencyId() != null) {
                    uploadParamsVO.getPatent().setAgencyId(patentAgencyService.getAgencyStringIdByName(uploadParamsVO.getPatent().getAgencyId()));
                }

            }
            //将装配对象中的数据保存到数据库
            dataToDBBro(params, uploadParamsVO);
            ImportTaskPatent importTaskPatent = new ImportTaskPatent();
            importTaskPatent.setImportTaskId(params.getTaskId());
            importTaskPatent.setPatentNo(uploadParamsVO.getPatent().getPatentNo());
            importTaskPatent.insert();
            //通过WebSocket 在每一次循环结束后 向前端发送完成进度
            WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                    .setTaskId(params.getTaskId())
                    .setComplete(false)
                    .setIndex(0)
                    .setTaskType(Constants.TASK_IMPORT_PATENT)
                    .setPercentage(total == 0 ? 0 : Math.round((total.equals(index) ? (index * 1D) : (index + 1D)) / total * 100D))
                    .setFileName("")
                    .setOldName(params.getOldName())
                    .setUrl("")
                    .setTotal(total), ResponseEnum.PATENT_IMPORT_TASK_SUCCESS), params.getUserId());

            return Response.success(uploadParamsVO.getPatent().getPatentNo());
        } catch (Exception e) {

            return Response.error();
        }
    }


    /**
     * @param uploadParamsVO 全局类
     * @date 2022-7-11
     * @name 数据库交互
     * @description 将装配完毕的VO类向数据库中不同的表进行添加或修改操作
     */
    @Transactional(rollbackFor = Exception.class)
    public void dataToDB(TaskParams params, UploadParamsVO uploadParamsVO, ProjectImportPatentVO projectImportPatentVO) {
        try {
            //保存法律状态（表"os_patent"）
            if (uploadParamsVO.getPatent() != null) {
                List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.PATENT_SIMPLE_STATUS));
                Integer simpleStatus = Integer.parseInt(systemDictList.stream()
                        .filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getLabel().equals(uploadParamsVO.getPatentSimpleStatus()))
                        .findFirst()
                        .orElse(new SystemDict()).getValue());
                uploadParamsVO.getPatent().setSimpleStatus(simpleStatus);
                uploadParamsVO.getPatent().updateById();
            }

            //保存权利要求（表"os_patent_right"）
            patentRightBusiness(uploadParamsVO);

            //保存说明书（表"os_patent_instruction_text"）
            if (uploadParamsVO.getPatentInstructionText() != null) {
                patentInstructionTextBusiness(uploadParamsVO);
            }

            //保存代理人（表"os_patent_agent"、表"os_patent_agent_link"）
            if (uploadParamsVO.getPatentAgentList() != null) {
                patentAgentBusiness(uploadParamsVO);
            }

            //保存简单同族（表""）
            patentSimplyFamilyBusiness(uploadParamsVO);

            //保存质押质权人（表"os_patent_pledge"）
            if (uploadParamsVO.getPatentPledgeList() != null) {
                patentPledgeBusiness(uploadParamsVO);
            }

            //保存许可人（表"os_patent_licensor"）
            if (uploadParamsVO.getPatentLicensorList() != null) {
                patentLicensorBusiness(uploadParamsVO);
            }

            //保存发明人（表"os_patent_inventor"、表"os_patent_inventor_relation"）
            patentInventorBusiness(uploadParamsVO);

            //保存申请人(原始)/权利人(当前)（表"os_patent_applicant"、表"os_applicant_attr"）
            patentApplicationBusiness(uploadParamsVO);

            //保存申请人地址（表""）
            patentApplicationAddressBusiness(uploadParamsVO);

            //保存专题库关联专利信息（表"os_thematic_pid"）
            if (uploadParamsVO.getPatent() != null) {
                patentThematicPidBusiness(uploadParamsVO, projectImportPatentVO.getProjectId());
            }

            //保存标引内容关联专利信息（表"os_patent_field_patent_link"、"os_patent_field_text"）
            if (uploadParamsVO.getPatent() != null) {
                patentProjectFieldPatentLinkBusiness(uploadParamsVO, projectImportPatentVO);
            }

            //保存文件夹关联专利信息（表"os_portfolio_link"）
            if (uploadParamsVO.getPatent() != null) {
                patentProjectFolderPatentLinkBusiness(uploadParamsVO, projectImportPatentVO);
            }

            //保存标签（表"os_patent_label"）
            if (uploadParamsVO.getPatentLabelList() != null) {
                patentLabelBusiness(uploadParamsVO, projectImportPatentVO);
            }

            //保存分类号关联（表"os_patent_typeno"）
            patentTypeNoBusiness(uploadParamsVO);

            //保存事务信息（表"os_patent_affair"）
            patentAffairBusiness(uploadParamsVO);

            //保存自定义字段
            if (uploadParamsVO.getCustomerFieldList() != null) {
                patentFieldBusiness(params, uploadParamsVO, projectImportPatentVO);
            }

        } catch (Exception e) {
            e.printStackTrace();
            if (uploadParamsVO.getPatent() != null) {
                ImportErrorLog importErrorLog = new ImportErrorLog();
                importErrorLog.setPatentId(uploadParamsVO.getPatent().getId())
                        .setPatentNo(uploadParamsVO.getPatent().getPatentNo())
                        .setCreateTime(new SimpleDateFormat("yyyy-MM-dd 24HI:mm:ss").format(new Date()))
                        .setCreateUserId(Integer.parseInt(params.getUserId()))
                        .setMistakeMessage(e.getMessage())
                        .setProjectId(params.getProjectId());
                importErrorLogMapper.insert(importErrorLog);
                FLAG += 1;
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


    /**
     * @param uploadParamsVO 全局类
     * @date 2022-7-11
     * @name 数据库交互
     * @description 将装配完毕的VO类向数据库中不同的表进行添加或修改操作(dataToDB兄弟类)
     */
    @Transactional(rollbackFor = Exception.class)
    public void dataToDBBro(TaskParams params, UploadParamsVO uploadParamsVO) {
        try {
            //专利信息 OS_PATENT
            if (uploadParamsVO.getPatent() != null) {
                List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.PATENT_SIMPLE_STATUS));
                Integer simpleStatus = Integer.parseInt(systemDictList.stream()
                        .filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getLabel().equals(uploadParamsVO.getPatentSimpleStatus()))
                        .findFirst()
                        .orElse(new SystemDict()).getValue());
                uploadParamsVO.getPatent().setSimpleStatus(simpleStatus);
                uploadParamsVO.getPatent().updateById();
            }
            //权利要求 OS_PATENT_RIGHT
            patentRightBusiness(uploadParamsVO);
            //说明书(文本) OS_PATENT_INSTRUCTION_TEXT
            if (uploadParamsVO.getPatentInstructionText() != null) {
                patentInstructionTextBusiness(uploadParamsVO);
            }
            //代理人 OS_PATENT_AGENT
            if (uploadParamsVO.getPatentAgentList() != null) {
                patentAgentBusiness(uploadParamsVO);
            }
            //质押质权人 OS_PATENT_PLEDGE
            if (uploadParamsVO.getPatentPledgeList() != null) {
                patentPledgeBusiness(uploadParamsVO);
            }
            //许可人 OS_PATENT_LICENSOR
            if (uploadParamsVO.getPatentLicensorList() != null) {
                patentLicensorBusiness(uploadParamsVO);
            }
            //简单同族 OS_PATENT_SIMPLEFAMILY
            patentSimplyFamilyBusiness(uploadParamsVO);
            //发明人 OS_PATENT_INVENTOR
            patentInventorBusiness(uploadParamsVO);
            //申请人(原始)/权利人(当前) OS_PATENT_APPLICATION || OS_APPLICATION_ATTR
            patentApplicationBusiness(uploadParamsVO);
            //申请人地址 OS_PATENT_APPLICATION
            patentApplicationAddressBusiness(uploadParamsVO);
            //分类号关联 OS_PATENT_TYPENO
            patentTypeNoBusiness(uploadParamsVO);
            //事务信息 OS_PATENT_AFFAIR
            patentAffairBusiness(uploadParamsVO);
        } catch (Exception e) {
            e.printStackTrace();
            if (uploadParamsVO.getPatent() != null) {
                ImportErrorLog importErrorLog = new ImportErrorLog();
                importErrorLog.setPatentId(uploadParamsVO.getPatent().getId())
                        .setPatentNo(uploadParamsVO.getPatent().getPatentNo())
                        .setCreateTime(new SimpleDateFormat("yyyy-MM-dd 24HI:mm:ss").format(new Date()))
                        .setCreateUserId(Integer.parseInt(params.getUserId()))
                        .setMistakeMessage(e.getMessage())
                        .setProjectId(params.getProjectId());
                importErrorLogMapper.insert(importErrorLog);
                FLAG += 1;
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * @param uploadParamsVO 全局类
     * @date 2022-7-11
     * @name 工具方法
     * @description 查询数据是否存在 如果存在 返回该条数据 如果不存在 新增一条数据
     */
    public void getOneOrInsertOne(UploadParamsVO uploadParamsVO) {
        if (uploadParamsVO.getPatent() != null) {
            uploadParamsVO.getPatent().setPatentNo(uploadParamsVO.getPatent().getPatentNo().trim());
            //用专利号查询该条数据是否存在
            Patent patent = patentService.getByPatentNo(uploadParamsVO.getPatent().getPatentNo());
            //如果不存在就新增一条
            if (patent == null) {
                uploadParamsVO.getPatent().insert();
            } else {
                uploadParamsVO.getPatent().setId(patent.getId());
            }
        }
    }

    //权利要求
    public void patentRightBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentRightParams对象保存权要基本信息
        PatentRightParams patentRightParams = new PatentRightParams();
        //装载专利id
        patentRightParams.setPatentId(uploadParamsVO.getPatent().getId());
        //装载专利号
        patentRightParams.setPatentNo(uploadParamsVO.getPatent().getPatentNo());
        if (uploadParamsVO.getPatentRight() != null) {
            //装载权利要求原文
            patentRightParams.setContent(uploadParamsVO.getPatentRight().getContent());
            //装载权利要求译文
            patentRightParams.setContentOut(uploadParamsVO.getPatentRight().getContentOut());
        }
        if (uploadParamsVO.getSelfContent() != null) {
            //装载独立权要
            patentRightParams.setSelfContent(uploadParamsVO.getSelfContent());
        }
        //开始保存权要入库(1.格式化权要 2.理出主次权要父子关系 3.权要入表"os_patent_right")
        patentRightService.updatePatentRight(patentRightParams);
        //暂未使用
        patentRightService.importAuthority(patentRightParams);
    }

    //说明书文本
    public void patentInstructionTextBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentInstructionTextParams对象装载说明书相关数据
        PatentInstructionTextParams patentInstructionTextParams = new PatentInstructionTextParams();
        //装载专利id
        patentInstructionTextParams.setPatentId(uploadParamsVO.getPatent().getId());
        //装载说明书
        patentInstructionTextParams.setManual(uploadParamsVO.getPatentInstructionText().getManual());
        //装载说明书（译）
        patentInstructionTextParams.setManualOut(uploadParamsVO.getPatentInstructionText().getManualOut());

        //开始保存说明书入表“os_patent_instruction_text”
        patentInstructionTextService.updatePatentInstructionText(patentInstructionTextParams);
    }

    //代理人
    public void patentAgentBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentAgentParams对象装载代理人相关数据
        PatentAgentParams patentAgentParams = new PatentAgentParams();
        //装载专利id
        patentAgentParams.setPatentId(uploadParamsVO.getPatent().getId());
        List<String> agentList = uploadParamsVO.getPatentAgentList().stream().map(PatentAgent::getName).collect(Collectors.toList());
        //装载代理人集合
        patentAgentParams.setAgent(agentList);
        //开始保存代理人信息入表“os_patent_agent”
        patentAgentService.updatePatentAgent(patentAgentParams);
    }

    //质押质权人
    public void patentPledgeBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentPledgeParams对象装载质押质权人相关数据
        PatentPledgeParams patentPledgeParams = new PatentPledgeParams();
        //装载专利id
        patentPledgeParams.setPatentId(uploadParamsVO.getPatent().getId());
        List<String> pledgeeList = uploadParamsVO.getPatentPledgeList().stream().map(PatentPledge::getPledgee).collect(Collectors.toList());
        List<String> pledgorList = uploadParamsVO.getPatentPledgeList().stream().map(PatentPledge::getPledgor).collect(Collectors.toList());
        //装载质权人集合
        patentPledgeParams.setPledgee(pledgeeList);
        //装载质押人集合
        patentPledgeParams.setPledgor(pledgorList);
        //开始保存质押质权人信息入表“os_patent_pledge”
        patentPledgeService.updatePatentPledge(patentPledgeParams);
    }


    //许可人
    public void patentLicensorBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentLicensorParams对象装载许可人相关数据
        PatentLicensorParams patentLicensorParams = new PatentLicensorParams();
        //装载专利id
        patentLicensorParams.setPatentId(uploadParamsVO.getPatent().getId());
        List<String> licensorList = uploadParamsVO.getPatentLicensorList().stream().map(PatentLicensor::getLicensor).collect(Collectors.toList());
        List<String> licenseeList = uploadParamsVO.getPatentLicensorList().stream().map(PatentLicensor::getLicensee).collect(Collectors.toList());
        List<String> typeList = uploadParamsVO.getPatentLicensorList().stream().map(PatentLicensor::getType).collect(Collectors.toList());
        //装载许可人
        patentLicensorParams.setLicensor(licensorList);
        //装载被许可人
        patentLicensorParams.setLicensee(licenseeList);
        //装载许可类型
        patentLicensorParams.setType(typeList);
        //开始保存许可人相关信息入专利信息许可人表“os_patent_licensor”
        patentLicensorService.updatePatentLicensor(patentLicensorParams);
    }


    //简单同族
    public void patentSimplyFamilyBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentSimpleFamilyParams对象装载简单同族相关数据
        PatentSimpleFamilyParams patentSimpleFamilyParams = new PatentSimpleFamilyParams();
        if (uploadParamsVO.getSimpleFamily() != null) {
            //装载简单同族
            patentSimpleFamilyParams.setSimpleFamily(uploadParamsVO.getSimpleFamily());
        }
        if (uploadParamsVO.getPatSnapFamily() != null) {
            //装载PatSnap同族
            patentSimpleFamilyParams.setPatSnapFamily(uploadParamsVO.getPatSnapFamily());
        }
        if (uploadParamsVO.getInpadocFamily() != null) {
            //装载Inpadoc同族
            patentSimpleFamilyParams.setInpadocFamily(uploadParamsVO.getInpadocFamily());
        }
        //装载专利id
        patentSimpleFamilyParams.setPatentId(uploadParamsVO.getPatent().getId());
        //装载专利号
        patentSimpleFamilyParams.setPatentNo(uploadParamsVO.getPatent().getPatentNo());
        //开始
        patentSimpleFamilyService.updatePatentSimpleFamily(patentSimpleFamilyParams);
    }

    //发明人
    public void patentInventorBusiness(UploadParamsVO uploadParamsVO) {
        //创建PatentInventorParams对象装载发明人相关数据
        PatentInventorParams patentInventorParams = new PatentInventorParams();
        if (uploadParamsVO.getPatentInventorList() != null) {
            List<String> addressList = uploadParamsVO.getPatentInventorList().stream().map(PatentInventor::getAddress).filter(Objects::nonNull).collect(Collectors.toList());
            //装载发明人地址集合
            patentInventorParams.setAddressList(addressList);
            List<String> nameList = uploadParamsVO.getPatentInventorList().stream().map(PatentInventor::getName).collect(Collectors.toList());
            //装载发明人名称集合
            patentInventorParams.setNameList(nameList);
        }
        if (uploadParamsVO.getFirstName() != null) {
            //装载第一发明人名称
            patentInventorParams.setFirstName(uploadParamsVO.getFirstName());
        }
        if (uploadParamsVO.getFirstAddress() != null) {
            //装载第一发明人地址
            patentInventorParams.setFirstAddress(uploadParamsVO.getFirstAddress());
        }
        //装载专利号
        patentInventorParams.setPatentId(uploadParamsVO.getPatent().getId());
        //开始装载发明人表实体类相关信息、专利与发明人关联表实体类集合相关信息，然后各自数据分别插入这两张表
        patentInventorService.updatePatentInventor(patentInventorParams);
    }

    //申请人(原始)/权利人(当前)
    public void patentApplicationBusiness(UploadParamsVO uploadParamsVO) {
        // 根据本条数据的名字查询所有的申请人信息
        List<String> name = new ArrayList<>();
        if (uploadParamsVO.getPatentApplicantCurrentName() != null) {
            name.addAll(uploadParamsVO.getPatentApplicantCurrentName());
        }
        if (uploadParamsVO.getPatentApplicantOriginalName() != null) {
            name.addAll(uploadParamsVO.getPatentApplicantOriginalName());
        }
        if (uploadParamsVO.getPatentApplicantStandardCurrentName() != null) {
            name.addAll(uploadParamsVO.getPatentApplicantStandardCurrentName());
        }
        if (uploadParamsVO.getPatentApplicantStandardOriginalName() != null) {
            name.addAll(uploadParamsVO.getPatentApplicantStandardOriginalName());
        }
        if (name.size() != 0) {
            List<PatentApplicant> patentApplicantList = patentApplicantService.list(Wrappers.<PatentApplicant>lambdaQuery().in(PatentApplicant::getName, name));
            //权利人
            if (uploadParamsVO.getPatentApplicantCurrentName() != null || uploadParamsVO.getPatentApplicantStandardCurrentName() != null)
                patentApplicantLinkService.updatePatentApplicantLink(uploadParamsVO.getPatentApplicantCurrentName(), uploadParamsVO.getPatentApplicantStandardCurrentName(), 1, uploadParamsVO.getPatent().getId(), patentApplicantList);
            //申请人
            if (uploadParamsVO.getPatentApplicantOriginalName() != null || uploadParamsVO.getPatentApplicantStandardOriginalName() != null)
                patentApplicantLinkService.updatePatentApplicantLink(uploadParamsVO.getPatentApplicantOriginalName(), uploadParamsVO.getPatentApplicantStandardOriginalName(), 2, uploadParamsVO.getPatent().getId(), patentApplicantList);
        }
    }

    public void patentApplicationAddressBusiness(UploadParamsVO uploadParamsVO) {
        PatentApplicantAddressParams patentApplicantAddressParams = new PatentApplicantAddressParams();
        patentApplicantAddressParams.setPatentId(uploadParamsVO.getPatent().getId());
        patentApplicantAddressParams.setCurrentAddress(uploadParamsVO.getPatentApplicantCurrentAddress());
        patentApplicantAddressParams.setOriginalAddress(uploadParamsVO.getPatentApplicantOriginalAddress());
        patentApplicantAddressParams.setCurrentCountry(uploadParamsVO.getPatentApplicantCurrentCountry());
        patentApplicantAddressParams.setOriginalCountry(uploadParamsVO.getPatentApplicantOriginalCountry());
        patentApplicantAddressParams.setFirstCurrentAddress(uploadParamsVO.getFirstAddress());
        patentApplicantService.updatePatentApplicantAddress(patentApplicantAddressParams);
    }

    public void patentThematicPidBusiness(UploadParamsVO uploadParamsVO, Integer projectId) {
        projectPatentLinkService.updateProjectPatent(projectId, uploadParamsVO.getPatent().getId());
    }

    public void patentProjectFieldPatentLinkBusiness(UploadParamsVO uploadParamsVO, ProjectImportPatentVO projectImportPatentVO) {
        projectFieldPatentLinkService.updateProjectFieldPatentLink(projectImportPatentVO, uploadParamsVO.getPatent().getId());
    }

    public void patentProjectFolderPatentLinkBusiness(UploadParamsVO uploadParamsVO, ProjectImportPatentVO projectImportPatentVO) {
        projectFolderPatentLinkService.updateProjectFolderLink(projectImportPatentVO, uploadParamsVO.getPatent().getId());
    }

    private void patentLabelBusiness(UploadParamsVO uploadParamsVO, ProjectImportPatentVO projectImportPatentVO) {
        PatentLabelParams patentLabelParams = new PatentLabelParams();
        patentLabelParams.setPatentId(uploadParamsVO.getPatent().getId());
        patentLabelParams.setProjectId(projectImportPatentVO.getProjectId());
        List<String> labelList = uploadParamsVO.getPatentLabelList().stream().map(PatentLabel::getName).collect(Collectors.toList());
        patentLabelParams.setLabel(labelList);

        patentLabelService.updatePatentLabel(patentLabelParams);
    }

    public void patentTypeNoBusiness(UploadParamsVO uploadParamsVO) {
        PatentClassNumberParams patentClassNumberParams = new PatentClassNumberParams();
        if (uploadParamsVO.getMainIpc() != null) {
            patentClassNumberParams.setMainIpc(uploadParamsVO.getMainIpc());
        }
        if (uploadParamsVO.getMainUpc() != null) {
            patentClassNumberParams.setMainUpc(uploadParamsVO.getMainUpc());
        }
        if (uploadParamsVO.getCpcList() != null) {
            patentClassNumberParams.setCpcList(uploadParamsVO.getCpcList());
        }
        if (uploadParamsVO.getLocList() != null) {
            patentClassNumberParams.setLocList(uploadParamsVO.getLocList());
        }
        if (uploadParamsVO.getUpcList() != null) {
            patentClassNumberParams.setUpcList(uploadParamsVO.getUpcList());
        }
        if (uploadParamsVO.getIpcList() != null) {
            patentClassNumberParams.setIpcList(uploadParamsVO.getIpcList());
        }
        patentClassNumberParams.setPatentId(uploadParamsVO.getPatent().getId());

        patentClassNumberLinkService.updatePatentClassNumberLink(patentClassNumberParams);
    }

    public void patentAffairBusiness(UploadParamsVO uploadParamsVO) {
        PatentAffairParams patentAffairParams = new PatentAffairParams();
        if (uploadParamsVO.getPatentAffair() != null) {
            patentAffairParams.setContent(uploadParamsVO.getPatentAffair().getContent());
            patentAffairParams.setStatusList(uploadParamsVO.getPatentAffair().getStatus());
            patentAffairParams.setDateTime(uploadParamsVO.getPatentAffair().getDateTime());
        }
        if (uploadParamsVO.getSimpleStatus() != null) {
            List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.PATENT_SIMPLE_STATUS));
            Integer simpleStatus = Integer.parseInt(systemDictList.stream()
                    .filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getLabel().equals(uploadParamsVO.getSimpleStatus()))
                    .findFirst()
                    .orElse(new SystemDict()).getValue());
            patentAffairParams.setSimpleStatus(simpleStatus);
        }
        patentAffairParams.setPatentId(uploadParamsVO.getPatent().getId());
        patentAffairService.updatePatientAffair(patentAffairParams);
    }

    private void patentFieldBusiness(TaskParams params, UploadParamsVO uploadParamsVO, ProjectImportPatentVO projectImportPatentVO) {
        PatentCustomFieldParams patentCustomFieldParams = new PatentCustomFieldParams();
        for (int i = 0; i < uploadParamsVO.getCustomerFieldList().size(); i++) {
            patentCustomFieldParams.setPatentId(uploadParamsVO.getPatent().getId());
            patentCustomFieldParams.setProjectId(projectImportPatentVO.getProjectId());
            patentCustomFieldParams.setUserId(Integer.parseInt(params.getUserId()));
            patentCustomFieldParams.put(uploadParamsVO.getCustomerFieldList().get(i).getKey(), uploadParamsVO.getCustomerFieldList().get(i).getFieldList());

        }

        patentService.updatePatentCustomField(patentCustomFieldParams);
    }


    @Async("singleThreadAsyncTaskExecutor")
    public void uploadPatentForProduct(TaskParams params, Integer productId) {
        Integer total = params.getRowList().size();
        try {
            //先解析Json文件 获得配置文件的Json串
            String getSettingJson = fileUtils.analysisJsonFile();
            //查找需求数据源的对应配置
            List<UploadSettingVO.Column> jsonData = UploadPatentBatchUtil.parsingConfigurationFilesBro(getSettingJson);
            Map<String, PictureData> pictureDataMap = ExcelUtils.getDataFromExcel(params.getPath());
            //将数据进行装配并进行数据库操作
            for (int i = 0; i < params.getRowList().size(); i++) {
                //获取每一行的数据
                Map<Object, Object> row = params.getRowList().get(i);
                //基础数据装配
                UploadParamsVO uploadParamsVO = UploadPatentBatchUtil.processData(row, jsonData);
                //查询数据是否存在 如果存在 返回该条数据 如果不存在 新增一条数据
                getOneOrInsertOne(uploadParamsVO);
                //专利信息需要特殊处理部分
                //专利信息(摘要附图)数据装配
                PictureData pictureData = pictureDataMap.get(String.valueOf(i + 1));
                if (uploadParamsVO.getPatent() != null) {
                    if (uploadParamsVO.getPatent().getId() != null && pictureData != null) {
                        uploadParamsVO.getPatent().setAbstractPath(patentImageService.updatePatentImage(uploadParamsVO.getPatent().getId(), pictureData));
                    }
                }
                //专利信息(代理机构)数据装配
                if (uploadParamsVO.getPatent() != null) {
                    if (uploadParamsVO.getPatent().getAgencyId() != null) {
                        uploadParamsVO.getPatent().setAgencyId(patentAgencyService.getAgencyStringIdByName(uploadParamsVO.getPatent().getAgencyId()));
                    }
                }
                //将装配对象中的数据保存到数据库
                dataToDBBro(params, uploadParamsVO);
                //添加关联关系
                assoProductPatentService.addPatents(Arrays.asList(uploadParamsVO.getPatent().getPatentNo()), productId);
                //通过WebSocket 在每一次循环结束后 向前端发送完成进度
                WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                        .setTaskId(params.getTaskId())
                        .setComplete(false)
                        .setIndex(i)
                        .setTaskType(Constants.TASK_IMPORT_PATENT)
                        .setPercentage(total == 0 ? 0 : Math.round((total.equals(i) ? (i * 1D) : (i + 1D)) / total * 100D))
                        .setFileName("")
                        .setOldName(params.getOldName())
                        .setUrl("")
                        .setTotal(total), ResponseEnum.PATENT_IMPORT_TASK_SUCCESS), params.getUserId());
            }

            SpringUtil.getBean(ProjectService.class).setImportPatentTaskStatus(2, params.getTaskId());
            WebSocketServer.sendInfo(Response.websocket(new TaskWebSocketDTO()
                    .setTaskId(params.getTaskId())
                    .setComplete(true)
                    .setIndex(total)
                    .setTaskType(Constants.TASK_IMPORT_PATENT)
                    .setPercentage(100L)
                    .setFileName("")
                    .setOldName(params.getOldName())
                    .setUrl("")
                    .setTotal(total), ResponseEnum.PATENT_IMPORT_TASK_SUCCESS), params.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            SpringUtil.getBean(ProjectService.class).setImportPatentTaskStatus(3, params.getTaskId());
            if (FLAG > 0) {
                int successCount = total - FLAG;
                WebSocketServer.sendInfo(Response.error("部分数据上传成功" + "\n" + "成功条数:" + successCount + "失败条数:" + FLAG), params.getUserId());
            }
            FLAG = 0;
        }
    }


    /**
     * @date 2022-7-11
     * @name 数据库交互
     * @description 将装配完毕的VO类向数据库中不同的表进行添加或修改操作(dataToDB兄弟类)
     */
    @Transactional(rollbackFor = Exception.class)
    public String dataToDBCell(PatentCell patentCell) throws ParseException {
        UploadParamsVO uploadParamsVO = new UploadParamsVO();
        Patent patent = new Patent();
        //设置专利号
        patent.setPatentNo(patentCell.getPatentNo());
        //设置摘要
        patent.setAbstractStr(patentCell.getAbstrText());
        //设置标题
        patent.setName(patentCell.getTitle());
        //设置公开日
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (patentCell.getPubilcDate() != null) {
            Date date = simpleDateFormat.parse(patentCell.getPubilcDate());
            Integer ts = (int) date.getTime();
            patent.setPublicDate(ts);
        }
        //设置申请号
        patent.setApplicationNo(patentCell.getApplicationNo());
        //设置申请日
        if (patentCell.getApplicationDate() != null) {
            Date date = simpleDateFormat.parse(patentCell.getApplicationDate());
            Integer ts = (int) date.getTime();
            patent.setApplicationDate(ts);
        }
        //设置摘要附图
        patent.setAbstractPath(patentCell.getPicUrl());
        //设置pdf文档
        if (patentCell.getPdf() != null) {
            patentInstructionService.edit(patentCell.getPatentNo(), patentCell.getPdf());
        }
        //设置公开号
        patent.setPublicNo(patentCell.getPublicNo());
        uploadParamsVO.setSimpleStatus(patentCell.getStatue());
        uploadParamsVO.setPatent(patent);
        getOneOrInsertOne(uploadParamsVO);
        if (patentCell.getAgency() != null && !patentCell.getAgency().equals("")) {
            uploadParamsVO.getPatent().setAgencyId(patentAgencyService.getAgencyStringIdByName(patentCell.getAgency()));
        }
        try {
            //专利信息 OS_PATENT
            if (uploadParamsVO.getPatent() != null) {
                List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.PATENT_SIMPLE_STATUS));
                Integer simpleStatus = Integer.parseInt(systemDictList.stream()
                        .filter(systemDict -> systemDict.getType().equals(Constants.PATENT_SIMPLE_STATUS) && systemDict.getLabel().equals(uploadParamsVO.getPatentSimpleStatus()))
                        .findFirst()
                        .orElse(new SystemDict()).getValue());
                uploadParamsVO.getPatent().setSimpleStatus(simpleStatus);
                uploadParamsVO.getPatent().updateById();
            }
            uploadParamsVO.setPatentRight(new PatentRight());
            uploadParamsVO.getPatentRight().setContent(StringUtils.join(patentCell.getRights(), ""));
            uploadParamsVO.setSelfContent(patentCell.getMainRignt());
            //权利要求 OS_PATENT_RIGHT
            if (uploadParamsVO.getPatentRight().getContent() != null) {
                patentRightBusiness(uploadParamsVO);
            }
            //说明书(文本) OS_PATENT_INSTRUCTION_TEXT
            uploadParamsVO.setPatentInstructionText(new PatentInstructionText());
            uploadParamsVO.getPatentInstructionText().setManual(patentCell.getPatentInstructionText());
            if (uploadParamsVO.getPatentInstructionText().getManual() != null) {
                patentInstructionTextBusiness(uploadParamsVO);
            }
            //发明人 OS_PATENT_INVENTOR
            if (patentCell.getInventors().size() != 0) {
                PatentInventorParams patentInventorParams = new PatentInventorParams();
                patentInventorParams.setPatentId(uploadParamsVO.getPatent().getId());
                patentInventorParams.setNameList(patentCell.getInventors());
                patentInventorParams.setAddressList(new ArrayList<>());
                patentInventorService.updatePatentInventor(patentInventorParams);
            }
            //申请人(原始)/权利人(当前) OS_PATENT_APPLICATION || OS_APPLICATION_ATTR
            uploadParamsVO.setPatentApplicantCurrentName(patentCell.getApplicationCurrents());
            uploadParamsVO.setPatentApplicantOriginalName(patentCell.getApplicationPersons());
            patentApplicationBusiness(uploadParamsVO);
            //申请人地址 OS_PATENT_APPLICATION
            uploadParamsVO.setPatentApplicantOriginalAddress(patentCell.getApplicationAddress());
            patentApplicationAddressBusiness(uploadParamsVO);
            //分类号关联 OS_PATENT_TYPENO
            uploadParamsVO.setIpcList(patentCell.getIpc());
            uploadParamsVO.setMainIpc(patentCell.getMainIpc());
            patentTypeNoBusiness(uploadParamsVO);
            //代理人 OS_PATENT_AGENT
            if (patentCell.getAgencyPersons() != null && patentCell.getAgencyPersons().size() != 0) {
                PatentAgentParams patentAgentParams = new PatentAgentParams();
                patentAgentParams.setPatentId(uploadParamsVO.getPatent().getId());
                patentAgentParams.setAgent(patentCell.getAgencyPersons());
                patentAgentService.updatePatentAgent(patentAgentParams);
            }
            //事务信息 OS_PATENT_AFFAIR
            if (patentCell.getPatentAffairs() != null && patentCell.getPatentAffairs().size() > 0) {
                patentAffairService.updatePatientAffairs(patentCell.getPatentAffairs(), uploadParamsVO.getPatent().getId());
            }
            //当专题库id不为null时添加专利到专题库
            if (patentCell.getProjectId() != null) {
                projectPatentLinkService.updateProjectPatent(patentCell.getProjectId(), uploadParamsVO.getPatent().getId());
            }
            return Response.success();
        } catch (Exception e) {
            e.printStackTrace();
            if (uploadParamsVO.getPatent() != null) {
                ImportErrorLog importErrorLog = new ImportErrorLog();
                importErrorLog.setPatentId(uploadParamsVO.getPatent().getId())
                        .setPatentNo(uploadParamsVO.getPatent().getPatentNo())
                        .setCreateTime(new SimpleDateFormat("yyyy-MM-dd 24HI:mm:ss").format(new Date()));
//                        .setCreateUserId(Integer.parseInt(params.getUserId()))
//                        .setMistakeMessage(e.getMessage())
//                        .setProjectId(params.getProjectId());
                importErrorLogMapper.insert(importErrorLog);
                FLAG += 1;
            }
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Response.error();
        }
    }

}
