package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.collect;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbCollectDataMethodService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbCollectDataStrategyService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbParitySyncDispatchService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.ISxThirdPartyDbParitySyncSqlBuilderService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.SxThirdPartyDbCollectDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.SxThirdPartyDbDynamicsFieldModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.dao.IDataSourceDao;
import cn.estsh.i3plus.mes.pcn.util.BsJdbcTemplate;
import cn.estsh.i3plus.mes.pcn.util.BsJdbcTemplateConfig;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.ReflectTool;
import cn.estsh.i3plus.pojo.base.bean.BaseBean;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesDataObject;
import cn.estsh.i3plus.pojo.mes.bean.MesDatasource;
import cn.estsh.i3plus.pojo.mes.bean.MesObjectCfg;
import cn.estsh.i3plus.pojo.mes.repository.MesDataObjectRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesObjectCfgRepository;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

@Slf4j
public class SxThirdPartyDbCollectDataCommonService implements ISxThirdPartyDbCollectDataStrategyService {

    private IDataSourceDao dataSourceDao;

    private MesDataObjectRepository dataObjectRepository;

    private MesObjectCfgRepository objectCfgRepository;

    private BsJdbcTemplateConfig jdbcTemplateConfig;

    private BsJdbcTemplate bsJdbcTemplate;

    private ISxThirdPartyDbParitySyncDispatchService paritySyncDispatchService;

    public SxThirdPartyDbCollectDataCommonService() {
        dataSourceDao = (IDataSourceDao) SpringContextsUtil.getBean("dataSourceDao");
        dataObjectRepository = (MesDataObjectRepository) SpringContextsUtil.getBean("mesDataObjectRepository");
        objectCfgRepository = (MesObjectCfgRepository) SpringContextsUtil.getBean("mesObjectCfgRepository");
        jdbcTemplateConfig = (BsJdbcTemplateConfig) SpringContextsUtil.getBean("bsJdbcTemplateConfig");
        paritySyncDispatchService = (ISxThirdPartyDbParitySyncDispatchService) SpringContextsUtil.getBean("sxThirdPartyDbParitySyncDispatchService");
    }

    @Override
    public void exec(SxThirdPartyDbCollectDataModel collect) {

        if (MesPcnExtConstWords.STATE_1.compareTo(collect.getState()) == 0) execBasic(collect);
        else if (MesPcnExtConstWords.STATE_2.compareTo(collect.getState()) == 0) execQuery(collect);
        else if (MesPcnExtConstWords.STATE_3.compareTo(collect.getState()) == 0) execFeedBack(collect);
        else return;

    }

    private void execBasic(SxThirdPartyDbCollectDataModel collect) {

        if (!checkIsSelfAddition(collect)) return;

        MesDatasource dataSourceDb = getDataSource(collect);

        if (!checkDatasource(collect, dataSourceDb)) return;

        MesDataObject dataObjectDb = getDataObjectByDsCode(collect, dataSourceDb.getDsCode());

        if (!checkDataObject(collect, dataObjectDb)) return;

        List<MesObjectCfg> objectCfgDbList = getObjectCfgListByObjectCode(collect);

        if (!checkObjectCfgList(collect, objectCfgDbList, dataObjectDb)) return;

        List<SxThirdPartyDbDynamicsFieldModel> dynamicsFieldList = getDynamicsFieldList(collect);

        if (!checkDynamicsField(collect, objectCfgDbList, dynamicsFieldList)) return;

        collect.dataSource(dataSourceDb).dataObject(dataObjectDb).objectCfgList(objectCfgDbList).dynamicsFieldList(dynamicsFieldList).state(MesPcnExtConstWords.STATE_2);

        if (collect.getNoExtraValidate()) exec(collect);

    }

    private void execQuery(SxThirdPartyDbCollectDataModel collect) {

        bsJdbcTemplate = jdbcTemplateConfig.getJdbcTemplate(collect.getDataSource());

        if (!checkBsJdbcTemplateConnect(collect, collect.getDataSource(), bsJdbcTemplate)) return;

        String sql = doAppendSql(collect);

        doCollectData(collect, sql, bsJdbcTemplate).state(MesPcnExtConstWords.STATE_3);

    }

