package com.yeejoin.amos.boot.module.jg.biz.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.annotation.FieldDisplayDefine;
import com.yeejoin.amos.boot.biz.common.annotation.Group;
import com.yeejoin.amos.boot.module.jg.api.dto.*;
import com.yeejoin.amos.boot.module.jg.biz.service.*;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgDesignInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgFactoryInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.IdxBizJgRegisterInfoMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class CommonEquipDataProcessService {

    private final IdxBizJgDesignInfoMapper idxBizJgDesignInfoMapper;

    private final IdxBizJgFactoryInfoMapper jgFactoryInfoMapper;

    private final IdxBizJgRegisterInfoMapper idxBizJgRegisterInfoMapper;

    private final IIdxBizJgTechParamsElevatorService iIdxBizJgTechParamsElevatorService;

    private final IIdxBizJgTechParamsVehicleService iIdxBizJgTechParamsVehicleService;

    private final IIdxBizJgTechParamsRopewayService iIdxBizJgTechParamsRopewayService;

    private final IIdxBizJgTechParamsRidesService iIdxBizJgTechParamsRidesService;

    private final IIdxBizJgTechParamsBoilerService iIdxBizJgTechParamsBoilerService;

    private final IIdxBizJgTechParamsVesselService iIdxBizJgTechParamsVesselService;

    private final IIdxBizJgTechParamsPipelineService iIdxBizJgTechParamsPipelineService;

    private final IIdxBizJgTechParamsLiftingService iIdxBizJgTechParamsLiftingService;

    private final EquipChangeDataUpdateService equipChangeDataUpdateService;

    private final IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;

    private final List<String> jsonFields = new ArrayList<>();


    @PostConstruct
    public void init() {
        Field[] fields1 = EquipRegisterChangeDataDto.class.getDeclaredFields();
        for (Field field : fields1) {
            field.setAccessible(true);
            FieldDisplayDefine fieldDisplayDefine = field.getAnnotation(FieldDisplayDefine.class);
            if (fieldDisplayDefine != null && fieldDisplayDefine.type() == JSON.class) {
                jsonFields.add(field.getName());
            }
        }
        Field[] fields2 = EquipFactoryChangeDataDto.class.getDeclaredFields();
        for (Field field : fields2) {
            field.setAccessible(true);
            FieldDisplayDefine fieldDisplayDefine = field.getAnnotation(FieldDisplayDefine.class);
            if (fieldDisplayDefine != null && fieldDisplayDefine.type() == JSON.class) {
                jsonFields.add(field.getName());
            }
        }
        // 设计信息构建
        Field[] fields3 = EquipDesignChangeDataDto.class.getDeclaredFields();
        for (Field field : fields3) {
            field.setAccessible(true);
            FieldDisplayDefine fieldDisplayDefine = field.getAnnotation(FieldDisplayDefine.class);
            if (fieldDisplayDefine != null && fieldDisplayDefine.type() == JSON.class) {
                jsonFields.add(field.getName());
            }
        }

        // 技术参数附件
        Field[] fields4 = TechParamsLiftingChangeFieldDto.class.getDeclaredFields();
        for (Field field : fields4) {
            field.setAccessible(true);
            FieldDisplayDefine fieldDisplayDefine = field.getAnnotation(FieldDisplayDefine.class);
            if (fieldDisplayDefine != null && fieldDisplayDefine.type() == JSON.class) {
                jsonFields.add(field.getName());
            }
        }
        Field[] fields5 = TechParamsPipelineChangeFieldDto.class.getDeclaredFields();
        for (Field field : fields5) {
            field.setAccessible(true);
            FieldDisplayDefine fieldDisplayDefine = field.getAnnotation(FieldDisplayDefine.class);
            if (fieldDisplayDefine != null && fieldDisplayDefine.type() == JSON.class) {
                jsonFields.add(field.getName());
            }
        }
    }

    public <T extends BaseChangeDataDto> T castMap2Bean(Map<String, Object> map, Class<T> clazz) {
        try {
            T t = clazz.newInstance();
            BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(map)), t, true);
            return t;
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }



    public void checkValidField(String record, BaseChangeDataDto changeDataDto, String equList, String equCategory, String equDefine) {
        // 注册信息
        if (changeDataDto instanceof EquipRegisterChangeDataDto) {
            EquipRegisterChangeDataDto registerChangeDataDto = (EquipRegisterChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.checkRegisterChangeData(record, registerChangeDataDto);
        }
        // 制造信息
        if (changeDataDto instanceof EquipFactoryChangeDataDto) {
            EquipFactoryChangeDataDto equipFactoryChangeDataDto = (EquipFactoryChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.checkFactoryChangeData(record, equipFactoryChangeDataDto, equList, equCategory, equDefine);
        }
        // 设计信息
        if (changeDataDto instanceof EquipDesignChangeDataDto) {
            EquipDesignChangeDataDto equipDesignChangeDataDto = (EquipDesignChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.checkDesignChangeData(record, equipDesignChangeDataDto);
        }
    }

    void buildChangeFields(String record, EquipDesignChangeDataDto equipDesignChangeDataDto, EquipFactoryChangeDataDto equipFactoryChangeDataDto, EquipRegisterChangeDataDto registerChangeDataDto, List<ChangeDataDto> allChangeColumns) {
        // 构造新对象行转列
        List<ChangeDataDto> designInfoNew = this.buildDesignInfoNew(equipDesignChangeDataDto, record);
        List<ChangeDataDto> factoryInfoNew = this.buildFactoryInfoNew(equipFactoryChangeDataDto, record);
        List<ChangeDataDto> registerInfoNew = this.buildRegisterInfoNew(registerChangeDataDto, record);
        // 老数据查询行转列
        List<ChangeDataDto> designInfoOld = this.buildDesignInfoOld(record);
        List<ChangeDataDto> factoryInfoOld = this.buildFactoryInfoOld(record);
        List<ChangeDataDto> registerInfoOld = this.buildRegisterInfoOld(record);
        allChangeColumns.addAll(this.mergeChangeFields(designInfoNew, designInfoOld));
        allChangeColumns.addAll(this.mergeChangeFields(factoryInfoNew, factoryInfoOld));
        allChangeColumns.addAll(this.mergeChangeFields(registerInfoNew, registerInfoOld));
    }

    void buildChangeFields(String record, EquipDesignChangeDataDto equipDesignChangeDataDto, EquipFactoryChangeDataDto equipFactoryChangeDataDto, EquipRegisterChangeDataDto registerChangeDataDto, EquipUseInfoChangeDataDto useInfoChangeDataDto, List<ChangeDataDto> allChangeColumns) {
        // 构造新对象行转列
        List<ChangeDataDto> designInfoNew = this.buildDesignInfoNew(equipDesignChangeDataDto, record);
        List<ChangeDataDto> factoryInfoNew = this.buildFactoryInfoNew(equipFactoryChangeDataDto, record);
        List<ChangeDataDto> registerInfoNew = this.buildRegisterInfoNew(registerChangeDataDto, record);
        List<ChangeDataDto> useInfoChangeNew = this.convertBeanField2Column2(useInfoChangeDataDto, record);
        // 老数据查询行转列
        List<ChangeDataDto> designInfoOld = this.buildDesignInfoOld(record);
        List<ChangeDataDto> factoryInfoOld = this.buildFactoryInfoOld(record);
        List<ChangeDataDto> registerInfoOld = this.buildRegisterInfoOld(record);
        List<ChangeDataDto> useInfoOld = this.buildUseInfoOld(record);
        allChangeColumns.addAll(this.mergeChangeFields(designInfoNew, designInfoOld));
        allChangeColumns.addAll(this.mergeChangeFields(factoryInfoNew, factoryInfoOld));
        allChangeColumns.addAll(this.mergeChangeFields(registerInfoNew, registerInfoOld));
        allChangeColumns.addAll(this.mergeChangeFields(useInfoChangeNew, useInfoOld));
    }

    /**
     * 业务处理-业务对象
     *
     * @param record        设备主键
     * @param changeDataDto 变更后数据
     */
    void dealBizDataForEquip(String record, BaseChangeDataDto changeDataDto) {
        // 注册信息
        if (changeDataDto instanceof EquipRegisterChangeDataDto) {
            EquipRegisterChangeDataDto registerChangeDataDto = (EquipRegisterChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateRegisterChangeData(record, registerChangeDataDto);
        }
        // 制造信息
        if (changeDataDto instanceof EquipFactoryChangeDataDto) {
            EquipFactoryChangeDataDto equipFactoryChangeDataDto = (EquipFactoryChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateFactoryChangeData(record, equipFactoryChangeDataDto);
        }
        // 设计信息
        if (changeDataDto instanceof EquipDesignChangeDataDto) {
            EquipDesignChangeDataDto equipDesignChangeDataDto = (EquipDesignChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateDesignChangeData(record, equipDesignChangeDataDto);
        }
        // 使用信息
        if (changeDataDto instanceof EquipUseInfoChangeDataDto) {
            EquipUseInfoChangeDataDto equipUseInfoChangeDataDto = (EquipUseInfoChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateUseInfoChangeData(record, equipUseInfoChangeDataDto);
        }
    }

    private String buildTableName(Class<?> clazz) {
        Group group = clazz.getAnnotation(Group.class);
        return String.format("\"%s_%s\"", "idx_biz_jg", group.value());
    }


    public List<ChangeDataDto> mergeChangeFields(List<ChangeDataDto> changeDataNew, List<ChangeDataDto> changeDataOld) {
        Map<String, ChangeDataDto> oldKv = changeDataOld.stream().collect(Collectors.toMap(ChangeDataDto::getColumnKey, Function.identity()));
        changeDataNew.forEach(o -> {
            // 正常不会出现此情况，old数据 大于等于 new 数据的key
            if (oldKv.get(o.getColumnKey()) != null) {
                o.setColumnOldValue(oldKv.get(o.getColumnKey()).getColumnOldValue());
            }
        });
        return changeDataNew.stream().filter(n -> !StringUtils.equals(n.getColumnNewValue(), n.getColumnOldValue())).collect(Collectors.toList());
    }

    private static TechParamsBoilerChangeFieldDto getTechParamsBoilerChangeField(Map<String, Object> changeData) {
        TechParamsBoilerChangeFieldDto newBoiler = new TechParamsBoilerChangeFieldDto();
        BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newBoiler, true);
        return newBoiler;
    }

    private TechParamsBoilerChangeFieldDto getTechParamsBoilerChangeField(String record) {
        IdxBizJgTechParamsBoiler boiler = iIdxBizJgTechParamsBoilerService.getOneData(record);
        TechParamsBoilerChangeFieldDto oldBoiler = new TechParamsBoilerChangeFieldDto();
        BeanUtil.copyProperties(boiler, oldBoiler);
        return oldBoiler;
    }

    BaseTechParamsFieldDto buildTechParamInfo(EquipRegisterChangeDataDto equipRegisterChangeDataDto, String record) {
        EquipmentClassifityEnum equipmentClassifityEnum = EquipmentClassifityEnum.getOne(equipRegisterChangeDataDto.getEquList());
        switch (Objects.requireNonNull(equipmentClassifityEnum)) {
            case GL:
                // 锅炉
                IdxBizJgTechParamsBoiler boiler = iIdxBizJgTechParamsBoilerService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(boiler, TechParamsBoilerChangeFieldDto.class);
            case YLRQ:
                // 压力容器
                IdxBizJgTechParamsVessel techParamsVessel = iIdxBizJgTechParamsVesselService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsVessel, TechParamsVesselChangeFieldDto.class);
            case DT:
                // 电梯
                IdxBizJgTechParamsElevator techParamsElevator = iIdxBizJgTechParamsElevatorService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsElevator, TechParamsElevatorChangeFieldDto.class);
            case QZJX:
                // 起重机械
                IdxBizJgTechParamsLifting techParamsLifting = iIdxBizJgTechParamsLiftingService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsLifting, TechParamsLiftingChangeFieldDto.class);
            case CC:
                // 场（厂）内专用机动车辆
                IdxBizJgTechParamsVehicle techParamsVehicle = iIdxBizJgTechParamsVehicleService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsVehicle, TechParamsVehicleChangeFieldDto.class);
            case YLSS:
                // 大型游乐设施
                IdxBizJgTechParamsRides techParamsRides = iIdxBizJgTechParamsRidesService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsRides, TechParamsRidesChangeFieldDto.class);
            case YLGD:
                // 压力管道
                IdxBizJgTechParamsPipeline techParamsPipeline = iIdxBizJgTechParamsPipelineService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsPipeline, TechParamsPipelineChangeFieldDto.class);
            case KYSD:
                // 客运索道
                IdxBizJgTechParamsRopeway techParamsRopeway = iIdxBizJgTechParamsRopewayService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                return BeanUtil.copyProperties(techParamsRopeway, TechParamsRopewayChangeFieldDto.class);
            default:
                break;
        }
        return null;
    }


    void updateTechParamInfo(EquipRegisterChangeDataDto equipRegisterChangeDataDto, String record, Map<String, Object> changeData, List<ChangeDataDto> allChange) {
        EquipmentClassifityEnum equipmentClassifityEnum = EquipmentClassifityEnum.getOne(equipRegisterChangeDataDto.getEquList());
        switch (Objects.requireNonNull(equipmentClassifityEnum)) {
            case GL:
                // 锅炉
                TechParamsBoilerChangeFieldDto newBoiler = getTechParamsBoilerChangeField(changeData);
                TechParamsBoilerChangeFieldDto oldBoiler = getTechParamsBoilerChangeField(record);
                // 字段行转列
                List<ChangeDataDto> boilerChangeDataNew = this.convertBeanField2Column2(newBoiler, record);
                List<ChangeDataDto> boilerChangeDataOld = this.convertBeanField2Column2(oldBoiler, record);
                // 比对
                List<ChangeDataDto> boilerChangeFields = this.mergeChangeFields(boilerChangeDataNew, boilerChangeDataOld);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsBoilerChangeFieldDto.class), record, boilerChangeFields);
                // 日志数据记录
                allChange.addAll(boilerChangeDataNew);
                break;
            case YLRQ:
                // 压力容器
                TechParamsVesselChangeFieldDto newVessel = new TechParamsVesselChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newVessel, true);
                IdxBizJgTechParamsVessel techParamsVessel = iIdxBizJgTechParamsVesselService.getOneData(record);
                TechParamsVesselChangeFieldDto oldVessel = BeanUtil.copyProperties(techParamsVessel, TechParamsVesselChangeFieldDto.class);
                // 字段行转列
                List<ChangeDataDto> newVesselChangeData = this.convertBeanField2Column2(newVessel, record);
                List<ChangeDataDto> oldVesselChangeData = this.convertBeanField2Column2(oldVessel, record);
                // 比对
                List<ChangeDataDto> vesselChangeFields = this.mergeChangeFields(newVesselChangeData, oldVesselChangeData);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsVesselChangeFieldDto.class), record, vesselChangeFields);
                // 日志数据记录
                allChange.addAll(vesselChangeFields);
                break;
            case DT:
                // 电梯
                TechParamsElevatorChangeFieldDto newElevator = new TechParamsElevatorChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newElevator, true);

                IdxBizJgTechParamsElevator techParamsElevator = iIdxBizJgTechParamsElevatorService.getOneData(record);
                TechParamsElevatorChangeFieldDto oldElevator = BeanUtil.copyProperties(techParamsElevator, TechParamsElevatorChangeFieldDto.class);
                // 字段行转列
                List<ChangeDataDto> newElevatorChangeData = this.convertBeanField2Column2(newElevator, record);
                List<ChangeDataDto> oldElevatorChangeData = this.convertBeanField2Column2(oldElevator, record);
                // 比对
                List<ChangeDataDto> elevatorChangeFields = this.mergeChangeFields(newElevatorChangeData, oldElevatorChangeData);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsElevatorChangeFieldDto.class), record, elevatorChangeFields);
                // 日志数据记录
                allChange.addAll(elevatorChangeFields);
                break;
            case QZJX:
                // 起重机械
                TechParamsLiftingChangeFieldDto newLifting = new TechParamsLiftingChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newLifting, true);

                IdxBizJgTechParamsLifting techParamsLifting = iIdxBizJgTechParamsLiftingService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                TechParamsLiftingChangeFieldDto oldLifting = BeanUtil.copyProperties(techParamsLifting, TechParamsLiftingChangeFieldDto.class);
                // 字段行转列
                List<ChangeDataDto> newLiftingChangeData = this.convertBeanField2Column2(newLifting, record);
                List<ChangeDataDto> oldLiftingChangeData = this.convertBeanField2Column2(oldLifting, record);
                // 比对
                List<ChangeDataDto> liftingChangeFields = this.mergeChangeFields(newLiftingChangeData, oldLiftingChangeData);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsLiftingChangeFieldDto.class), record, liftingChangeFields);
                // 日志数据记录
                allChange.addAll(liftingChangeFields);
                break;
            case CC:
                // 场（厂）内专用机动车辆
                TechParamsVehicleChangeFieldDto newVehicle = new TechParamsVehicleChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newVehicle, true);

                IdxBizJgTechParamsVehicle techParamsVehicle = iIdxBizJgTechParamsVehicleService.getOneData(record);
                TechParamsVehicleChangeFieldDto oldVehicle = BeanUtil.copyProperties(techParamsVehicle, TechParamsVehicleChangeFieldDto.class);
                // 字段行转列
                List<ChangeDataDto> newVehicleChangeData = this.convertBeanField2Column2(newVehicle, record);
                List<ChangeDataDto> oldVehicleChangeData = this.convertBeanField2Column2(oldVehicle, record);
                // 比对
                List<ChangeDataDto> vehicleChangeFields = this.mergeChangeFields(newVehicleChangeData, oldVehicleChangeData);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsVehicleChangeFieldDto.class), record, vehicleChangeFields);
                // 日志数据记录
                allChange.addAll(vehicleChangeFields);
                break;
            case YLSS:
                // 大型游乐设施
                TechParamsRidesChangeFieldDto newRides = new TechParamsRidesChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newRides, true);

                IdxBizJgTechParamsRides techParamsRides = iIdxBizJgTechParamsRidesService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                TechParamsRidesChangeFieldDto oldRides = BeanUtil.copyProperties(techParamsRides, TechParamsRidesChangeFieldDto.class);
                // 字段行转列
                List<ChangeDataDto> newRidesChangeData = this.convertBeanField2Column2(newRides, record);
                List<ChangeDataDto> oldRidesChangeData = this.convertBeanField2Column2(oldRides, record);
                // 比对
                List<ChangeDataDto> ridesChangeFields = this.mergeChangeFields(newRidesChangeData, oldRidesChangeData);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsRidesChangeFieldDto.class), record, ridesChangeFields);
                // 日志数据记录
                allChange.addAll(ridesChangeFields);
                break;
            case YLGD:
                // 压力管道
                TechParamsPipelineChangeFieldDto newPipeline = new TechParamsPipelineChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newPipeline, true);
                savePieLineTechParam(record, allChange, newPipeline);
                break;
            case KYSD:
                // 客运索道
                TechParamsRopewayChangeFieldDto newRopeway = new TechParamsRopewayChangeFieldDto();
                BeanUtil.copyProperties(JSON.parse(JSONObject.toJSONString(changeData)), newRopeway, true);

                IdxBizJgTechParamsRopeway techParamsRopeway = iIdxBizJgTechParamsRopewayService.getOneData(record);
                // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
                TechParamsRopewayChangeFieldDto oldRopeway = BeanUtil.copyProperties(techParamsRopeway, TechParamsRopewayChangeFieldDto.class);
                // 字段行转列
                List<ChangeDataDto> newRopewayChangeData = this.convertBeanField2Column2(newRopeway, record);
                List<ChangeDataDto> oldRopewayChangeData = this.convertBeanField2Column2(oldRopeway, record);
                // 比对
                List<ChangeDataDto> ropewayChangeFields = this.mergeChangeFields(newRopewayChangeData, oldRopewayChangeData);
                // 业务处理
                equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsRopewayChangeFieldDto.class), record, ropewayChangeFields);
                // 日志数据记录
                allChange.addAll(ropewayChangeFields);
                break;
            default:
                break;
        }
    }

    public void savePieLineTechParam(String record, List<ChangeDataDto> allChange, TechParamsPipelineChangeFieldDto newPipeline) {
        IdxBizJgTechParamsPipeline techParamsPipeline = iIdxBizJgTechParamsPipelineService.getOneData(record);
        // 技术参数对象转换为全部技术参数 ，其他无用字段去掉
        TechParamsPipelineChangeFieldDto oldPipeline = BeanUtil.copyProperties(techParamsPipeline, TechParamsPipelineChangeFieldDto.class);
        // 字段行转列
        List<ChangeDataDto> newPipelineChangeData = this.convertBeanField2Column2(newPipeline, record);
        List<ChangeDataDto> oldPipelineChangeData = this.convertBeanField2Column2(oldPipeline, record);
        // 比对
        List<ChangeDataDto> pipelineChangeFields = this.mergeChangeFields(newPipelineChangeData, oldPipelineChangeData);
        // 业务处理
        equipChangeDataUpdateService.updateTechParamByRecord(this.buildTableName(TechParamsPipelineChangeFieldDto.class), record, pipelineChangeFields);
        // 日志数据记录
        allChange.addAll(pipelineChangeFields);
    }

    public List<ChangeDataDto> convertBeanField2Column2(Object beanData, String changeId) {
        List<ChangeDataDto> changeData = new ArrayList<>();
        Group group = beanData.getClass().getAnnotation(Group.class);
        Field[] fields = beanData.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            FieldDisplayDefine displayDefine = field.getAnnotation(FieldDisplayDefine.class);
            try {
                if (displayDefine != null && displayDefine.isExist()) {
                    String fieldName = displayDefine.value();
                    ChangeDataDto changeDataDto = new ChangeDataDto();
                    changeDataDto.setColumnKey(field.getName());
                    changeDataDto.setColumnFamily(group.value());
                    changeDataDto.setColumnLabel(fieldName);
                    changeDataDto.setChangeId(changeId);
                    Object oV = field.get(beanData);
                    if (oV instanceof String) {
                        String value = (String) field.get(beanData);
                        changeDataDto.setColumnNewValue(value);
                        changeDataDto.setColumnOldValue(value);
                    } else if (oV instanceof Number) {
                        String value = String.valueOf(field.get(beanData));
                        changeDataDto.setColumnNewValue(value);
                        changeDataDto.setColumnOldValue(value);
                    }
                    changeData.add(changeDataDto);
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return changeData;
    }

    public List<ChangeDataDto> buildDesignInfoNew(Object changeDataDto, String record) {
        return this.convertBeanField2Column2(changeDataDto, record);
    }

    private List<ChangeDataDto> buildFactoryInfoNew(EquipFactoryChangeDataDto changeDataDto, String record) {
        return this.convertBeanField2Column2(changeDataDto, record);
    }

    private List<ChangeDataDto> buildRegisterInfoNew(EquipRegisterChangeDataDto changeDataDto, String record) {
        return this.convertBeanField2Column2(changeDataDto, record);
    }

    public List<ChangeDataDto> buildDesignInfoOld(String record) {
        EquipDesignChangeDataDto changeDataDto = new EquipDesignChangeDataDto();
        IdxBizJgDesignInfo designInfo = idxBizJgDesignInfoMapper.selectOne(new LambdaQueryWrapper<IdxBizJgDesignInfo>().eq(IdxBizJgDesignInfo::getRecord, record));
        BeanUtil.copyProperties(designInfo, changeDataDto);
        changeDataDto.setDesignDate(DateUtil.formatDate(designInfo.getDesignDate()));
        return this.convertBeanField2Column2(changeDataDto, record);
    }

    private List<ChangeDataDto> buildFactoryInfoOld(String record) {
        EquipFactoryChangeDataDto changeDataDto = new EquipFactoryChangeDataDto();
        IdxBizJgFactoryInfo factoryInfo = jgFactoryInfoMapper.selectOne(new LambdaQueryWrapper<IdxBizJgFactoryInfo>().eq(IdxBizJgFactoryInfo::getRecord, record));
        BeanUtil.copyProperties(factoryInfo, changeDataDto);
        changeDataDto.setProduceDate(DateUtil.formatDate(factoryInfo.getProduceDate()));
        return this.convertBeanField2Column2(changeDataDto, record);
    }

    private List<ChangeDataDto> buildRegisterInfoOld(String record) {
        EquipRegisterChangeDataDto changeDataDto = new EquipRegisterChangeDataDto();
        IdxBizJgRegisterInfo registerInfo = idxBizJgRegisterInfoMapper.selectOne(new LambdaQueryWrapper<IdxBizJgRegisterInfo>().eq(IdxBizJgRegisterInfo::getRecord, record));
        BeanUtil.copyProperties(registerInfo, changeDataDto);
        return this.convertBeanField2Column2(changeDataDto, record);
    }

    private List<ChangeDataDto> buildUseInfoOld(String record) {
        EquipUseInfoChangeDataDto changeDataDto = new EquipUseInfoChangeDataDto();
        IdxBizJgUseInfo useInfo = idxBizJgUseInfoService.getOneData(record);
        BeanUtil.copyProperties(useInfo, changeDataDto);
        return this.convertBeanField2Column2(changeDataDto, record);
    }
    

    Map<String, Object> cast2UnderCase(Map<String, Object> re) {
        // 由于历史遗留问题，和前端保存统一，要转成大写下滑线驼峰
        Map<String, Object> result = new HashMap<>();
        re.forEach((k, v) -> {
            result.put(CharSequenceUtil.toUnderlineCase(k).toUpperCase(), v);
        });
        return result;
    }

    void castJsonFields(Map<String, Object> re) {
        jsonFields.forEach(field -> {
            if (re.containsKey(field) && re.get(field) instanceof String) {
                re.put(field, JSON.parse((String) re.get(field)));
            }
        });
    }

    EquipDesignChangeDataDto buildDesignInfo(String record) {
        EquipDesignChangeDataDto changeDataDto = new EquipDesignChangeDataDto();
        IdxBizJgDesignInfo designInfo = idxBizJgDesignInfoMapper.selectOne(new LambdaQueryWrapper<IdxBizJgDesignInfo>().eq(IdxBizJgDesignInfo::getRecord, record));
        BeanUtil.copyProperties(designInfo, changeDataDto);
        changeDataDto.setDesignDate(DateUtil.formatDate(designInfo.getDesignDate()));
        return changeDataDto;
    }

    EquipFactoryChangeDataDto buildFactoryInfo(String record) {
        EquipFactoryChangeDataDto changeDataDto = new EquipFactoryChangeDataDto();
        IdxBizJgFactoryInfo factoryInfo = jgFactoryInfoMapper.selectOne(new LambdaQueryWrapper<IdxBizJgFactoryInfo>().eq(IdxBizJgFactoryInfo::getRecord, record));
        BeanUtil.copyProperties(factoryInfo, changeDataDto);
        changeDataDto.setProduceDate(DateUtil.formatDate(factoryInfo.getProduceDate()));
        return changeDataDto;
    }

    EquipRegisterChangeDataDto buildRegisterInfo(String record) {
        EquipRegisterChangeDataDto changeDataDto = new EquipRegisterChangeDataDto();
        IdxBizJgRegisterInfo registerInfo = idxBizJgRegisterInfoMapper.selectOne(new LambdaQueryWrapper<IdxBizJgRegisterInfo>().eq(IdxBizJgRegisterInfo::getRecord, record));
        BeanUtil.copyProperties(registerInfo, changeDataDto);
        return changeDataDto;
    }

    EquipUseInfoChangeDataDto buildUseInfo(String record) {
        EquipUseInfoChangeDataDto changeDataDto = new EquipUseInfoChangeDataDto();
        IdxBizJgUseInfo useInfo = idxBizJgUseInfoService.getOneData(record);
        BeanUtil.copyProperties(useInfo, changeDataDto);
        return changeDataDto;
    }
}
