package com.boman.web.core.mapper;

import com.alibaba.fastjson.JSONObject;
import com.boman.common.core.utils.obj.ObjectUtils;
import com.boman.domain.dto.QueryBySqlDto;
import com.boman.web.core.utils.ColumnUtils;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.jdbc.SQL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Consumer;

import static com.boman.common.core.utils.obj.ObjectUtils.*;
import static com.boman.domain.constant.FormDataConstant.*;

/**
 * @author shiqian
 * @description 通用的mapper
 * @date 2021年03月22日 11:36
 **/
@Mapper
@Component
public interface StandardMapper {

    Logger LOGGER = LoggerFactory.getLogger(StandardMapper.class);


    /* ***************************************************** insert ******************************************************/
    /** {@link SqlProvider#insert(Map)} */
    @InsertProvider(type = SqlProvider.class, method = "insert")
    int insert(@Param("tableName") String var1, @Param("model") JSONObject var2);

    /** {@link SqlProvider#insertList(Map)} */
    @InsertProvider(type = SqlProvider.class, method = "insertList")
    int insertList(@Param("tableName") String tableName, @Param("dataList") List<JSONObject> dataList);


    /* ***************************************************** delete ******************************************************/
    /** {@link SqlProvider#deleteByIdList(java.util.Map)} */
    @DeleteProvider(type = SqlProvider.class, method = "deleteByIdList")
    int deleteByIdList(@Param("tableName") String var1, @Param("idList") List<Long> idList, @Param("pkName") String pkName);

    /**
     * 功能描述: 通用删除数据  {@link SqlProvider#delete(java.util.Map)}
     *
     * @param tableName        tableName
     * @param condition        condition
     * @param packColCondition packColCondition
     * @return int
     */
    @DeleteProvider(type = SqlProvider.class, method = "delete")
    Integer delete(@Param("tableName") String tableName, @Param("condition") JSONObject condition
            , @Param("packColCondition") JSONObject packColCondition);


    /* ***************************************************** update ******************************************************/
    /**  {@link SqlProvider#updateByIdList(Map)} */
    @UpdateProvider(type = SqlProvider.class, method = "updateByIdList")
    int updateByIdList(@Param("tableName") String tableName, @Param("pkName") String pkName
            , @Param("idList") List<Long> idList, @Param("model") JSONObject models);

    /**  {@link SqlProvider#updateByForeignKey(Map)} */
    @UpdateProvider(type = SqlProvider.class, method = "updateByForeignKey")
    int updateByForeignKey(@Param("tableName") String tableName, @Param("foreignKeyName") String foreignKeyName
            , @Param("foreignKeyList") List<Long> foreignKeyList, @Param("model") JSONObject models);

    /**
     * 功能描述: 通用修改
     *
     * @param tableName      tableName
     * @param packCommitData packCommitData
     * @param condition      condition
     * @return int
     */
    @UpdateProvider(type = SqlProvider.class, method = "update")
    int update(@Param("tableName") String tableName, @Param("packCommitData") JSONObject packCommitData
            , @Param("packColCondition") JSONObject packColCondition, @Param("condition") JSONObject condition);

    /**
     * 功能描述: 逻辑删除 {@link SqlProvider#objectLogicDelete(java.util.Map)}
     *
     * @param tableName tableName
     * @param pkName    pkName
     * @param idList    idList
     * @param model     model
     * @return int
     */
    @UpdateProvider(type = SqlProvider.class, method = "objectLogicDelete")
    int objectLogicDelete(@Param("tableName") String tableName, @Param("pkName") String pkName
            , @Param("idList") List<Long> idList, @Param("model") JSONObject model);


    /* ***************************************************** select ******************************************************/
    @Select("select max(${pkName}) from ${tableName}")
    Integer selectMaxId(@Param("tableName") String tableName, @Param("pkName") String pkName);

