package com.tykj.model.service.impl;


import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.base.consumer.FourComsumer;
import com.tykj.base.result.ApiException;
import com.tykj.base.result.ResultUtil;
import com.tykj.model.create_util.BaseCreateUtil;
import com.tykj.model.dao.ColumnInfoDao;
import com.tykj.model.dao.QuoteDao;
import com.tykj.model.dao.RuleDao;
import com.tykj.model.dao.TableInfoDao;
import com.tykj.model.entity.ColumnInfo;
import com.tykj.model.entity.Quote;
import com.tykj.model.entity.TableInfo;
import com.tykj.model.entity.customEnums.ConnectionType;
import com.tykj.model.entity.vo.*;


import com.tykj.model.service.ModelService;
import com.tykj.model.utils.SessionUtil;
import com.tykj.model.utils.SqlTypeUtil;
import com.tykj.model.utils.SqlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.hibernate.Session;
import org.hibernate.StaleStateException;
import org.hibernate.internal.SessionImpl;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.Query;
import org.hibernate.type.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;


import static com.tykj.model.utils.CheckUtils.validationQuote;
import static com.tykj.model.utils.CheckUtils.validationRule;
import static com.tykj.model.utils.HqlUtil.createQuery;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;


/**
 * @ClassName ModelImpl
 * @Description TODO
 * @Author WWW
 * @Date 2021/2/26 13:39
 * @Version 1.0
 */

@Service
@Slf4j
public class ModelImpl implements ModelService {

    @Autowired
    BaseCreateUtil baseCreateUtil;
    @Autowired
    private TableInfoDao tableInfoDao;

    @Autowired
    private ColumnInfoDao columnInfoDao;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SessionUtil sessionUtil;

    @Autowired
    private Environment env;

    @Autowired
    private QuoteDao quoteDao;

    @Autowired
    private RuleDao ruleDao;

    /**
     * @param
     * @return java.util.List<com.tykj.workflowcore.model_layer.model.TableInfo>
     * @Author WWW
     * @Description 得到所有表
     * @Date 16:14 2021/3/5
     **/
    @Override
    public Page<TableInfo> pageAllEntities(SearchTableInfoVo searchTableInfoVo) {
        PredicateBuilder<TableInfo> and = createPredicateBySearchTableInfoVo(searchTableInfoVo);
        return tableInfoDao.findAll(and.build(), searchTableInfoVo.getPageable());

    }

    @Override
    public List<TableInfo> listAllEntities(SearchTableInfoVo stv) {
        PredicateBuilder<TableInfo> and = createPredicateBySearchTableInfoVo(stv);
        return tableInfoDao.findAll(and.build());
    }

    private PredicateBuilder<TableInfo> createPredicateBySearchTableInfoVo(SearchTableInfoVo stv) {
        PredicateBuilder<TableInfo> and = Specifications.and();
        if (!isNull(stv)) {
            and.like(!isNull(stv.getModelName()) && isNotEmpty(stv.getModelName()), "modelName", "%" + stv.getModelName() + "%");
            and.like(!isNull(stv.getModelTitle()) && isNotEmpty(stv.getModelTitle()), "modelTitle", "%" + stv.getModelTitle() + "%");
            and.in(!isNull(stv.getModelType()) && stv.getModelType().length > 0, "modelType", stv.getModelType());
            and.in(!isNull(stv.getIds()) && stv.getIds().length > 0, "id", stv.getIds());
        }
        return and;
    }

    /**
     * @param scv
     * @return java.util.List<com.tykj.workflowcore.model_layer.model.ColumnInfo>
     * @Author WWW
     * @Description 根据表名得到所有字段名
     * @Date 16:15 2021/3/5
     **/
    @Override
    public List<ColumnInfo> showModelFields(SearchColumnInfoVo scv) {
        PredicateBuilder<ColumnInfo> and = Specifications.and();
        and.eq(!isNull(scv.getDbId()), "dbId", scv.getDbId());
        and.eq(!isNull(scv.getDbName()) && isNotEmpty(scv.getDbName()), "dbName", scv.getDbName());
        return columnInfoDao.findAll(and.build());
    }


