package com.yunzhupaas.base.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.vertical_blank.sqlformatter.SqlFormatter;
import com.google.common.collect.ImmutableList;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.ActionResultCode;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.entity.DataInterfaceEntity;
import com.yunzhupaas.base.entity.DataSetEntity;
import com.yunzhupaas.base.mapper.DataSetMapper;
import com.yunzhupaas.base.model.datainterface.*;
import com.yunzhupaas.base.model.dataset.*;
import com.yunzhupaas.base.service.DataInterfaceService;
import com.yunzhupaas.base.service.DataSetService;
import com.yunzhupaas.base.service.DbLinkService;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.base.util.DataInterfaceParamUtil;
import com.yunzhupaas.base.util.dataSet.DataSetConfigUtil;
import com.yunzhupaas.constant.*;
import com.yunzhupaas.database.model.dbfield.DbFieldModel;
import com.yunzhupaas.database.model.dbfield.JdbcColumnModel;
import com.yunzhupaas.database.model.dto.PrepSqlDTO;
import com.yunzhupaas.database.model.entity.DbLinkEntity;
import com.yunzhupaas.database.source.DbBase;
import com.yunzhupaas.database.sql.util.SqlFastUtil;
import com.yunzhupaas.database.util.ConnUtil;
import com.yunzhupaas.database.util.DbTypeUtil;
import com.yunzhupaas.database.util.DynamicDataSourceUtil;
import com.yunzhupaas.database.util.JdbcUtil;
import com.yunzhupaas.emnus.DsJoinTypeEnum;
import com.yunzhupaas.emnus.SearchMethodEnum;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.model.visualJson.FieLdsModel;
import com.yunzhupaas.model.visualJson.config.ConfigModel;
import com.yunzhupaas.permission.entity.OrganizeEntity;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.entity.UserRelationEntity;
import com.yunzhupaas.permission.service.OrganizeAdministratorService;
import com.yunzhupaas.permission.service.OrganizeService;
import com.yunzhupaas.permission.service.UserRelationService;
import com.yunzhupaas.permission.service.UserService;
import com.yunzhupaas.util.*;
import com.yunzhupaas.util.treeutil.SumTree;
import com.yunzhupaas.util.visiual.YunzhupaasKeyConsts;
import lombok.Cleanup;
import lombok.SneakyThrows;
import oracle.sql.TIMESTAMP;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.exceptions.PersistenceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.SQLSyntaxErrorException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据集合
 *
 * @author 云筑产品开发平台组
 * @version v5.0.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2024/5/6 14:07:11
 */
@Service
public class DataSetServiceImpl extends SuperServiceImpl<DataSetMapper, DataSetEntity> implements DataSetService {

    @Autowired
    private OrganizeService organizeApi;
    @Autowired
    private UserService userApi;
    @Autowired
    private UserRelationService userRelationApi;
    @Autowired
    private OrganizeAdministratorService organizeAdminTratorApi;
    @Autowired
    private DbLinkService dbLinkService;
    @Autowired
    private DataInterfaceService dataInterfaceService;