    /**
     * 功能描述: 根据id查所有
     * {@link SqlProvider#selectById(Map)}
     *
     * @param tableName 表名
     * @param pkName    主键名称
     * @param id        主键值
     * @param other     other is empty => select * from table where id = #{id}
     * @return com.alibaba.fastjson.JSONObject
     */
    @SelectProvider(type = SqlProvider.class, method = "selectById")
    JSONObject selectById(@Param("tableName") String tableName, @Param("pkName") String pkName, @Param("id") Long id, @Param("other") String other);

    /**
     * 功能描述: 根据id查所有
     * {@link SqlProvider#selectByIdList(Map)}
     *
     * @param tableName 表名
     * @param pkName    主键名称
     * @param idList    主键值
     * @param showData  需要展示的列
     * @return com.alibaba.fastjson.JSONObject
     */
    @SelectProvider(type = SqlProvider.class, method = "selectByIdList")
    List<JSONObject> selectByIdList(@Param("tableName") String tableName
            , @Param("pkName") String pkName
            , @Param("idList") List<Long> idList
            , @Param("showData") List<String> showData);

    /**
     * 功能描述: 自定义查询，需要查询的字段和value都在condition中
     * {@link SqlProvider#selectByCondition(Map)}
     *
     * @param tableName tableName
     * @param condition 封装好的查询条件
     * @param showData  需要查询的列
     * @param orderBy   orderBy
     * @param limit     分页
     * @param offset    分页， 可以为null
     * @return java.util.List<com.alibaba.fastjson.JSONObject>
     */
    @SelectProvider(type = SqlProvider.class, method = "selectByCondition")
    List<JSONObject> selectByCondition(@Param("tableName") String tableName
            , @Param("condition") JSONObject condition
            , @Param("packCondition") JSONObject packCondition
            , @Param("showData") List<String> showData
            , @Param("orderBy") String orderBy
            , @Param("limit") int limit
            , @Param("offset") int offset);

    /**
     * 功能描述: 自定义查询，需要查询的字段和value都在condition中
     * {@link SqlProvider#selectByLeftJoinCondition(Map)}
     *
     * @param queryBySql queryBySql
     * @param condition  封装好的查询条件
     * @param showData   需要查询的列
     * @param orderBy    orderBy
     * @param limit      分页
     * @param offset     分页， 可以为null
     * @return java.util.List<com.alibaba.fastjson.JSONObject>
     */
    @SelectProvider(type = SqlProvider.class, method = "selectByLeftJoinCondition")
    List<JSONObject> selectByLeftJoinCondition(@Param("queryBySql") QueryBySqlDto queryBySql
            , @Param("packCondition") JSONObject packCondition
            , @Param("condition") JSONObject condition
            , @Param("showData") List<String> showData
            , @Param("orderBy") String orderBy
            , @Param("limit") int limit
            , @Param("offset") int offset);


    /**
     * 功能描述: 自定义查询，需要查询的字段和value都在condition中
     * {@link SqlProvider#countByCondition(Map)}
     *
     * @param tableName tableName
     * @param condition condition
     * @return int
     */
    @SelectProvider(type = SqlProvider.class, method = "countByCondition")
    int countByCondition(@Param("tableName") String tableName, @Param("packCondition") JSONObject packCondition, @Param("condition") JSONObject condition);

    /**
     * 功能描述: 连表查询
     * {@link SqlProvider#countByLeftJoinCondition(Map)}
     *
     * @param queryBySql dto
     * @param condition  condition
     * @return int
     */
    @SelectProvider(type = SqlProvider.class, method = "countByLeftJoinCondition")
    int countByLeftJoinCondition(@Param("packCondition") JSONObject packCondition, @Param("queryBySql") QueryBySqlDto queryBySql, @Param("condition") JSONObject condition);