    private void execFeedBack(SxThirdPartyDbCollectDataModel collect) {

        if (CollectionUtils.isEmpty(collect.getMapList())) return;

        MesDataObject dataObjectDb = collect.getDataObject();
        
        if (collect.getIsSelfAdditionBoo()) execFeedBack2DataObject(collect, dataObjectDb);
        else execFeedBack2ThirdPartyDb(collect, dataObjectDb);

        collect.complete();

    }

    private Boolean checkIsSelfAddition(SxThirdPartyDbCollectDataModel collect) {
        collect.setIsSelfAdditionBoo(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr().equals(collect.getIsSelfAddition()) ? true : false);
        if (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValueStr().equals(collect.getIsSelfAddition()) ||
                CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr().equals(collect.getIsSelfAddition())) return true;
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- %s:[%s]配置错误 ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), MesPcnExtConstWords.IS_SELF_ADDITION, collect.getIsSelfAddition())));
        return false;
    }

    private MesDatasource getDataSource(SxThirdPartyDbCollectDataModel collect) {
        MesDatasource dataSourceDb = dataSourceDao.getDataSourceByObjectCode(collect.getObjectCode(), collect.getOrganizeCode());
        log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} EXEC --- EXEC COMMON --- MesDatasource:{} ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), null == dataSourceDb ? MesPcnExtConstWords.EMPTY : JSONObject.toJSONString(dataSourceDb));
        return dataSourceDb;
    }

    private Boolean checkDatasource(SxThirdPartyDbCollectDataModel collect, MesDatasource dataSourceDb) {
        if (null != dataSourceDb && !StringUtils.isEmpty(dataSourceDb.getDsType()) &&
                (CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_MARIA_DB.name().equals(dataSourceDb.getDsType()) ||
                CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_SQL_SERVER.name().equals(dataSourceDb.getDsType()) ||
                CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_ORACLE.name().equals(dataSourceDb.getDsType()) ||
                CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_POSTGRE_SQL.name().equals(dataSourceDb.getDsType()))) return true;
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- 未配置有效的地址清单[MesDatasource] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode())));
        return false;
    }

    private MesDataObject getDataObjectByDsCode(SxThirdPartyDbCollectDataModel collect, String dsCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(collect.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(dsCode, MesPcnExtConstWords.DS_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(collect.getObjectCode(), MesPcnExtConstWords.OBJECT_CODE, packBean);
        MesDataObject dataObjectDb = dataObjectRepository.getByProperty(packBean);
        log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} EXEC --- EXEC COMMON --- MesDataObject:{} ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), null == dataObjectDb ? MesPcnExtConstWords.EMPTY : JSONObject.toJSONString(dataObjectDb));
        return dataObjectDb;
    }

    private Boolean checkDataObject(SxThirdPartyDbCollectDataModel collect, MesDataObject dataObjectDb) {
        if (!collect.getIsSelfAdditionBoo()) {
            if (!checkDataObjectValue(collect, dataObjectDb.getFieldPk(), MesPcnExtConstWords.FIELD_PK)) return false;
            if (!checkDataObjectValue(collect, dataObjectDb.getFeedField(), MesPcnExtConstWords.FEED_FIELD)) return false;
            if (!checkDataObjectValue(collect, dataObjectDb.getFeedValue(), MesPcnExtConstWords.FEED_VALUE)) return false;
            if (!checkDataObjectValue(collect, dataObjectDb.getReadFlagValue(), MesPcnExtConstWords.READ_FLAG_VALUE)) return false;
        } else {
            if (!checkDataObjectValue(collect, dataObjectDb.getSelfAddition(), MesPcnExtConstWords.SELF_ADDITION)) return false;
        }
        return true;
    }

    private Boolean checkDataObjectValue(SxThirdPartyDbCollectDataModel collect, String value, String field) {
        if (!StringUtils.isEmpty(value)) return true;
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- MesDataObject:[%s] IS NULL ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), field)));
        return false;
    }

    private List<MesObjectCfg> getObjectCfgListByObjectCode(SxThirdPartyDbCollectDataModel collect) {
        DdlPackBean pBean = DdlPackBean.getDdlPackBean(collect.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(collect.getObjectCode(), MesPcnExtConstWords.OBJECT_CODE, pBean);
        List<MesObjectCfg> objectCfgDbList = objectCfgRepository.findByHqlWhere(pBean);
        objectCfgDbList = CollectionUtils.isEmpty(objectCfgDbList) ? null :
                objectCfgDbList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getFieldCode()))).collect(Collectors.toList());
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- MesObjectCfg:size[%s] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), CollectionUtils.isEmpty(objectCfgDbList) ? MesPcnExtConstWords.ZERO : objectCfgDbList.size())));
        return objectCfgDbList;
    }

    private Boolean checkObjectCfgList(SxThirdPartyDbCollectDataModel collect, List<MesObjectCfg> objectCfgDbList, MesDataObject dataObjectDb) {
        if (CollectionUtils.isEmpty(objectCfgDbList)) return false;
        if (collect.getIsSelfAdditionBoo() && !checkDataObjectNecessaryFieldIsInObjectCfgList(collect, objectCfgDbList, dataObjectDb.getSelfAddition(), MesPcnExtConstWords.SELF_ADDITION)) return false;
        if (!collect.getIsSelfAdditionBoo() && !checkDataObjectNecessaryFieldIsInObjectCfgList(collect, objectCfgDbList, dataObjectDb.getFieldPk(), MesPcnExtConstWords.FIELD_PK)) return false;
        collect.noError();
        return true;
    }

    private List<SxThirdPartyDbDynamicsFieldModel> getDynamicsFieldList(SxThirdPartyDbCollectDataModel collect) {
        try {
            return !StringUtils.isEmpty(collect.getDynamicsReflectField()) ? JSONObject.parseArray(collect.getDynamicsReflectField(), SxThirdPartyDbDynamicsFieldModel.class) : null;
        } catch (Exception e) {
            throw new ImppBusiException(String.format("动态反射字段[%s]转换异常:%s", collect.getDynamicsReflectField(), e.getMessage()));
        }
    }

    private Boolean checkDynamicsField(SxThirdPartyDbCollectDataModel collect, List<MesObjectCfg> objectCfgDbList, List<SxThirdPartyDbDynamicsFieldModel> dynamicsFieldList) {
        List<String> sourceFieldList = CollectionUtils.isEmpty(dynamicsFieldList) ? null :
                dynamicsFieldList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getSourceField()) &&
                        !StringUtils.isEmpty(o.getTargetField()))).map(SxThirdPartyDbDynamicsFieldModel::getSourceField).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(sourceFieldList)) return true;
        List<String> fieldCodeList = objectCfgDbList.stream().filter(o -> (null != o &&
                o.getIsSave() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue())).map(MesObjectCfg::getFieldCode).collect(Collectors.toList());
        return checkFieldIsExistObjectCfg(collect, sourceFieldList.toArray(new String[sourceFieldList.size()]), fieldCodeList, MesPcnExtConstWords.DYNAMICS_REFLECT_FIELD);
    }

    private Boolean checkDataObjectNecessaryFieldIsInObjectCfgList(SxThirdPartyDbCollectDataModel collect, List<MesObjectCfg> objectCfgDbList, String fieldCode, String field) {
        Optional<MesObjectCfg> objectCfgOp = objectCfgDbList.stream().filter(o -> (null != o && o.getFieldCode().equals(fieldCode))).findFirst();
        if (null != objectCfgOp && objectCfgOp.isPresent()) return true;
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- MesObjectCfg未配置MesDataObject对应字段%s:[%s] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), field, fieldCode)));
        return false;
    }

    private Boolean checkBsJdbcTemplateConnect(SxThirdPartyDbCollectDataModel collect, MesDatasource dataSourceDb, BsJdbcTemplate bsJdbcTemplate) {
        if (null == bsJdbcTemplate) {
            log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- BsJdbcTemplate 获取失败 ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode())));
            return false;
        }
        Boolean isConnected = jdbcTemplateConfig.checkDbConn(dataSourceDb);
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- BsJdbcTemplate:isConnected[%s] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), isConnected)));
        if (isConnected) collect.noError();
        return isConnected;
    }

    private String doAppendSql(SxThirdPartyDbCollectDataModel collect) {
        MesDataObject dataObjectDb = collect.getDataObject();

        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append(MesPcnExtConstWords.SELECT);
        for (MesObjectCfg mesObjectCfg : collect.getObjectCfgList()) {
            sqlBuilder.append(mesObjectCfg.getFieldCode()).append(MesPcnExtConstWords.COMMA);
        }
        sqlBuilder = new StringBuilder(sqlBuilder.substring(0, sqlBuilder.toString().length() - 1));
        sqlBuilder.append(MesPcnExtConstWords.ONE_SPACE).append(MesPcnExtConstWords.FROM).append(MesPcnExtConstWords.ONE_SPACE)
                .append(collect.getOtherTableName()).append(MesPcnExtConstWords.WHERE);

        if (collect.getIsSelfAdditionBoo()) {
            sqlBuilder.append(dataObjectDb.getSelfAddition())
                    .append(MesPcnExtConstWords.GREATER_THAN)
                    .append(StringUtils.isEmpty(dataObjectDb.getSelfAdditionValue()) ? 0 : dataObjectDb.getSelfAdditionValue());
        } else {
            sqlBuilder.append(dataObjectDb.getFeedField()).append(MesPcnExtConstWords.EQ).append(dataObjectDb.getReadFlagValue());
        }

        sqlBuilder = appendArr(sqlBuilder, getArr(collect.getSerialNumberArrField()));
        sqlBuilder = appendArr(sqlBuilder, getArr(collect.getProductSnArrField()));

        sqlBuilder.append(MesPcnExtConstWords.ORDER_BY).append(collect.getOrderField());

        return modifySqlByDbType(collect, sqlBuilder.toString(), collect.getDataSource().getDsType());
    }

    private StringBuilder appendArr(StringBuilder sqlBuilder, String[] arr) {
        if (null != arr) {
            for (String snField : arr) {
                if (StringUtils.isEmpty(snField)) continue;
                sqlBuilder.append(MesPcnExtConstWords.AND_SPACE).append(snField).append(MesPcnExtConstWords.IS_NOT_NULL).append(MesPcnExtConstWords.AND_SPACE).append(snField).append(MesPcnExtConstWords.NOT_EQ_EMPTY);
            }
        }
        return sqlBuilder;
    }

    private String modifySqlByDbType(SxThirdPartyDbCollectDataModel collect, String sql, String dataSourceType) {
        if (CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_MARIA_DB.name().equals(dataSourceType)) {
            sql = new StringJoiner(MesPcnExtConstWords.ONE_SPACE).add(sql).add(MesPcnExtConstWords.LIMIT).add(collect.getLimitRows()).toString();
        } else if (CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_SQL_SERVER.name().equals(dataSourceType)) {
            sql = sql.replaceFirst(MesPcnExtConstWords.SELECT, new StringJoiner(MesPcnExtConstWords.ONE_SPACE).add(MesPcnExtConstWords.SELECT_TOP).add(collect.getLimitRows()).toString());
        } else if (CommonEnumUtil.DATA_SOURCE_TYPE.SOURCE_ORACLE.name().equals(dataSourceType)) {
            sql = sql.replaceFirst(MesPcnExtConstWords.SELECT, MesPcnExtConstWords.SELECT_ROWNUM).
                    replaceFirst(MesPcnExtConstWords.WHERE, new StringBuilder().append(MesPcnExtConstWords.WHERE_ROWNUM_GREATER_THAN).append(collect.getLimitRows()).append(MesPcnExtConstWords.AND_SPACE).toString());
        } else {
            sql = new StringJoiner(MesPcnExtConstWords.ONE_SPACE).add(sql).add(MesPcnExtConstWords.LIMIT).add(collect.getLimitRows()).toString();
        }
        log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} EXEC --- EXEC COMMON --- QUERY SQL:[{}] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), sql);
        return sql;
    }

    private SxThirdPartyDbCollectDataModel doCollectData(SxThirdPartyDbCollectDataModel collect, String sql, BsJdbcTemplate bsJdbcTemplate) {
        List<Map<String, Object>> mapList = bsJdbcTemplate.getJdbcTemplate().queryForList(sql, new HashMap<>());
        collect.mapList(mapList).execSize(CollectionUtils.isEmpty(mapList) ? MesPcnExtConstWords.ZERO : mapList.size());
        log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} EXEC --- EXEC COMMON --- COLLECT_DATA:size[{}] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), collect.getExecSize());
        return collect;
    }

    private void execFeedBack2DataObject(SxThirdPartyDbCollectDataModel collect, MesDataObject dataObjectDb) {
        OptionalLong op = collect.getMapList().stream().mapToLong(o -> Long.parseLong(String.valueOf(o.get(dataObjectDb.getSelfAddition())))).max();
        if (null != op && op.isPresent()) {
            dataObjectDb.setSelfAdditionValue(op.getAsLong());
            ConvertBean.serviceModelUpdate(dataObjectDb, collect.getUserInfo());
            log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} EXEC --- EXEC COMMON --- FEED BACK MesDataObject:{} ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), JSONObject.toJSONString(dataObjectDb));
            dataObjectRepository.save(dataObjectDb);
        }
    }

    private void execFeedBack2ThirdPartyDb(SxThirdPartyDbCollectDataModel collect, MesDataObject dataObjectDb) {

        StringBuilder sb = new StringBuilder(MesPcnExtConstWords.UPDATE)
                .append(collect.getOtherTableName())
                .append(MesPcnExtConstWords.SET)
                .append(dataObjectDb.getFeedField())
                .append(MesPcnExtConstWords.ONE_SPACE).append(MesPcnExtConstWords.EQ).append(MesPcnExtConstWords.ONE_SPACE)
                .append(dataObjectDb.getFeedValue())
                .append(MesPcnExtConstWords.WHERE)
                .append(dataObjectDb.getFieldPk()).append(MesPcnExtConstWords.IN_LEFT);
        StringJoiner stringJoiner = new StringJoiner(MesPcnExtConstWords.COMMA);
        for (Map<String, Object> map : collect.getMapList()) {
            stringJoiner.add(map.get(dataObjectDb.getFieldPk()).toString());
        }
        sb.append(stringJoiner).append(MesPcnExtConstWords.IN_RIGHT);
        log.info("工厂{}第三方DB数据采集 --- CFG_CODE: {} EXEC --- CFG_KEY: {} EXEC --- EXEC COMMON --- FEED BACK SQL:[{}] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), sb.toString());
        bsJdbcTemplate.getJdbcTemplate().update(sb.toString(), new HashMap<>());
    }

    @Override
    public Boolean checkFieldIsNull(SxThirdPartyDbCollectDataModel collect, String fieldValue, String field, String fieldName) {
        if (!StringUtils.isEmpty(fieldValue)) return true;
        log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- cfgValue:%s 未设置:%s字段[%s] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), collect.getCfgValue(), fieldName, field)));
        return false;
    }

    @Override
    public Boolean checkFieldIsExistObjectCfg(SxThirdPartyDbCollectDataModel collect, String[] arr, List<String> fieldCodeList, String field) {
        if (null == arr) return true;
        for (String snField : arr) {
            if (StringUtils.isEmpty(snField) || fieldCodeList.contains(snField)) continue;
            log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- MesObjectCfg未配置%s对应字段[%s] ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), field, snField)));
            return false;
        }
        return true;
    }

    @Override
    public String[] getArr(String snField) {
        if (StringUtils.isEmpty(snField)) return null;
        return snField.split(MesPcnExtConstWords.COMMA);
    }

    @Override
    public String assembleSn(Map<String, Object> map, String snField) {
        if (StringUtils.isEmpty(snField)) return null;
        String[] snArr = snField.split(MesPcnExtConstWords.COMMA);

        String serialNumber = MesPcnExtConstWords.EMPTY;
        StringBuilder snBuilder = new StringBuilder(serialNumber);
        for (String s : snArr) {
            snBuilder.append(map.get(s) == null ? MesPcnExtConstWords.EMPTY : String.valueOf(map.get(s)).trim());
        }
        serialNumber = snBuilder.toString();
        return serialNumber.toUpperCase();
    }

    @Override
    public void packDynamicsField(SxThirdPartyDbCollectDataModel collect, Map<String, Object> map, Object obj) {
        List<SxThirdPartyDbDynamicsFieldModel> dynamicsFieldList = collect.getDynamicsFieldList();
        if (CollectionUtils.isEmpty(dynamicsFieldList)) return;
        for (SxThirdPartyDbDynamicsFieldModel dynamicsField : dynamicsFieldList) {
            if (null == dynamicsField) continue;
            Object value = map.get(dynamicsField.getSourceField());
            if (StringUtils.isEmpty(value)) continue;
            String valueStr = String.valueOf(value).replaceAll(MesPcnExtConstWords.ONE_SPACE, MesPcnExtConstWords.EMPTY).trim();
            setObjectAttr(obj, dynamicsField.getTargetField(), valueStr);
        }
    }

    @Override
    public void packDefaultField(SxThirdPartyDbCollectDataModel collect, BaseBean baseBean) {
        if (StringUtils.isEmpty(collect.getDefaultValueField())) return;
        try {
            Map<String, Object> defaultFieldValueMap = JSONObject.parseObject(collect.getDefaultValueField(), Map.class);
            if (CollectionUtils.isEmpty(defaultFieldValueMap)) return;
            ReflectTool.setObjectAttr(baseBean, defaultFieldValueMap);
        } catch (Exception e) {
            throw new ImppBusiException(String.format("默认字段[%s]处理异常:%s", collect.getDefaultValueField(), e.getMessage()));
        }
    }

    @Override
    public void setObjectAttr(Object obj, String fieldName, Object value) {
        try {
            ReflectTool.setObjectAttr(obj, fieldName, value);
        } catch (Exception e) {
            throw new ImppBusiException(String.format("目标字段[%s]反射写值[%s]异常:%s", fieldName, value, e.getMessage()));
        }
    }

    @Override
    public void execMethodField(SxThirdPartyDbCollectDataModel collect, Object obj) {
        if (StringUtils.isEmpty(collect.getMethodField())) return;
        try {
            Map<String, String> methodFieldMap = JSONObject.parseObject(collect.getMethodField(), Map.class);
            if (CollectionUtils.isEmpty(methodFieldMap)) return;

            Map<String, ISxThirdPartyDbCollectDataMethodService> methodImplMap = null;
            for (String field : methodFieldMap.keySet()) {
                if (StringUtils.isEmpty(field)) continue;
                ISxThirdPartyDbCollectDataMethodService methodService = (ISxThirdPartyDbCollectDataMethodService) SpringContextsUtil.getBean(methodFieldMap.get(field));
                if (null == methodFieldMap) throw new ImppBusiException(String.format("业务自定义方法[%s]不存在", methodFieldMap.get(field)));
                if (CollectionUtils.isEmpty(methodImplMap)) methodImplMap = new LinkedHashMap<>();
                methodImplMap.put(field, methodService);
            }
            if (CollectionUtils.isEmpty(methodImplMap)) return;

            for (String field : methodImplMap.keySet()) {
                if (StringUtils.isEmpty(field)) continue;
                Object value = methodImplMap.get(field).exec(collect, obj);
                if (StringUtils.isEmpty(value)) continue;
                setObjectAttr(obj, field, value);
            }
        } catch (Exception e) {
            throw new ImppBusiException(String.format("业务自定义方法字段%s:[%s]处理异常:%s", MesPcnExtConstWords.METHOD_FIELD, collect.getMethodField(), e.getMessage()));
        }
    }

    @Override
    public Boolean saveParitySyncData(SxThirdPartyDbCollectDataModel collect) {
        if (CollectionUtils.isEmpty(collect.getMapList()) || StringUtils.isEmpty(collect.getParitySyncTableName())) return false;
        try {
            ISxThirdPartyDbParitySyncSqlBuilderService builderService =
                    (ISxThirdPartyDbParitySyncSqlBuilderService) SpringContextsUtil.getBean(MesPcnExtEnumUtil.SX_PARITY_SYNC_SQL_BUILDER_STRATEGY.valueOfClazz(collect.getParitySyncDatabase()));
            paritySyncDispatchService.exec(collect, builderService);
        } catch (Exception e) {
            log.info(collect.error(String.format("工厂%s第三方DB数据采集 --- CFG_CODE: %s EXEC --- CFG_KEY: %s EXEC --- EXEC COMMON --- 对等同步执行异常:%s ---", collect.getOrganizeCode(), collect.getCfgCode(), collect.getObjectCode(), e.getMessage())));
            return false;
        }
        return true;
    }

}
