package cn.cslg.pas.service;

import cn.cslg.pas.common.core.base.Constants;
import cn.cslg.pas.common.core.exception.CustomException;
import cn.cslg.pas.common.model.PersonnelVO;
import cn.cslg.pas.common.model.dto.*;
import cn.cslg.pas.common.model.vo.*;
import cn.cslg.pas.common.utils.*;
import cn.cslg.pas.common.utils.SecurityUtils.LoginUtils;
import cn.cslg.pas.domain.*;
import cn.cslg.pas.exception.XiaoShiException;
import cn.cslg.pas.mapper.ProductMapper;
import cn.cslg.pas.mapper.ProjectMapper;
import cn.cslg.pas.mapper.asso.AssoStructurePatentMapper;
import cn.cslg.pas.service.asso.TaskConditionService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 专题库表 服务实现类
 * </p>
 *
 * @author 王岩
 * @since 2022-01-24
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class ProjectService extends ServiceImpl<ProjectMapper, Project> {

    private final ProjectUserService projectUserService;
    private final PatentService patentService;
    private final PatentApplicantService patentApplicantService;
    private final PatentAgencyService patentAgencyService;
    private final PatentAgentService patentAgentService;
    private final PatentAgentLinkService patentAgentLinkService;
    private final PatentLicensorService patentLicensorService;
    private final PatentPledgeService patentPledgeService;
    private final PatentAffairService patentAffairService;
    private final PatentApplicantLinkService patentApplicantLinkService;
    private final PatentApplicantMergeLinkService patentApplicantMergeLinkService;
    private final PatentInventorService patentInventorService;
    private final PatentInventorLinkService patentInventorLinkService;
    private final PatentSimpleFamilyService patentSimpleFamilyService;
    private final PatentSimpleFamilyLinkService patentSimpleFamilyLinkService;
    private final PatentClassNumberLinkService patentClassNumberLinkService;
    private final ProjectPatentLinkService projectPatentLinkService;
    private final TaskService taskService;
    private final TaskConditionService taskConditionService;
    private final PatentImageService patentImageService;
    private final ProjectFieldPatentLinkService projectFieldPatentLinkService;
    private final ProjectFolderService projectFolderService;
    private final ProjectFieldService projectFieldService;
    private final ProjectFieldOptionService projectFieldOptionService;
    private final ProjectFieldTreeService projectFieldTreeService;
    private final ProjectFieldTextService projectFieldTextService;
    private final ProjectFileService projectFileService;
    private final SystemDictService systemDictService;
    private final PatentInstructionService patentInstructionService;
    private final PatentInstructionTextService patentInstructionTextService;
    private final PatentRightService patentRightService;
    private final FileUtils fileUtils;
    private final PatentLabelService patentLabelService;
    private final CacheUtils cacheUtils;
    private final ProjectExportService projectExportService;
    private final PatentInventorMergeService patentInventorMergeService;
    private final UserService userService;
    private final LoginUtils loginUtils;
    private final RequestService requestService;
    private final AssoStructurePatentMapper assoStructurePatentMapper;
    private final ProductMapper productMapper;
    private final ProjectMapper projectMapper;
    private final IEventService eventService;
    private final IAssoEventProjectService assoEventProjectService;
    private final CopyService copyService;

    public Project getProjectByName(String name) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
        queryWrapper.eq(Project::getName, name);
        queryWrapper.eq(Project::getTenantId, personnelVO.getTenantId());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    public Project getProjectByName(String name, Integer loginId) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginId);
        queryWrapper.eq(Project::getName, name);
        queryWrapper.eq(Project::getTenantId, personnelVO.getTenantId());
        queryWrapper.last("limit 1");
        return this.getOne(queryWrapper);
    }

    public IPage<Project> getPageList(ProjectVO params) throws IOException {
        List<Integer> projectIds = new ArrayList<Integer>() {{
            add(-1);
        }};
        //TODO 代码控制不同类型的角色查询权限
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
        if (personnelVO.getRoleType() == null || personnelVO.getRoleType() != 1) {
            params.setPersonnelId(loginUtils.getId());
            if (personnelVO.getRoleType() != null && personnelVO.getRoleType() == 2) {
                params.setTenantId(personnelVO.getTenantId());
            }
        }
        //分页查询专题库列表
        IPage<Project> pageList = baseMapper.getPageList(new Page<>(params.getCurrent(), params.getSize()), params);
        List<Project> dataList = pageList.getRecords();
        this.setDataList(dataList);
        pageList.setRecords(dataList);
        return pageList;
    }

    public List<Project> getProjectByIds(List<Integer> ids) throws IOException {
        if (ids == null || ids.size() == 0) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Project::getId, ids);
        //根据ids查询专题库列表
        List<Project> dataList = this.list(queryWrapper);
        //↓根据专题库id查询专题库时，查询到的就是一条，就将当前专题库的产品名字赋值(他妈的两个控制层方法调当前业务层，坑爹)
        if (dataList.size() == 1) {
            for (Project project : dataList) {
                Integer productId = project.getProductId();
                if (productId != null) {
                    ProductVO queryResult = productMapper.getStandardById(productId);
                    String productName = queryResult.getProductName();
                    project.setProductName(productName);
                }
            }
        }
        try {
            //获取所属部门对应信息
            String jsonObject = requestService.getDepartmentFromPCS(dataList);
            JSONArray jsonArray1 = JSON.parseArray(jsonObject);
            List<ProjectVO.Department> departmentList = jsonArray1.toJavaList(ProjectVO.Department.class);
            for (Project project : dataList) {
                for (ProjectVO.Department department : departmentList) {
                    if (project.getDepartmentId() != null) {
                        if (project.getDepartmentId().equals(department.getId())) {
                            project.setDepartmentName(department.getDepartmentName());
                        }
                    }
                }
            }
            List<Integer> personnelIds = dataList.stream().map(Project::getPersonnelId).collect(Collectors.toList());
            //获取专题库负责人对应信息
            String jsonObject1 = requestService.getPersonnelFromPCS(personnelIds);
            JSONArray jsonArray = JSON.parseArray(jsonObject1);
            List<ProjectVO.Personnel> personnelList = jsonArray.toJavaList(ProjectVO.Personnel.class);
            for (Project project : dataList) {
                for (ProjectVO.Personnel personnel : personnelList) {
                    if (project.getPersonnelId() != null) {
                        if (project.getPersonnelId().equals(personnel.getId())) {
                            project.setPersonnelName(personnel.getPersonnelName());
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.setDataList(dataList);
        return dataList;
    }

    public List<Project> getProjectByCreateId(Integer createBy) {
        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Project::getCreateBy, createBy);
        return this.list(queryWrapper);
    }

    public Project getProjectById(Integer id) {
        Project project = this.getById(id);
        try {
            String res = requestService.getClientByIds(Arrays.asList(project.getClientId()));
            JSONArray jsonArray2 = JSON.parseArray(res);
            List<ClientDTO> clientList = jsonArray2.toJavaList(ClientDTO.class);
            if (clientList != null && clientList.size() != 0) {
                project.setClientName(clientList.get(0).getName());
            }
        } catch (Exception e) {
        }

        return project;
    }

    private void setDataList(List<Project> dataList) throws IOException {
        //获得委托方的id集合
        List<Integer> clientIds = dataList.stream().map(Project::getClientId).collect(Collectors.toList());
        //获得负责人的id集合
        List<Integer> personIds = dataList.stream().map(Project::getPersonnelId).collect(Collectors.toList());
        //获得创建人的id集合
        List<Integer> createIds = dataList.stream().map(Project::getCreateBy).collect(Collectors.toList());
        personIds.addAll(createIds);
        //获取所属部门对应信息
        String jsonObject = requestService.getDepartmentFromPCS(dataList);
        JSONArray jsonArray1 = JSON.parseArray(jsonObject);
        List<ProjectVO.Department> departmentList = jsonArray1.toJavaList(ProjectVO.Department.class);
        //获取专题库负责人对应信息
        String jsonObject1 = requestService.getPersonnelFromPCS(personIds);
        JSONArray jsonArray = JSON.parseArray(jsonObject1);
        List<ProjectVO.Personnel> personnelList = jsonArray.toJavaList(ProjectVO.Personnel.class);
        //获取专题库委托方对应信息
        List<ClientDTO> clientList = new ArrayList<>();
        if (clientIds.size() > 0) {
            String jsonObject2 = requestService.getClientByIds(clientIds);
            JSONArray jsonArray2 = JSON.parseArray(jsonObject2);
            clientList = jsonArray2.toJavaList(ClientDTO.class);
        }
        for (Project project : dataList) {
            //装载负责人名
            for (ProjectVO.Personnel personnel : personnelList) {
                if (project.getPersonnelId() != null) {
                    if (project.getPersonnelId().equals(personnel.getId())) {
                        project.setPersonnelName(personnel.getPersonnelName());
                    }
                }
                //装载创建人名
                if (project.getCreateBy() != null) {
                    if (project.getCreateBy().equals(personnel.getId())) {
                        project.setCreateName(personnel.getPersonnelName());
                    }
                }

            }

            //装载委托方名
            for (ClientDTO clientDTO : clientList) {
                if (project.getClientId() != null) {
                    if (project.getClientId().equals(clientDTO.getId())) {
                        project.setClientName(clientDTO.getName());
                    }
                }
            }
            Integer productId = project.getProductId();
            //装载产品id
            if (productId != null) {
                ProductVO queryResult = productMapper.getStandardById(productId);
                String productName = queryResult.getProductName();
                project.setProductName(productName);
            }
            //装载部门
            for (ProjectVO.Department department : departmentList) {
                if (project.getDepartmentId() != null) {
                    if (project.getDepartmentId().equals(department.getId())) {
                        project.setDepartmentName(department.getDepartmentName());
                    }
                }
            }

        }


        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.ENTERPRISE_APPLICATION_SCENARIO, Constants.INVESTIGATION_TYPE));
        dataList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getScenario())) {
                item.setScenarioList(StringUtils.changeStringToInteger(item.getScenario(), ","));
                item.setScenarioName(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.ENTERPRISE_APPLICATION_SCENARIO) && item.getScenarioList().contains(Integer.parseInt(systemDict.getValue()))).map(SystemDict::getLabel).collect(Collectors.toList()));
                item.setScenario(null);
            }
            if (StringUtils.isNotEmpty(item.getType())) {
                item.setTypeList(StringUtils.changeStringToInteger(item.getType(), ","));
                item.setTypeName(systemDictList.stream().filter(systemDict -> systemDict.getType().equals(Constants.INVESTIGATION_TYPE) && item.getTypeList().contains(Integer.parseInt(systemDict.getValue()))).map(SystemDict::getLabel).collect(Collectors.toList()));
                item.setType(null);
            } else {
                item.setTypeList(new ArrayList<Integer>());
            }
        });
    }

    public List<Project> getAllProjectByMySelf() throws IOException {
        ProjectVO params = new ProjectVO();
        PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
        if (personnelVO.getRoleType() == null || personnelVO.getRoleType() != 1) {
            params.setPersonnelId(loginUtils.getId());
            if (personnelVO.getRoleType() != null && personnelVO.getRoleType() == 2) {
                params.setTenantId(personnelVO.getTenantId());
            }
        }
        List<Project> projectList = baseMapper.getListForCount(params);
        this.setDataList(projectList);
        return projectList;
    }

    public Map<Object, Object> getProjectStatusTotal() throws IOException {
        Map<Object, Object> map = new HashMap<>();
        List<Project> projectList = this.getAllProjectByMySelf();
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.ENTERPRISE_APPLICATION_SCENARIO));
        for (SystemDict systemDict : systemDictList) {
            Map<String, Object> result = new HashMap<>();
            List<Project> tempList = projectList.stream().filter(item -> item.getScenarioList() != null && item.getScenarioList().contains(Integer.parseInt(systemDict.getValue()))).collect(Collectors.toList());
            result.put("completed", tempList.stream().filter(item -> item.getStatus().equals("1")).count());
            result.put("unfinished", tempList.stream().filter(item -> item.getStatus().equals("0")).count());
            map.put(systemDict.getLabel(), result);
        }
        return map;
    }

    public Map<String, Object> getProjectTypeTotal(String scenario) throws IOException {
        Map<String, Object> map = new HashMap<>();
        List<Project> projectList = this.getAllProjectByMySelf();
        projectList = projectList.stream().filter(item -> item.getScenarioName() != null && item.getScenarioName().contains(scenario)).collect(Collectors.toList());
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Collections.singletonList(Constants.INVESTIGATION_TYPE));
        for (SystemDict systemDict : systemDictList) {
            map.put(systemDict.getLabel(), projectList.stream().filter(item -> item.getTypeList().contains(Integer.parseInt(systemDict.getValue()))).count());
        }
        return map;
    }

    public Map<Object, Object> getScenarioAndTypeTotal() throws IOException {
        List<Project> projectList = this.getAllProjectByMySelf();
        List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.ENTERPRISE_APPLICATION_SCENARIO, Constants.INVESTIGATION_TYPE));
        List<Integer> clientIds = projectList.stream().map(Project::getClientId).collect(Collectors.toList());
        List<ClientDTO> clientList = new ArrayList<>();
        if (clientIds.size() > 0) {
            String res = requestService.getClientByIds(clientIds);
            JSONArray jsonArray2 = JSON.parseArray(res);
            clientList = jsonArray2.toJavaList(ClientDTO.class);
        }
        Map<Object, Object> type = new HashMap<>();
        Map<Object, Object> scenario = new HashMap<>();
        Map<Object, Object> result = new HashMap<>();
        Map<Object, Object> client = new HashMap<>();
        Map<Object, Object> create = new HashMap<>();
        systemDictList.forEach(systemDict -> {
            switch (systemDict.getType()) {
                case Constants.ENTERPRISE_APPLICATION_SCENARIO:
                    scenario.put(systemDict.getLabel(), projectList.stream().filter(item -> item.getScenarioList() != null && item.getScenarioList().contains(Integer.parseInt(systemDict.getValue()))).count());
                    break;
                case Constants.INVESTIGATION_TYPE:
                    type.put(systemDict.getLabel(), projectList.stream().filter(item -> item.getTypeList().contains(Integer.parseInt(systemDict.getValue()))).count());
                    break;
            }
        });
        clientList.forEach(item -> client.put(item.getName(), projectList.stream().filter(project -> item.getId().equals(project.getClientId())).count()));
        Date date = DateUtil.date();
        for (int i = 0; i < 6; i++) {
            Date finalDate = date;
            create.put(DateUtil.format(date, "yyyy-MM"), projectList.stream().filter(item -> (item.getCreateTime() * 1000L) >= DateUtil.beginOfMonth(finalDate).getTime() && (item.getCreateTime() * 1000L) <= DateUtil.endOfMonth(finalDate).getTime()).count());
            date = DateUtil.offset(date, DateField.MONTH, -1);
        }
        result.put("scenario", scenario);
        result.put("type", type);
        result.put("client", client);
        result.put("create", create);
        return result;
    }

    private List<Object> getClientIds(List<Integer> clientIds) {
        Map<Object, Long> map = clientIds.stream().collect(Collectors.groupingBy(p -> p, Collectors.counting()));
        return map.entrySet().stream()
                .sorted((Map.Entry<Object, Long> o1, Map.Entry<Object, Long> o2) -> o2.getValue().intValue() - o1.getValue().intValue())
                .map(Map.Entry::getKey).collect(Collectors.toList())
                .subList(0, Math.min(map.size(), 10));
    }

    public String getImportProjectName(String name) {
        String tempName = name + "(1)";
        Project project1 = this.getProjectByName(name);
        if (project1 == null) {
            return name;
        }
        Project project2 = this.getProjectByName(tempName);
        if (project2 != null) {
            tempName = this.getImportProjectName(tempName);
        }
        return tempName;
    }

    public String getImportProjectName(String name, Integer userId) {
        String tempName = name + "(1)";
        Project project1 = this.getProjectByName(name, userId);
        if (project1 == null) {
            return name;
        }
        Project project2 = this.getProjectByName(tempName, userId);
        if (project2 != null) {
            tempName = this.getImportProjectName(tempName, userId);
        }
        return tempName;
    }

    public Integer importProject(Integer projectId, String json, Integer userId) throws IOException {
        if ((projectId == null || projectId.equals(0)) && StringUtils.isEmpty(json)) {
            return 0;
        }
        if (StringUtils.isEmpty(json)) {
            return projectId;
        }
        Project temp = this.getById(projectId);
        Project data = JsonUtils.jsonToPojo(json, Project.class);
        if (data.getClientId() != null) {
            temp.setClientId(data.getClientId());
        }
        if (temp == null) {
            temp = new Project();
        }
        String projectName = temp.getName();
        BeanUtils.copyProperties(data, temp);
        if (projectName == null || !projectName.equals(data.getName())) {
            temp.setName(this.getImportProjectName(temp.getName(), userId));
        }

        if (projectId == null || projectId.equals(0)) {
            temp.setCreateBy(userId);
            temp.setCreateTime(DateUtils.getDateTime());
            temp.setId(null);
        } else {
            temp.setId(projectId);
        }
        temp.insertOrUpdate();
        return temp.getId();
    }

    @Transactional
    public Integer add(Project project) throws IOException {
        PersonnelVO user = cacheUtils.getLoginUserPersonnel(loginUtils.getId());
        //检查专题库名称是否被占用
        Project temp = this.getProjectByName(project.getName());
        if (temp != null) {
            ThrowException.throwXiaoShiException("专题库名称已存在");
        }
        if ((project.getClientId() == null || project.getClientId() == -1) && project.getClientName() != null && project.getClientName() != "") {
            ClientDTO clientDTO = new ClientDTO();
            clientDTO.setName(project.getClientName());
            clientDTO.setTenantId(user.getTenantId());
            String res = requestService.addClient(clientDTO);
            JSONObject jsonObject = JSONObject.parseObject(res);
            Integer clientId = Integer.parseInt(jsonObject.get("data").toString());
            project.setClientId(clientId);
        }
        project.setScenario(StringUtils.join(project.getScenarioList(), ","));
        project.setType(StringUtils.join(project.getTypeList(), ","));
        project.setCreateBy(loginUtils.getId());
        project.setCreateTime(DateUtils.getDateTime());
        project.setTenantId(user.getTenantId());
        //专题库表新增数据
        log.info("专题库表新增数据");
        project.insert();
        this.addProjectUser(project.getId());

        //新增事件
        List<EventAddNewDTO> eventAddNewDTOs = project.getEventAddNewDTOs();
        if (eventAddNewDTOs != null && eventAddNewDTOs.size() > 0) {
            ProjectEventAddNewDTO projectEventAddNewDTO = new ProjectEventAddNewDTO()
                    .setEventAddNewDTOs(eventAddNewDTOs)
                    .setProjectId(project.getId());
            eventService.addNewEvent(projectEventAddNewDTO);
        }

        log.info("新增专题库完成");
        return project.getId();
    }

    @Transactional
    public String edit(Project project) throws IOException {
        //检查当前专题库的修改是否要修改产品
        Integer projectId = project.getId();
        Integer newProductId = project.getProductId();
        ProjectStandardVO queryResult = projectMapper.getStandardById(projectId);
        Integer oldProductId = queryResult.getProductId();
        //若当前产品id和原产品id不一致，则表示当前的修改要修改产品
        if (newProductId != null && !newProductId.equals(oldProductId)) {
            //检查当前专题库产品架构是否已标引，若已标引则不允许修改产品
            int count = assoStructurePatentMapper.countByProjectId(projectId);
            if (count > 0) {
                String message = "修改专题库失败，该专题库产品或架构已被标引，无法更换产品或架构";
                log.info("{}", message);
                throw new XiaoShiException(message);
            }
        }

        Project temp = this.getProjectByName(project.getName());
        //检查尝试修改的新专题库名称是否被占用
        if (temp != null && !temp.getId().equals(project.getId())) {
            return Response.error("专题库名称已存在");
        }
        if (project.getClientId() == null || project.getClientId() == -1) {
            ClientDTO clientDTO = new ClientDTO();
            clientDTO.setName(project.getClientName());
            clientDTO.setTenantId(project.getTenantId());
            String res = requestService.addClient(clientDTO);
            JSONObject jsonObject = JSONObject.parseObject(res);
            Integer clientId = Integer.parseInt(jsonObject.get("data").toString());
            project.setClientId(clientId);
        }
        project.setScenario(StringUtils.join(project.getScenarioList(), ","));
        project.setType(StringUtils.join(project.getTypeList(), ","));
        //专题库表修改数据
        log.info("专题库表修改数据");
        project.updateById();
        return Response.success();
    }

    @Transactional
    public String delete(Integer id) {
        //专题库表删除数据
        log.info("专题库表删除数据");
        this.removeById(id);
        this.deleteProjectUser(id, loginUtils.getId());
        projectPatentLinkService.deleteByProjectId(id);
        projectFolderService.deleteByProjectId(id);
        projectFieldService.deleteByProjectId(id);
        projectUserService.deleteByProjectId(id);
        projectFileService.deleteByProjectId(id);
        patentApplicantMergeLinkService.deleteByProjectId(id);
        //陈宇 ↓ 删除专题库产品架构标引表（asso_structure_patent）数据
        assoStructurePatentMapper.deleteByProjectId(id);
        //陈宇 ↓ 删除任务表（os_task）和任务条件关联表（asso_osTask_qrtzTask）数据
        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getProjectId, id));
        //陈宇 ↓ 删除任务表（os_task）数据
        taskService.removeByIds(tasks.stream().map(Task::getId).collect(Collectors.toList()));
        //陈宇 ↓ 若是网站导入任务则还要删除任务条件关联表（asso_osTask_qrtzTask）数据
        List<Integer> taskConditionIds = tasks.stream().filter(item -> item.getTaskConditionId() != null).map(Task::getTaskConditionId).collect(Collectors.toList());
        if (taskConditionIds.size() > 0) {
            taskConditionService.removeByIds(taskConditionIds);
        }

        return Response.success();
    }

    private Integer getNewClientId(String name) throws IOException {
        String res = requestService.getClientByName(name);
        ClientDTO client = JSONObject.parseObject(res, ClientDTO.class);
        Integer clientId = 0;
        if (client == null) {
            client.setName(name);
            String res2 = requestService.addClient(client);

            JSONObject jsonObject = JSONObject.parseObject(res2);
            clientId = Integer.parseInt(jsonObject.get("data").toString());
        } else {
            clientId = client.getId();
        }
        return clientId;
    }

    private void addProjectUser(Integer projectId) {
        ProjectUser user = new ProjectUser();
        user.setUserId(loginUtils.getId());
        user.setProjectId(projectId);
        user.setCreateTime(DateUtils.getDateTime());
        user.setType(2);
        user.insert();
    }

    private void deleteProjectUser(Integer projectId, Integer userId) {
        projectUserService.remove(Wrappers.<ProjectUser>lambdaQuery().eq(ProjectUser::getUserId, userId).eq(ProjectUser::getProjectId, projectId));
    }

    @Transactional(rollbackFor = Exception.class)
    public String importExcel(MultipartFile file) {
        try {
            PersonnelVO user = cacheUtils.getLoginUserPersonnel(loginUtils.getId());
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<Map<String, Object>> readAll = reader.readAll();
            List<SystemDict> systemDictList = systemDictService.getSystemDictListByType(Arrays.asList(Constants.INVESTIGATION_TYPE, Constants.ENTERPRISE_APPLICATION_SCENARIO));
            for (Map<String, Object> row : readAll) {
                Project project = new Project();
                project.setSort(1);
                project.setName(row.get("专题库名称").toString());
                project.setClientId(this.getNewClientId(row.get("委托方").toString()));
                project.setRemark(row.get("备注").toString());
                project.setCreateBy(loginUtils.getId());
                project.setCreateTime(DateUtils.getDateTime());
                List<String> typeName = StringUtils.changeStringToString(row.get("调查类型").toString(), ";");
                List<Integer> typeList = systemDictList.stream().filter(item -> item.getType().equals(Constants.INVESTIGATION_TYPE) && typeName.contains(item.getLabel())).map(SystemDict::getValue).map(Integer::parseInt).collect(Collectors.toList());
                project.setType(StringUtils.join(typeList, ","));
                List<String> scenarioName = StringUtils.changeStringToString(row.get("企业应用场景").toString(), ";");
                List<Integer> scenarioList = systemDictList.stream().filter(item -> item.getType().equals(Constants.ENTERPRISE_APPLICATION_SCENARIO) && scenarioName.contains(item.getLabel())).map(SystemDict::getValue).map(Integer::parseInt).collect(Collectors.toList());
                project.setScenario(StringUtils.join(scenarioList, ","));
                project.setTechnicalTheme(row.get("技术主题").toString());
                project.setContractNo(row.get("合同号").toString());
                project.setInnerFile(row.get("内部案卷").toString());
                Object caseDate = row.get("委案日");
                if (StringUtils.isNotNull(caseDate)) {
                    project.setCaseDate(caseDate.toString());
                }
                project.setStatus(row.get("处理状态").toString().equals("处理中") ? "0" : "1");
                Object update = row.get("是否更新");
                if (StringUtils.isNotNull(update)) {
                    project.setUpdate(update.toString().equals("是") ? 1 : 0);
                    project.setUpdateTime(row.get("更新周期").toString());
                } else {
                    project.setUpdate(0);
                    project.setUpdateTime("一天");
                }
                project.insert();
                List<String> userName = StringUtils.changeStringToString(row.get("管理员").toString(), ";");
                List<User> userList = userService.getUserByNames(userName);
                List<ProjectUser> projectUserList = new ArrayList<>();
                userList.forEach(item -> {
                    ProjectUser projectUser = new ProjectUser();
                    projectUser.setProjectId(project.getId());
                    projectUser.setUserId(item.getId());
                    projectUser.setCreateTime(DateUtils.getDateTime());
                    projectUser.setType(2);
                    projectUserList.add(projectUser);
                });
                projectUserService.saveOrUpdateBatch(projectUserList);
            }
            return Response.success(true);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Response.error();
        }
    }

    @Transactional
    public String share(Integer id, List<Integer> userIds, List<ProjectUser.User> users) {
        ProjectUser user = new ProjectUser();
        user.setType(3);
        user.setRemark("用户分享");
        user.setProjectId(id);
        user.setUserIds(userIds);
        user.setUsers(users);
        return projectUserService.add(user);
    }

    public TaskParams getImportPatentTaskParams(MultipartFile file, Integer projectId) {
        //将包含多件专利的Excel文件上传至本地，并返回文件对象fileDTO
        UploadFileDTO fileDTO = fileUtils.uploadFile(file);

        //获得文件路径
        String path = fileUtils.getPath(fileDTO.getPath());

        //创建集合rowList，准备装载Excel中所有行数据（元素个数=总行数，元素=行数据，第一个元素=表头行数据）
        List<List<Object>> rowList = new ArrayList<>();
        //集合mapList，准备装载Excel中的全部专利的数据（每一个元素的key：表头(如"公开号")  value：表头对应的专利内容(如"CN204445352U")）
        List<Map<Object, Object>> mapList = new ArrayList<>();

        //使用excel工具类解析读取文件（通过Sax方式按行读取），将内容装载到集合rowList（元素数量=总行数，元素=行数据，第一个元素=表头行数据）
        ExcelUtil.readBySax(path, -1, (sheetIndex, rowIndex, row) -> rowList.add(row));

        //遍历rowList集合，将集合第一个元素（表头行内容）作为keys，其余元素（专利行内容）作为values，将键列表keys和值列表values转换为Map集合
        for (int i = 1; i < rowList.size(); i++) {
            mapList.add(IterUtil.toMap(rowList.get(0), rowList.get(i)));
        }

        //新增任务（专利导入导出任务表）
        Integer taskId = taskService.add(fileDTO, projectId, null, rowList.size() - 1, 1, 0, file.getOriginalFilename());
        TaskParams taskParams = new TaskParams();
        taskParams.setTaskId(taskId);
        taskParams.setPath(path);
        taskParams.setTaskType(1);
        taskParams.setRowList(mapList);
        taskParams.setUserId(String.valueOf(loginUtils.getId()));
        taskParams.setOldName(file.getOriginalFilename());
        return taskParams;
    }

    //获得
    public TaskParams getImportPatentTaskParamsBro(MultipartFile file, Integer productId) {
        //上传文档
        UploadFileDTO fileDTO = fileUtils.uploadFile(file);
        //获得文档保存的路径
        String path = fileUtils.getPath(fileDTO.getPath());
        List<List<Object>> rowList = new ArrayList<>();
        //解析excel文件并保存进map里
        List<Map<Object, Object>> mapList = new ArrayList<>();
        ExcelUtil.readBySax(path, -1, (sheetIndex, rowIndex, row) -> rowList.add(row));
        for (int i = 1; i < rowList.size(); i++) {
            mapList.add(IterUtil.toMap(rowList.get(0), rowList.get(i)));
        }
        Integer taskId = taskService.add(fileDTO, null, productId, rowList.size() - 1, 1, 0, file.getOriginalFilename());
        TaskParams taskParams = new TaskParams();
        taskParams.setPath(path);
        taskParams.setTaskId(taskId);
        taskParams.setTaskType(1);
        taskParams.setRowList(mapList);
        taskParams.setUserId(String.valueOf(loginUtils.getId()));
        taskParams.setOldName(file.getOriginalFilename());
        taskParams.setProductId(productId);
        return taskParams;
    }


    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void setImportPatentTaskStatus(Integer status, Integer taskId) {
        taskService.updateStatus(taskId, status, DateUtils.getDateTime());
    }

    public void saveDataToJsonFile(String tempPath, String fileName, String data) throws IOException {
        String path = tempPath + FileUtils.FILE_SEPARATOR + fileName;
        FileOutputStream fileOutputStream = new FileOutputStream(path);
        fileOutputStream.write(data.getBytes(StandardCharsets.UTF_8));
        fileOutputStream.close();
    }

    public void copyFileToTempDirectory(String src, String tempPath, String directoryName, String fileName) {
        String dest = tempPath + FileUtils.FILE_SEPARATOR + directoryName + FileUtils.FILE_SEPARATOR + fileName;
        File file = FileUtil.file(fileUtils.getSystemPath(src));
        if (FileUtil.exist(file)) {
            FileUtil.copy(file, new File(dest), true);
        }
    }

    @Async
    public void export(ProjectExportVO params, Integer exportId, Integer userId) {
        try {
            String json = cacheUtils.getSelectPatentIds(params.getKey());
            List<Integer> patentIds = StringUtils.changeStringToInteger(json, ",");
            List<Patent> patentList = patentService.getPatentListByIds(patentIds);
            String directoryName = IdUtil.simpleUUID();
            String fileName = directoryName + ".zip";
            String tempPath = fileUtils.getTempPath(directoryName);
            String url = fileUtils.getDirectory(fileName);
            String savePath = fileUtils.getSystemPath(url);
            File directory = new File(tempPath);
            if (!directory.exists()) {
                boolean success = directory.mkdir();
                if (!success) {
                    throw new Exception("数据导出时创建文件夹失败");
                }
            }
            WebSocketServer.sendInfo(Response.websocket(true, ResponseEnum.PROJECT_EXPORT_TASK_SUCCESS), String.valueOf(userId));
            if (params.getProjectInfo()) {
                Project project = this.getProjectById(params.getProjectId());
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_INFO_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(project)));
            }
            if (params.getProjectReport() != null && params.getProjectReport().size() != 0) {
                List<ProjectFile> projectFileList = projectFileService.getProjectFileByIds(params.getProjectReport());
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_REPORT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFileList)));
                projectFileList.forEach(item -> this.copyFileToTempDirectory(item.getUrl(), tempPath, Constants.PROJECT_REPORT_DIRECTORY_NAME, item.getFileName()));
            }
            if (params.getProjectFile() != null && params.getProjectFile().size() != 0) {
                List<ProjectFile> projectFileList = projectFileService.getProjectFileByIds(params.getProjectFile());
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_FILE_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFileList)));
                projectFileList.forEach(item -> this.copyFileToTempDirectory(item.getUrl(), tempPath, Constants.PROJECT_FILE_DIRECTORY_NAME, item.getFileName()));
            }
            if (params.getPatentImage()) {
                List<PatentImage> patentImageList = patentImageService.getPatentImageByPatentIds(patentIds);
                this.saveDataToJsonFile(tempPath, Constants.PATENT_IMAGE_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentImageList)));
                patentImageList.forEach(item -> this.copyFileToTempDirectory(item.getUrl(), tempPath, Constants.PATENT_IMAGE_DIRECTORY_NAME, item.getFileName()));
            }
            if (params.getPatentInstruction()) {
                List<String> patentNo = patentList.stream().map(Patent::getPatentNo).collect(Collectors.toList());
                List<PatentInstruction> patentInstructionList = patentInstructionService.getPatentInstructionByPatentNo(patentNo);
                this.saveDataToJsonFile(tempPath, Constants.PATENT_INSTRUCTION_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentInstructionList)));
                patentInstructionList.forEach(item -> this.copyFileToTempDirectory(item.getUrl(), tempPath, Constants.PATENT_INSTRUCTION_DIRECTORY_NAME, item.getFileName()));
            }
            if (params.getPatentBase()) {
                List<PatentApplicantLink> patentApplicantLinkList = patentApplicantLinkService.getApplicantAttributesListByPatentIds(patentIds);
                List<PatentApplicantMergeLink> patentApplicantMergeLinkList = patentApplicantMergeLinkService.getPatentApplicantMergeLinkListByProjectId(params.getProjectId());
                List<Integer> patentApplicantIds = new ArrayList<>();
                patentApplicantLinkList.forEach(item -> patentApplicantIds.add(item.getApplicantId()));
                patentApplicantMergeLinkList.forEach(item -> patentApplicantIds.add(item.getMergeId()));
                List<PatentApplicant> patentApplicantList = patentApplicantService.getPatentApplicantByIds(patentApplicantIds);
                List<PatentAffair> patentAffairList = patentAffairService.getPatentAffairListByPatentIds(patentIds);
                List<PatentAgency> patentAgencyList = patentAgencyService.getPatentAgencyByIds(patentList.stream().filter(item -> StringUtils.isNotEmpty(item.getAgencyId())).map(item -> Integer.parseInt(item.getAgencyId())).collect(Collectors.toList()));
                List<PatentAgentLink> patentAgentLinkList = patentAgentLinkService.getPatentAgentLinkByPatentIds(patentIds);
                List<PatentAgent> patentAgentList = patentAgentService.getPatentAgentByIds(patentAgentLinkList.stream().map(PatentAgentLink::getAgentId).collect(Collectors.toList()));
                List<PatentInstructionText> patentInstructionTextList = patentInstructionTextService.getPatentInstructionTextByPatentIds(patentIds);
                List<PatentInventorLink> patentInventorLinkList = patentInventorLinkService.getPatentInventorLinkByPatentIds(patentIds);
                List<PatentInventorMerge> patentInventorMergeList = patentInventorMergeService.getPatentInventorMergeByProjectId(params.getProjectId());
                List<Integer> patentInventorIds = new ArrayList<>();
                patentInventorLinkList.forEach(item -> patentInventorIds.add(item.getInventorId()));
                patentInventorMergeList.forEach(item -> patentInventorIds.add(item.getMergeId()));
                List<PatentInventor> patentInventorList = patentInventorService.getPatentInventorByIds(patentInventorIds);
                List<PatentLicensor> patentLicensorList = patentLicensorService.getPatentLicensorByPatentIds(patentIds);
                List<PatentPledge> patentPledgeList = patentPledgeService.getPatentPledgeByPatentIds(patentIds);
                List<PatentRight> patentRightList = patentRightService.getPatentRightByPatentIds(patentIds);
                List<Integer> patentFamilyIds = new ArrayList<>();
                patentList.forEach(item -> {
                    patentFamilyIds.add(item.getSimpleFamily());
                    patentFamilyIds.add(item.getInpadocFamily());
                    patentFamilyIds.add(item.getPatSnapFamily());
                });
                List<PatentSimpleFamilyLink> patentSimpleFamilyLinkList = patentSimpleFamilyLinkService.getPatentSimpleFamilyLinkByFamilyIds(patentFamilyIds);
                List<PatentSimpleFamily> patentSimpleFamilyList = patentSimpleFamilyService.getPatentSimpleFamilyByIds(patentFamilyIds);
                List<PatentClassNumberLink> patentClassNumberLinkList = patentClassNumberLinkService.getPatentClassNumberLinkByPatentIds(patentIds);
                this.saveDataToJsonFile(tempPath, Constants.PATENT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_AFFAIR_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentAffairList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_AGENCY_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentAgencyList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_AGENT_LINK_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentAgentLinkList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_AGENT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentAgentList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_INSTRUCTION_TEXT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentInstructionTextList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_INVENTOR_LINK_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentInventorLinkList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_INVENTOR_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentInventorList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_INVENTOR_MERGE_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentInventorMergeList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_LICENSOR_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentLicensorList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_PLEDGE_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentPledgeList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_RIGHT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentRightList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_FAMILY_LINK_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentSimpleFamilyLinkList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_FAMILY_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentSimpleFamilyList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_CLASS_NUMBER_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentClassNumberLinkList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_APPLICANT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentApplicantList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_APPLICANT_LINK_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentApplicantLinkList)));
                this.saveDataToJsonFile(tempPath, Constants.PATENT_APPLICANT_MERGE_LINK_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentApplicantMergeLinkList)));
            }
            if (params.getPatentField() != null && params.getPatentField().size() != 0) {
                if (params.getPatentField().contains(0)) {
                    List<PatentLabel> patentLabelList = patentLabelService.getPatentLabelByPatentIdsAndProjectId(patentIds, params.getProjectId());
                    this.saveDataToJsonFile(tempPath, Constants.PATENT_LABEL_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patentLabelList)));
                }
                List<ProjectField> projectFieldList = projectFieldService.getFieldListByIds(params.getPatentField());
                List<Integer> projectFieldIds = projectFieldList.stream().map(ProjectField::getId).collect(Collectors.toList());
                List<ProjectFieldOption> projectFieldOptionList = projectFieldOptionService.getFieldOptionList(projectFieldIds);
                List<ProjectFieldTree> projectFieldTreeList = projectFieldTreeService.getProjectFieldTreeOptionByFieldIds(projectFieldIds);
                List<ProjectFieldText> projectFieldTextList = projectFieldTextService.getProjectFieldTextByFieldIds(projectFieldIds);
                List<ProjectFieldPatentLink> projectFieldPatentLinkList = new ArrayList<>();
                for (Integer fieldId : params.getPatentField()) {
                    projectFieldPatentLinkList.addAll(projectFieldPatentLinkService.getProjectPatentLinkByPatentIdsAndFieldId(patentIds, fieldId));
                }
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_FIELD_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFieldList)));
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_FIELD_OPTION_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFieldOptionList)));
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_FIELD_TREE_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFieldTreeList)));
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_FIELD_TEXT_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFieldTextList)));
                this.saveDataToJsonFile(tempPath, Constants.PROJECT_FIELD_PATENT_LINK_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(projectFieldPatentLinkList)));
            }
            List<Patent> patents = patentService.getPatentIdAndPatentNoByIds(patentIds);
            this.saveDataToJsonFile(tempPath, Constants.PATENT_ID_PATENT_NO_FILE_NAME, Objects.requireNonNull(JsonUtils.objectToJson(patents)));
            File file = ZipUtil.zip(tempPath, savePath);
            FileUtil.del(tempPath);
            ProjectExport projectExport = projectExportService.getById(exportId);
            projectExport.setUrl(url);
            projectExport.setFileName(fileName);
            projectExport.setStatus(1);
            projectExport.setFileSize(FileUtil.size(file));
            projectExport.updateById();
            WebSocketServer.sendInfo(Response.websocket(true, ResponseEnum.PROJECT_EXPORT_TASK_SUCCESS), String.valueOf(userId));
        } catch (Exception e) {
            e.printStackTrace();
            WebSocketServer.sendInfo(Response.websocket(false, ResponseEnum.PROJECT_EXPORT_TASK_ERROR), String.valueOf(userId));
        }
    }

    @Async("singleThreadAsyncTaskExecutor")
    @Transactional(rollbackFor = Exception.class)
    public void importData(String url, ProjectImportVO params, Integer userId, Integer importId) {
        String tempPath = null;
        ProjectImportStatusService projectImportStatusService = SpringUtil.getBean(ProjectImportStatusService.class);
        try {
            String tempDirectoryName = IdUtil.simpleUUID();
            tempPath = fileUtils.getTempPath(tempDirectoryName);
            String tempSavePath = fileUtils.getSystemPath(url);
            File tempDirectory = new File(tempPath);
            if (!tempDirectory.exists()) {
                boolean success = tempDirectory.mkdir();
                if (!success) {
                    throw new Exception("数据导入时创建文件夹失败");
                }
            }
            projectImportStatusService.add(importId, userId, 2);
            ZipUtil.unzip(tempSavePath, tempPath);
            String projectJson = this.parseTempFileData(tempPath, Constants.PROJECT_INFO_FILE_NAME);
            Integer projectId = params.getProjectId();
            if (StringUtils.isNotEmpty(projectJson)) {
                projectImportStatusService.add(importId, userId, 3);
                projectId = this.importProject(params.getProjectId(), projectJson, userId);
            }
            if (projectId.equals(0)) {
                projectImportStatusService.add(importId, userId, 100);
                throw new CustomException("数据包未包含专题库信息");
            }
            String projectReportJson = this.parseTempFileData(tempPath, Constants.PROJECT_REPORT_FILE_NAME);
            String projectFileJson = this.parseTempFileData(tempPath, Constants.PROJECT_FILE_FILE_NAME);
            if (StringUtils.isNotEmpty(projectReportJson) || StringUtils.isNotEmpty(projectFileJson)) {
                projectImportStatusService.add(importId, userId, 4);
                projectFileService.importProjectFile(projectId, userId, tempPath, projectFileJson, projectReportJson);
            }
            String patentIdPatentNoJson = this.parseTempFileData(tempPath, Constants.PATENT_ID_PATENT_NO_FILE_NAME);
            String patentJson = this.parseTempFileData(tempPath, Constants.PATENT_FILE_NAME);
            String patentAffairJson = this.parseTempFileData(tempPath, Constants.PATENT_AFFAIR_FILE_NAME);
            String patentAgencyJson = this.parseTempFileData(tempPath, Constants.PATENT_AGENCY_FILE_NAME);
            String patentAgentJson = this.parseTempFileData(tempPath, Constants.PATENT_AGENT_FILE_NAME);
            String patentAgentLinkJson = this.parseTempFileData(tempPath, Constants.PATENT_AGENT_LINK_FILE_NAME);
            String patentInventorJson = this.parseTempFileData(tempPath, Constants.PATENT_INVENTOR_FILE_NAME);
            String patentInventorMergeJson = this.parseTempFileData(tempPath, Constants.PATENT_INVENTOR_MERGE_FILE_NAME);
            String patentInventorLinkJson = this.parseTempFileData(tempPath, Constants.PATENT_INVENTOR_LINK_FILE_NAME);
            String patentApplicantJson = this.parseTempFileData(tempPath, Constants.PATENT_APPLICANT_FILE_NAME);
            String patentApplicantLinkJson = this.parseTempFileData(tempPath, Constants.PATENT_APPLICANT_LINK_FILE_NAME);
            String patentApplicantMergeLinkJson = this.parseTempFileData(tempPath, Constants.PATENT_APPLICANT_MERGE_LINK_FILE_NAME);
            String patentFamilyJson = this.parseTempFileData(tempPath, Constants.PATENT_FAMILY_FILE_NAME);
            String patentFamilyLinkJson = this.parseTempFileData(tempPath, Constants.PATENT_FAMILY_LINK_FILE_NAME);
            String patentClassNumberJson = this.parseTempFileData(tempPath, Constants.PATENT_CLASS_NUMBER_FILE_NAME);
            String patentInstructionTextJson = this.parseTempFileData(tempPath, Constants.PATENT_INSTRUCTION_TEXT_FILE_NAME);
            String patentRightJson = this.parseTempFileData(tempPath, Constants.PATENT_RIGHT_FILE_NAME);
            String patentLicensorJson = this.parseTempFileData(tempPath, Constants.PATENT_LICENSOR_FILE_NAME);
            String patentPledgeJson = this.parseTempFileData(tempPath, Constants.PATENT_PLEDGE_FILE_NAME);
            if (StringUtils.isNotEmpty(patentJson)) {
                projectImportStatusService.add(importId, userId, 8);
                patentService.importPatent(projectId, patentJson, patentAffairJson, patentAgencyJson, patentFamilyJson, patentFamilyLinkJson, patentInventorJson, patentInventorLinkJson, patentAgentJson, patentAgentLinkJson, patentApplicantJson, patentApplicantLinkJson, patentApplicantMergeLinkJson, patentClassNumberJson, patentInstructionTextJson, patentRightJson, patentLicensorJson, patentPledgeJson, patentInventorMergeJson);
            }
            projectImportStatusService.add(importId, userId, 9);
            projectPatentLinkService.importProjectPatentLink(projectId, patentIdPatentNoJson);
            String projectFieldJson = this.parseTempFileData(tempPath, Constants.PROJECT_FIELD_FILE_NAME);
            if (StringUtils.isNotEmpty(projectFieldJson)) {
                String projectFieldTextJson = this.parseTempFileData(tempPath, Constants.PROJECT_FIELD_TEXT_FILE_NAME);
                String projectFieldOptionJson = this.parseTempFileData(tempPath, Constants.PROJECT_FIELD_OPTION_FILE_NAME);
                String projectFieldTreeJson = this.parseTempFileData(tempPath, Constants.PROJECT_FIELD_TREE_FILE_NAME);
                String projectFieldPatentLink = this.parseTempFileData(tempPath, Constants.PROJECT_FIELD_PATENT_LINK_FILE_NAME);
                projectImportStatusService.add(importId, userId, 5);
                projectFieldService.importProjectField(projectId, userId, patentIdPatentNoJson, projectFieldJson, projectFieldTextJson, projectFieldOptionJson, projectFieldTreeJson, projectFieldPatentLink);
            }
            String patentImageJson = this.parseTempFileData(tempPath, Constants.PATENT_IMAGE_FILE_NAME);
            if (StringUtils.isNotEmpty(patentImageJson)) {
                projectImportStatusService.add(importId, userId, 6);
                patentImageService.importPatentImage(tempPath, patentIdPatentNoJson, patentImageJson);
            }
            String patentInstructionJson = this.parseTempFileData(tempPath, Constants.PATENT_INSTRUCTION_FILE_NAME);
            if (StringUtils.isNotEmpty(patentInstructionJson)) {
                projectImportStatusService.add(importId, userId, 7);
                patentInstructionService.importPatentInstruction(userId, tempPath, patentIdPatentNoJson, patentInstructionJson);
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            projectImportStatusService.add(importId, userId, 101);
        } finally {
            FileUtil.del(tempPath);
            projectImportStatusService.add(importId, userId, 200);
            cacheUtils.deleteUserImport(userId);
        }
    }

    private String parseTempFileData(String path, String fileName) throws IOException {
        String src = path + FileUtil.FILE_SEPARATOR + fileName;
        if (!FileUtil.exist(src)) {
            return null;
        }
        File file = new File(src);
        FileReader fileReader = new FileReader(file);
        Reader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
        int ch;
        StringBuffer sb = new StringBuffer();
        while ((ch = reader.read()) != -1) {
            sb.append((char) ch);
        }
        fileReader.close();
        reader.close();
        return sb.toString();
    }

    //主页面 导出列表功能
    public void exportProject(HttpServletResponse response) {
        try {
            ProjectVO params = new ProjectVO();
            params.setSize(99999999999L);
            params.setCurrent(1L);
            params.setMyself(false);
            ProjectVO.Sort sort = new ProjectVO.Sort();
            sort.setProp("create_time");
            sort.setOrder("desc");
            params.setSort(sort);
            IPage<Project> pageList = this.getPageList(params);
            List<Project> projectList = pageList.getRecords();
            List<List<String>> row = new ArrayList<>();
            row.add(CollUtil.newArrayList("#", "名称", "委托方", "调查类型", "应用场景", "技术主题", "合同号", "委案日", "创建人"));
            for (int i = 0; i < projectList.size(); i++) {
                Project project = projectList.get(i);
                row.add(CollUtil.newArrayList(String.valueOf(i + 1), project.getName(), project.getClientName(), StringUtils.join(project.getTypeName(), ","), StringUtils.join(project.getScenarioName(), ","), project.getTechnicalTheme(), project.getContractNo(), project.getCaseDate(), project.getCreateName()));
            }
            List<List<String>> rows = CollUtil.newArrayList(row);
            ExcelWriter writer = ExcelUtil.getWriter(true);
            OutputStream out = response.getOutputStream();
            writer.write(rows, true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + IdUtil.simpleUUID() + ".xlsx");
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param projectCopyDTO
     * @return
     * @throws IOException
     * @deprecated 复制专题库
     */
    @Transactional
    public Integer copy(ProjectCopyDTO projectCopyDTO) throws IOException {
        Integer oldId = projectCopyDTO.getId();
        //复制专题库基本信息
        Project project = this.getById(oldId);
        project.setTenantId(projectCopyDTO.getTenantId());
        project.setId(null);
        project.insert();
        //复制专题库专利
        LambdaQueryWrapper<ProjectPatentLink> patentLinkWrapper = new LambdaQueryWrapper<>();
        patentLinkWrapper.eq(ProjectPatentLink::getProjectId, oldId);
        List<ProjectPatentLink> projectPatentLinkList = projectPatentLinkService.list(patentLinkWrapper);
        projectPatentLinkList.forEach(
                item -> {
                    item.setProjectId(project.getId());
                    item.setId(null);
                }
        );
        projectPatentLinkService.saveBatch(projectPatentLinkList);
        //复制专题库标引信息
        copyService.CopyPatentLabels(oldId, project.getId());
        //复制专题库文件夹
        copyService.CopyProjectFolder(oldId, project.getId());
        return project.getId();
    }

}