    /**
     * 功能描述: 根据tableName和map(属性名和属性值)进行查查
     * {@link SqlProvider#getByMap(java.util.Map)}
     *
     * @param tableName tableName
     * @param condition 属性名和属性值 条件
     * @param limitOne  true sql加上limit 1,   false 则不加
     * @return java.util.List<com.alibaba.fastjson.JSONObject>
     */
    @SelectProvider(type = SqlProvider.class, method = "getByMap")
    List<JSONObject> getByMap(@Param("tableName") String tableName, @Param("packCondition") JSONObject packCondition
            , @Param("condition") JSONObject condition
            , @Param("limitOne") boolean limitOne);

    /**
     * 功能描述: 获取最新的一条数据 create desc
     *
     * @param tableName tableName
     * @return com.alibaba.fastjson.JSONObject
     */
    @Select("select * from ${tableName} order by create_time desc limit 1")
    JSONObject getNewest(@Param("tableName") String tableName);


    /* ***************************************************** SqlProvider ******************************************************/
    @SuppressWarnings("unchecked")
    class SqlProvider {

        /* ***************************************************** insert ******************************************************/
        public String insert(Map<String, Object> para) {
            JSONObject model = (JSONObject) para.get("model");
            String tableName = (String) para.get("tableName");
            if (isNullOrEmpty(tableName)) {
                throw new IllegalArgumentException("tableName 无效");
            } else if (isNullOrEmpty(model)) {
                throw new IllegalArgumentException("model 无效");
            } else {
                SQL sql = new SQL();
                Set<String> keySet = model.keySet();
                sql.INSERT_INTO(tableName);

                for (int i = 0; i < model.size(); ++i) {
                    String key = (String) keySet.toArray()[i];
                    sql.VALUES(key, "#{model." + key + "}");
                }

                String sqlStr = sql.toString();
                LOGGER.info("新增的sql语句为: {} \r\n 新增的数据为: {}", sqlStr, model);
                return sqlStr;
            }
        }

        public String insertList(Map<String, Object> para) {
            List<JSONObject> dataList = (List<JSONObject>) para.get("dataList");
            String tableName = (String) para.get("tableName");
            if (isNullOrEmpty(tableName)) {
                throw new IllegalArgumentException("tableName 无效");
            }

            if (ObjectUtils.isEmpty(dataList)) {
                throw new IllegalArgumentException("需要插入的数据为空");
            }

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("insert into ").append(tableName).append(" ( ");
            JSONObject keySet = dataList.get(0);
            stringBuilder.append(String.join(", ", keySet.keySet()));
            stringBuilder.append(" ) ").append("values ");

            for (int i = 0; i < dataList.size(); i++) {
                JSONObject data = dataList.get(i);
                StringBuilder values = new StringBuilder();
                values.append(" ( ");
                for (Map.Entry<String, Object> entry : data.entrySet()) {
                    values.append(String.format("#{dataList[%d].", i)).append(entry.getKey()).append("}, ");
                }

                String beforeLast = StringUtils.substringBeforeLast(values.toString(), ", ");
                stringBuilder.append(beforeLast).append(" ), ");
            }

            String sqlStr = stringBuilder.toString();
            sqlStr = sqlStr.substring(0, sqlStr.lastIndexOf(","));
            LOGGER.info("批量新增的sql语句为: {} \r\n 新增的数据为: {}", sqlStr, dataList);
            return sqlStr;
        }



        /* ***************************************************** delete ******************************************************/
        public String delete(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            JSONObject condition = (JSONObject) para.get("condition");
            JSONObject packColCondition = (JSONObject) para.get("packColCondition");

            StringBuilder sql = new StringBuilder();
            sql.append("DELETE FROM ");
            sql.append(tableName);
            packCondition(packColCondition, sql);

            String sqlStr = sql.toString();
            LOGGER.info("通用删除的sql语句为: {} \r\n packColCondition: {}", sqlStr, packColCondition);
            return sqlStr;
        }