    @Override
    public List<DataSetEntity> getList(DataSetPagination pagination) {
        QueryWrapper<DataSetEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtil.isNotEmpty(pagination.getKeyword())) {
            queryWrapper.lambda().like(DataSetEntity::getFullName, pagination.getKeyword());
        }
        if (StringUtil.isNotEmpty(pagination.getObjectType())) {
            queryWrapper.lambda().eq(DataSetEntity::getObjectType, pagination.getObjectType());
        }
        if (StringUtil.isNotEmpty(pagination.getObjectId())) {
            queryWrapper.lambda().eq(DataSetEntity::getObjectId, pagination.getObjectId());
        }
        queryWrapper.lambda().orderByAsc(DataSetEntity::getCreatorTime);
        return list(queryWrapper);
    }

    @Override
    public void create(List<DataSetForm> listSet, String ObjectType, String ObjectId) {
        QueryWrapper<DataSetEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DataSetEntity::getObjectType, ObjectType);
        queryWrapper.lambda().eq(DataSetEntity::getObjectId, ObjectId);
        List<DataSetEntity> list = list(queryWrapper);
        if (CollectionUtils.isNotEmpty(listSet)) {
            List<String> nameList = listSet.stream().map(DataSetForm::getFullName).distinct()
                    .collect(Collectors.toList());
            if (listSet.size() != nameList.size()) {
                throw new DataException(MsgCode.SYS046.get());
            }
            List<String> collect = listSet.stream().map(DataSetForm::getId).collect(Collectors.toList());
            for (DataSetEntity entity : list) {
                if (!collect.contains(entity.getId())) {
                    this.removeById(entity.getId());
                }
            }
            for (DataSetForm item : listSet) {
                item.setObjectType(ObjectType);
                item.setObjectId(ObjectId);
                DataSetEntity entity = JsonUtil.getJsonToBean(item, DataSetEntity.class);
                if (StringUtil.isNotEmpty(item.getId()) && this.getById(item.getId()) != null) {
                    entity.setLastModifyUserId(UserProvider.getUser().getUserId());
                    entity.setLastModifyTime(new Date());
                } else {
                    entity.setId(RandomUtil.uuId());
                    entity.setCreatorUserId(UserProvider.getUser().getUserId());
                    entity.setCreatorTime(new Date());
                }
                this.setIgnoreLogicDelete().removeById(entity.getId());
                this.setIgnoreLogicDelete().saveOrUpdate(entity);
                this.clearIgnoreLogicDelete();
            }
        } else {
            this.remove(queryWrapper);
        }
    }

    @FunctionalInterface
    private interface MultiConsumer<T, S, U> {
        void accept(T t, S s, U u);
    }

    @Override
    @DSTransactional
    public SumTree<TableTreeModel> getTabFieldStruct(DataSetEntity item) throws Exception {
        // 配置式
        if (Objects.equals(item.getType(), 3)) {
            return getInterfaceFields(item);
        }
        // 配置式
        if (Objects.equals(item.getType(), 2)) {
            return getConfigureSQL(item);
        }
        // SQL语句
        TableTreeModel printTable = new TableTreeModel();
        if (StringUtil.isNotEmpty(
                ParameterUtil.checkContainsSensitive(item.getDataConfigJson(), DbSensitiveConstant.PRINT_SENSITIVE))) {
            throw new DataException(MsgCode.SYS047.get());
        }
        MultiConsumer<DataSetEntity, List<List<JdbcColumnModel>>, DbLinkEntity> consumer = (dataSetEntity, dataList,
                dbLinkEntity) -> {
            Set<String> tableNameSet = new HashSet<>();
            String parentId = dataSetEntity.getId();
            String headTable = dataSetEntity.getFullName();
            printTable.setId(parentId);
            printTable.setChildren(treeSetField(tableNameSet, dbLinkEntity, dataList.get(0), parentId));
            printTable.setFullName(headTable);
            printTable.setParentId("struct");
        };
        sqlCommon(item, consumer, new HashMap<>(), true);
        return printTable;
    }

    public List<SumTree<TableTreeModel>> treeSetField(Set<String> tableNameSet, DbLinkEntity dbLinkEntity,
            List<JdbcColumnModel> dbJdbcModelList, String parentId) {
        List<SumTree<TableTreeModel>> list = new ArrayList<>();
        for (Map<String, String> mapOne : getFieldMap(dbLinkEntity, dbJdbcModelList, tableNameSet)) {
            TableTreeModel fieldModel = new TableTreeModel();
            fieldModel.setId(mapOne.get("field"));
            fieldModel.setFullName(mapOne.get("fieldName"));
            fieldModel.setLabel(mapOne.get("comment"));
            fieldModel.setParentId(parentId);
            list.add(fieldModel);
        }
        return list;
    }

    private List<Map<String, String>> getFieldMap(DbLinkEntity dbLinkEntity, List<JdbcColumnModel> dbJdbcModelList,
            Set<String> tableNameSet) {
        List<Map<String, String>> mapList = new ArrayList<>();
        // JdbcTableModel tableComment = null;
        Map<String, List<DbFieldModel>> tableFiledsMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(dbJdbcModelList)) {
            // 部分数据库，无法从元数据中查出表、字段注释，比如Oracle
            // tableComment = PrintDevUtil.getColumnComment(dbLinkEntity,
            // dbJdbcModelList.get(0).getTable());
            try {
                for (JdbcColumnModel jdbcColumnModel : dbJdbcModelList) {
                    if (StringUtil.isNotBlank(jdbcColumnModel.getTable())
                            && !tableFiledsMap.containsKey(jdbcColumnModel.getTable())) {
                        tableFiledsMap.put(jdbcColumnModel.getTable(),
                                SqlFastUtil.getFieldList(dbLinkEntity, jdbcColumnModel.getTable()));
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        for (JdbcColumnModel model : dbJdbcModelList) {
            // 获取表名
            Map<String, String> map = new HashMap<>();
            String tableInfo = model.getTable();
            String fieldInfo = model.getField();
            String comment = "";
            List<DbFieldModel> dbFieldModels = tableFiledsMap.get(tableInfo);
            if (CollectionUtils.isNotEmpty(dbFieldModels)) {
                String columnComment = "";
                for (DbFieldModel column : dbFieldModels) {
                    if (column.getField().equalsIgnoreCase(fieldInfo)) {
                        columnComment = column.getFieldName();
                    }
                }
                fieldInfo = fieldInfo + " (" + columnComment + ")";
                comment = columnComment;
            }
            tableNameSet.add(tableInfo); // 表名
            map.put("fieldName", fieldInfo);// 表字段
            map.put("field", model.getLabel());
            map.put("comment", comment);
            mapList.add(map);
        }
        return mapList;
    }

    public void sqlCommon(DataSetEntity dataSetEntity,
            MultiConsumer<DataSetEntity, List<List<JdbcColumnModel>>, DbLinkEntity> consumer,
            Map<String, Object> params, boolean isFieldStruct) throws Exception {
        DbLinkEntity dbLinkEntity = dbLinkService.getResource(dataSetEntity.getDbLinkId());
        // 转换json
        List<Object> values = new ArrayList<>();
        String sql = replaceSql(dataSetEntity.getDataConfigJson(), dataSetEntity.getParameterJson(), params, values);

        List<List<JdbcColumnModel>> dataList;
        String addition;
        try {
            if (DbTypeUtil.checkOracle(dbLinkEntity)) {
                addition = "SELECT major.* FROM\n" +
                        "\t(SELECT 1 from dual) temp\n" +
                        "LEFT JOIN \n" +
                        " \t({sql}) major\n" +
                        "ON \n" +
                        "\t1 = 1";
            } else {
                addition = "SELECT major.* FROM\n" +
                        "\t(SELECT 1 AS tempColumn) AS temp\n" +
                        "LEFT JOIN \n" +
                        " \t({sql}) AS major\n" +
                        "ON \n" +
                        "\t1 = 1";
            }
            boolean isFunction = StringUtil.isNotEmpty(sql) && sql.toLowerCase().startsWith("call");// 判断是否存储过程
            // isFieldStruct 获取结构时才走sql替换
            sql = isFunction || !isFieldStruct ? sql : addition.replace("{sql}", sql);
            dataList = JdbcUtil.queryJdbcColumns(new PrepSqlDTO(sql, values).withConn(dbLinkEntity)).get();
            if (dataList.size() == 0) {
                dataList = (JdbcUtil.queryJdbcColumns(new PrepSqlDTO(sql, values).withConn(dbLinkEntity))
                        .setIsValue(false).get());
            }
        } catch (Exception e) {
            throw new DataException(MsgCode.PRI007.get());
        }
        if (dataList.size() == 0) {
            throw new DataException(MsgCode.PRI004.get());
        }
        consumer.accept(dataSetEntity, dataList, dbLinkEntity);
    }

    @SneakyThrows
    @Override
    @DSTransactional
    public Map<String, Object> getDataMapOrList(DataSetEntity entity, Map<String, Object> params, String formId,
            boolean outIsMap) {
        Map<String, Object> printDataMap = new HashMap<>();
        DataSetForm dataSetForm = JsonUtil.getJsonToBean(entity, DataSetForm.class);
        dataSetForm.setFormId(formId);
        // 数据接口
        if (Objects.equals(entity.getType(), 3)) {
            try {
                dataSetForm.setNoPage(true);
                DataSetViewInfo previewDataInterface = getPreviewDataInterface(dataSetForm);
                if (outIsMap) {
                    printDataMap.put(entity.getFullName(), previewDataInterface.getPreviewData().get(0));
                } else {
                    printDataMap.put(entity.getFullName(), previewDataInterface.getPreviewData());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return printDataMap;
        }
        // 配置式 获取数据
        if (Objects.equals(entity.getType(), 2)) {
            dataSetForm.setNoPage(true);
            List<Map<String, Object>> previewData = getPreviewData(dataSetForm).getPreviewData();
            if (outIsMap) {
                printDataMap.put(entity.getFullName(), previewData.get(0));
            } else {
                printDataMap.put(entity.getFullName(), previewData);
            }
            return printDataMap;
        }
        // sql语句获取数据
        try {
            MultiConsumer<DataSetEntity, List<List<JdbcColumnModel>>, DbLinkEntity> consumer = (dataSetEntity, dataList,
                    dbLinkEntity) -> {
                List<Map<String, Object>> lists = swapData(dataList);
                if (outIsMap) {
                    printDataMap.put(dataSetEntity.getFullName(), lists.get(0));
                } else {
                    printDataMap.put(dataSetEntity.getFullName(), lists);
                }
            };
            params.put("@formId", formId);
            sqlCommon(entity, consumer, params, false);
        } catch (Exception e) {
            e.printStackTrace();
            // throw new Exception(e.getMessage());
        }
        return printDataMap;
    }

    @Override
    public Map<String, Object> getDataList(DataSetQuery query) {
        Map<String, Object> dataMapOrList = new HashMap<>();
        List<FieLdsModel> queryList = StringUtil.isNotEmpty(query.getQueryList())
                ? JsonUtil.getJsonToList(query.getQueryList(), FieLdsModel.class)
                : new ArrayList<>();
        List<DataSetEntity> dataSetList = getList(new DataSetPagination(query.getType(), query.getId()));
        Map<String, Object> queryMap = query.getMap() != null ? query.getMap() : new HashMap<>();
        Map<String, Map<String, FieLdsModel>> queryData = new HashMap<>();
        for (String key : queryMap.keySet()) {
            String vModel = key.replace("-", ".");
            String[] name = key.split("-");
            String model = name[0];
            Map<String, FieLdsModel> fieLdsModelMap = queryData.get(model) != null ? queryData.get(model)
                    : new HashMap<>();
            FieLdsModel fieLdsModel = queryList.stream().filter(t -> Objects.equals(t.getVModel(), vModel)).findFirst()
                    .orElse(null);
            if (fieLdsModel != null) {
                fieLdsModelMap.put(key, fieLdsModel);
            }
            queryData.put(model, fieLdsModelMap);
        }
        for (DataSetEntity item : dataSetList) {
            Map<String, Object> map = new HashMap<>();
            Map<String, FieLdsModel> fieLdMap = queryData.get(item.getFullName()) != null
                    ? queryData.get(item.getFullName())
                    : new HashMap<>();
            boolean isInterfaceSql = true;
            if (Objects.equals(item.getType(), 2)) {
                DataSetForm dataSetForm = JsonUtil.getJsonToBean(item, DataSetForm.class);
                dataSetForm.setFormId(query.getFormId());
                String previewSqlText = getPreviewData(dataSetForm).getPreviewSqlText();
                item.setDataConfigJson(previewSqlText);
                item.setType(1);
            }
            if (Objects.equals(item.getType(), 3)) {
                DataInterfaceEntity info = dataInterfaceService.getInfo(item.getInterfaceId());
                isInterfaceSql = info != null && Objects.equals(info.getType(), 1);
                if (info != null && Objects.equals(info.getType(), 1)) {
                    if (StringUtil.isNotEmpty(item.getParameterJson())) {
                        List<DataInterfaceModel> jsonToList = JsonUtil.getJsonToList(item.getParameterJson(),
                                DataInterfaceModel.class);
                        Map<String, String> dataMap = new HashMap<>();
                        dataInterfaceService.paramSourceTypeReplaceValue(jsonToList, dataMap);
                        map.putAll(dataMap);
                    }
                    DataConfigJsonModel configJsonModel = JsonUtil.getJsonToBean(info.getDataConfigJson(),
                            DataConfigJsonModel.class);
                    SqlDateModel countSqlDateModel = JsonUtil.getJsonToBean(configJsonModel.getSqlData(),
                            SqlDateModel.class);
                    item.setDbLinkId(countSqlDateModel.getDbLinkId());
                    item.setDataConfigJson(countSqlDateModel.getSql());
                    item.setType(1);
                }
            }

            // sql语句
            if (Objects.equals(item.getType(), 1)) {
                if (fieLdMap.size() > 0) {
                    int num = 0;
                    String sql = item.getDataConfigJson();
                    DataSetEntity queryEntity = new DataSetEntity();
                    queryEntity.setDataConfigJson("select * from (" + sql + ") t where 1=1 ");
                    queryEntity.setDbLinkId(item.getDbLinkId());
                    for (String key : fieLdMap.keySet()) {
                        FieLdsModel fieLdsModel = fieLdMap.get(key);
                        if (fieLdsModel != null) {
                            String[] name = key.split("-");
                            String model = name.length > 1 ? name[1] : name[0];
                            keyJson(fieLdsModel, model, queryMap.get(key));
                            num = value(fieLdsModel, queryEntity, model, num, map);
                        }
                    }
                    item.setDataConfigJson(queryEntity.getDataConfigJson());
                }
            }
            Map<String, Object> dataList = new HashMap<>();
            Map<String, Object> dataMapOrList1 = getDataMapOrList(item, map, null, false);
            for (String key : dataMapOrList1.keySet()) {
                try {
                    List<Map<String, Object>> data = (List<Map<String, Object>>) dataMapOrList1.get(key);
                    List<FieLdsModel> queryCondition = new ArrayList<>(fieLdMap.values());
                    List<Map<String, Object>> interfaceData = new ArrayList<>();
                    if (queryCondition.size() > 0 && !isInterfaceSql) {
                        for (Map<String, Object> dataMap : data) {
                            boolean hasExtra = mapCompar(queryCondition, dataMap);
                            if (hasExtra) {
                                interfaceData.add(dataMap);
                            }
                        }
                        dataList.put(key, interfaceData);
                    } else {
                        dataList.put(key, data);
                    }
                } catch (Exception e) {
                }
            }
            dataMapOrList.putAll(dataList);
        }
        return dataMapOrList;
    }

    private List<Map<String, Object>> swapData(List<List<JdbcColumnModel>> dbJdbcModelList) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (List<JdbcColumnModel> mods : dbJdbcModelList) {
            Map<String, Object> map = new HashMap<>(16);
            for (JdbcColumnModel mod : mods) {
                Object value = mod.getValue();
                if (value != null) {
                    value = swapCulomn(value, mod);
                } else {
                    value = "";
                }
                map.put(mod.getLabel(), value);
            }
            mapList.add(map);
        }
        return mapList;
    }

    private String replaceSql(String sql, String paramJson, Map<String, Object> params, List<Object> values) {
        Map<String, Object> map = new HashMap<>();
        for (String key : params.keySet()) {
            map.put(key, params.get(key));
        }
        // 系统内置参数替换
        Map<Double, DataInterfaceMarkModel> systemParameter = dataInterfaceService.systemParameterOne(sql,
                UserProvider.getUser());
        if (sql.contains(DataInterfaceVarConst.FORM_ID)) {
            DataInterfaceParamUtil.getParamModel(systemParameter, sql, DataInterfaceVarConst.FORM_ID,
                    params.get(DataInterfaceVarConst.FORM_ID));
        }
        // 自定义参数替换
        sql = dataInterfaceService.customizationParameter(paramJson, sql, map, systemParameter);
        // 参数替换为占位符
        sql = dataInterfaceService.getHandleArraysSql(sql, values, systemParameter);
        return sql;
    }

    private Object swapCulomn(Object obj, JdbcColumnModel mod) {
        // if (mod.getDataType().equalsIgnoreCase("decimal")) {
        // assert obj instanceof BigDecimal;
        // return ((BigDecimal) obj).toPlainString();
        // }
        if (obj instanceof Clob) {
            Clob clob = (Clob) obj;
            StringBuilder sb = new StringBuilder();
            // 获取CLOB字段的内容长度
            int length = 0;
            // 以流的形式读取CLOB字段的内容
            try (Reader reader = clob.getCharacterStream()) {
                length = (int) clob.length();
                char[] buffer = new char[length];
                int bytesRead;
                // 逐个字符读取并添加到字符串构建器中
                while ((bytesRead = reader.read(buffer)) != -1) {
                    sb.append(buffer, 0, bytesRead);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (StringUtil.isNotEmpty(sb.toString())) {
                return sb.toString();
            }
        } else if (obj instanceof LocalDateTime || obj instanceof Timestamp || obj instanceof TIMESTAMP) {
            LocalDateTime dateTime = null;
            if (obj instanceof LocalDateTime) {
                dateTime = (LocalDateTime) obj;
            } else if (obj instanceof Timestamp) {
                dateTime = ((Timestamp) obj).toLocalDateTime();
            } else {
                dateTime = LocalDateTimeUtil.of(cn.hutool.core.date.DateUtil.parse(obj.toString()));
            }
            return dateTime != null ? new Date(DateUtil.localDateTime2Millis(dateTime)) : obj;
        }
        return obj;
    }

    private void keyJson(FieLdsModel fieLdsModel, String key, Object object) {
        convertUserSelectData(fieLdsModel);
        // 封装查询
        ConfigModel config = fieLdsModel.getConfig();
        Integer searchType = fieLdsModel.getSearchType();
        config.setYunzhupaasKey(fieLdsModel.getType());
        String yunzhupaasKey = config.getYunzhupaasKey();
        // 模糊搜索
        boolean isMultiple = fieLdsModel.getSearchMultiple() || fieLdsModel.getMultiple();
        List<String> type = YunzhupaasKeyConsts.SelectIgnore;
        // 文本框搜索
        List<String> base = YunzhupaasKeyConsts.BaseSelect;
        if (isMultiple || type.contains(yunzhupaasKey)) {
            if (object instanceof String) {
                object = ImmutableList.of(object);
            }
            searchType = 4;
        }
        if (base.contains(yunzhupaasKey) && searchType == 3) {
            searchType = 2;
        }
        String symbol = searchType == 1 ? SearchMethodEnum.Equal.getSymbol()
                : searchType == 3 ? SearchMethodEnum.Between.getSymbol()
                        : searchType == 2 ? SearchMethodEnum.Like.getSymbol() : SearchMethodEnum.Included.getSymbol();
        fieLdsModel.setSymbol(symbol);
        if (object instanceof List) {
            fieLdsModel.setFieldValue(JsonUtil.getObjectToString(object));
        } else {
            fieLdsModel.setFieldValue(String.valueOf(object));
        }

        // 封装数据
        List<String> dateControl = YunzhupaasKeyConsts.DateSelect;
        dateControl.add("date");
        List<String> numControl = YunzhupaasKeyConsts.NumSelect;
        List<String> dataList = new ArrayList<>();
        String value = fieLdsModel.getFieldValue();
        Object fieldValue = fieLdsModel.getFieldValue();
        Object fieldValueTwo = fieLdsModel.getFieldValue();
        if (fieLdsModel.getFieldValue() == null) {
            fieldValue = "";
        }
        List<String> controlList = new ArrayList() {
            {
                addAll(numControl);
                addAll(dateControl);
                add(YunzhupaasKeyConsts.TIME);
                add("time");
            }
        };
        // 处理数据
        if (controlList.contains(yunzhupaasKey) && StringUtil.isNotEmpty(value)
                && !SearchMethodEnum.Like.getSymbol().equals(fieLdsModel.getSymbol())) {
            int num = 0;
            List<String> data = new ArrayList<>();
            try {
                data.addAll(JsonUtil.getJsonToList(value, String.class));
            } catch (Exception e) {
                data.add(value);
                data.add(value);
            }
            String valueOne = data.get(0);
            String valueTwo = data.get(1);
            // 数字
            if (numControl.contains(yunzhupaasKey)) {
                fieldValue = valueOne != null ? new BigDecimal(valueOne) : valueOne;
                fieldValueTwo = valueTwo != null ? new BigDecimal(valueTwo) : valueTwo;
                num++;
            }
            // 日期
            if (dateControl.contains(yunzhupaasKey)) {
                fieldValue = new Date();
                fieldValueTwo = new Date();
                if (ObjectUtil.isNotEmpty(valueOne)) {
                    fieldValue = new Date(Long.valueOf(valueOne));
                }
                if (ObjectUtil.isNotEmpty(valueTwo)) {
                    fieldValueTwo = new Date(Long.valueOf(valueTwo));
                }
                num++;
            }
            if (num == 0) {
                fieldValue = valueOne;
                fieldValueTwo = valueTwo;
            }
        }
        List<String> idList = new ArrayList<>();
        try {
            List<List<String>> list = JsonUtil.getJsonToBean(value, List.class);
            Set<String> dataAll = new HashSet<>();
            for (int i = 0; i < list.size(); i++) {
                List<String> list1 = new ArrayList<>();
                for (int k = 0; k < list.get(i).size(); k++) {
                    list1.add(list.get(i).get(k));
                    idList.add(list.get(i).get(list.get(i).size() - 1));
                }
                dataAll.add(JSONArray.toJSONString(list1));
            }
            dataList = new ArrayList<>(dataAll);
        } catch (Exception e) {
            try {
                Set<String> dataAll = new HashSet<>();
                List<String> list = JsonUtil.getJsonToList(value, String.class);
                List<String> mast = new ArrayList() {
                    {
                        add(YunzhupaasKeyConsts.CASCADER);
                        add(YunzhupaasKeyConsts.ADDRESS);
                        add(YunzhupaasKeyConsts.COMSELECT);
                        add(YunzhupaasKeyConsts.CURRORGANIZE);
                    }
                };
                if (mast.contains(yunzhupaasKey)) {
                    dataAll.add(JSONArray.toJSONString(list));
                } else {
                    for (int k = 0; k < list.size(); k++) {
                        String data = list.get(k);
                        dataAll.add(data);
                    }
                }
                if (list.size() > 0) {
                    idList.add(list.get(list.size() - 1));
                }
                dataList.addAll(new ArrayList<>(dataAll));
            } catch (Exception e1) {
                idList.add(value);
                dataList.add(value);
            }
        }
        boolean isIncludeSubordinate = fieLdsModel.getIsIncludeSubordinate();
        if (isIncludeSubordinate) {
            switch (yunzhupaasKey) {
                case YunzhupaasKeyConsts.COMSELECT:
                    for (String org : idList) {
                        // 获取子组织
                        List<String> underOrganizations = organizeApi.getUnderOrganizations(org, false);
                        // 获取组织全路径
                        for (String itemOrg : underOrganizations) {
                            OrganizeEntity organizeEntity = organizeApi.getInfo(itemOrg);
                            if (organizeEntity != null) {
                                if (StringUtil.isNotEmpty(organizeEntity.getOrganizeIdTree())) {
                                    String[] split = organizeEntity.getOrganizeIdTree().split(",");
                                    if (split.length > 0) {
                                        dataList.add(JSONArray.toJSONString(Arrays.asList(split)));
                                    }
                                }
                            }
                        }
                    }
                    break;
                case YunzhupaasKeyConsts.USERSELECT:
                    for (String userId : idList) {
                        // 获取下属用户
                        List<UserEntity> underOrganizations = userApi.getListByManagerId(userId, null);
                        List<String> collect = underOrganizations.stream().map(UserEntity::getId)
                                .collect(Collectors.toList());
                        dataList.addAll(collect);
                    }
                    break;
                case YunzhupaasKeyConsts.DEPSELECT:
                    for (String org : idList) {
                        // 获取子部门
                        List<String> underOrganizations = organizeApi.getUnderOrganizations(org, false);
                        dataList.addAll(underOrganizations);
                    }
                    break;
            }
        }
        if (dataList.size() == 0) {
            dataList.add("yunzhupaasNullList");
        }
        fieLdsModel.setVModel(key);
        fieLdsModel.setFieldValueOne(fieldValue);
        fieLdsModel.setFieldValueTwo(fieldValueTwo);
        fieLdsModel.setDataList(dataList);
    }

    private void convertUserSelectData(FieLdsModel fieLdsModel) {
        List<String> symbolList = ImmutableList.of(SearchMethodEnum.Equal.getSymbol(),
                SearchMethodEnum.NotEqual.getSymbol());
        String yunzhupaasKey = fieLdsModel.getConfig().getYunzhupaasKey();
        String fieldValue = fieLdsModel.getFieldValue();
        String symbol = fieLdsModel.getSymbol();
        if (StringUtil.isNotEmpty(fieldValue) && YunzhupaasKeyConsts.CUSTOMUSERSELECT.equals(yunzhupaasKey)) {
            if (!symbolList.contains(symbol)) {
                List<String> dataValues = new ArrayList<>();
                List<String> values = new ArrayList<>();
                try {
                    values = JsonUtil.getJsonToList(fieldValue, String.class);
                } catch (Exception e) {
                }
                dataValues.addAll(values);
                for (String userVal : values) {
                    String userValue = userVal.substring(0, userVal.indexOf("--"));
                    UserEntity userEntity = userApi.getInfo(userValue);
                    if (userEntity != null) {
                        dataValues.add(userValue);
                        // 在用户关系表中取出
                        List<UserRelationEntity> groupRel = Optional
                                .ofNullable(userRelationApi.getListByUserId(userValue, PermissionConst.GROUP))
                                .orElse(new ArrayList<>());
                        List<UserRelationEntity> orgRel = Optional
                                .ofNullable(userRelationApi.getListByUserId(userValue, PermissionConst.ORGANIZE))
                                .orElse(new ArrayList<>());
                        List<UserRelationEntity> posRel = Optional
                                .ofNullable(userRelationApi.getListByUserId(userValue, PermissionConst.POSITION))
                                .orElse(new ArrayList<>());
                        List<UserRelationEntity> roleRel = Optional
                                .ofNullable(userRelationApi.getListByUserId(userValue, PermissionConst.ROLE))
                                .orElse(new ArrayList<>());
                        if (groupRel.size() > 0) {
                            for (UserRelationEntity split : groupRel) {
                                dataValues.add(split.getObjectId());
                            }
                        }
                        if (StringUtil.isNotEmpty(userEntity.getOrganizeId())) {
                            // 向上递归 查出所有上级组织
                            List<String> allUpOrgIDs = new ArrayList<>();
                            organizeApi.upWardRecursion(allUpOrgIDs, userEntity.getOrganizeId());
                            for (String orgID : allUpOrgIDs) {
                                dataValues.add(orgID);
                            }
                        }
                        if (posRel.size() > 0) {
                            for (UserRelationEntity split : posRel) {
                                dataValues.add(split.getObjectId());
                            }
                        }
                        if (roleRel.size() > 0) {
                            for (UserRelationEntity split : roleRel) {
                                dataValues.add(split.getObjectId());
                            }
                        }
                    }
                }
                fieLdsModel.setFieldValue(JsonUtil.getObjectToString(dataValues));
            }
        }
    }

    private Integer value(FieLdsModel fieLdsModel, DataSetEntity queryEntity, String key, int num,
            Map<String, Object> map) {
        try {
            DbLinkEntity linkEntity = dbLinkService.getResource(queryEntity.getDbLinkId());
            @Cleanup
            Connection connection = ConnUtil.getConnOrDefault(linkEntity);
            String dbType = connection.getMetaData().getDatabaseProductName().trim();
            boolean isSqlServer = "Microsoft SQL Server".equalsIgnoreCase(dbType);
            SearchMethodEnum symbol = SearchMethodEnum.getSearchMethod(fieLdsModel.getSymbol());
            String querySql = queryEntity.getDataConfigJson();
            String sql = "{" + key + num + "} ";
            Object fieldValue = fieLdsModel.getFieldValueOne();
            Object fieldValueTwo = fieLdsModel.getFieldValueTwo();
            switch (symbol) {
                case IsNull:
                    querySql += "AND " + key + " IS NULL ";
                    break;
                case IsNotNull:
                    querySql += "AND " + key + " IS NOT NULL ";
                    break;
                case Equal:
                    querySql += "AND " + key + " = " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    break;
                case NotEqual:
                    querySql += "AND " + key + " <> " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    break;
                case GreaterThan:
                    querySql += "AND " + key + " > " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    break;
                case LessThan:
                    querySql += "AND " + key + " < " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    break;
                case GreaterThanOrEqual:
                    querySql += "AND " + key + " >= " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    break;
                case LessThanOrEqual:
                    querySql += "AND " + key + " <= " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    break;
                case Like:
                    querySql += "AND " + key + " LIKE " + sql;
                    if (isSqlServer) {
                        fieldValue = String.valueOf(fieldValue).replaceAll("\\[", "[[]");
                    }
                    map.put(key + num, "%" + fieldValue + "%");
                    num++;
                    break;
                case NotLike:
                    querySql += "AND " + key + " NOT LIKE " + sql;
                    if (isSqlServer) {
                        fieldValue = String.valueOf(fieldValue).replaceAll("\\[", "[[]");
                    }
                    map.put(key + num, "%" + fieldValue + "%");
                    num++;
                    break;
                case Between:
                    querySql += "AND " + key + " BETWEEN " + sql;
                    map.put(key + num, fieldValue);
                    num++;
                    String two = "{" + key + num + "} ";
                    querySql += " AND " + two;
                    map.put(key + num, fieldValueTwo);
                    num++;
                    break;
                case Included:
                case NotIncluded:
                    List<String> dataList = fieLdsModel.getDataList();
                    querySql += "AND  ( ";
                    for (int i = 0; i < dataList.size(); i++) {
                        String value = dataList.get(i);
                        if (isSqlServer) {
                            value = String.valueOf(value).replaceAll("\\[", "[[]");
                        }
                        boolean isLast = i == dataList.size() - 1;
                        switch (symbol) {
                            case Included:
                                querySql += key + " LIKE {" + key + num + "} ";
                                querySql += isLast ? "" : " OR ";
                                map.put(key + num, "%" + value + "%");
                                break;
                            default:
                                querySql += key + " NOT LIKE {" + key + num + "} ";
                                querySql += isLast ? "" : " AND ";
                                map.put(key + num, "%" + value + "%");
                                break;
                        }
                        num++;
                    }
                    querySql += " ) ";
                    break;
            }
            queryEntity.setDataConfigJson(querySql);
        } catch (Exception e) {
            e.getMessage();
        }
        return num;
    }

    /**
     * 获取配置式字段
     *
     * @param item
     * @return
     */
    private TableTreeModel getConfigureSQL(DataSetEntity item) {
        TableTreeModel printTable = new TableTreeModel();
        String parentId = item.getId();
        String headTable = item.getFullName();

        String dbType = null;
        try {
            DbLinkEntity linkEntity = dbLinkService.getResource(item.getDbLinkId());
            @Cleanup
            Connection connection = ConnUtil.getConnOrDefault(linkEntity);
            dbType = DbTypeUtil.getDbEncodeByProductName(connection.getMetaData().getDatabaseProductName().trim());
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<DsConfigModel> dsConfigModels = DataSetConfigUtil.analyzeJson(item.getVisualConfigJson(), dbType);

        List<DsConfigFields> listDF = new ArrayList<>();
        DataSetConfigUtil.getAllFields(dsConfigModels, listDF);

        List<SumTree<TableTreeModel>> list = new ArrayList<>();
        for (DsConfigFields configFields : listDF) {
            TableTreeModel fieldModel = new TableTreeModel();
            String fieldAlias = configFields.getFieldAlias();
            String filed;
            String fieldName;
            if (StringUtil.isNotEmpty(fieldAlias)) {
                filed = fieldAlias;
                fieldName = configFields.getFieldName().replace(configFields.getField(), fieldAlias);
            } else {
                filed = configFields.getField();
                fieldName = configFields.getFieldName();
            }
            fieldModel.setId(filed);
            fieldModel.setFullName(fieldName);
            fieldModel.setLabel(fieldName);
            list.add(fieldModel);
        }
        printTable.setId(parentId);
        printTable.setChildren(list);
        printTable.setFullName(headTable);
        printTable.setParentId("struct");
        return printTable;
    }

    @Override
    public DataSetViewInfo getPreviewData(DataSetForm dataSetForm) {
        DataSetViewInfo dataSetViewInfo = new DataSetViewInfo();
        Map<String, Object> systemParam = this.getSystemParam(
                dataSetForm.getVisualConfigJson() + dataSetForm.getFilterConfigJson(), dataSetForm.getFormId());
        try {
            DbLinkEntity linkEntity = dbLinkService.getResource(dataSetForm.getDbLinkId());
            DynamicDataSourceUtil.switchToDataSource(linkEntity);

            @Cleanup
            Connection connection = ConnUtil.getConnOrDefault(linkEntity);
            String dbType = DbTypeUtil
                    .getDbEncodeByProductName(connection.getMetaData().getDatabaseProductName().trim());
            List<Object> values = new ArrayList<>();
            List<DsConfigModel> dsConfigModels = DataSetConfigUtil.analyzeJson(dataSetForm.getVisualConfigJson(),
                    dbType);

            // 字段配置
            List<DsConfigFields> listDF = new ArrayList<>();
            DataSetConfigUtil.getAllFields(dsConfigModels, listDF);
            List<Map<String, String>> previewColumns = new ArrayList<>();
            for (DsConfigFields configFields : listDF) {
                Map<String, String> map = new HashMap<>();
                String fieldAlias = configFields.getFieldAlias();
                String filed;
                String fieldName;
                if (StringUtil.isNotEmpty(fieldAlias)) {
                    filed = fieldAlias;
                    fieldName = configFields.getFieldName().replace(configFields.getField(), fieldAlias);
                } else {
                    filed = configFields.getField();
                    fieldName = configFields.getFieldName();
                }
                map.put("title", filed);
                map.put("label", fieldName);
                previewColumns.add(map);
            }

            String sql = DataSetConfigUtil.assembleSql(dsConfigModels,
                    DsParamModel.builder().dbType(dbType).values(values).systemParam(systemParam)
                            .filterConfigJson(dataSetForm.getFilterConfigJson()).build());

            if (DbBase.MYSQL.equals(dbType) && sql.contains(DsJoinTypeEnum.FULL_JOIN.getCode())) {
                throw new DataException(MsgCode.SYS129.get());
            }

            Object[] valueArr = new Object[values.size()];
            for (int i = 0; i < values.size(); i++) {
                if (values.get(i) instanceof String) {
                    valueArr[i] = "'" + values.get(i) + "'";
                } else {
                    valueArr[i] = values.get(i);
                }
            }
            String replace = sql.replace("?", "%s");
            String sqlValue = String.format(replace, valueArr);
            String formatSql = SqlFormatter.format(sqlValue);

            if (!dataSetForm.isNoPage()) {
                PageHelper.startPage(1, 20, false);
            }
            String objectToString = JsonUtil.getObjectToStringAsDate(
                    JdbcUtil.queryList(new PrepSqlDTO(sql, values).withConn(linkEntity, null)).setIsAlias(true).get());
            List<Map<String, Object>> data = JsonUtil.getJsonToListMap(objectToString);

            dataSetViewInfo.setPreviewSqlText(formatSql);
            dataSetViewInfo.setPreviewData(data);
            dataSetViewInfo.setPreviewColumns(previewColumns);
        } catch (DataException dataE) {
            throw new DataException(dataE.getMessage());
        } catch (SQLSyntaxErrorException | PersistenceException sqlE) {
            throw new DataException(MsgCode.PRI007.get());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DynamicDataSourceUtil.clearSwitchDataSource();
        }
        return dataSetViewInfo;
    }

    /**
     * 获取系统参数
     *
     * @return
     */
    public Map<String, Object> getSystemParam(String str, String formId) {
        Map<String, Object> map = new HashMap<>();
        UserInfo userInfo = UserProvider.getUser();

        map.put(DataInterfaceVarConst.FORM_ID, ObjectUtil.isNotEmpty(formId) ? formId : DataInterfaceVarConst.FORM_ID);

        // 当前用户
        String userId = userInfo.getUserId();
        map.put(DataInterfaceVarConst.USER, userId);

        // 当前用户及下属
        List<String> subOrganizeIds = new ArrayList<>();
        if (userInfo.getSubordinateIds().size() > 0) {
            subOrganizeIds = userInfo.getSubordinateIds();
        }
        subOrganizeIds.add(userInfo.getUserId());
        map.put(DataInterfaceVarConst.USERANDSUB, subOrganizeIds);

        // 当前组织
        String orgId = userInfo.getOrganizeId();
        if (StringUtil.isNotEmpty(userInfo.getDepartmentId())) {
            orgId = userInfo.getDepartmentId();
        }
        map.put(DataInterfaceVarConst.ORG, orgId);

        // 当前组织及子组织
        if (str.contains(DataInterfaceVarConst.ORGANDSUB)) {
            List<String> underOrganizations = organizeApi.getUnderOrganizations(orgId, false);
            underOrganizations.add(orgId);
            map.put(DataInterfaceVarConst.ORGANDSUB, underOrganizations);
        }

        // 当前分管组织
        if (str.contains(DataInterfaceVarConst.CHARORG)) {
            List<String> orgIds = organizeAdminTratorApi.getOrganizeUserList(YunzhupaasConst.CURRENT_ORG_SUB);
            map.put(DataInterfaceVarConst.CHARORG, orgIds);
        }
        return map;
    }

    /**
     * 数据接口获取字段列表
     *
     * @param item
     * @return
     */
    private TableTreeModel getInterfaceFields(DataSetEntity item) {
        TableTreeModel printTable = new TableTreeModel();
        String parentId = item.getId();
        String headTable = item.getFullName();

        DataInterfaceEntity info = dataInterfaceService.getInfo(item.getInterfaceId());
        if (info == null) {
            throw new DataException(MsgCode.FM001.get());
        }
        String fieldJson = info.getFieldJson();

        if (StringUtil.isEmpty(fieldJson) || "[]".equals(fieldJson)) {
            throw new DataException(MsgCode.SYS133.get());
        }

        List<FieldModel> fieldList = JsonUtil.getJsonToList(fieldJson, FieldModel.class);
        List<SumTree<TableTreeModel>> list = new ArrayList<>();
        for (FieldModel configFields : fieldList) {
            TableTreeModel fieldModel = new TableTreeModel();
            fieldModel.setId(configFields.getDefaultValue());
            fieldModel.setFullName(configFields.getDefaultValue() + "(" + configFields.getField() + ")");
            fieldModel.setLabel(configFields.getField());
            list.add(fieldModel);
        }
        printTable.setId(parentId);
        printTable.setChildren(list);
        printTable.setFullName(headTable);
        printTable.setParentId("struct");
        return printTable;
    }

    @Override
    public DataSetViewInfo getPreviewDataInterface(DataSetForm dataSetForm) {
        DataSetViewInfo dataSetViewInfo = new DataSetViewInfo();
        DataInterfaceEntity info = dataInterfaceService.getInfo(dataSetForm.getInterfaceId());
        if (info == null) {
            throw new DataException(MsgCode.FM001.get());
        }
        String fieldJson = info.getFieldJson();

        if (StringUtil.isEmpty(fieldJson) || "[]".equals(fieldJson)) {
            throw new DataException(MsgCode.SYS133.get());
        }
        List<FieldModel> fieldList = JsonUtil.getJsonToList(fieldJson, FieldModel.class);
        List<Map<String, String>> previewColumns = new ArrayList<>();
        for (FieldModel configFields : fieldList) {
            Map<String, String> map = new HashMap<>();
            map.put("title", configFields.getDefaultValue());
            map.put("label", configFields.getField());
            previewColumns.add(map);
        }
        List<Map<String, Object>> data = new ArrayList<>();
        try {
            HashMap<String, String> paramMap = new HashMap<>(16);
            if (StringUtil.isNotEmpty(dataSetForm.getParameterJson())) {
                List<DataInterfaceModel> jsonToList = JsonUtil.getJsonToList(dataSetForm.getParameterJson(),
                        DataInterfaceModel.class);
                jsonToList.stream().forEach(t -> {
                    if (Objects.equals(t.getSourceType(), 4)
                            && DataInterfaceVarConst.FORM_ID.equals(t.getRelationField())) {
                        t.setDefaultValue(dataSetForm.getFormId());
                    }
                });
                dataInterfaceService.paramSourceTypeReplaceValue(jsonToList, paramMap);
            }
            ActionResult actionResult = dataInterfaceService.infoToId(dataSetForm.getInterfaceId(), null, paramMap);
            if (ActionResultCode.Success.getCode().equals(actionResult.getCode())) {
                data = (List<Map<String, Object>>) actionResult.getData();
            }
            if (!dataSetForm.isNoPage()) {
                if (data.size() > 20) {
                    data = new ArrayList<>(data.subList(0, 20));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new DataException(MsgCode.FA037.get());
        }
        dataSetViewInfo.setPreviewData(data);
        dataSetViewInfo.setPreviewColumns(previewColumns);
        return dataSetViewInfo;
    }

    public static boolean mapCompar(List<FieLdsModel> searchList, Map<String, Object> hashMap2) {
        boolean isChange = false;
        for (FieLdsModel item : searchList) {
            String realValue = hashMap2.get(item.getVModel()) == null ? "" : (String) hashMap2.get(item.getVModel());
            switch (item.getSearchType()) {
                case 2:
                    if (realValue.indexOf(item.getFieldValue()) >= 0) {
                        isChange = true;
                    }
                    break;
                case 3:// between
                    List<String> longList = new ArrayList() {
                        {
                            add(YunzhupaasKeyConsts.NUM_INPUT);
                            add(YunzhupaasKeyConsts.DATE);
                        }
                    };
                    if (longList.contains(item.getConfig().getYunzhupaasKey())) {
                        Long valueLong = Long.parseLong(realValue);
                        Long valueLongOne = (Long) item.getFieldValueOne();
                        Long valueLongTwo = (Long) item.getFieldValueTwo();
                        if (valueLong >= valueLongOne && valueLong <= valueLongTwo) {
                            isChange = true;
                        }
                    } else {
                        String valueLongOne = (String) item.getFieldValueOne();
                        String valueLongTwo = (String) item.getFieldValueTwo();
                        if (realValue.compareTo(valueLongOne) >= 0 && realValue.compareTo(valueLongTwo) <= 0) {
                            isChange = true;
                        }
                    }
                    break;
                case 4:// 包含
                    List<String> dataList = item.getDataList();
                    for (String value : dataList) {
                        isChange = value.indexOf(realValue) >= 0;
                    }
                    if (isChange) {
                        return true;
                    }
                    break;
                default:// 1,其他条件都按等于查询
                    isChange = item.getFieldValue().equals(realValue);
                    break;
            }
        }
        return isChange;
    }

}
