package com.xdap.self_development.service.impl;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.definesys.mpaas.query.MpaasQuery;
import com.definesys.mpaas.query.MpaasQueryFactory;
import com.xdap.api.moudle.user.pojo.XdapUsers;
import com.xdap.self_development.common.BusinessDatabase;
import com.xdap.self_development.controller.request.EngineParamDetailExcel;
import com.xdap.self_development.controller.request.EngineParamDetailRequest;
import com.xdap.self_development.domain.dto.EngineDeptUpdateDTO;
import com.xdap.self_development.domain.dto.EngineDeptUpdateItem;
import com.xdap.self_development.domain.dto.EngineParamDetailDTO;
import com.xdap.self_development.domain.enums.CurrentNodeEnum;
import com.xdap.self_development.domain.enums.DistributeStatusEnum;
import com.xdap.self_development.domain.enums.ParamOperationEnum;
import com.xdap.self_development.domain.enums.ParamValueVersionEnum;
import com.xdap.self_development.domain.pojo.*;
import com.xdap.self_development.domain.view.MenuParamView;
import com.xdap.self_development.exception.CommonException;
import com.xdap.self_development.exception.ExcelImportException;
import com.xdap.self_development.listener.EngineParamDetailListener;
import com.xdap.self_development.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.Collator;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 发动机参数详情服务实现类
 *
 * @version 1.0
 * @since 2025
 */
@Slf4j
@Service
public class EngineParamDetailServiceImpl implements EngineParamDetailService {

    @Resource
    private BusinessDatabase bd;
    @Resource
    private MpaasQueryFactory sw;
    @Resource
    private DataEntryEngineModelService dataEntryEngineModelService;
    @Resource
    private DataEntryService dataEntryService;
    @Resource
    private XdapDeptUsersService xdapDeptUsersService;
    @Resource
    private ResponsiblePerService responsiblePerService;
    @Resource
    private ModelRoleService modelRoleService;

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private Comparator<String> getPartsNameComparator() {
        Collator collator = Collator.getInstance(Locale.CHINA);
        return (a, b) -> {
            if ("/".equals(a) && !"/".equals(b)) {
                return -1;
            }
            if (!"/".equals(a) && "/".equals(b)) {
                return 1;
            }
            return collator.compare(a, b);
        };
    }