        public String deleteByIdList(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            String pkName = (String) para.get("pkName");
            List<Long> idList = (List<Long>) para.get(ID_LIST);

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("delete ").append(" from ").append(tableName).append(" where ").append(pkName).append(" in ( ");

            for (int i = 0; i < idList.size(); ++i) {
                wholeSql.append(String.format("#{idList[%d]}", i));
                wholeSql.append(",");
            }

            wholeSql.setCharAt(wholeSql.length() - 1, ')');
            String sqlStr = wholeSql.toString();
            LOGGER.info("通用删除的sql语句为：{} \r\n deleteByIds idList: {}", sqlStr, idList);
            return sqlStr;
        }



        /* ***************************************************** update ******************************************************/

        public String updateByIdList(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            String pkName = (String) para.get("pkName");
            List<Long> idList = (List<Long>) para.get("idList");
            JSONObject models = (JSONObject) para.get("model");
            JSONObject packCommitData = (JSONObject) para.get("packCommitData");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("update ").append(tableName).append(" set ");
            for (Map.Entry<String, Object> entry : models.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                wholeSql.append(key).append(" = ").append(value).append(" , ");
            }

            for (Map.Entry<String, Object> entry : packCommitData.entrySet()) {
                String key = entry.getKey();
                Object valueObj = entry.getValue();
                List<String> types = ((List<String>) valueObj);
                /** {@link com.boman.web.core.utils.ColumnUtils.packColCondition} 这里是拼参数的地方 **/
                Object value = types.get(0);
                String queryType = types.get(1);
                String columnType = types.get(2);
                wholeSql.append(key).append(covert(queryType, columnType, key, value)).append(" , ");
            }

            wholeSql = new StringBuilder(StringUtils.substringBeforeLast(wholeSql.toString(), ","));
            wholeSql.append(" where ").append(pkName).append(" in ( ");

            for (int i = 0; i < idList.size(); ++i) {
                wholeSql.append(String.format("#{idList[%d]}", i));
                wholeSql.append(",");
            }

            wholeSql.setCharAt(wholeSql.length() - 1, ')');
            String sqlStr = wholeSql.toString();
            LOGGER.info("批量更新的sql语句为: {} \r\n 更改的数据为: {} \r\n idList: {}", sqlStr, models, idList);
            return sqlStr;
        }

        public String update(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            JSONObject packCommitData = (JSONObject) para.get("packCommitData");
            JSONObject packColCondition = (JSONObject) para.get("packColCondition");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("update ").append(tableName).append(" set ");

            for (Map.Entry<String, Object> entry : packCommitData.entrySet()) {
                String key = entry.getKey();
                Object valueObj = entry.getValue();
                List<String> types = ((List<String>) valueObj);
                /** {@link com.boman.web.core.utils.ColumnUtils.packColCondition} 这里是拼参数的地方 **/
                Object value = types.get(0);
                String queryType = types.get(1);
                String columnType = types.get(2);
                wholeSql.append(key).append(covert(queryType, columnType, key, value)).append(" , ");
            }

            wholeSql = new StringBuilder(StringUtils.substringBeforeLast(wholeSql.toString(), " , "));
            packCondition(packColCondition, wholeSql);

            String sqlStr = wholeSql.toString();
            LOGGER.info("通用的更新sql语句为: {} \r\n 提交的数据为: {} \r\n 条件为: {}", sqlStr, packCommitData, packColCondition);
            return sqlStr;
        }

        public String objectLogicDelete(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            String pkName = (String) para.get("pkName");
            List<String> idList = (List<String>) para.get("idList");
            JSONObject model = (JSONObject) para.get("model");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("update ").append(tableName).append(" set ");

            for (Map.Entry<String, Object> entry : model.entrySet()) {
                Object valueObj = entry.getValue();
                wholeSql.append(entry.getKey()).append(" = ").append("'").append(valueObj.toString()).append("'").append(" , ");
            }

            wholeSql = new StringBuilder(StringUtils.substringBeforeLast(wholeSql.toString(), " , "));
            wholeSql.append(" where ").append(pkName).append(" in ( ").append(ColumnUtils.joinList1(idList)).append(" ) ");

            String sqlStr = wholeSql.toString();
            LOGGER.info("逻辑删除sql语句为: {} \r\n 提交的数据为: {} \r\n idList: {}", sqlStr, model, idList);
            return sqlStr;
        }