    /**
     * @param tableVO
     * @return com.tykj.workflowcore.model_layer.model.TableVO
     * @Author WWW
     * @Description 完全新建一张表
     * @Date 16:16 2021/3/5
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TableInfo newTable(TableVO tableVO) {

//        String xmlMapping = createTable(tableVO);
        String xmlMapping = baseCreateUtil.createTable(tableVO);
        // 表名判重
        modelNameIsExist(tableVO.getModelName().toUpperCase());
        //向数据库中生成这张表

        List<ColumnVO> dataList = tableVO.getDataList();
        //构建TableInfo
        TableInfo tableInfo = new TableInfo();
        tableInfo.setModelName(tableVO.getModelName().toUpperCase());
        tableInfo.setModelTitle(tableVO.getModelTitle());
        tableInfo.setXml(xmlMapping);

        tableInfo.setDescription(tableVO.getDescription());
        tableInfoDao.save(tableInfo);

//        System.out.println(1/0);
        //构建字段
        //默认存储ID字段
        ColumnInfo cId = new ColumnInfo(0, "ID", "主键", "java.lang.Integer", 11, tableInfo.getModelName().toUpperCase(), tableInfo.getId(), "主键");
        columnInfoDao.save(cId);
        for (ColumnVO columnVO : dataList) {
            ColumnInfo columnInfo = new ColumnInfo(
                    columnVO.getPrimaryKey()
                    , columnVO.getFieldName().toUpperCase()
                    , columnVO.getFieldTitle()
                    , columnVO.getFieldType()
                    , columnVO.getFieldLength()
                    , tableInfo.getModelName().toUpperCase()
                    , tableInfo.getId()
                    , columnVO.getDescription()
            );
            ColumnInfo save = columnInfoDao.save(columnInfo);
            sessionUtil.addXml(xmlMapping);
/***/
//            List<Quote> quoteList = columnVO.getQuoteList();
//            if (quoteList != null) {
//                for (Quote quote : quoteList) {
//                    if (isNotEmpty(quote.getValue())) {
//                        quote.setColumnId(save.getId());
//                        quoteDao.save(quote);
//                    }
//                }
//            }
        }
        //关闭会话
        return tableInfo;
    }

    /**
     * @param map
     * @return int
     * @Author WWW
     * @Description 根据表名新增数据
     * @Date 16:17 2021/3/5
     **/
    @Override
    public int operationValueByEntityName(Map<String, Object> map, SessionImpl session, BiConsumer<String, Object> saveOrDelete, FourComsumer<TableInfo, Object, Type, String> valitor) {
        session.getTransaction().begin();
        for (String tableName :
                map.keySet()) {
            Object values = map.get(tableName);
            if (values instanceof Map) {
                //插入数据
                operationValue(tableName, (Map) values, session, saveOrDelete, valitor);
            }
        }
        try {
            session.getTransaction().commit();
        } catch (Exception e) {
            //todo 等会捕捉一下
            if (e.getMessage().contains("Batch update returned unexpected row count from")) {
                throw new ApiException("要操作对象的主键不存在");
            }
        } finally {
            session.close();
        }
        return 0;
    }

    @Override
    public int operationValueByEntityNameList(List<Map<String, Object>> mapList, SessionImpl session, BiConsumer<String, Object> biConsumer, FourComsumer<TableInfo, Object, Type, String> valitor) {
        session.getTransaction().begin();
        for (Map<String, Object> map : mapList) {
            for (String tableName :
                    map.keySet()) {
                Object values = map.get(tableName);
                if (values instanceof Map) {
                    //插入数据
                    operationValue(tableName, (Map) values, session, biConsumer, valitor);
                }
            }
        }
        try {
            session.getTransaction().commit();
        } catch (StaleStateException staleStateException) {
            if (staleStateException.getMessage().contains("Batch update returned unexpected row count from")) {
                throw new ApiException("要操作对象的主键不存在");
            }
        } finally {
            session.close();
        }
        return 0;
    }


    /**
     * @param tableName
     * @param map
     * @return void
     * @Author WWW
     * @Description 新增参数的方法
     * @Date 16:17 2021/3/5
     **/
    public void operationValue(String tableName,
                               Map map,
                               SessionImpl session,
                               BiConsumer<String, Object> saveOrDelete,
                               FourComsumer<TableInfo, Object, Type, String> valitor) {

        TableInfo tableInfo = tableInfoDao.findByModelName(tableName);
        EntityPersister entityPersister = session.getEntityPersister(tableName, map);
        //主键类型推断
        String identifierPropertyName = entityPersister.getIdentifierPropertyName();
        if (map.containsKey(identifierPropertyName)) {
            changeValueToTargetType(map, map.get(identifierPropertyName), entityPersister.getIdentifierType(), identifierPropertyName);
        }
        //类型推断 根据目标值的类型强转目标值的目标类型
        Type[] propertyTypes = entityPersister.getPropertyTypes();
        //这个是列名 数组
        String[] propertyNames = entityPersister.getEntityPersister().getPropertyNames();
        //这个是插入的值 数组
        Object[] propertyValuesToInsert = entityPersister.getPropertyValuesToInsert(map, null, session);
        for (int i = 0; i < propertyValuesToInsert.length; i++) {
            Object value = propertyValuesToInsert[i];
            Type propertyType = propertyTypes[i];
            //根据目标Type转换
            changeValueToTargetType(map, value, propertyType, propertyNames[i]);
            //验证
            if (valitor != null) {
                valitor.accept(tableInfo, value, propertyType, propertyNames[i]);
            }
        }
        saveOrDelete.accept(tableName, map);
    }


    /**
     * @param name
     * @return java.util.List
     * @Author WWW
     * @Description 通过表名查询所有信息
     * @Date 10:51 2021/3/11
     **/
    @Override
    public List<Map<String, Object>> findAllByName(String name) {
        if (name != null && name != "") {
            String sql = "select * from " + name;
            try {
                return jdbcTemplate.queryForList(sql);
            } catch (Exception e) {
                throw new ApiException("查询SQL语句错误！");
            }
        }
        return new ArrayList<>();
    }

    @Override
    public List<Map<String, Object>> complexQuery(String tableName, List<String> columnNames, List<QueryCondition> queryConditions, String groupName) {
        if (Strings.isNotEmpty(tableName)) {
            String query = createQuery(tableName, columnNames, queryConditions, groupName);
            Session session = sessionUtil.getSession();
            Query query1 = session.createQuery(query);
            List<Map<String, Object>> list = query1.list();
            session.close();
            return list;
        }
        return new ArrayList<>();
    }

    @Override
    public List<Map<String, Object>> findAllByName(String name, List<OrderCondition> orderConditions) {
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotEmpty(name)) {
            if (orderConditions.size() > 0) {
                for (OrderCondition orderCondition : orderConditions) {
                    sb.append(orderCondition.getColumns() + " " + orderCondition.getSortValue() + " ,");
                }
            }
            String sql = sb.substring(0, sb.toString().lastIndexOf(","));
            try {
                return jdbcTemplate.queryForList("select * from  " + name + " order by " + sql);
            } catch (Exception e) {
                throw new ApiException("操作数据库失败，请联系管理员");
            }
        }
        return new ArrayList<>();
    }

    @Override
    public CustomPage complexQueryWithGroup(String tableName, GroupCondition groupCondition, List<String> columnNames, List<QueryCondition> queryConditions, String groupByColumn, Integer page, Integer size) {
        if (Strings.isNotEmpty(tableName)) {
            List<QueryCondition> queryConditionList = new ArrayList<>();
            if (queryConditions != null) {
                queryConditionList.addAll(queryConditions);
            }
            if (groupCondition != null) {
                if (StringUtils.isNotEmpty(groupCondition.getValue())) {
                    queryConditionList.add(new QueryCondition(
                            groupByColumn,
                            "like",
                            groupCondition.getValue(),
                            ConnectionType.AND
                    ));
                }
            }
            String query = createQuery(tableName, columnNames, queryConditionList, Strings.EMPTY);
            Session session = sessionUtil.getSession();
            Query query1 = session.createQuery(query);
            List list1 = query1.list();
            page = page - 1;
            query1.setFirstResult(page * size);
            query1.setMaxResults(size);
            List list2 = query1.list();
            session.close();
            return new CustomPage(list1.size(), list2);
        }
//        }
        return null;
    }

    private QueryCondition queryCondition(String groupByColumn, GroupCondition groupCondition) {
        return new QueryCondition(
                groupByColumn,
                "like",
                groupCondition.getValue(),
                ConnectionType.AND
        );
    }

    /**
     * 更新表结构
     * @param updateTableInfoVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateTable(UpdateTableInfoVO updateTableInfoVO) {
        //tableInfo和columnInfo变化
        //查询到TableInfo和ColumnInfo
        TableVO tableVO = updateTableInfoVO.getTableVO();

        Integer dbId = updateTableInfoVO.getDbId();
        TableInfo tableInfo = tableInfoDao.findById(dbId).orElseThrow(() -> new RuntimeException("未找到该id的表信息"));

        // todo 记录一个 oldTableInfo 用于回滚

        tableInfo.setUpdatedTime(new Date());
        tableInfo.setDescription(tableVO.getDescription());
        tableInfo.setModelTitle(tableVO.getModelTitle());


        List<ColumnInfo> originalColumnInfos = columnInfoDao.findAllByDbId(dbId);
        //新的字段信息
        List<ColumnInfo> currentColumnInfos = tableVO.getDataList().stream()
                .map(columnVO -> columnInfo(tableInfo.getId(), tableInfo.getModelName(), columnVO))
                .collect(Collectors.toList());

        //根据ColumnInfo集合得出表实际改动的sql语句集合
        List<String> sqls = getTableSqls(tableInfo.getModelName(), originalColumnInfos, currentColumnInfos);
        //执行sql语句
        for (String sql : sqls) {
            try {
                jdbcTemplate.execute(sql);
            } catch (Exception exception) {
                //todo
                exception.printStackTrace();
                throw new ApiException("出错");
//                if (exception instanceof OSQLException) {
//                    String error = exception.getMessage();
//                    error.substring(error.lastIndexOf(":"));
//                    return ResultUtil.failed("已有数据类型不能转换"+error);
//                }
//                if (exception instanceof SQLSyntaxErrorException) {
//                    return ResultUtil.failed("sql语法错误"+ exception.getMessage());
//                }
            }

        }

        //重新保存字段信息
        List<ColumnInfo> columnsForAdd = getColumnsForAdd(originalColumnInfos, currentColumnInfos);
        for (ColumnInfo columnInfo : columnsForAdd) {
            columnInfoDao.save(columnInfo);
        }
        List<ColumnInfo> columnsForUpdate = getColumnsForUpdate(originalColumnInfos, currentColumnInfos);
        for (ColumnInfo columnInfo : columnsForUpdate) {
            columnInfoDao.save(columnInfo);
        }
        List<ColumnInfo> columnsFordDelete = getColumnsFordDelete(originalColumnInfos, currentColumnInfos);
        for (ColumnInfo originColumnInfo : columnsFordDelete) {
            columnInfoDao.delete(originColumnInfo);
        }
        String xml = baseCreateUtil.createTable(tableVO);
        tableInfo.setXml(xml);
//        System.out.println(1/0);
        tableInfoDao.save(tableInfo);
        sessionUtil.deleteTableInMeteData(tableInfo.getModelName());

        return xml;

    }

    /**
     * 对象类型转换
     * ColumnVo -> ColumnInfo
     */
    private ColumnInfo columnInfo(Integer dbId, String dbName, ColumnVO columnVO) {
        ColumnInfo columnInfo = new ColumnInfo();

        columnInfo.setId(columnVO.getId());
        columnInfo.setFieldName(columnVO.getFieldName());
        columnInfo.setFieldType(columnVO.getFieldType());
        columnInfo.setFieldLength(columnVO.getFieldLength());
        columnInfo.setFieldTitle(columnVO.getFieldTitle());
        columnInfo.setFieldLength(columnVO.getFieldLength());
        columnInfo.setDescription(columnVO.getDescription());
        columnInfo.setDbId(dbId);
        columnInfo.setDbName(dbName);
        columnInfo.setPrimaryKey(columnVO.getPrimaryKey());

        return columnInfo;

    }

    /**
     * 根据ColumnInfo集合得出表实际改动的sql语句集合
     * 根据ColumnInfo的id来匹配字段变化
     */
    private List<String> getTableSqls(String table, List<ColumnInfo> origin, List<ColumnInfo> current) {
        //取到当前环境名
        String driverType = env.getProperty("spring.datasource.driver-class-name");
        Map<String, String> sqlTypeMap = SqlTypeUtil.getSqlTypeMap(driverType);
        List<String> result = new ArrayList<>();
        //遍历获取新增和更新列的情况
        for (ColumnInfo columnInfo : current) {
            ColumnInfo originColumnInfo = origin.stream()
                    .filter(columnInfo1 -> Objects.equals(columnInfo.getId(), columnInfo1.getId()))
                    .findAny()
                    .orElse(null);
            if (isNull(originColumnInfo)) {
                String sql = SqlUtil.addColumn(table, columnInfo.getFieldName(), columnInfo.getFieldType(), columnInfo.getFieldLength(), sqlTypeMap);
                result.add(sql);
            } else {
                //判断 originColumnInfo 和 columnInfo 是否存在不一样的地方
                if (!columnInfo.getFieldType().equals(originColumnInfo.getFieldType())
                        || !columnInfo.getFieldLength().equals(originColumnInfo.getFieldLength())
                ) {
                    String sql = SqlUtil.updateColumnType(table, originColumnInfo.getFieldName(), columnInfo.getFieldName(), columnInfo.getFieldType(), columnInfo.getFieldLength(), driverType, sqlTypeMap);
                    result.add(sql);
                }
                if (!columnInfo.getFieldName().equals(originColumnInfo.getFieldName())) {
                    String sql = SqlUtil.updateColumnName(table, originColumnInfo.getFieldName(), columnInfo.getFieldName());
                    result.add(sql);
                }

            }
        }
        //遍历获取删除列的情况
        for (ColumnInfo originColumnInfo : origin) {
            if (!"id".equals(originColumnInfo.getFieldName())) {
                boolean noneMatch = current.stream()
                        .noneMatch(columnInfo1 -> Objects.equals(originColumnInfo.getId(), columnInfo1.getId()));
                if (noneMatch) {
                    String sql = SqlUtil.deleteColumn(table, originColumnInfo.getFieldName());
                    result.add(sql);
                }
            }

        }
        return result;
    }

    private List<ColumnInfo> getColumnsForAdd(List<ColumnInfo> origin, List<ColumnInfo> current) {
        List<ColumnInfo> result = new ArrayList<>();
        for (ColumnInfo columnInfo : current) {
            ColumnInfo originColumnInfo = origin.stream()
                    .filter(columnInfo1 -> Objects.equals(columnInfo.getId(), columnInfo1.getId()))
                    .findAny()
                    .orElse(null);
            if (isNull(originColumnInfo)) {
                result.add(columnInfo);
            }
        }
        return result;
    }

    private List<ColumnInfo> getColumnsForUpdate(List<ColumnInfo> origin, List<ColumnInfo> current) {
        List<ColumnInfo> result = new ArrayList<>();
        for (ColumnInfo columnInfo : current) {
            ColumnInfo originColumnInfo = origin.stream()
                    .filter(columnInfo1 -> Objects.equals(columnInfo.getId(), columnInfo1.getId()))
                    .findAny()
                    .orElse(null);
            if (nonNull(originColumnInfo)) {
                result.add(columnInfo);
            }
        }
        return result;
    }

    private List<ColumnInfo> getColumnsFordDelete(List<ColumnInfo> origin, List<ColumnInfo> current) {
        List<ColumnInfo> result = new ArrayList<>();
        for (ColumnInfo originColumnInfo : origin) {
            boolean noneMatch = current.stream()
                    .noneMatch(columnInfo1 -> Objects.equals(originColumnInfo.getId(), columnInfo1.getId()));
            if (noneMatch) {
                result.add(originColumnInfo);
            }
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delTable(DelTableVO delTableVO) {
        Optional<TableInfo> byId = tableInfoDao.findById(delTableVO.getId());
        if (!byId.isPresent()) {
            throw new ApiException("此id已经被删除！");
        } else {
            TableInfo tableInfo = byId.get();
            try {
                tableInfoDao.deleteById(delTableVO.getId());
                List<ColumnInfo> allByDbId = columnInfoDao.findAllByDbId(delTableVO.getId());
                columnInfoDao.deleteAll(allByDbId);
                String sql1 = "DROP  TABLE " + tableInfo.getModelName().toUpperCase();
                log.info(sql1);
                jdbcTemplate.execute(sql1);
                //删除SEQUENCE
                if ("com.oscar.Driver".equals(env.getProperty("spring.datasource.driver-class-name"))) {
                    String sql = "DROP SEQUENCE " + "SEQUENCE_" + tableInfo.getModelName().toUpperCase() + " CASCADE;";
                    log.info(sql);
                    jdbcTemplate.execute(sql);
                }
                //删除此session
                sessionUtil.deleteTableInMeteData(tableInfo.getModelName());
            } catch (Exception e) {
                throw new ApiException("删除表时出现错误！");
            }
            return 1;
        }
    }


    @Override
    public TableAndColumnInfoVO getTableInfoAndColumnInfoByBatch(Integer[] ids) {
        TableAndColumnInfoVO tableAndColumnInfoVO = new TableAndColumnInfoVO();
        PredicateBuilder<TableInfo> builder1 = Specifications.and();
        builder1.in(ids != null, "id", ids);
        List<TableInfo> allTableInfos = tableInfoDao.findAll(builder1.build());

        PredicateBuilder<ColumnInfo> builder2 = Specifications.and();
        builder2.in(ids != null, "dbId", ids);
        List<ColumnInfo> allColumnInfos = columnInfoDao.findAll(builder2.build());

        tableAndColumnInfoVO.setTableInfos(allTableInfos);
        tableAndColumnInfoVO.setColumnInfos(allColumnInfos);
        return tableAndColumnInfoVO;
    }


    @Override
    public List<Map<String, Object>> executeQuery(String sql) {
        try {
            return jdbcTemplate.queryForList(sql);
        } catch (ApiException e) {
            throw new ApiException("sql语法错误！");
        }

    }

    @Override
    public void deleteAllBytableName(String tableName) {
        String sql = "delete  from " + tableName;
        jdbcTemplate.execute(sql);
    }

    void changeValueToTargetType(Map map, Object value, Type propertyType, String propertyName) {
        // TimestampType
        if ("UPDATE_TIME".equals(propertyName)) {
            map.put(propertyName, new Date());
        }
        // TimestampType

        if (propertyType instanceof TimestampType) {
            if (value instanceof String) {
                if (StringUtils.isNotEmpty((String) value)) {
                    try {
                        Date parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) value);
                        map.put(propertyName, parse);
                    } catch (Exception e) {
                        throw new ApiException("时间格式输入错误,时间格式请参照=>\"yyyy-MM-dd HH:mm:ss");
                    }
                } else {
                    map.put(propertyName, null);
                }
            }
            if (value instanceof LocalDateTime) {
                map.put(propertyName, Date.from(((LocalDateTime) value).atZone(ZoneId.systemDefault()).toInstant()));
            }
        }
        if (propertyType instanceof IntegerType) {
            //然后调用强转方法
            try {
                int i1 = Integer.valueOf(value + "");
                map.put(propertyName, i1);
            } catch (Exception e) {
                throw new ApiException("字段：" + propertyName + "的类型是数字类型的。他的值不能为：" + value);
            }

        }
        if (propertyType instanceof StringType) {
            //然后调用强转方法
            map.put(propertyName, value + "");
            //
        }
        if (propertyType instanceof BooleanType) {

            map.put(propertyName, value);

        }

        if (propertyType instanceof DoubleType) {
            try {
                Double i1 = Double.valueOf(value + "");
                map.put(propertyName, i1);
            } catch (Exception e) {
                throw new ApiException("字段：" + propertyName + "的类型是浮点数类型的。他的值不能为：" + value);
            }
        }
    }

    @Override
    public void validationAllRuleAndQuote(TableInfo tableInfo, Object value, Type propertyType, String propertyNames) {
        if (propertyType instanceof StringType) {
            // 通过 tableInfo 的 Id  + columnName 为查询条件 查出 columnInfo
            ColumnInfo columnInfo = columnInfoDao.findByDbIdAndFieldName(tableInfo.getId(), propertyNames);
            //引用校验
            if (!isNull(quoteDao.findAllByColumnId(columnInfo.getId()))) {
                List<String> quotes = quoteDao.findAllByColumnId(columnInfo.getId()).stream().map(Quote::getValue).collect(Collectors.toList());
                if (!validationQuote(quotes, value)) {
                    throw new ApiException("引用校验不通过！");
                }
            }
            //规则校验
            if (!isNull(ruleDao.findAllByColumnId(columnInfo.getId()))) {
                String regular = ruleDao.findAllByColumnId(columnInfo.getId()).getRegular();
                if (!validationRule(regular, (String) value)) {
                    throw new ApiException("正则校验不通过！");
                }
            }
        }
    }

    private Boolean isNotEmpty(String str) {
        return StringUtils.isNotEmpty(str);
    }

    private void modelNameIsExist(String tableName) {
        List<String> collect = tableInfoDao.findAll()
                .stream()
                .map(TableInfo::getModelName)
                .collect(Collectors.toList());
        if (collect.contains(tableName)) {
            throw new ApiException("表名已经存在！");
        }
    }
}