    /**
     * 返回参数列表
     * 根据模型ID和TC数据标志选择参数列表
     *
     * @param modelID 发动机型号ID
     * @param tcData  TC数据标识
     * @return 参数列表映射
     */
    @Override
    public Map<String, Set<String>> selectParamList(String modelID, String tcData, String userId) {
        List<ParameterPojo> allParameters;
        if (ObjectUtils.isNotEmpty(tcData) && "tc".equals(tcData)) {
            allParameters = selectAllAndTcByNewVersion();
        } else {
            allParameters = selectAllByNewVersion();
        }
        List<ParameterPojo> parameters = selectParamByIsUserId(allParameters, userId);

        List<TemplatePojo> templates = bd.getBusinessDatabase()
                .eq("status", "COMPLETE")
                .doQuery(TemplatePojo.class);
        if (ObjectUtils.isEmpty(templates)) {
            throw new CommonException("未找到未找到已发布的参数模板");
        }

        AtomicInteger seq = new AtomicInteger(1);
        LinkedHashMap<String, Integer> subsystemOrderMap = parameters.stream()
                .sorted(Comparator
                        .comparing(ParameterPojo::getSubsystemName, Collator.getInstance(Locale.CHINA))
                        .thenComparing(ParameterPojo::getParameterName, Collator.getInstance(Locale.CHINA))
                )
                .map(ParameterPojo::getSubsystemName)
                .distinct()
                .collect(Collectors.toMap(
                        s -> s,
                        s -> seq.getAndIncrement(), // 每次获取当前值，再自增（从1开始）
                        (o, n) -> o,
                        LinkedHashMap::new
                ));

        Map<String, Set<String>> collect = parameters.stream()
                .collect(Collectors.groupingBy(
                        ParameterPojo::getSubsystemName,
                        Collectors.mapping(
                                ParameterPojo::getPartsName,  // 提取 零部件名称字段
                                Collectors.toSet()
                        )
                ));
        if (ObjectUtils.isNotEmpty(modelID)) {
            subsystemOrderMap.put("整车参数", 0);
            DataEntryEngineModelPojo dataEntryEngineModelPojo = dataEntryEngineModelService.selectBymodelId(modelID);
            //状态代号
            String productNumber = dataEntryEngineModelPojo.getProductNumber();
            //板块
            String plate = dataEntryEngineModelPojo.getPlate();
            //平台
            String platform = dataEntryEngineModelPojo.getPlatform();
            //系列
            String series = dataEntryEngineModelPojo.getSeries();
            //细分市场
            String marketSegment = dataEntryEngineModelPojo.getMarketSegment();
            //项目名称
            String projectName = dataEntryEngineModelPojo.getProjectName();
            //项目编号
            String projectNumber = dataEntryEngineModelPojo.getProjectNumber();
            //品牌
            String brand = dataEntryEngineModelPojo.getBrand();
            //排放
            String emission = dataEntryEngineModelPojo.getEmission();
            String burnType = dataEntryEngineModelPojo.getBurnType();
            String engineCapacity = dataEntryEngineModelPojo.getEngineCapacity();
            Date productionDate = dataEntryEngineModelPojo.getProductionDate();
            String manufacturerName = dataEntryEngineModelPojo.getManufacturerName();
            String manufacturerAbbreviation = dataEntryEngineModelPojo.getManufacturerAbbreviation();
            Set<String> strings = new HashSet<>();
            if ("玉柴".equals(dataEntryEngineModelPojo.getYcOrOth())) {
                strings.add("状态代号:" + productNumber);
            } else {
                strings.add("产品编号:" + productNumber);
                strings.add("品牌:" + brand);
                strings.add("厂家全称:" + manufacturerName);
                strings.add("厂家简称:" + manufacturerAbbreviation);
                strings.add("生产日期:" + new SimpleDateFormat("yyyy-MM-dd").format(productionDate));
            }
            strings.add("产品型号:" + dataEntryEngineModelPojo.getModelName());
            strings.add("板块:" + plate);
            strings.add("平台:" + platform);
            strings.add("系列:" + series);
            strings.add("细分市场:" + marketSegment);
            strings.add("项目名称:" + projectName);
            strings.add("项目编号:" + projectNumber);
            strings.add("排放:" + emission);
            strings.add("燃烧类型:" + burnType);
            strings.add("排量:" + engineCapacity);

            collect.put("整车参数", strings);
        }
        // 保持顺序
        return collect.entrySet().stream()
                .sorted(Comparator.comparing(entry ->
                        subsystemOrderMap.getOrDefault(entry.getKey(), Integer.MAX_VALUE)
                ))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new  // 保持顺序
                ));
    }

    private static String nvl(Object obj) {
        return obj == null ? "" : obj.toString();
    }

    public Map<String, Set<String>> selectParamListByDetails(String modelID, Integer parameterVersion, String userId) {
        if (parameterVersion == null) {
            DataEntryEngineModelPojo engineModel = bd.getBusinessDatabase()
                    .eq("id", modelID)
                    .doQueryFirst(DataEntryEngineModelPojo.class);
            if (engineModel == null) {
                throw new CommonException("未找到该型号的参数");
            }
            parameterVersion = engineModel.getVersionNumber();
        }

        List<EngineParamDetailPojo> pojoList = selectByIsUserId(modelID, parameterVersion, userId);
        
        log.info("selectParamListByDetails - modelID: {}, parameterVersion: {}, userId: {}, pojoList size: {}", 
                modelID, parameterVersion, userId, pojoList.size());
        
        Collator collator = Collator.getInstance(Locale.CHINA);
        Comparator<String> partsComparator = getPartsNameComparator();
        
        AtomicInteger seq = new AtomicInteger(1);
        LinkedHashMap<String, Integer> subsystemOrderMap = pojoList.stream()
                .sorted(Comparator
                        .comparing(EngineParamDetailPojo::getSubsystemName, collator)
                        .thenComparing(EngineParamDetailPojo::getPartsName, partsComparator)
                        .thenComparing(EngineParamDetailPojo::getParameterName, collator)
                )
                .map(EngineParamDetailPojo::getSubsystemName)
                .distinct()
                .collect(Collectors.toMap(
                        s -> s,
                        s -> seq.getAndIncrement(),
                        (o, n) -> o,
                        LinkedHashMap::new
                ));

        Map<String, Set<String>> collect = pojoList.stream()
                .sorted(Comparator
                        .comparing(EngineParamDetailPojo::getSubsystemName, collator)
                        .thenComparing(EngineParamDetailPojo::getPartsName, partsComparator)
                )
                .collect(Collectors.groupingBy(
                        EngineParamDetailPojo::getSubsystemName,
                        LinkedHashMap::new,
                        Collectors.mapping(
                                EngineParamDetailPojo::getPartsName,
                                Collectors.toCollection(LinkedHashSet::new)
                        )
                ));
        if (ObjectUtils.isNotEmpty(modelID)) {
            subsystemOrderMap.put("整车参数", 0);
            DataEntryEngineModelPojo dataEntryEngineModelPojo = bd.getBusinessDatabase()
                    .eq("id", modelID)
                    .doQueryFirst(DataEntryEngineModelPojo.class);
            if (dataEntryEngineModelPojo == null) {
                throw new CommonException("未找到机型的数据");
            }
            //状态代号
            String productNumber = nvl(dataEntryEngineModelPojo.getProductNumber());
            //板块
            String plate = nvl(dataEntryEngineModelPojo.getPlate());
            //平台
            String platform = nvl(dataEntryEngineModelPojo.getPlatform());
            //系列
            String series = nvl(dataEntryEngineModelPojo.getSeries());
            //细分市场
            String marketSegment = nvl(dataEntryEngineModelPojo.getMarketSegment());
            //项目名称
            String projectName = nvl(dataEntryEngineModelPojo.getProjectName());
            //项目编号
            String projectNumber = nvl(dataEntryEngineModelPojo.getProjectNumber());
            //品牌
            String brand = nvl(dataEntryEngineModelPojo.getBrand());
            //排放
            String emission = nvl(dataEntryEngineModelPojo.getEmission());
            String burnType = nvl(dataEntryEngineModelPojo.getBurnType());
            String engineCapacity = nvl(dataEntryEngineModelPojo.getEngineCapacity());
            String productionDateStr;
            if (dataEntryEngineModelPojo.getProductionDate() != null) {
                productionDateStr = new SimpleDateFormat("yyyy-MM-dd").format(dataEntryEngineModelPojo.getProductionDate());
            } else {
                productionDateStr = ""; // 或者设置一个默认值
            }
            String manufacturerName = nvl(dataEntryEngineModelPojo.getManufacturerName());
            String manufacturerAbbreviation = nvl(dataEntryEngineModelPojo.getManufacturerAbbreviation());
            Set<String> strings = new HashSet<>();
            if ("玉柴".equals(dataEntryEngineModelPojo.getYcOrOth())) {
                strings.add("状态代号:" + productNumber);
            } else {
                strings.add("产品编号:" + productNumber);
                strings.add("品牌:" + brand);
                strings.add("厂家全称:" + manufacturerName);
                strings.add("厂家简称:" + manufacturerAbbreviation);
                strings.add("生产日期:" + productionDateStr);
            }
            strings.add("产品型号:" + dataEntryEngineModelPojo.getModelName());
            strings.add("板块:" + plate);
            strings.add("平台:" + platform);
            strings.add("系列:" + series);
            strings.add("细分市场:" + marketSegment);
            strings.add("项目名称:" + projectName);
            strings.add("项目编号:" + projectNumber);
            strings.add("排放:" + emission);
            strings.add("燃烧类型:" + burnType);
            strings.add("排量:" + engineCapacity);

            collect.put("整车参数", strings);
        }
        // 保持顺序
        return collect.entrySet().stream()
                .sorted(Comparator.comparing(entry ->
                        subsystemOrderMap.getOrDefault(entry.getKey(), Integer.MAX_VALUE)
                ))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new
                ));
    }

    private Map<String, Set<String>> selectParamListByDetailsForFilledBy(String modelID, Integer parameterVersion, String userId) {
        if (parameterVersion == null) {
            DataEntryEngineModelPojo engineModel = bd.getBusinessDatabase()
                    .eq("id", modelID)
                    .doQueryFirst(DataEntryEngineModelPojo.class);
            if (engineModel == null) {
                throw new CommonException("未找到该型号的参数");
            }
            parameterVersion = engineModel.getVersionNumber();
        }

        List<EngineParamDetailPojo> pojoList = bd.getBusinessDatabase()
                .eq("engine_model_id", modelID)
                .eq("major_version", parameterVersion)
                .eq("filled_by", userId)
                .eq("is_distributed_filled", 1)
                .in("version_status", Arrays.asList(1, null))
                .doQuery(EngineParamDetailPojo.class);

        return buildParamListMap(pojoList, modelID);
    }

    private Map<String, Set<String>> selectParamListByDetailsForFilledByHistory(String modelID, Integer parameterVersion, String userId) {
        if (parameterVersion == null) {
            DataEntryEngineModelPojo engineModel = bd.getBusinessDatabase()
                    .eq("id", modelID)
                    .doQueryFirst(DataEntryEngineModelPojo.class);
            if (engineModel == null) {
                throw new CommonException("未找到该型号的参数");
            }
            parameterVersion = engineModel.getVersionNumber();
        }

        List<EngineParamDetailPojo> pojoList = bd.getBusinessDatabase()
                .eq("engine_model_id", modelID)
                .eq("major_version", parameterVersion)
                .eq("filled_by", userId)
                .eq("is_distributed_filled", 1)
                .in("version_status", Arrays.asList(0, 2, 4))
                .doQuery(EngineParamDetailPojo.class);

        return buildParamListMap(pojoList, modelID);
    }

    private Map<String, Set<String>> buildParamListMap(List<EngineParamDetailPojo> pojoList, String modelID) {
        Collator collator = Collator.getInstance(Locale.CHINA);
        Comparator<String> partsComparator = getPartsNameComparator();
        
        AtomicInteger seq = new AtomicInteger(1);
        LinkedHashMap<String, Integer> subsystemOrderMap = pojoList.stream()
                .sorted(Comparator
                        .comparing(EngineParamDetailPojo::getSubsystemName, collator)
                        .thenComparing(EngineParamDetailPojo::getPartsName, partsComparator)
                        .thenComparing(EngineParamDetailPojo::getParameterName, collator)
                )
                .map(EngineParamDetailPojo::getSubsystemName)
                .distinct()
                .collect(Collectors.toMap(
                        s -> s,
                        s -> seq.getAndIncrement(),
                        (o, n) -> o,
                        LinkedHashMap::new
                ));

        Map<String, Set<String>> collect = pojoList.stream()
                .sorted(Comparator
                        .comparing(EngineParamDetailPojo::getSubsystemName, collator)
                        .thenComparing(EngineParamDetailPojo::getPartsName, partsComparator)
                )
                .collect(Collectors.groupingBy(
                        EngineParamDetailPojo::getSubsystemName,
                        LinkedHashMap::new,
                        Collectors.mapping(
                                EngineParamDetailPojo::getPartsName,
                                Collectors.toCollection(LinkedHashSet::new)
                        )
                ));
        
        if (ObjectUtils.isNotEmpty(modelID)) {
            subsystemOrderMap.put("整车参数", 0);
            DataEntryEngineModelPojo dataEntryEngineModelPojo = bd.getBusinessDatabase()
                    .eq("id", modelID)
                    .doQueryFirst(DataEntryEngineModelPojo.class);
            if (dataEntryEngineModelPojo == null) {
                throw new CommonException("未找到机型的数据");
            }
            
            String productNumber = nvl(dataEntryEngineModelPojo.getProductNumber());
            String plate = nvl(dataEntryEngineModelPojo.getPlate());
            String platform = nvl(dataEntryEngineModelPojo.getPlatform());
            String series = nvl(dataEntryEngineModelPojo.getSeries());
            String marketSegment = nvl(dataEntryEngineModelPojo.getMarketSegment());
            String projectName = nvl(dataEntryEngineModelPojo.getProjectName());
            String projectNumber = nvl(dataEntryEngineModelPojo.getProjectNumber());
            String brand = nvl(dataEntryEngineModelPojo.getBrand());
            String emission = nvl(dataEntryEngineModelPojo.getEmission());
            String burnType = nvl(dataEntryEngineModelPojo.getBurnType());
            String engineCapacity = nvl(dataEntryEngineModelPojo.getEngineCapacity());
            String productionDateStr;
            if (dataEntryEngineModelPojo.getProductionDate() != null) {
                productionDateStr = new SimpleDateFormat("yyyy-MM-dd").format(dataEntryEngineModelPojo.getProductionDate());
            } else {
                productionDateStr = "";
            }
            String manufacturerName = nvl(dataEntryEngineModelPojo.getManufacturerName());
            String manufacturerAbbreviation = nvl(dataEntryEngineModelPojo.getManufacturerAbbreviation());
            
            Set<String> strings = new HashSet<>();
            if ("玉柴".equals(dataEntryEngineModelPojo.getYcOrOth())) {
                strings.add("状态代号:" + productNumber);
            } else {
                strings.add("产品编号:" + productNumber);
                strings.add("品牌:" + brand);
                strings.add("厂家全称:" + manufacturerName);
                strings.add("厂家简称:" + manufacturerAbbreviation);
                strings.add("生产日期:" + productionDateStr);
            }
            strings.add("产品型号:" + dataEntryEngineModelPojo.getModelName());
            strings.add("板块:" + plate);
            strings.add("平台:" + platform);
            strings.add("系列:" + series);
            strings.add("细分市场:" + marketSegment);
            strings.add("项目名称:" + projectName);
            strings.add("项目编号:" + projectNumber);
            strings.add("排放:" + emission);
            strings.add("燃烧类型:" + burnType);
            strings.add("排量:" + engineCapacity);

            collect.put("整车参数", strings);
        }
        
        return collect.entrySet().stream()
                .sorted(Comparator.comparing(entry ->
                        subsystemOrderMap.getOrDefault(entry.getKey(), Integer.MAX_VALUE)
                ))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue,
                        (oldValue, newValue) -> oldValue,
                        LinkedHashMap::new
                ));
    }

    private List<EngineParamDetailPojo> selectByIsUserId(String modelID, Integer parameterVersion, String userId) {
        // 没有人则返回全部
        List<EngineParamDetailPojo> pojoList = bd.getBusinessDatabase()
                .eq("engine_model_id", modelID)
                .eq("major_version", parameterVersion)
                .doQuery(EngineParamDetailPojo.class);
        if (userId == null || userId.isEmpty()) {
            return pojoList;
        }
        List<MenuParamView> menuParamViews = modelRoleService.selectPersByUser(userId);
        // 管理员返回全部
        for (MenuParamView menuParamView : menuParamViews) {
            if (menuParamView.getIsAdmin() != null &&
                    menuParamView.getIsAdmin() == 1) {
                return pojoList;
            }
        }

        // 过滤返回
        DataEntryEngineModelPojo model = bd.getBusinessDatabase()
                .eq("id", modelID)
                .doQueryFirst(DataEntryEngineModelPojo.class);

        // 权限路径集合
        Set<String> result = menuParamViews.stream()
                .map(MenuParamView::getPermissionPath)
                .collect(Collectors.toSet());
        return pojoList.stream()
                .filter(pojo ->
                        modelRoleService.matchesAnyPermission(
                                pojo,
                                modelRoleService.buildPermissionIndex(result),
                                model.getYcOrOth() + "发动机数据"
                        ))
                .collect(Collectors.toList());
    }

    /**
     * 查询参数列表和模型
     * 根据模型ID获取参数列表和模型信息
     *
     * @param modelID 发动机型号ID
     * @return 参数列表和模型映射
     */
    @Override
    public Map<String, Map<String, Set<String>>> selectParamListAndModel(String modelID, Integer parameterVersion, String userId) {
        HashMap<String, Map<String, Set<String>>> map = new HashMap<>();
        DataEntryEngineModelPojo dataEntryEngineModelPojo = dataEntryEngineModelService.selectBymodelId(modelID);
        if (ObjectUtils.isEmpty(dataEntryEngineModelPojo)) {
            throw new CommonException("未找到该机型");
        }
        String s = dataEntryEngineModelPojo.getProductNumber();
        Map<String, Set<String>> stringListMap = selectParamListByDetails(modelID, parameterVersion, userId);
        map.put(s, stringListMap);
        return map;
    }

    @Override
    public Map<String, Map<String, Set<String>>> selectParamListAndModelForFilledBy(String modelID, Integer parameterVersion, String userId) {
        HashMap<String, Map<String, Set<String>>> map = new HashMap<>();
        DataEntryEngineModelPojo dataEntryEngineModelPojo = dataEntryEngineModelService.selectBymodelId(modelID);
        if (ObjectUtils.isEmpty(dataEntryEngineModelPojo)) {
            throw new CommonException("未找到该机型");
        }
        String s = dataEntryEngineModelPojo.getProductNumber();
        Map<String, Set<String>> stringListMap = selectParamListByDetailsForFilledBy(modelID, parameterVersion, userId);
        map.put(s, stringListMap);
        return map;
    }

    @Override
    public Map<String, Map<String, Set<String>>> selectParamListAndModelForFilledByHistory(String modelID, Integer parameterVersion, String userId) {
        HashMap<String, Map<String, Set<String>>> map = new HashMap<>();
        DataEntryEngineModelPojo dataEntryEngineModelPojo = dataEntryEngineModelService.selectBymodelId(modelID);
        if (ObjectUtils.isEmpty(dataEntryEngineModelPojo)) {
            throw new CommonException("未找到该机型");
        }
        String s = dataEntryEngineModelPojo.getProductNumber();
        Map<String, Set<String>> stringListMap = selectParamListByDetailsForFilledByHistory(modelID, parameterVersion, userId);
        map.put(s, stringListMap);
        return map;
    }


    /**
     * Excel导入
     * 从Excel文件导入参数详情数据
     *
     * @param file   Excel文件
     * @param modelId 型号ID
     * @param userId 用户ID
     * @return void
     */
    @Override
    public void excelImport(MultipartFile file, String modelId, String userId) {

        DataEntryEngineModelPojo modelPojo =
                dataEntryEngineModelService.selectBymodelId(modelId);
        if (ObjectUtils.isEmpty(modelPojo)) {
            throw new ExcelImportException("发动机型号不存在");
        }
        try {
            EasyExcel.read(
                    file.getInputStream(),
                    EngineParamDetailExcel.class,
                    new EngineParamDetailListener(
                            bd,
                            modelPojo,
                            userId
                    )
            ).build().readAll();
        } catch (IOException e) {
            log.error("导入失败IO异常");
        } catch (RuntimeException e) {
            throw new ExcelImportException(e.getMessage());
        }
    }

    /**
     * Excel导出
     * 导出参数详情数据到Excel文件
     *
     * @param response HTTP响应对象
     * @param modelId  型号ID
     * @param userId   用户ID
     * @return void
     */
    @Override
    public void excelExport(
            HttpServletResponse response,
            String modelId,
            String userId,
            java.util.List<String> subsystemParts
    ) {
        DataEntryEngineModelPojo model = bd.getBusinessDatabase()
                .eq("id", modelId)
                .doQueryFirst(DataEntryEngineModelPojo.class);
        if (ObjectUtils.isEmpty(model)) {
            throw new CommonException("机型不存在，请检查");
        }
        
        Set<String> subsystemSet = new HashSet<>();
        Set<String> typeSet = new HashSet<>();
        
        if (subsystemParts != null && !subsystemParts.isEmpty()) {
            for (String subsystemType : subsystemParts) {
                if (subsystemType.split("-").length != 2) {
                    throw new CommonException("查询条件异常,需子系统-零部件名称,若零部件为空则传入\"/\"");
                }
                String subsystem = subsystemType.split("-")[0];
                String type = subsystemType.split("-")[1];
                subsystemSet.add(subsystem);
                typeSet.add(type);
            }
        }
        
        MpaasQuery query = bd.getBusinessDatabase()
                .eq("engine_model_id", model.getId());
        
        if (!subsystemSet.isEmpty()) {
            query.in("subsystem_name", subsystemSet);
        }
        if (!typeSet.isEmpty()) {
            query.in("parts_name", typeSet);
        }
        
        query.eq("last_updated_by", userId);
        query.eq("major_version", model.getVersionNumber());
        
        List<EngineParamDetailPojo> engineParams = query.doQuery(EngineParamDetailPojo.class);
        
        if (ObjectUtils.isEmpty(engineParams)) {
            query = bd.getBusinessDatabase()
                    .eq("engine_model_id", model.getId());
            
            if (!subsystemSet.isEmpty()) {
                query.in("subsystem_name", subsystemSet);
            }
            if (!typeSet.isEmpty()) {
                query.in("parts_name", typeSet);
            }
            
            query.eq("filled_by", userId);
            query.eq("major_version", model.getVersionNumber());
            
            engineParams = query.doQuery(EngineParamDetailPojo.class);
        }
        
        if (ObjectUtils.isEmpty(engineParams)) {
            log.error("模板参数为空");
            throw new ExcelImportException(
                    "模板参数未配置"
            );
        }
        
        Map<String, EngineParamDetailPojo> uniqueParamsMap = new LinkedHashMap<>();
        for (EngineParamDetailPojo param : engineParams) {
            String key = param.getParameterName() + "_" + param.getPartsName();
            EngineParamDetailPojo existing = uniqueParamsMap.get(key);
            
            if (existing == null) {
                uniqueParamsMap.put(key, param);
            } else {
                boolean shouldReplace = false;
                
                if (param.getLastUpdateDate() != null && existing.getLastUpdateDate() != null) {
                    if (param.getLastUpdateDate().after(existing.getLastUpdateDate())) {
                        shouldReplace = true;
                    }
                } else if (param.getLastUpdateDate() != null) {
                    shouldReplace = true;
                }
                
                if (shouldReplace) {
                    uniqueParamsMap.put(key, param);
                }
            }
        }
        List<EngineParamDetailPojo> uniqueParams = new ArrayList<>(uniqueParamsMap.values());
        
        Collator collator = Collator.getInstance(Locale.CHINA);
        Comparator<String> partsComparator = getPartsNameComparator();
        
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12);
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);

        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, new WriteCellStyle());

        List<String> sheetNames = uniqueParams.stream()
                .map(EngineParamDetailPojo::getSubsystemName)
                .distinct()
                .sorted(collator)
                .collect(Collectors.toList());

        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build()) {
            setupResponse(response, "参数值导入模板" + (formatter.format(LocalDateTime.now())));
            for (int i = 0; i < sheetNames.size(); i++) {
                String sheetName = sheetNames.get(i);
                List<EngineParamDetailPojo> parameterList = uniqueParams.stream()
                        .filter(x -> x.getSubsystemName().equals(sheetName))
                        .sorted(Comparator
                                .comparing(EngineParamDetailPojo::getPartsName, partsComparator)
                                .thenComparing(EngineParamDetailPojo::getParameterName, collator)
                        )
                        .collect(Collectors.toList());
                List<EngineParamDetailExcel> engineParamDetailExcels = new ArrayList<>();
                for (EngineParamDetailPojo parameter : parameterList) {
                    EngineParamDetailExcel engineParamDetailExcel = new EngineParamDetailExcel();
                    BeanUtils.copyProperties(parameter, engineParamDetailExcel);
                    engineParamDetailExcel.setId(parameter.getId());
                    engineParamDetailExcels.add(engineParamDetailExcel);
                }
                WriteSheet sheet = EasyExcel.writerSheet(i, sheetNames.get(i))
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        .head(EngineParamDetailExcel.class)
                        .build();
                excelWriter.write(engineParamDetailExcels, sheet);
            }
        } catch (Exception e) {
            throw new CommonException("导出Excel文件异常");
        }
    }

    /**
     * 根据参数查询值
     * 根据参数详情请求查询参数值
     *
     * @param engineParamDetailRequest 发动机参数详情请求
     * @return 参数详情DTO列表
     */
    @Override
    public List<EngineParamDetailDTO> selectValueByParam(EngineParamDetailRequest engineParamDetailRequest) {
        String engineModelID = engineParamDetailRequest.getEngineModelID();
        String subsystemName = engineParamDetailRequest.getSubsystemName();
        String parameterType = engineParamDetailRequest.getParameterType();
        if (ObjectUtils.isEmpty(engineModelID) || ObjectUtils.isEmpty(subsystemName) || ObjectUtils.isEmpty(parameterType)) {
            throw new CommonException("传入参数为空，请检查");
        }
        List<EngineParamDetailPojo> detailPojos = bd.getBusinessDatabase()
                .eq("engine_model_id", engineModelID)
                .eq("subsystem_name", subsystemName)
                .eq("parameter_type", parameterType)
                .doQuery(EngineParamDetailPojo.class);
        ArrayList<EngineParamDetailDTO> engineParamDetailDTOS = new ArrayList<>();
        for (EngineParamDetailPojo detailPojo : detailPojos) {
            EngineParamDetailDTO engineParamDetailDTO = new EngineParamDetailDTO();
            BeanUtils.copyProperties(detailPojo, engineParamDetailDTO);
            engineParamDetailDTOS.add(engineParamDetailDTO);
        }
        return engineParamDetailDTOS;
    }

    /**
     * 根据多个参数查询值
     * 根据参数详情请求查询多个参数的值
     *
     * @param request 发动机参数详情请求
     * @return 参数详情DTO映射
     */
    @Override
    public Map<String, List<EngineParamDetailDTO>> selectValueByMoreParam(EngineParamDetailRequest request) {
        List<EngineParamDetailDTO> engineParamDetailDTOS = new ArrayList<>();

        // 获取当前机型
        DataEntryEngineModelPojo model = bd.getBusinessDatabase()
                .eq("id", request.getEngineModelID())
                .doQueryFirst(DataEntryEngineModelPojo.class);
        if (ObjectUtils.isEmpty(model)) {
            throw new CommonException("机型不存在，请检查");
        }

        // 根据条件过滤查询
        Set<String> subsystemSet = new HashSet<>();
        Set<String> typeSet = new HashSet<>();
        request.getSubsystemParts().forEach(subsystemType -> {
            if (subsystemType.split("-").length != 2) {
                throw new CommonException("查询条件异常,需子系统-零部件名称,若零部件为空则传入“/”");
            }
            String subsystem = subsystemType.split("-")[0];
            String type = subsystemType.split("-")[1];
            subsystemSet.add(subsystem);
            typeSet.add(type);
        });

        MpaasQuery query = bd.getBusinessDatabase()
                .eq("engine_model_id", model.getId())
                .in("subsystem_name", subsystemSet)
                .in("parts_name", typeSet);

        //若传入填写人则查询填写人需要填写的参数
        if (ObjectUtils.isNotEmpty(request.getFilledById())) {
            query.eq("last_updated_by", request.getFilledById());
            query.eq("major_version", model.getVersionNumber());
        } else if (ObjectUtils.isNotEmpty(request.getResponsiblePersonId())) {
            //若传入责任人则查询责任人需要分发的参数
            query.eq("responsible_person_id", request.getResponsiblePersonId());
            query.eq("major_version", model.getVersionNumber());
        } else {
            Integer version = model.getVersionNumber();
            if (request.getParameterVersion() != null) {
                version = request.getParameterVersion();
            }
            query.eq("major_version", version);
        }

        List<EngineParamDetailPojo> pojoList = query.doQuery(EngineParamDetailPojo.class);

        if (ObjectUtils.isNotEmpty(request.getFilledById()) && pojoList.isEmpty()) {
            pojoList.addAll(
                    bd.getBusinessDatabase()
                            .eq("engine_model_id", model.getId())
                            .in("subsystem_name", subsystemSet)
                            .in("parts_name", typeSet)
                            .eq("filled_by", request.getFilledById())
                            .eq("major_version", model.getVersionNumber())
                            .doQuery(EngineParamDetailPojo.class)
            );
        }

        Set<String> userList = new HashSet<>();
        Set<String> parameterList = new HashSet<>();
        pojoList.forEach(item -> {
            if (ObjectUtils.isNotEmpty(item.getFilledBy())) {
                userList.add(item.getFilledBy());
            }
            if (ObjectUtils.isNotEmpty(item.getResponsiblePersonId())) {
                userList.add(item.getResponsiblePersonId());
            }
            parameterList.add(item.getParameterId());
        });

        List<XdapUsers> users = xdapDeptUsersService.selectUserByIds(userList);
        Map<String, XdapUsers> usersMap = users.stream()
                .collect(Collectors.toMap(XdapUsers::getId, user -> user));
        List<ParameterPojo> parameterPojos = bd.getBusinessDatabase()
                .in("id", parameterList)
                .doQuery(ParameterPojo.class);
        Map<String, ParameterPojo> parameterPojoMap = parameterPojos.stream()
                .collect(Collectors.toMap(ParameterPojo::getId, parameterPojo -> parameterPojo));

        // 构建返回
        for (EngineParamDetailPojo detail : pojoList) {
            EngineParamDetailDTO engineParamDetailDTO = new EngineParamDetailDTO();
            BeanUtils.copyProperties(detail, engineParamDetailDTO);

            engineParamDetailDTO.setFilledBy(null);
            engineParamDetailDTO.setFiller(null);
            engineParamDetailDTO.setResPerson(null);
            engineParamDetailDTO.setResPersonId(null);
            engineParamDetailDTO.setIsDistributedFilled(0);
            engineParamDetailDTO.setIsDistributedRes(0);

            if (ObjectUtils.isNotEmpty(detail.getFilledBy())) {
                XdapUsers filler = usersMap.getOrDefault(detail.getFilledBy(), null);
                engineParamDetailDTO.setFiller(filler);
                engineParamDetailDTO.setFilledBy(ObjectUtils.isEmpty(filler) ? "" : filler.getUsername());
                engineParamDetailDTO.setIsDistributedFilled(1);
            }
            if (ObjectUtils.isNotEmpty(detail.getResponsiblePersonId())) {
                XdapUsers responsiblePerson = usersMap.getOrDefault(detail.getResponsiblePersonId(), null);
                engineParamDetailDTO.setResPerson(responsiblePerson);
                engineParamDetailDTO.setResPersonId(ObjectUtils.isEmpty(responsiblePerson) ? "" : responsiblePerson.getUsername());
                engineParamDetailDTO.setIsDistributedRes(1);
            }

            engineParamDetailDTO.setUnit(null);
            if (ObjectUtils.isNotEmpty(detail.getParameterId())) {
                ParameterPojo parameter = parameterPojoMap.getOrDefault(detail.getParameterId(), null);
                engineParamDetailDTO.setUnit(ObjectUtils.isEmpty(parameter) ? "" : parameter.getUnit());
            }

            engineParamDetailDTO.setId(detail.getId());
            engineParamDetailDTO.setApprovalId(detail.getApprovalId());
            engineParamDetailDTOS.add(engineParamDetailDTO);
        }

        // 排序返回
        Collator collator = Collator.getInstance(Locale.CHINA);
        Comparator<String> partsComparator = getPartsNameComparator();
        
        List<EngineParamDetailDTO> detailDTOList = engineParamDetailDTOS.stream()
                .sorted(Comparator
                        .comparing(EngineParamDetailDTO::getSubsystemName, collator)
                        .thenComparing(EngineParamDetailDTO::getPartsName, partsComparator)
                        .thenComparing(EngineParamDetailDTO::getParameterName, collator)
                )
                .collect(Collectors.toList());

        return detailDTOList.stream()
                .collect(Collectors.groupingBy(
                        EngineParamDetailDTO::getSubsystemName,
                        LinkedHashMap::new,
                        Collectors.toList()
                ));
    }

    /**
     * 修改数据
     * 保存编辑 此处不开始审批
     *
     * @param engineParamDetailPojos 参数详情POJO列表
     * @param currentUserId         当前用户ID
     * @return void
     */
    @Override
    public void updateParamValue(List<EngineParamDetailPojo> engineParamDetailPojos, String currentUserId) {
        // 获取欲更新参数列表
        List<String> detailIds = engineParamDetailPojos.stream()
                .map(EngineParamDetailPojo::getId)
                .collect(Collectors.toList());
        List<EngineParamDetailPojo> details = bd.getBusinessDatabase()
                .in("id", detailIds)
                .doQuery(EngineParamDetailPojo.class);

        // 检查修改的参数是否都在审核中
        EngineParamDetailPojo unEditParam = bd.getBusinessDatabase()
                .in("id", detailIds)
                .eq("version_status", ParamValueVersionEnum.UNDER.getCode())
                .doQueryFirst(EngineParamDetailPojo.class);

        if (ObjectUtils.isNotEmpty(unEditParam)) {
            throw new CommonException("您修改参数中有正在审批中的,请在审批通过后再修改");
        }

        // 转换参数详情为map
        Map<String, EngineParamDetailPojo> detailMap = details.stream()
                .collect(Collectors.toMap(EngineParamDetailPojo::getId, pojo -> pojo));

        // 遍历更新参数值
        for (EngineParamDetailPojo requestDetail : engineParamDetailPojos) {
            EngineParamDetailPojo detail = detailMap.get(requestDetail.getId());

            //通过操作状态对应不同操作新增和更新都新增数据为小版本且为草稿状态
            if (requestDetail.getOperation().equals(String.valueOf(ParamOperationEnum.UPDATE))) {
                bd.getBusinessDatabase()
                        .update("minor_version", requestDetail.getParameterValue())
                        .update("version_status", ParamValueVersionEnum.DRAFT.getCode())
                        .update("operation", String.valueOf(ParamOperationEnum.UPDATE))
                        .update("last_updated_by", currentUserId)
                        .update("last_update_date", new Date())
                        .eq("id", detail.getId())
                        .doUpdate(EngineParamDetailPojo.class);
            } else if (requestDetail.getOperation().equals(String.valueOf(ParamOperationEnum.DELETE))) {
                bd.getBusinessDatabase()
                        .update("is_delete", "1")
                        .update("version_status", ParamValueVersionEnum.DRAFT.getCode())
                        .update("operation", String.valueOf(ParamOperationEnum.DELETE))
                        .update("last_updated_by", currentUserId)
                        .update("last_update_date", new Date())
                        .eq("id", requestDetail.getId())
                        .doUpdate(EngineParamDetailPojo.class);
            }
        }
    }

    /**
     * 更新并插入填写人
     * 分解任务并更新填写人信息
     *
     * @param engineParamDetailPojos 参数详情POJO列表
     * @param userID                 用户ID
     * @return void
     */
    //分解任务
    @Override
    public void updateToInsertFiledBy(List<EngineParamDetailPojo> engineParamDetailPojos, String userID) {
        String engineModelId = engineParamDetailPojos.get(0).getEngineModelId();

        // 检查是否有当前任务待办
        TodoTaskPojo todoTaskPojo = bd.getBusinessDatabase()
                .eq("owner_id", userID)
                .eq("model_id", engineModelId)
                .eq("data_type", "任务分解")
                .eq("is_delete", 0)
                .doQueryFirst(TodoTaskPojo.class);
        if (todoTaskPojo == null) {
            throw new CommonException("没有分解任务,请刷新重试");
        }

        DataEntryEngineModelPojo modelPojo = dataEntryEngineModelService.selectBymodelId(engineModelId);
        XdapUsers xdapUsers = xdapDeptUsersService.selectUserByID(userID);
        ArrayList<TodoTaskPojo> todoTaskPojos = new ArrayList<>();

        //分解任务更新填写人
        for (EngineParamDetailPojo engineParamDetailPojo : engineParamDetailPojos) {
            bd.getBusinessDatabase()
                    .update("is_distributed_filled", 1)
                    .update("filled_by", engineParamDetailPojo.getFilledBy())
                    .eq("id", engineParamDetailPojo.getId())
                    .doUpdate(EngineParamDetailPojo.class);
        }

        //为每个填写人分配任务
        Set<String> filledBys = engineParamDetailPojos.stream()
                .map(EngineParamDetailPojo::getFilledBy)
                .collect(Collectors.toSet());
        for (String filledBy : filledBys) {
            // 检查是否有当前填写人的待办，有就不增加代办
            List<TodoTaskPojo> filledTodos = bd.getBusinessDatabase()
                    .eq("model_id", modelPojo.getId())
                    .eq("data_type", CurrentNodeEnum.REPAIR.getDesc())
                    .eq("is_delete", 0)
                    .eq("owner_id", filledBy)
                    .eq("process_title", modelPojo.getModelName() + "-" + "填写参数任务")
                    .doQuery(TodoTaskPojo.class);
            if (!filledTodos.isEmpty()) {
                continue;
            }

            TodoTaskPojo todoTask = new TodoTaskPojo();
            todoTask.setCreatedById(userID);
            todoTask.setDocumentNo(UUID.randomUUID().toString());
            todoTask.setProcessTitle(modelPojo.getModelName()+"-"+"填写参数任务");
            todoTask.setCurrentNode("待维护");
            todoTask.setStatusCode(null);
            todoTask.setModelName(modelPojo.getModelName());
            todoTask.setModelId(modelPojo.getId());
            todoTask.setCreationDate(todoTaskPojo.getCreationDate());
            todoTask.setDataType(CurrentNodeEnum.REPAIR.getDesc());
            todoTask.setVersionNumber(modelPojo.getVersionNumber());
            todoTask.setOwnerId(filledBy);
            todoTask.setCurrentProcessor(JSON.toJSONString(Collections.singletonList(filledBy)));
            todoTask.setIsDelete(0);
            todoTask.setCreatedBy(ObjectUtils.isNotEmpty(xdapUsers) ? xdapUsers.getUsername() : "");
            todoTaskPojos.add(todoTask);
        }
        if (!todoTaskPojos.isEmpty()) {
            bd.getBusinessDatabase().doBatchInsert(todoTaskPojos);
        }

        // 每次分发填写人时进行检测
        // 这个责任人相关的填写人是否都已经填写完成，如果没有则待办不动，如果填写完了,则待办完成
        List<EngineParamDetailPojo> toBeDistributedParams = bd.getBusinessDatabase()
                .eq("engine_model_id", engineModelId)
                .eq("major_version", modelPojo.getVersionNumber())
                .eq("responsible_person_id", userID)
                .eq("is_distributed_filled", 0)
                .doQuery(EngineParamDetailPojo.class);

        if (ObjectUtils.isEmpty(toBeDistributedParams)) {
            // 填写人是否都已经填写完成
            // 清除责任人待办
            bd.getBusinessDatabase()
                    .eq("model_id", modelPojo.getId())
                    .eq("data_type", CurrentNodeEnum.JOBSPLIT.getDesc())
                    .eq("owner_id", userID)
                    .update("is_delete", 1)
                    .doUpdate(TodoTaskPojo.class);
        }
        InitiatedTaskPojo initiatedTask = bd.getBusinessDatabase()
                .eq("model_id", modelPojo.getId())
                .eq("data_type", CurrentNodeEnum.JOBSPLIT.getDesc())
                .eq("created_by_id", userID)
                .eq("process_title", modelPojo.getModelName() + "-" + "分发参数填写人任务")
                .doQueryFirst(InitiatedTaskPojo.class);

        String disStatus = ObjectUtils.isEmpty(toBeDistributedParams) ? "已分解" : "待分解";
        if (ObjectUtils.isEmpty(initiatedTask)) {
            InitiatedTaskPojo initiatedTaskPojo = new InitiatedTaskPojo();
            initiatedTaskPojo.setCreatedById(userID);
            initiatedTaskPojo.setDocumentNo(UUID.randomUUID().toString());
            initiatedTaskPojo.setProcessTitle(modelPojo.getModelName() + "-" + "分发参数填写人任务");
            initiatedTaskPojo.setCurrentNode(disStatus);
            initiatedTaskPojo.setCurrentProcessor(ObjectUtils.isEmpty(toBeDistributedParams) ? null : JSON.toJSONString(filledBys));
            initiatedTaskPojo.setStatusCode(null/*String.valueOf(ParamValueVersionEnum.DRAFT.getCode())*/);
            initiatedTaskPojo.setModelName(ObjectUtils.isNotEmpty(modelPojo) ? modelPojo.getModelName() : "");
            initiatedTaskPojo.setModelId(modelPojo.getId());
            initiatedTaskPojo.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
            initiatedTaskPojo.setDataType(CurrentNodeEnum.JOBSPLIT.getDesc());
            initiatedTaskPojo.setVersionNumber(ObjectUtils.isNotEmpty(modelPojo) ? modelPojo.getVersionNumber() : 0);
            initiatedTaskPojo.setIsDelete(0);
            initiatedTaskPojo.setCreatedBy(ObjectUtils.isNotEmpty(xdapUsers) ? xdapUsers.getUsername() : "");
            bd.getBusinessDatabase().doInsert(initiatedTaskPojo);
        } else {
            bd.getBusinessDatabase()
                    .eq("id", initiatedTask.getId())
                    .update("current_node", disStatus)
                    .update("current_processor", ObjectUtils.isEmpty(toBeDistributedParams) ? null : JSON.toJSONString(filledBys))
                    .doUpdate(InitiatedTaskPojo.class);
        }

        CompletedTaskPojo completedTask = bd.getBusinessDatabase()
                .eq("model_id", modelPojo.getId())
                .eq("data_type", CurrentNodeEnum.JOBSPLIT.getDesc())
                .eq("created_by_id", userID)
                .eq("process_title", modelPojo.getModelName() + "-" + "分发参数填写人任务")
                .doQueryFirst(CompletedTaskPojo.class);

        String distStatus = ObjectUtils.isEmpty(toBeDistributedParams) ? "已分解" : "待分解";
        if (ObjectUtils.isEmpty(completedTask)) {
            CompletedTaskPojo completedTaskPojo = new CompletedTaskPojo();
            completedTaskPojo.setCreatedById(userID);
            completedTaskPojo.setDocumentNo(UUID.randomUUID().toString());
            completedTaskPojo.setProcessTitle(modelPojo.getModelName() + "-" + "分发参数填写人任务");
            completedTaskPojo.setCurrentNode(distStatus);
            completedTaskPojo.setCurrentProcessor(ObjectUtils.isEmpty(toBeDistributedParams) ? null : JSON.toJSONString(filledBys));
            completedTaskPojo.setStatusCode(null/*String.valueOf(ParamValueVersionEnum.DRAFT.getCode())*/);
            completedTaskPojo.setModelName(ObjectUtils.isNotEmpty(modelPojo) ? modelPojo.getModelName() : "");
            completedTaskPojo.setModelId(modelPojo.getId());
            completedTaskPojo.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
            completedTaskPojo.setDataType(CurrentNodeEnum.JOBSPLIT.getDesc());
            completedTaskPojo.setVersionNumber(ObjectUtils.isNotEmpty(modelPojo) ? modelPojo.getVersionNumber() : 0);
            completedTaskPojo.setOwnerId(userID);
            completedTaskPojo.setIsDelete(0);
            completedTaskPojo.setCreatedBy(ObjectUtils.isNotEmpty(xdapUsers) ? xdapUsers.getUsername() : "");
            bd.getBusinessDatabase().doInsert(completedTaskPojo);
        } else {
            bd.getBusinessDatabase()
                    .eq("id", completedTask.getId())
                    .update("current_node", distStatus)
                    .update("current_processor", ObjectUtils.isEmpty(toBeDistributedParams) ? null : JSON.toJSONString(filledBys))
                    .doUpdate(CompletedTaskPojo.class);
        }
    }

    /**
     * 查询所有新版本参数
     * 查询所有最新版本的参数信息
     *
     * @return 参数POJO列表
     */
    @Override
    public List<ParameterPojo> selectAllByNewVersion() {
        //读取已通过审核的版本COMPLETE(已完成)
        List<TemplatePojo> templates = bd.getBusinessDatabase()
                .eq("status", "COMPLETE")
                .doQuery(TemplatePojo.class);
        if (ObjectUtils.isEmpty(templates)) {
            throw new CommonException("未找到未找到已发布的参数模板");
        }

        //查找最新模板关联的参数
        List<String> templateIds = templates.stream()
                .map(TemplatePojo::getId)
                .collect(Collectors.toList());
        List<TemplateAndParameterPojo> templateAndParameters = bd.getBusinessDatabase()
                .in("template_id", templateIds)
                .doQuery(TemplateAndParameterPojo.class);
        List<String> pIds = templateAndParameters.stream()
                .map(TemplateAndParameterPojo::getParameterId)
                .collect(Collectors.toList());

        // 返回参数列表
        return bd.getBusinessDatabase()
                .in("id", pIds)
                .doQuery(ParameterPojo.class);
    }


    /**
     * 查询所有新版本参数包括TC
     * 查询所有最新版本的参数信息，包括TC数据
     *
     * @return 参数POJO列表
     */
    @Override
    public List<ParameterPojo> selectAllAndTcByNewVersion() {
        //读取已通过审核的版本 DRAFT(草稿)、APPROVING（审批中）、COMPLETE(已完成)、RETURNED(已撤回)、REJECTED(已拒绝)
        List<TemplatePojo> templates =
                bd.getBusinessDatabase()
                        .eq("status", "COMPLETE")
                        .doQuery(TemplatePojo.class);
        if (ObjectUtils.isEmpty(templates)) {
            throw new CommonException("未找到未找到已发布的参数模板");
        }
        //查找每个模板最新版本
        // 每组内按版本号降序，取第一个（最新版本）
        Map<String, TemplatePojo> latestTemplateMap = templates.stream()
                // 按模板ID分组
                .collect(Collectors.toMap(TemplatePojo::getTemplateName, Function.identity(), BinaryOperator.maxBy(Comparator.comparingInt(TemplatePojo::getVersion))));
        ArrayList<TemplatePojo> templatesMax = new ArrayList<>(latestTemplateMap.values());
        List<String> strings = templatesMax.stream().map(TemplatePojo::getId).collect(Collectors.toList());
        //查找最新模板关联的参数
        List<TemplateAndParameterPojo> templateAndParameters =
                bd.getBusinessDatabase()
                        .in("template_id", strings)
                        .doQuery(TemplateAndParameterPojo.class);
        List<String> pIds = templateAndParameters.stream().map(TemplateAndParameterPojo::getParameterId).collect(Collectors.toList());

        return bd.getBusinessDatabase()
                .in("id", pIds)
                .doQuery(ParameterPojo.class);
    }

    /**
     * 根据模型查询新版本参数详情
     * 根据模型ID查询最新版本的参数详情
     *
     * @param modelId 模型ID
     * @return 参数详情POJO列表
     */
    @Override
    public List<EngineParamDetailPojo> selectByModelNewVersion(String modelId) {

        if (ObjectUtils.isEmpty(modelId)) {
            return Collections.emptyList();
        }
        List<EngineParamDetailPojo> engineParamDetailPojos = bd.getBusinessDatabase()
                .eq("engine_model_id", modelId)
                .doQuery(EngineParamDetailPojo.class);

        //根据机型ID查找机型
        DataEntryEngineModelPojo dataEntryEngineModelPojo = dataEntryEngineModelService.selectBymodelId(modelId);

        if (ObjectUtils.isEmpty(dataEntryEngineModelPojo)) {
            throw new CommonException("机型不存在");
        }

        return engineParamDetailPojos.stream().filter(
                x -> Objects.equals(x.getMajorVersion(), dataEntryEngineModelPojo.getVersionNumber())
        ).collect(Collectors.toList());
    }

    /**
     * 根据责任人ID查询参数详情
     * 根据责任人ID查询相关的参数详情
     *
     * @param resId 责任人ID
     * @return 参数详情POJO列表
     */
    @Override
    public List<EngineParamDetailPojo> selectByResId(String resId) {
        if (ObjectUtils.isEmpty(resId)) {
            return Collections.emptyList();
        }
        List<EngineParamDetailPojo> engineParamDetailPojos = bd.getBusinessDatabase()
                .eq("responsible_person_id", resId)
                .doQuery(EngineParamDetailPojo.class);
        if (ObjectUtils.isEmpty(engineParamDetailPojos)) {
            log.warn("该责任人无待办参数");
            return Collections.emptyList();
        }
        EngineParamDetailPojo engineParamDetailPojoMaxVersion = engineParamDetailPojos.stream()
                .sorted(Comparator.comparing(EngineParamDetailPojo::getMajorVersion)
                        .reversed()).collect(Collectors.toList()).get(0);

        return engineParamDetailPojos.stream().filter(
                x -> Objects.equals(x.getMajorVersion(), engineParamDetailPojoMaxVersion.getMajorVersion())
        ).collect(Collectors.toList());
    }

    /**
     * 根据ID查询参数详情
     * 根据ID查询单个参数详情
     *
     * @param id 参数详情ID
     * @return 参数详情POJO
     */
    @Override
    public EngineParamDetailPojo selectById(String id) {
        List<EngineParamDetailPojo> engineParamDetailPojos = bd.getBusinessDatabase()
                .eq("id", id)
                .doQuery(EngineParamDetailPojo.class);
        if (ObjectUtils.isNotEmpty(engineParamDetailPojos)) {
            return engineParamDetailPojos.get(0);
        }
        return null;
    }

    /**
     * 查询版本列表
     * 根据模型ID查询版本列表
     *
     * @param modelId 模型ID
     * @return 版本号列表
     */
    @Override
    public List<Integer> selectVersionList(String modelId) {
        if (ObjectUtils.isNotEmpty(modelId)) {
            List<EngineParamDetailPojo> detailPojos = bd.getBusinessDatabase()
                    .eq("engine_model_id", modelId)
                    .doQuery(EngineParamDetailPojo.class);
            return detailPojos.stream().map(EngineParamDetailPojo::getMajorVersion)
                    .distinct().collect(Collectors.toList());
        }
        return Collections.emptyList();
    }

    /**
     * 根据类型查询人员
     * 根据子系统、部门和类型查询相关人员
     *
     * @param subSystem 子系统
     * @param dept      部门
     * @param type      类型
     * @return 用户POJO列表
     */
    @Override
    public List<XdapUsers> selectPersonoByType(String subSystem, String dept, Integer type) {
        List<XdapUsers> xdapUsersPojos = new ArrayList<>();
        List<ResponsiblePersonPojo> personPojos = responsiblePerService.selectBysubSystemDept(subSystem, dept);
        if (ObjectUtils.isEmpty(personPojos)) {
            throw new CommonException("该子系统和部门没有查找到相关人子系统:" + subSystem + ",部门:" + dept);
        }
        try {
            List<ResponsiblePersonPojo> collected = personPojos.stream().filter(x -> Objects.equals(x.getPersonLevel(), type)).collect(Collectors.toList());
            List<String> userIds = collected.stream().map(ResponsiblePersonPojo::getUserId).collect(Collectors.toList());
            for (String id : new ArrayList<>(userIds)) {
                xdapUsersPojos.add(xdapDeptUsersService.selectUserByID(id));
            }
        } catch (Exception e) {
            throw new CommonException("根据TYPE查询异常");
        }

        return xdapUsersPojos;
    }


    /**
     * 设置响应
     * 设置HTTP响应头部信息用于文件下载
     *
     * @param response HTTP响应对象
     * @param fileName 文件名
     * @return void
     */
    private void setupResponse(HttpServletResponse response, String fileName) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
    }

    @Override
    public List<ParameterPojo> selectParamByIsUserId(List<ParameterPojo> list, String userId) {
        // 没有人则返回全部
        if (userId == null || userId.isEmpty()) {
            return list;
        }
        List<MenuParamView> menuParamViews = modelRoleService.selectPersByUser(userId);
        // 管理员返回全部
        for (MenuParamView menuParamView : menuParamViews) {
            if (menuParamView.getIsAdmin() != null && menuParamView.getIsAdmin() == 1) {
                return list;
            }
        }

        Set<String> result = menuParamViews.stream()
                .map(MenuParamView::getPermissionPath)
                .collect(Collectors.toSet());

        return list.stream()
                .filter(pojo ->
                        modelRoleService.matchesAnyPermission(
                                pojo,
                                modelRoleService.buildPermissionIndex(result),
                                Arrays.asList("玉柴发动机数据", "竞品发动机数据")
                        ))
                .collect(Collectors.toList());
    }

    @Override
    public List<EngineParamDetailPojo> selectModelParamByIsUserId(List<EngineParamDetailPojo> list, String userId) {
        // 没有人则返回全部
        if (userId == null || userId.isEmpty()) {
            return list;
        }
        List<MenuParamView> menuParamViews = modelRoleService.selectPersByUser(userId);
        // 管理员返回全部
        for (MenuParamView menuParamView : menuParamViews) {
            if (menuParamView.getIsAdmin() != null && menuParamView.getIsAdmin() == 1) {
                return list;
            }
        }

        Set<String> result = menuParamViews.stream()
                .map(MenuParamView::getPermissionPath)
                .collect(Collectors.toSet());

        return list.stream()
                .filter(pojo ->
                        modelRoleService.matchesAnyPermission(
                                pojo,
                                modelRoleService.buildPermissionIndex(result),
                                Arrays.asList("玉柴发动机数据", "竞品发动机数据")
                        ))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void updateDept(EngineDeptUpdateDTO engineDeptUpdateDTO) {
        if (engineDeptUpdateDTO.getList().isEmpty()) {
            throw new CommonException("部门信息不能为空");
        }

        // 检查机型
        DataEntryEngineModelPojo model = bd.getBusinessDatabase()
                .eq("id", engineDeptUpdateDTO.getModelId())
                .in("distribute_status",
                        DistributeStatusEnum.UNDISTRIBUTED.getCode(),
                        DistributeStatusEnum.COMPLETE.getCode()
                )
                .doQueryFirst(DataEntryEngineModelPojo.class);
        if (model == null) {
            throw new CommonException("机型不存在或已分发");
        }

        // 检查当前版本机型是否有参数正在审批中
        List<EngineParamDetailPojo> paramsInApproval = bd.getBusinessDatabase()
                .eq("engine_model_id", model.getId())
                .eq("major_version", model.getVersionNumber())
                .eq("version_status", ParamValueVersionEnum.UNDER.getCode())
                .doQuery(EngineParamDetailPojo.class);
        if (!paramsInApproval.isEmpty()) {
            throw new CommonException("当前版本机型有参数正在审批中，请等待审批完成");
        }

        // 整理部门和参数
        Map<String, List<String>> deptMap = engineDeptUpdateDTO.getList().stream()
                .filter(item -> item.getDepartment() != null && !item.getDepartment().isEmpty())
                .collect(Collectors.groupingBy(
                        EngineDeptUpdateItem::getDepartment,
                        Collectors.mapping(EngineDeptUpdateItem::getParamId, Collectors.toList())
                ));

        for (Map.Entry<String, List<String>> entry : deptMap.entrySet()) {
            String department = entry.getKey();
            List<String> paramIds = entry.getValue();
            // 更新部门信息
            bd.getBusinessDatabase()
                    .update("department", department)
                    .in("id", paramIds)
                    .doUpdate(EngineParamDetailPojo.class);
        }
    }
}