        public String updateByForeignKey(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            String foreignKeyName = (String) para.get("foreignKeyName");
            List<Long> foreignKeyList = (List<Long>) para.get("foreignKeyList");
            JSONObject models = (JSONObject) para.get("model");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("update ").append(tableName).append(" set ");
            for (Map.Entry<String, Object> entry : models.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                wholeSql.append(key).append(covert(EQ, CHAR, key, value)).append(" , ");
            }

            wholeSql = new StringBuilder(StringUtils.substringBeforeLast(wholeSql.toString(), ","));
            wholeSql.append(" where ").append(foreignKeyName).append(" in ( ");

            for (Long id : foreignKeyList) {
                wholeSql.append(id);
                wholeSql.append(",");
            }

            wholeSql.setCharAt(wholeSql.length() - 1, ')');
            String sqlStr = wholeSql.toString();
            LOGGER.info("批量更新的sql语句为: {}, \r\n 更改的数据为: {}, \r\n foreignKeyList: {}", sqlStr, models, foreignKeyList);
            return sqlStr;

        }



        /* ***************************************************** select ******************************************************/

        public String selectByCondition(Map<String, Object> para) {
            JSONObject packCondition = (JSONObject) para.get("packCondition");
            String tableName = (String) para.get("tableName");
            String orderBy = (String) para.get("orderBy");
            int limit = (int) para.get("limit");
            int offset = (int) para.get("offset");
            List<String> showData = (List<String>) para.get("showData");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("select ");
            // showData
            StringBuilder showDataSql = new StringBuilder();
            // 调用之前进行了判空，showData肯定不为空
            for (Object columnObj : showData) {
                String columnName = (String) columnObj;
                showDataSql.append(columnName).append(", ");
            }
            wholeSql.append(StringUtils.substringBeforeLast(showDataSql.toString(), ","));
//
            wholeSql.append(" from ").append(tableName);
            // 条件
            packCondition(packCondition, wholeSql);
            wholeSql.append(" order by ").append(orderBy(orderBy)).append(" limit ").append(limit);
            if (isNotEmpty(offset)) {
                wholeSql.append(", ").append(offset);
            }

            String result = wholeSql.toString();
            LOGGER.info("查询拼出的sql语句为：{} \r\n selectByCondition 查询条件: {}", result, packCondition);
            return result;
        }

        public String selectByLeftJoinCondition(Map<String, Object> para) {
            QueryBySqlDto queryBySql = (QueryBySqlDto) para.get("queryBySql");
            JSONObject packCondition = (JSONObject) para.get("packCondition");
            String orderBy = (String) para.get("orderBy");
            int limit = (int) para.get("limit");
            int offset = (int) para.get("offset");
            List<String> showData = (List<String>) para.get("showData");

            String beforeSql = QueryBySqlDto.buildDataSql(showData, queryBySql);
            StringBuilder wholeSql = new StringBuilder(beforeSql);

            // 条件
            packCondition(packCondition, wholeSql);
            wholeSql.append(" order by ").append(orderBy(orderBy)).append(" limit ").append(limit);
            if (isNotEmpty(offset)) {
                wholeSql.append(", ").append(offset);
            }

            String result = wholeSql.toString();
            LOGGER.info("selectByLeftJoinCondition的sql语句为：{} \r\n 查询条件: {}", result, packCondition);
            return result;
        }

        public String getByMap(Map<String, Object> para) {
            JSONObject packCondition = (JSONObject) para.get("packCondition");
            String tableName = (String) para.get("tableName");
            boolean limitOne = (boolean) para.get("limitOne");

            String result;
            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("select * from ").append(tableName);
            if (isEmpty(packCondition)) {
                result = wholeSql.toString();
            } else {
                // 条件
                packCondition(packCondition, wholeSql);
                result = wholeSql.toString();
            }

            result = limitOne ? result + " limit 1" : result;
            LOGGER.info("查询拼出的sql语句为: {} \r\n getByMap 查询条件: {}", result, packCondition);
            return result;
        }

        public String selectByIdList(Map<String, Object> para) {
            String tableName = (String) para.get("tableName");
            String pkName = (String) para.get("pkName");
            List<Long> idList = (List<Long>) para.get(ID_LIST);
            List<String> showData = (List<String>) para.get("showData");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("select ");
            // showData
            StringBuilder showDataSql = new StringBuilder();
            if (isNotEmpty(showData)) {
                for (String columnName : showData) {
                    showDataSql.append(columnName).append(", ");
                }
                wholeSql.append(StringUtils.substringBeforeLast(showDataSql.toString(), ","));
            } else {
                showDataSql.append(" * ");
            }

            wholeSql.append(" from ").append(tableName).append(" where ").append(pkName).append(" in ( ");

            for (int i = 0; i < idList.size(); ++i) {
                wholeSql.append(String.format("#{idList[%d]}", i));
                wholeSql.append(",");
            }

            wholeSql.setCharAt(wholeSql.length() - 1, ')');
            String sqlStr = wholeSql.toString();
            LOGGER.info("查询拼出的sql语句为：{} \r\n selectByIdList idList: {}", sqlStr, idList);
            return sqlStr;
        }

        public String countByCondition(Map<String, Object> para) {
            JSONObject packCondition = (JSONObject) para.get("packCondition");
            String tableName = (String) para.get("tableName");

            StringBuilder wholeSql = new StringBuilder();
            wholeSql.append("select count(1)");
            wholeSql.append(" from ").append(tableName);
            // 条件
            packCondition(packCondition, wholeSql);

            String result = wholeSql.toString();
            LOGGER.info("查询count拼出的sql语句为: {} \r\n countByCondition 查询条件: {}", result, packCondition);
            return result;
        }

        public String countByLeftJoinCondition(Map<String, Object> para) {
            QueryBySqlDto queryBySql = (QueryBySqlDto) para.get("queryBySql");
            JSONObject packCondition = (JSONObject) para.get("packCondition");

            String beforeSql = QueryBySqlDto.buildCountSql(queryBySql);
            StringBuilder wholeSql = new StringBuilder(beforeSql);
            // 条件
            packCondition(packCondition, wholeSql);

            String result = wholeSql.toString();
            LOGGER.info("查询countByLeftJoinCondition拼出的sql语句为: {} \r\n 查询条件: {}", result, packCondition);
            return result;
        }

        public String selectById(Map<String, Object> params) {
            String tableName = (String) params.get("tableName");
            String pkName = (String) params.get("pkName");
            Long id = (Long) params.get("id");
            StringBuilder sqlBuilder = new StringBuilder();
            String other =  (String) params.get("other");
            if(StringUtils.isEmpty(other)) {
                sqlBuilder.append("select * from ")
                        .append(tableName).append(" where ")
                        .append(pkName).append(" = ").append(id).append(" limit 1");
            }else {
                sqlBuilder.append("select ").append(" t.id,t.message_code,t.message_situation,t.place_on_file, ")
                        .append("t.message_time,t.`status`,t.has_annex,t.send_time,t.message_upload,")
                        .append("t.message_enclosure,t.message_body,t.send_user_id,u.nick_name as send_user_name,")
                        .append("t.message_title,t.finish_time,t.message_remark,t.create_by,t.create_time,t.update_by,")
                        .append("t.update_time from ")
                        .append(tableName).append(" t ").append(" join sys_user u on u.id = t.send_user_id ").append(" where ")
                        .append(" t.").append(pkName).append(" = ").append(id).append(" limit 1");
            }
            return sqlBuilder.toString();
        }


        /* ***************************************************** utils ******************************************************/

        /**
         * 功能描述: 判断传过来的值是否需要转义
         *
         * @param packCondition 封装的条件
         * @param wholeSql      sql
         */
        private void packCondition(JSONObject packCondition, StringBuilder wholeSql) {
            if (isEmpty(packCondition)) {
                return;
            }

            wholeSql.append(" where ");
            StringBuilder conditionSql = new StringBuilder();
            for (Map.Entry<String, Object> entry : packCondition.entrySet()) {
                String key = entry.getKey();
                Object valueObj = entry.getValue();
                List<String> types = ((List<String>) valueObj);
                /** {@link com.boman.web.core.utils.ColumnUtils.packColCondition} 这里是拼参数的地方 **/
                Object value = types.get(0);
                String queryType = types.get(1);
                String columnType = types.get(2);
                conditionSql.append(key).append(covert(queryType, columnType, key, value)).append(" and ");
            }

            wholeSql.append(StringUtils.substringBeforeLast(conditionSql.toString(), " and"));
        }

        /**
         * 功能描述: 仅此用来拼装查询条件，不做他用
         *
         * @param queryType  like > < =
         * @param columnType varchar char textarea timestamp
         * @param key        key
         * @param valueObj   valueObj
         * @return java.lang.String
         */
        private String covert(String queryType, String columnType, String key, Object valueObj) {
            // false 不需要转义
            boolean needEscape = columnType.contains(VARCHAR) || columnType.contains(CHAR) || columnType.contains(DATETIME) || columnType.contains(TIMESTAMP);
            Object value;
            switch (queryType) {
                case EQ:
                    value = needEscape ? escapeStr(String.valueOf(valueObj)) : valueObj;
                    return " = " + value;
                case LIKE:
                    return " like concat('%', #{condition." + key + "}, '%')";
                case NE:
                    value = needEscape ? escapeStr(String.valueOf(valueObj)) : valueObj;
                    return " != " + value;
                case GT:
                    value = needEscape ? escapeStr(String.valueOf(valueObj)) : valueObj;
                    return " > " + value;
                case GTE:
                    value = needEscape ? escapeStr(String.valueOf(valueObj)) : valueObj;
                    return " >= " + value;
                case LT:
                    value = needEscape ? escapeStr(String.valueOf(valueObj)) : valueObj;
                    return " < " + value;
                case LTE:
                    value = needEscape ? escapeStr(String.valueOf(valueObj)) : valueObj;
                    return " <= " + value;
                default:
                    // in
                    List<Object> list = valueObj instanceof List ? ((List<Object>) valueObj) : Lists.newArrayList(valueObj);
                    return " in (" + ColumnUtils.joinList(list) + ")";
            }
        }

        static final String[] READONLY_COLUMNS = new String[]{"OWNERID", "OWNERNAME", "OWNERENAME", "CREATIONDATE", "ID"};

        public SqlProvider() {
        }

        private static boolean isReadOnly(String column) {
            String[] var1 = READONLY_COLUMNS;
            int var2 = var1.length;

            for (String readonlyColumn : var1) {
                if (readonlyColumn.equals(column)) {
                    return true;
                }
            }

            return false;
        }

        private static boolean isNullOrEmpty(String str) {
            return str == null || str.length() == 0 || str.trim().length() == 0;
        }

        private static boolean isNullOrEmpty(JSONObject json) {
            return json == null || json.isEmpty();
        }

        private static void keyToUpper(JSONObject json) {
            String[] keys = new String[json.size()];
            json.keySet().toArray(keys);
            int var3 = keys.length;

            for (String key : keys) {
                if (!key.equals(key.toUpperCase())) {
                    json.put(key.toUpperCase(), json.get(key));
                    json.remove(key);
                }
            }
        }

        public static String orderBy(String orderBy) {
            String base = " create_time desc ";
            if (isNullOrEmpty(orderBy)) {
                return base;
            }

            String replace = orderBy.replace(" ", "");
            if (replace.contains("create_timedesc")) {
                return base;
            }

            return orderBy + ", " + base;
        }

    }
}