package com.xjrsoft.module.form.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.DbUtil;
import cn.hutool.db.Entity;
import cn.hutool.db.GlobalDbConfig;
import cn.hutool.db.Page;
import cn.hutool.db.PageResult;
import cn.hutool.db.Session;
import cn.hutool.db.dialect.DialectFactory;
import cn.hutool.db.meta.Column;
import cn.hutool.db.meta.JdbcType;
import cn.hutool.db.meta.MetaUtil;
import cn.hutool.db.meta.Table;
import cn.hutool.db.sql.Condition;
import cn.hutool.db.sql.Direction;
import cn.hutool.db.sql.Order;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.enums.DeleteMark;
import com.xjrsoft.common.enums.EnabledMark;
import com.xjrsoft.common.enums.OracleFieldsType;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.handler.XjrEntityHandler;
import com.xjrsoft.common.handler.XjrEntityListHandler;
import com.xjrsoft.common.model.generator.ComponentConfig;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.runner.XjrSqlConnRunner;
import com.xjrsoft.common.utils.DatasourceUtil;
import com.xjrsoft.common.utils.JdbcToJavaUtil;
import com.xjrsoft.common.utils.LocalDateTimeUtil;
import com.xjrsoft.module.app.entity.AppFuncDesign;
import com.xjrsoft.module.app.service.IAppFuncDesignService;
import com.xjrsoft.module.authority.utils.AuthorityUtil;
import com.xjrsoft.module.form.dto.AppFormExecuteAddOrUpdateDto;
import com.xjrsoft.module.form.dto.AppFormExecuteDeleteDto;
import com.xjrsoft.module.form.dto.AppFormExecuteInfoDto;
import com.xjrsoft.module.form.dto.AppFormExecuteListDto;
import com.xjrsoft.module.form.dto.AppFormExecutePageDto;
import com.xjrsoft.module.form.dto.FormExecuteAddOrUpdateDto;
import com.xjrsoft.module.form.dto.FormExecuteDeleteDto;
import com.xjrsoft.module.form.dto.FormExecuteInfoDto;
import com.xjrsoft.module.form.dto.FormExecuteListDto;
import com.xjrsoft.module.form.dto.FormExecutePageDto;
import com.xjrsoft.module.form.dto.FormExecuteWorkflowAddDto;
import com.xjrsoft.module.form.dto.FormExecuteWorkflowInfoDto;
import com.xjrsoft.module.form.dto.FormExecuteWorkflowUpdateDto;
import com.xjrsoft.module.form.entity.FormDesignConfig;
import com.xjrsoft.module.form.entity.FormRelease;
import com.xjrsoft.module.form.entity.FormReleaseConfig;
import com.xjrsoft.module.form.entity.FormTemplate;
import com.xjrsoft.module.form.mapper.FormReleaseMapper;
import com.xjrsoft.module.form.mapper.FormTemplateMapper;
import com.xjrsoft.module.form.service.IFormExecuteService;
import com.xjrsoft.module.form.utils.FormDataTransUtil;
import com.xjrsoft.module.form.vo.DeskColumnsVo;
import com.xjrsoft.module.form.vo.DeskTableInfoVo;
import com.xjrsoft.module.generator.constant.ComponentTypeConstant;
import com.xjrsoft.module.generator.entity.ColumnConfig;
import com.xjrsoft.module.generator.entity.ListConfig;
import com.xjrsoft.module.generator.entity.QueryConfig;
import com.xjrsoft.module.generator.entity.TableConfig;
import com.xjrsoft.module.generator.entity.TableFieldConfig;
import com.xjrsoft.module.generator.entity.TableStructureConfig;
import com.xjrsoft.module.generator.utils.GeneratorUtil;
import com.xjrsoft.module.system.service.ICodeRuleService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.TimestampValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.util.SelectUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.apache.commons.lang3.tuple.Triple;
import org.camunda.bpm.engine.impl.calendar.DateTimeUtil;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: tzx
 * @Date: 2022/5/11 15:05
 */
@Service
@AllArgsConstructor
public class FormExecuteServiceImpl implements IFormExecuteService {

    private final FormReleaseMapper formReleaseMapper;

    private final FormTemplateMapper formTemplateMapper;

    private final ICodeRuleService codeRuleService;

    private final IAppFuncDesignService appFuncDesignService;

    /**
     * 需要模糊查询的
     */
    private final List<String> LIKE_CLASS_NAME = Collections.singletonList("String");

    /**
     * 需要完全对比判断
     */
    private final List<String> EQ_CLASS_NAME = Arrays.asList("Integer", "Long", "Double", "Float", "Boolean");

    /**
     * 时间类型
     */
    private final List<String> TIME_CLASS_NAME = Collections.singletonList("LocalDateTime");

    @Override
    @SneakyThrows
    public List<Entity> list(FormExecuteListDto dto) {
        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = formRelease.getConfigJson();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);

        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            List<ColumnConfig> columnConfigs = formReleaseConfig.getListConfig().getColumnConfigs();
            List<String> fieldsList = columnConfigs.stream().map(ColumnConfig::getColumnName).collect(Collectors.toList());
            // 添加权限所属人字段返回
            if (BooleanUtils.isTrue(formDesignConfig.getIsDataAuth())) {
                fieldsList.add(GlobalConstant.AUTH_USER_ID);
            }

            List<Entity> listData = getListDataByExpression(tableName, fieldsList, formDesignConfig, formReleaseConfig, dto.getParams());
            if (dto.getIsTrans()) {
                // 关联数据显示转换
                FormDataTransUtil.transData(listData, formDesignConfig);
            }
            return listData;
        } else {
            throw new MyException("主表不存在");
        }

    }

    @Override
    public List<Entity> appList(AppFormExecuteListDto dto) {

        AppFuncDesign funcDesign = appFuncDesignService.getById(dto.getFuncId());
//        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = funcDesign.getJsonContent();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(configJson, FormDesignConfig.class);

        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            List<ColumnConfig> columnConfigs = formReleaseConfig.getListConfig().getColumnConfigs();
            List<String> fieldsList = columnConfigs.stream().map(ColumnConfig::getColumnName).collect(Collectors.toList());
            // 添加权限所属人字段返回
            if (BooleanUtils.isTrue(formDesignConfig.getIsDataAuth())) {
                fieldsList.add(GlobalConstant.AUTH_USER_ID);
            }

            List<Entity> listData = getListDataByExpression(tableName, fieldsList, formDesignConfig, formReleaseConfig, dto.getParams());
            if (dto.getIsTrans()) {
                // 关联数据显示转换
                FormDataTransUtil.transData(listData, formDesignConfig);
            }
            return listData;
        } else {
            throw new MyException("主表不存在");
        }
    }

    @Override
    public PageOutput<Entity> page(FormExecutePageDto dto) {

        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = formRelease.getConfigJson();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);

        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            //构建分页参数
            Page page = new Page(dto.getLimit() - 1, dto.getSize());
            String field = dto.getField();
            String orderStr = dto.getOrder();
            ListConfig listConfig = formReleaseConfig.getListConfig();
            if (StrUtil.isBlank(field)) {
                field = StrUtil.emptyToDefault(listConfig.getOrderBy(), tableConfig.getPkField());
                orderStr = StrUtil.emptyToDefault(listConfig.getOrderType(), "desc");
            }
            if (StrUtil.isNotBlank(field)) {
                Order order = new Order();
                order.setDirection(Direction.ASC);
                if (orderStr.equals("descend") || orderStr.equals("desc")) {
                    order.setDirection(Direction.DESC);
                }
//                order.setDirection(StrUtil.equalsIgnoreCase(orderStr, "descend") ? Direction.DESC : Direction.ASC);
                order.setField(field);
                page.setOrder(order);
            }

            List<ColumnConfig> columnConfigs = listConfig.getColumnConfigs();
            Set<String> fieldsList = columnConfigs.stream().map(ColumnConfig::getColumnName).collect(Collectors.toSet());
            // 添加权限所属人字段返回
            if (BooleanUtils.isTrue(formDesignConfig.getIsDataAuth())) {
                fieldsList.add(GlobalConstant.AUTH_USER_ID);
            }

            PageOutput<Entity> pageData = getPageDataByExpression(tableName, fieldsList, formDesignConfig, formReleaseConfig, dto.getParams(), page);
            if (dto.getIsTrans()) {
                // 关联数据显示转换
                FormDataTransUtil.transData(pageData.getList(), formDesignConfig);
            }
            return pageData;
        } else {
            throw new MyException("主表不存在");
        }
    }

    @Override
    public PageOutput<Entity> appPage(AppFormExecutePageDto dto) {
        AppFuncDesign funcDesign = appFuncDesignService.getById(dto.getFuncId());
//        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = funcDesign.getJsonContent();
        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(configJson, FormDesignConfig.class);

        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            //构建分页参数
            Page page = new Page(dto.getLimit() - 1, dto.getSize());
            String field = dto.getField();
            String orderStr = dto.getOrder();
            ListConfig listConfig = formReleaseConfig.getListConfig();
            if (StrUtil.isBlank(field)) {
                field = StrUtil.emptyToDefault(listConfig.getOrderBy(), tableConfig.getPkField());
                orderStr = StrUtil.emptyToDefault(listConfig.getOrderType(), "desc");
            }
            if (StrUtil.isNotBlank(field)) {
                Order order = new Order();
                order.setDirection(StrUtil.equalsIgnoreCase(orderStr, "desc") ? Direction.DESC : Direction.ASC);
                order.setField(field);
                page.setOrder(order);
            }

            List<ColumnConfig> columnConfigs = listConfig.getColumnConfigs();
            Set<String> fieldsList = columnConfigs.stream().map(ColumnConfig::getColumnName).collect(Collectors.toSet());
            // 添加权限所属人字段返回
            if (BooleanUtils.isTrue(formDesignConfig.getIsDataAuth())) {
                fieldsList.add(GlobalConstant.AUTH_USER_ID);
            }

            PageOutput<Entity> pageData = getPageDataByExpression(tableName, fieldsList, formDesignConfig, formReleaseConfig, dto.getParams(), page);
            if (dto.getIsTrans()) {
                // 关联数据显示转换
                FormDataTransUtil.transData(pageData.getList(), formDesignConfig);
            }
            return pageData;
        } else {
            throw new MyException("主表不存在");
        }
    }

    @Override
    public Object info(FormExecuteInfoDto dto) {
        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = formRelease.getConfigJson();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            Map<String, List<ComponentConfig>> formComponentListMap = GeneratorUtil.buildFormComponentList(formDesignConfig.getFormJson().getList());
            List<String> fieldsList = new ArrayList<>();
            for (ComponentConfig config : formComponentListMap.get(tableName)) {
                String type = config.getType();
                if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.TIME_RANGE) || StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.DATE_RANGE)) {
                    fieldsList.add(config.getBindStartTime());
                    fieldsList.add(config.getBindEndTime());
                } else {
                    fieldsList.add(config.getBindField());
                }
            }

            return getFormData(tableName, fieldsList, formDesignConfig, dto.getId());
        } else {
            throw new MyException("主表不存在");
        }

    }

    @Override
    public Object appInfo(AppFormExecuteInfoDto dto) {
        AppFuncDesign funcDesign = appFuncDesignService.getById(dto.getFuncId());
//        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = funcDesign.getJsonContent();

        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(configJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            Map<String, List<ComponentConfig>> formComponentListMap = GeneratorUtil.buildFormComponentList(formDesignConfig.getFormJson().getList());
            List<String> fieldsList = new ArrayList<>();
            for (ComponentConfig config : formComponentListMap.get(tableName)) {
                String type = config.getType();
                if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.TIME_RANGE) || StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.DATE_RANGE)) {
                    fieldsList.add(config.getBindStartTime());
                    fieldsList.add(config.getBindEndTime());
                } else {
                    fieldsList.add(config.getBindField());
                }
            }

            return getFormData(tableName, fieldsList, formDesignConfig, dto.getId());
        } else {
            throw new MyException("主表不存在");
        }
    }

    @Override
    public Boolean add(FormExecuteAddOrUpdateDto dto) {

        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        Map<String, Object> formData = dto.getFormData();

        String configJson = formRelease.getConfigJson();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        return insertFormData(formData, template);

    }

    @Override
    public Boolean appAdd(AppFormExecuteAddOrUpdateDto dto) {
        AppFuncDesign funcDesign = appFuncDesignService.getById(dto.getFuncId());

        String configJson = funcDesign.getJsonContent();

        Map<String, Object> formData = dto.getFormData();


        //自定义表单数据
        FormTemplate template = new FormTemplate();
        template.setFormJson(configJson);

        return insertFormData(formData, template);
    }

    public Boolean saveMainBatch(Long formTemplateId, List<Map<String, Object>> dataList) {
        FormTemplate template = formTemplateMapper.selectById(formTemplateId);
        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();
        List<Entity> toSaveList = new ArrayList<>();
        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();
            //获取表里所有字段
            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pk = columns.stream().filter(Column::isPk).findFirst();

            for (Map<String, Object> data : dataList) {
                Entity where = Entity.create(tableName);
                // 处理字段值
                Map<String, Object> toSaveFormData = handleFormDataForSave(data, formDesignConfig, tableName, new ArrayList<>());

                //formData 默认插入雪花Id主键
                pk.ifPresent(column -> toSaveFormData.put(column.getName(), IdUtil.getSnowflakeNextId()));
                where.putAll(toSaveFormData);
                //如果有审计字段  默认填充值
                putAuditEntityInsertData(where, columns);

                toSaveList.add(where);
            }
            try {
                Db.use(datasource).insert(toSaveList);
                return true;
            } catch (SQLException e) {
                throw new MyException("批量新增数据失败！");
            }
        }
        return false;
    }

    @Override
    public Boolean update(FormExecuteAddOrUpdateDto dto) {
        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());

        String configJson = formRelease.getConfigJson();

        Map<String, Object> formData = dto.getFormData();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        return updateFormData(formData, template);
    }

    @Override
    public Boolean appUpdate(AppFormExecuteAddOrUpdateDto dto) {

        AppFuncDesign funcDesign = appFuncDesignService.getById(dto.getFuncId());

        String configJson = funcDesign.getJsonContent();

        Map<String, Object> formData = dto.getFormData();


        //自定义表单数据
        FormTemplate template = new FormTemplate();
        template.setFormJson(configJson);

        return updateFormData(formData, template);
    }


    @Override
    public Boolean delete(FormExecuteDeleteDto dto) {

        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());


        String configJson = formRelease.getConfigJson();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity entity = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pkOptinal = columns.stream().filter(Column::isPk).findFirst();
            Column pk;
            if (pkOptinal.isPresent()) {
                pk = pkOptinal.get();
            } else {
                throw new MyException("主键不存在");
            }


            //获取所有需要删除的id
            List<String> keyValues = dto.getIds();

            //获取到所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            Entity where = Entity.create(tableName);

            if (StrUtil.equalsIgnoreCase(JdbcToJavaUtil.getClassName(pk), "Long")) {
                where.set(pk.getName(), keyValues.stream().map(Long::parseLong).collect(Collectors.toList()));
            } else {
                where.set(pk.getName(), keyValues);
            }

            //如果有审计字段  默认填充值
            putAuditEntityUpdateData(entity, columns);

            //如果包含逻辑删除字段
            if (columns.stream().anyMatch(x -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, x.getName()))) {

                Session session = Session.create(datasource);
                try {
                    session.beginTransaction();

                    for (TableConfig tableConfig : tableConfigList) {

                        Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableConfig.getTableName())).findFirst();

                        if (childTableConfig.isPresent()) {

                            List<Entity> entities = session.find(where);

                            List<Object> allPkValue = entities.stream().map(x -> x.get(childTableConfig.get().getRelationTableField())).collect(Collectors.toList());

                            //删除子表单数据
                            Entity childDeleteWhere = Entity.create(tableConfig.getTableName()).
                                    set(childTableConfig.get().getRelationField(), allPkValue);

                            //没做子表单的软删除
                            session.del(childDeleteWhere);

                        }
                    }

                    // 更新主表数据
                    entity.set(GlobalConstant.DELETE_MARK, DeleteMark.DELETED.getCode());
                    session.update(entity, where);


                    session.commit();
                } catch (SQLException e) {
                    session.quietRollback();
                    throw new MyException("删除数据失败，数据回滚！");
                }
            } else {

                Session session = Session.create(datasource);
                try {
                    session.beginTransaction();


                    //删除子表数据
                    for (TableConfig tableConfig : tableConfigList) {

                        Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableConfig.getTableName())).findFirst();

                        if (childTableConfig.isPresent()) {

                            List<Entity> entities = session.find(where);

                            List<Object> allPkValue = entities.stream().map(x -> x.get(childTableConfig.get().getRelationTableField())).collect(Collectors.toList());

                            //删除子表单数据
                            Entity childDeleteWhere = Entity.create(tableConfig.getTableName()).
                                    set(childTableConfig.get().getRelationField(), allPkValue);

                            //没做子表单的软删除
                            session.del(childDeleteWhere);

                        }
                    }

                    //删除主表数据
                    session.del(where);


                    session.commit();
                } catch (SQLException e) {
                    session.quietRollback();
                    throw new MyException("删除数据失败，数据回滚！");
                }
            }

            return true;
        } else {
            throw new MyException("主表不存在");
        }
    }

    @Override
    public Boolean appDelete(AppFormExecuteDeleteDto dto) {
        AppFuncDesign funcDesign = appFuncDesignService.getById(dto.getFuncId());

        String configJson = funcDesign.getJsonContent();

        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(configJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity entity = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pkOptinal = columns.stream().filter(Column::isPk).findFirst();
            Column pk;
            if (pkOptinal.isPresent()) {
                pk = pkOptinal.get();
            } else {
                throw new MyException("主键不存在");
            }


            //获取所有需要删除的id
            List<String> keyValues = dto.getIds();

            //获取到所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            Entity where = Entity.create(tableName);

            where.set(pk.getName(), keyValues);

            //如果有审计字段  默认填充值
            putAuditEntityUpdateData(entity, columns);

            //如果包含逻辑删除字段
            if (columns.stream().anyMatch(x -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, x.getName()))) {

                Session session = Session.create(datasource);
                try {
                    session.beginTransaction();

                    for (TableConfig tableConfig : tableConfigList) {

                        Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableConfig.getTableName())).findFirst();

                        if (childTableConfig.isPresent()) {

                            List<Entity> entities = session.find(where);

                            List<Object> allPkValue = entities.stream().map(x -> x.get(childTableConfig.get().getRelationTableField())).collect(Collectors.toList());

                            //删除子表单数据
                            Entity childDeleteWhere = Entity.create(tableConfig.getTableName()).
                                    set(childTableConfig.get().getRelationField(), allPkValue);

                            //没做子表单的软删除
                            session.del(childDeleteWhere);

                        }
                    }

                    // 更新主表数据
                    entity.set(GlobalConstant.DELETE_MARK, DeleteMark.DELETED.getCode());
                    session.update(entity, where);


                    session.commit();
                } catch (SQLException e) {
                    session.quietRollback();
                    throw new MyException("删除数据失败，数据回滚！");
                }
            } else {

                Session session = Session.create(datasource);
                try {
                    session.beginTransaction();


                    //删除子表数据
                    for (TableConfig tableConfig : tableConfigList) {

                        Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableConfig.getTableName())).findFirst();

                        if (childTableConfig.isPresent()) {

                            List<Entity> entities = session.find(where);

                            List<Object> allPkValue = entities.stream().map(x -> x.get(childTableConfig.get().getRelationTableField())).collect(Collectors.toList());

                            //删除子表单数据
                            Entity childDeleteWhere = Entity.create(tableConfig.getTableName()).
                                    set(childTableConfig.get().getRelationField(), allPkValue);

                            //没做子表单的软删除
                            session.del(childDeleteWhere);

                        }
                    }

                    //删除主表数据
                    session.del(where);


                    session.commit();
                } catch (SQLException e) {
                    session.quietRollback();
                    throw new MyException("删除数据失败，数据回滚！");
                }
            }

            return true;
        } else {
            throw new MyException("主表不存在");
        }
    }

    @Override
    @SneakyThrows
    public Triple<Session, Long, Long> workflowAdd(FormExecuteWorkflowAddDto dto) {
        Map<String, Object> formData = dto.getFormData();
        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(dto.formId);

        return insertFormByWorkflow(formData, template);
    }

    @Override
    public Triple<Session, Long, Long> workflowUpdate(FormExecuteWorkflowUpdateDto dto) {
        Map<String, Object> formData = dto.getFormData();
        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(dto.formId);

        return updateFormDataByWorkflow(formData, template);
    }

    @Override
    public Triple<Session, Boolean, Long> workflowAddOrUpdate(FormExecuteWorkflowUpdateDto dto) {
        Map<String, Object> formData = dto.getFormData();
        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(dto.formId);
        return insertOrUpdateFormDataByWorkflow(formData, template);
    }

    @Override
    public Object workFlowInfo(FormExecuteWorkflowInfoDto dto) {

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(dto.getFormId());

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            Optional<TableStructureConfig> mainConfig = formDesignConfig.getTableStructureConfigs().stream().filter(x -> x.getTableName().equals(tableName)).findFirst();

            if (!mainConfig.isPresent()) {
                throw new MyException("主表不存在");
            }
            List<String> fieldsList = mainConfig.get().getTableFieldConfigs().stream().map(TableFieldConfig::getFieldName).collect(Collectors.toList());

            return getFormData(tableName, fieldsList, formDesignConfig, dto.getId().toString());
        } else {
            throw new MyException("主表不存在");
        }
    }


    private boolean insertFormData(Map<String, Object> formData, FormTemplate template) {
        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity where = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pk = columns.stream().filter(Column::isPk).findFirst();

            long keyValue = IdUtil.getSnowflakeNextId();

            //遍历所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            //所有子表数据
            Map<String, List<Entity>> childMaps = new HashMap<>(tableConfigList.size());
            // 自动编码code
            List<String> autoCodeList = new ArrayList<>();
            // 处理字段值
            Map<String, Object> toSaveFormData = handleFormDataForSave(formData, formDesignConfig, tableName, autoCodeList);

            //formData 默认插入雪花Id主键
            if (pk.isPresent()) {
                formData.put(pk.get().getName(), keyValue);
                toSaveFormData.put(pk.get().getName(), keyValue);
            }

            //构建子表单数据
            wrapperChildEntity(datasource, tableConfigList, childMaps, formData, formDesignConfig, keyValue, autoCodeList);


            //此时的formData 已经是剔除了子表单数据了
            where.putAll(toSaveFormData);
            //如果有审计字段  默认填充值
            putAuditEntityInsertData(where, columns);

            Session session = Session.create(datasource);
            try {
                session.beginTransaction();
                // 保存主表数据
                session.insert(where);
                // 保存子表数据
                for (Map.Entry<String, List<Entity>> tableMap : childMaps.entrySet()) {
                    List<Entity> childList = tableMap.getValue();
                    session.insert(childList);
                }
                codeRuleService.useEncode(autoCodeList);
                session.commit();
            } catch (SQLException e) {
                session.quietRollback();
                throw new MyException("新增数据失败，数据回滚！", e);
            }

            return true;
        } else {
            throw new MyException("主表不存在");
        }
    }

    private boolean updateFormData(Map<String, Object> formData, FormTemplate template) {
        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity entity = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
            Column pk;
            if (pkOptional.isPresent()) {
                pk = pkOptional.get();
            } else {
                throw new MyException("主键不存在");
            }


            //遍历所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            //所有子表数据
            Map<String, List<Entity>> childMaps = new HashMap<>(tableConfigList.size());

            //更新的时候默认使用string 的key  因为客户的表 可能什么类型的主键都有  所以默认使用string
            String keyValue = MapUtil.get(formData, pk.getName(), String.class);


            Object keyValue2 = null;
            if (StrUtil.equalsIgnoreCase(JdbcToJavaUtil.getClassName(pk), "Long")) {
                keyValue2 = Long.valueOf(keyValue);
            } else {
                keyValue2 = keyValue;
            }
            //where 拼接 id
            Entity where = Entity.create(tableName).set(pk.getName(), keyValue2);

            //构建子表单数据
            wrapperChildEntity(datasource, tableConfigList, childMaps, formData, formDesignConfig, keyValue2, null);

            // 处理字段值
            formData = handleFormDataForSave(formData, formDesignConfig, tableName, null);

            //此时的formData 已经是剔除了子表单数据了
            entity.putAll(formData);

            //主表如果有审计字段  默认填充值
            putAuditEntityUpdateData(entity, columns);

            Session session = Session.create(datasource);
            try {
                session.beginTransaction();
                // 更新主表数据
                session.update(entity, where);


                // 遍历数据 根据 表名 保存子表数据
                for (Map.Entry<String, List<Entity>> tableMap : childMaps.entrySet()) {
                    //先删除子表单数据 然后再新增  这里使用物理删除  不再逻辑删除。  tableMap的key  就是 子表的表名
                    Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableMap.getKey())).findFirst();

                    if (childTableConfig.isPresent()) {
                        //删除子表单数据
                        Entity childDeleteWhere = Entity.create(tableMap.getKey()).set(childTableConfig.get().getRelationField(), keyValue2);
                        session.del(childDeleteWhere);

                        //再重新新增
                        List<Entity> childList = tableMap.getValue();
                        session.insert(childList);
                    }

                }
                session.commit();
            } catch (SQLException e) {
                session.quietRollback();
                throw new MyException("修改数据失败，数据回滚！", e);
            }

            return true;
        } else {
            throw new MyException("主表不存在");
        }
    }

    @SneakyThrows
    private Triple<Session, Long, Long> insertFormByWorkflow(Map<String, Object> formData, FormTemplate template) {

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity where = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pk = columns.stream().filter(Column::isPk).findFirst();

            long keyValue = IdUtil.getSnowflakeNextId();

            //遍历所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            //所有子表数据
            Map<String, List<Entity>> childMaps = new HashMap<>(tableConfigList.size());

            // 自动编码code
            List<String> autoCodeList = new ArrayList<>();

            //构建子表单数据
            //深拷贝一份表单数据 避免修改原表单数据
            Map<String, Object> newFormData = ObjectUtil.cloneIfPossible(formData);
            Map<String, List<Map<String, Object>>> childFormData = wrapperChildEntity(datasource, tableConfigList, childMaps, newFormData, formDesignConfig, keyValue, autoCodeList);

            // 处理字段值
            newFormData = handleFormDataForSave(newFormData, formDesignConfig, tableName, autoCodeList);

            //formData 默认插入雪花Id主键
            if (pk.isPresent()) {
                newFormData.put(pk.get().getName(), keyValue);
            }

            //此时的formData 已经是剔除了子表单数据了
            where.putAll(newFormData);

            //如果有审计字段  默认填充值
            putAuditEntityInsertData(where, columns);

            Session session = Session.create(datasource);
            session.beginTransaction();
            // 保存主表数据
            session.insert(where);
            // 保存子表数据
            for (Map.Entry<String, List<Entity>> tableMap : childMaps.entrySet()) {
                List<Entity> childList = tableMap.getValue();
                session.insert(childList);
                //工作流调用自定义表单方法 添加数据 必须需要这一行代码 构建之后的子表单数据 覆盖原formData 数据
                formData.put(tableMap.getKey() + "List", childFormData.get(tableMap.getKey()));
            }
            // 使用自动编码
            codeRuleService.useEncode(autoCodeList);

            //返回值元组，  用于多返回值  left 为当前session middle 为formId  right为当前主表主键
            return new ImmutableTriple<>(session, template.getId(), keyValue);
        } else {
            throw new MyException("主表不存在");
        }
    }

    @SneakyThrows
    private Triple<Session, Long, Long> updateFormDataByWorkflow(Map<String, Object> formData, FormTemplate template) {
        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity entity = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
            Column pk;
            if (pkOptional.isPresent()) {
                pk = pkOptional.get();
            } else {
                throw new MyException("主键不存在");
            }


            //遍历所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            //所有子表数据
            Map<String, List<Entity>> childMaps = new HashMap<>(tableConfigList.size());

            //更新的时候默认使用string 的key  因为客户的表 可能什么类型的主键都有  所以默认使用string
            //TODO 可能会出现各种类型的主键 目前是建议客户使用Long类型主键
            Long keyValue = MapUtil.get(formData, pk.getName(), Long.class);

            //where 拼接 id
            Entity where = Entity.create(tableName);

            //构建子表单数据
            //深拷贝一份表单数据 避免修改原表单数据
            Map<String, Object> newFormData = ObjectUtil.cloneIfPossible(formData);
            Map<String, List<Map<String, Object>>> childFormData = wrapperChildEntity(datasource, tableConfigList, childMaps, newFormData, formDesignConfig, keyValue, null);

            // 处理字段值
            newFormData = handleFormDataForSave(newFormData, formDesignConfig, tableName, null);

            //此时的formData 已经是剔除了子表单数据了
            newFormData.remove(pk.getName());
            entity.putAll(newFormData);

            //主表如果有审计字段  默认填充值
            putAuditEntityUpdateData(entity, columns);

            Session session = Session.create(datasource);
            session.beginTransaction();

            if (pk.getTypeName().equals("varchar")) { //常用主键为String类型，默认为Long类型
                where = where.set(pk.getName(), keyValue.toString());
            } else {
                where = where.set(pk.getName(), keyValue);
            }
            // 更新主表数据
            session.update(entity, where);

            // 遍历数据 根据 表名 保存子表数据
            for (Map.Entry<String, List<Entity>> tableMap : childMaps.entrySet()) {
                //先删除子表单数据 然后再新增  这里使用物理删除  不再逻辑删除。  tableMap的key  就是 子表的表名
                Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableMap.getKey())).findFirst();

                if (childTableConfig.isPresent()) {
                    //删除子表单数据
                    Entity childDeleteWhere = Entity.create(tableMap.getKey()).set(childTableConfig.get().getRelationField(), keyValue);
                    session.del(childDeleteWhere);

                    //再重新新增
                    List<Entity> childList = tableMap.getValue();
                    session.insert(childList);

                    //工作流调用自定义表单方法 必须需要这一行代码 构建之后的子表单数据 覆盖原formData 数据
                    formData.put(tableMap.getKey() + "List", childFormData.get(tableMap.getKey()));
                }

            }
            return new ImmutableTriple<>(session, template.getId(), keyValue);
        } else {
            throw new MyException("主表不存在");
        }
    }

    @SneakyThrows
    private Triple<Session, Boolean, Long> insertOrUpdateFormDataByWorkflow(Map<String, Object> formData, FormTemplate template) {
        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);
        //表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            String tableName = mainTable.get().getTableName();

            Entity entity = Entity.create(tableName);

            DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
            //获取表里所有字段
            Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
            Column pk;
            if (pkOptional.isPresent()) {
                pk = pkOptional.get();
            } else {
                throw new MyException("主键不存在");
            }


            //遍历所有子表
            List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

            //所有子表数据
            Map<String, List<Entity>> childMaps = new HashMap<>(tableConfigList.size());

            //更新的时候默认使用string 的key  因为客户的表 可能什么类型的主键都有  所以默认使用string
            //TODO 可能会出现各种类型的主键 目前是建议客户使用Long类型主键
            Long keyValue = MapUtil.get(formData, pk.getName(), Long.class);

            //如果不为空就是更新
            if (ObjectUtil.isNotNull(keyValue)) {
                //where 拼接 id
                Entity where = Entity.create(tableName).set(pk.getName(), keyValue);


                //构建子表单数据
                //深拷贝一份表单数据 避免修改原表单数据
                Map<String, Object> newFormData = ObjectUtil.cloneIfPossible(formData);
                Map<String, List<Map<String, Object>>> childFormData = wrapperChildEntity(datasource, tableConfigList, childMaps, newFormData, formDesignConfig, keyValue, null);

                // 处理字段值
                Map<String, Object> toSaveFormData = handleFormDataForSave(newFormData, formDesignConfig, tableName, null);
                //此时的formData 已经是剔除了子表单数据了
                toSaveFormData.remove(pk.getName());
                entity.putAll(toSaveFormData);

                //主表如果有审计字段  默认填充值
                putAuditEntityUpdateData(entity, columns);

                Session session = Session.create(datasource);
                session.beginTransaction();
                // 更新主表数据
                session.update(entity, where);

                // 遍历数据 根据 表名 保存子表数据
                for (Map.Entry<String, List<Entity>> tableMap : childMaps.entrySet()) {
                    //先删除子表单数据 然后再新增  这里使用物理删除  不再逻辑删除。  tableMap的key  就是 子表的表名
                    Optional<TableConfig> childTableConfig = tableConfigList.stream().filter(x -> x.getTableName().equals(tableMap.getKey())).findFirst();

                    if (childTableConfig.isPresent()) {
                        //删除子表单数据
                        Entity childDeleteWhere = Entity.create(tableMap.getKey()).set(childTableConfig.get().getRelationField(), keyValue);
                        session.del(childDeleteWhere);

                        //再重新新增
                        List<Entity> childList = tableMap.getValue();
                        session.insert(childList);

                        //工作流调用自定义表单方法 必须需要这一行代码 构建之后的子表单数据 覆盖原formData 数据
                        formData.put(tableMap.getKey() + "List", childFormData.get(tableMap.getKey()));
                    }

                }
                //返回值元组，  用于多返回值  left 为当前session middle 为false 代表新增 为true 代表更新  right为当前主表主键
                return new ImmutableTriple<>(session, true, keyValue);
            }
            //新增
            else {
                Entity where = Entity.create(tableName);
                //formData 默认插入雪花Id主键
                keyValue = IdUtil.getSnowflakeNextId();

                //构建子表单数据
                //深拷贝一份表单数据 避免修改原表单数据
                Map<String, Object> newFormData = ObjectUtil.cloneIfPossible(formData);

                if (ObjectUtil.isNull(newFormData)) {
                    newFormData = new HashMap<>();
                }
                // 自动编码code
                List<String> autoCodeList = new ArrayList<>();
                Map<String, List<Map<String, Object>>> childFormData = wrapperChildEntity(datasource, tableConfigList, childMaps, newFormData, formDesignConfig, keyValue, autoCodeList);

                // 处理字段值
                Map<String, Object> toSaveFormData = handleFormDataForSave(newFormData, formDesignConfig, tableName, autoCodeList);
                toSaveFormData.put(pk.getName(), keyValue);
                formData.put(pk.getName(), keyValue);
                //此时的formData 已经是剔除了子表单数据了
                where.putAll(toSaveFormData);

                //如果有审计字段  默认填充值
                putAuditEntityInsertData(where, columns);

                Session session = Session.create(datasource);
                session.beginTransaction();
                // 保存主表数据
                session.insert(where);
                // 保存子表数据
                for (Map.Entry<String, List<Entity>> tableMap : childMaps.entrySet()) {
                    List<Entity> childList = tableMap.getValue();
                    session.insert(childList);
                    //工作流调用自定义表单方法 添加数据 必须需要这一行代码 构建之后的子表单数据 覆盖原formData 数据
                    formData.put(tableMap.getKey() + "List", childFormData.get(tableMap.getKey()));
                }
                codeRuleService.useEncode(autoCodeList);
                //返回值元组，  用于多返回值  left 为当前session middle 为false 代表新增 为true 代表更新  right为当前主表主键
                return new ImmutableTriple<>(session, false, keyValue);
            }


        } else {
            throw new MyException("主表不存在");
        }
    }

    /**
     * 根据配置信息获取不分页列表数据
     *
     * @param tableName         主表名
     * @param fieldsList        列表所有字段名
     * @param formDesignConfig  表单配置
     * @param formReleaseConfig 表单发布配置
     * @param params            入参
     * @return 列表数据
     */
    @SneakyThrows
    private List<Entity> getListDataByExpression(String tableName, List<String> fieldsList, FormDesignConfig formDesignConfig, FormReleaseConfig formReleaseConfig, Map<String, Object> params) {
        DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());

        //获取表里所有字段
        Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
        Collection<Column> columns = tableMeta.getColumns();
        Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
        Column pkColumn;

        if (pkOptional.isPresent()) {
            pkColumn = pkOptional.get();
            fieldsList.add(0, pkColumn.getName());
        } else {
            throw new MyException("主键不存在");
        }

        List<net.sf.jsqlparser.schema.Column> jsqlColumn = new ArrayList<>();
        for (String field : fieldsList) {
            jsqlColumn.add(new net.sf.jsqlparser.schema.Column(field));
        }
        Select select = SelectUtils.buildSelectFromTableAndExpressions(new net.sf.jsqlparser.schema.Table(tableName), jsqlColumn.toArray(new net.sf.jsqlparser.schema.Column[0]));
        PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); // 转换为更细化的Select对象

        List<QueryConfig> queryConfigs = formReleaseConfig.getListConfig().getQueryConfigs();

        //如果有左侧树 需要把所选项目 where 条件加上
        if (formReleaseConfig.getListConfig().getIsLeftMenu()) {
            //如果已经包含此字段  就不添加了
            if (queryConfigs.stream().noneMatch(x -> StrUtil.equals(x.getFieldName(), formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName()))) {
                QueryConfig queryConfig = new QueryConfig();
                queryConfig.setFieldName(formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName());
                queryConfig.setIsDate(false);
                queryConfigs.add(queryConfig);
            }

        }
        Expression queryExpression = null;

        //遍历所有查询条件
        for (QueryConfig queryConfig : queryConfigs) {

            //如果是日期类型 默认设置查询参数为两个
            if (queryConfig.getIsDate()) {
                //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
                String startTime = MapUtil.get(params, queryConfig.getFieldName() + GlobalConstant.START_TIME_SUFFIX, String.class);
                String endTime = MapUtil.get(params, queryConfig.getFieldName() + GlobalConstant.END_TIME_SUFFIX, String.class);

                //如果全都没有数据 则跳过
                if (startTime == null && endTime == null) {
                    continue;
                }

                if (startTime != null) {
                    GreaterThanEquals geq = new GreaterThanEquals(); // ">="
                    geq.setLeftExpression(new net.sf.jsqlparser.schema.Column(queryConfig.getFieldName() + GlobalConstant.START_TIME_SUFFIX));
                    geq.setRightExpression(new StringValue(startTime));

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = geq;
                    } else {
                        queryExpression = new AndExpression(queryExpression, geq);
                    }
                }

                if (endTime != null) {
                    MinorThanEquals leq = new MinorThanEquals();// "<="
                    leq.setLeftExpression(new net.sf.jsqlparser.schema.Column(queryConfig.getFieldName() + GlobalConstant.END_TIME_SUFFIX));
                    leq.setRightExpression(new StringValue(endTime));

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = leq;
                    } else {
                        queryExpression = new AndExpression(queryExpression, leq);
                    }
                }

            } else {

                Object value = MapUtil.get(params, queryConfig.getFieldName(), Object.class);
                //如果没有数据 则跳过
                if (value == null || StrUtil.isEmpty(String.valueOf(value))) {
                    continue;
                }

                //因为前端传入过来的key  默认都是驼峰命名  但是数据库里面的字段是下划线命名  需要转换一下 再判断是否存在
                Optional<Column> columnOptional = columns.stream().filter(column -> StrUtil.equalsIgnoreCase(column.getName(), queryConfig.getFieldName())).findFirst();

                if (!columnOptional.isPresent()) {
                    continue;
                }

                String className = JdbcToJavaUtil.getClassName(columnOptional.get());

                if (LIKE_CLASS_NAME.contains(className)) {

                    LikeExpression likeExpression = new LikeExpression(); // 创建Like表达式对象
                    likeExpression.setLeftExpression(new net.sf.jsqlparser.schema.Column(queryConfig.getFieldName()));
                    likeExpression.setRightExpression(new StringValue(StringPool.PERCENT + value + StringPool.PERCENT));

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = likeExpression;
                    } else {
                        queryExpression = new AndExpression(queryExpression, likeExpression);
                    }

                }

                if (EQ_CLASS_NAME.contains(className)) {
                    EqualsTo eq = new EqualsTo();
                    eq.setLeftExpression(new net.sf.jsqlparser.schema.Column(queryConfig.getFieldName()));
                    eq.setRightExpression(new StringValue(String.valueOf(value)));

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = eq;
                    } else {
                        queryExpression = new AndExpression(queryExpression, eq);
                    }
                }

                if (TIME_CLASS_NAME.contains(className)) {
                    //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
                    String startTime = MapUtil.get(params, queryConfig.getFieldName() + GlobalConstant.START_TIME_SUFFIX, String.class);
                    String endTime = MapUtil.get(params, queryConfig.getFieldName() + GlobalConstant.END_TIME_SUFFIX, String.class);

                    if (startTime != null) {
                        GreaterThanEquals geq = new GreaterThanEquals(); // ">="
                        geq.setLeftExpression(new net.sf.jsqlparser.schema.Column(queryConfig.getFieldName() + GlobalConstant.START_TIME_SUFFIX));
                        geq.setRightExpression(new StringValue(startTime));

                        //如果是第一个条件 直接赋值
                        if (ObjectUtil.isNull(queryExpression)) {
                            queryExpression = geq;
                        } else {
                            queryExpression = new AndExpression(queryExpression, geq);
                        }
                    }

                    if (endTime != null) {
                        MinorThanEquals leq = new MinorThanEquals();// "<="
                        leq.setLeftExpression(new net.sf.jsqlparser.schema.Column(queryConfig.getFieldName() + GlobalConstant.END_TIME_SUFFIX));
                        leq.setRightExpression(new StringValue(endTime));

                        //如果是第一个条件 直接赋值
                        if (ObjectUtil.isNull(queryExpression)) {
                            queryExpression = leq;
                        } else {
                            queryExpression = new AndExpression(queryExpression, leq);
                        }
                    }
                }

            }
        }

        //判断是否存在删除标记字段  如果带有删除标记字段则进行删除标记字段的判断
        if (columns.stream().anyMatch(column -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName()))) {
            EqualsTo eq = new EqualsTo();
            eq.setLeftExpression(new net.sf.jsqlparser.schema.Column(GlobalConstant.DELETE_MARK));
            eq.setRightExpression(new LongValue(DeleteMark.NODELETE.getCode()));

            //如果是第一个条件 直接赋值
            if (ObjectUtil.isNull(queryExpression)) {
                queryExpression = eq;
            } else {
                queryExpression = new AndExpression(queryExpression, eq);
            }
        }


        Expression dataAuthExpression = AuthorityUtil.getDataAuthExpressionByTableName(tableName, null);

        if (ObjectUtil.isNotNull(dataAuthExpression)) {
            if (queryExpression == null) {
                queryExpression = dataAuthExpression;
            } else {
                queryExpression = new AndExpression(queryExpression, dataAuthExpression);
            }
        }
        plainSelect.setWhere(queryExpression);

        //将所有查询的数据id 转string
        List<Entity> entities = DbUtil.use(datasource).query(plainSelect.toString());

        for (Entity entity : entities) {
            entity.set(pkColumn.getName(), entity.get(pkColumn.getName()).toString());
        }
        return entities;
    }


    /**
     * 根据配置信息获取不分页列表数据
     *
     * @param tableName         主表名
     * @param fieldsList        列表所有字段名
     * @param formDesignConfig  表单配置
     * @param formReleaseConfig 表单发布配置
     * @param params            入参
     * @return 列表数据
     */
    @SneakyThrows
    private List<Entity> getListData(String tableName, List<String> fieldsList, FormDesignConfig formDesignConfig, FormReleaseConfig formReleaseConfig, Map<String, Object> params) {
        DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());

        //获取表里所有字段
        Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
        Collection<Column> columns = tableMeta.getColumns();
        Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
        Column pkColumn;

        if (pkOptional.isPresent()) {
            pkColumn = pkOptional.get();
            fieldsList.add(0, pkColumn.getName());
        } else {
            throw new MyException("主键不存在");
        }

        Entity where = Entity.create(tableName).setFieldNames(fieldsList);

        List<QueryConfig> queryConfigs = formReleaseConfig.getListConfig().getQueryConfigs();


        //如果有左侧树 需要把所选项目 where 条件加上
        if (formReleaseConfig.getListConfig().getIsLeftMenu()) {
            //如果已经包含此字段  就不添加了
            if (queryConfigs.stream().noneMatch(x -> StrUtil.equals(x.getFieldName(), formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName()))) {
                QueryConfig queryConfig = new QueryConfig();
                queryConfig.setFieldName(formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName());
                queryConfig.setIsDate(false);
                queryConfigs.add(queryConfig);
            }

        }

        //遍历所有查询条件
        for (QueryConfig queryConfig : queryConfigs) {

            //如果是日期类型 默认设置查询参数为两个
            if (queryConfig.getIsDate()) {
                //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
                wrapperDateQuery(params, where, queryConfig);

            } else {

                Object value = params.get(queryConfig.getFieldName());
                //如果没有数据 则跳过
                if (value == null || StrUtil.isEmpty(String.valueOf(value))) {
                    continue;
                }

                //因为前端传入过来的key  默认都是驼峰命名  但是数据库里面的字段是下划线命名  需要转换一下 再判断是否存在
                Optional<Column> columnOptional = columns.stream().filter(column -> StrUtil.equalsIgnoreCase(StringUtils.underlineToCamel(column.getName()), queryConfig.getFieldName())).findFirst();

                //如果有这个字段 判断是属于什么java类型  然后设置查询参数
                columnOptional.ifPresent(column -> {
                    String className = JdbcToJavaUtil.getClassName(column);

                    wrapperPageQueryCondition(params, where, queryConfig, value, className);

                });


            }
        }

        //判断是否存在删除标记字段  如果带有删除标记字段则进行删除标记字段的判断
        if (columns.stream().anyMatch(column -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName()))) {
            where.set(GlobalConstant.DELETE_MARK, DeleteMark.NODELETE.getCode());
        }

        //将所有查询的数据id 转string
        List<Entity> entities = Db.use(datasource).find(where);

        for (Entity entity : entities) {
            entity.set(pkColumn.getName(), entity.get(pkColumn.getName()).toString());
        }
        return entities;
    }

    /**
     * 根据配置信息获取分页列表数据
     *
     * @param tableName         主表名
     * @param fieldsList        列表所有字段名
     * @param formDesignConfig  表单配置
     * @param formReleaseConfig 表单发布配置
     * @param params            入参
     * @param page              分页参数
     * @return 列表数据
     */
    @SneakyThrows
    private PageOutput<Entity> getPageDataByExpression(String tableName, Set<String> fieldsList, FormDesignConfig formDesignConfig, FormReleaseConfig formReleaseConfig, Map<String, Object> params, Page page) {
        DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
        //获取表里所有字段
        Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
        Collection<Column> columns = tableMeta.getColumns();

        Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
        Column pkColumn;

        if (pkOptional.isPresent()) {
            pkColumn = pkOptional.get();
            fieldsList.add(pkColumn.getName());
        } else {
            throw new MyException("主键不存在");
        }


        List<net.sf.jsqlparser.schema.Column> jsqlColumn = new ArrayList<>();
        for (String field : fieldsList) {
            jsqlColumn.add(new net.sf.jsqlparser.schema.Column(field));
        }
        Select select = SelectUtils.buildSelectFromTableAndExpressions(new net.sf.jsqlparser.schema.Table(tableName), jsqlColumn.toArray(new net.sf.jsqlparser.schema.Column[0]));
        PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); // 转换为更细化的Select对象

        List<QueryConfig> queryConfigs = formReleaseConfig.getListConfig().getQueryConfigs();

        //如果有左侧树 需要把所选项目 where 条件加上
        if (formReleaseConfig.getListConfig().getIsLeftMenu()) {
            //如果已经包含此字段  就不添加了
            if (queryConfigs.stream().noneMatch(x -> StrUtil.equals(x.getFieldName(), formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName()))) {
                QueryConfig queryConfig = new QueryConfig();
                queryConfig.setFieldName(formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName());
                queryConfig.setIsDate(false);
                queryConfigs.add(queryConfig);
            }

        }
        Expression queryExpression = null;

        //遍历所有查询条件
        for (QueryConfig queryConfig : queryConfigs) {
            String fieldName = queryConfig.getFieldName();
            //如果是日期类型 默认设置查询参数为两个
            if (queryConfig.getIsDate()) {
                //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
                String startTime = MapUtil.get(params, fieldName + GlobalConstant.START_TIME_SUFFIX, String.class);
                String endTime = MapUtil.get(params, fieldName + GlobalConstant.END_TIME_SUFFIX, String.class);

                //如果全都没有数据 则跳过
                if (startTime == null && endTime == null) {
                    continue;
                }
                Expression startRightExp = null;
                Expression endRightExp = null;
                Column queryColumn = columns.stream().filter(c -> StrUtil.equalsIgnoreCase(c.getName(), fieldName)).findFirst().get();
                JdbcType type = queryColumn.getTypeEnum();
                if (type == JdbcType.TIME) {
                    if (StrUtil.isNotEmpty(startTime)) startRightExp = new StringValue(startTime);
                    if (StrUtil.isNotEmpty(endTime)) endRightExp = new StringValue(endTime);
                } else if (type == JdbcType.DATE || type == JdbcType.TIMESTAMP) {
                    if (StrUtil.isNotEmpty(startTime))
                        startRightExp = new TimestampValue().withValue(Timestamp.valueOf(LocalDateTimeUtil.parseDateByLength(startTime)));
                    if (StrUtil.isNotEmpty(endTime))
                        endRightExp = new TimestampValue().withValue(Timestamp.valueOf(LocalDateTimeUtil.parseDateByLength(endTime)));
                } else if (StrUtil.equalsIgnoreCase(queryColumn.getTypeName(), OracleFieldsType.TIME.getType())) {
                    // oracle时间字段处理
                    if (StrUtil.isNotEmpty(startTime))
                        startRightExp = new StringValue(StringPool.ZERO + StringPool.SPACE + startTime);
                    if (StrUtil.isNotEmpty(endTime))
                        endRightExp = new StringValue(StringPool.ZERO + StringPool.SPACE + endTime);
                }
                if (startTime != null) {
                    GreaterThanEquals geq = new GreaterThanEquals(); // ">="
                    geq.setLeftExpression(new net.sf.jsqlparser.schema.Column(fieldName));
                    geq.setRightExpression(startRightExp == null ? new StringValue(startTime) : startRightExp);

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = geq;
                    } else {
                        queryExpression = new AndExpression(queryExpression, geq);
                    }
                }

                if (endTime != null) {
                    MinorThanEquals leq = new MinorThanEquals();// "<="
                    leq.setLeftExpression(new net.sf.jsqlparser.schema.Column(fieldName));
                    leq.setRightExpression(endRightExp == null ? new StringValue(endTime) : endRightExp);

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = leq;
                    } else {
                        queryExpression = new AndExpression(queryExpression, leq);
                    }
                }

            } else {

                Object value = MapUtil.get(params, fieldName, Object.class);
                //如果没有数据 则跳过
                if (value == null || StrUtil.isEmpty(String.valueOf(value))) {
                    continue;
                }

                //因为前端传入过来的key  默认都是驼峰命名  但是数据库里面的字段是下划线命名  需要转换一下 再判断是否存在
                Optional<Column> columnOptional = columns.stream().filter(column -> StrUtil.equalsIgnoreCase(column.getName(), fieldName)).findFirst();

                if (!columnOptional.isPresent()) {
                    continue;
                }

                String className = JdbcToJavaUtil.getClassName(columnOptional.get());

                if (LIKE_CLASS_NAME.contains(className)) {

                    LikeExpression likeExpression = new LikeExpression(); // 创建Like表达式对象
                    likeExpression.setLeftExpression(new net.sf.jsqlparser.schema.Column(fieldName));
                    likeExpression.setRightExpression(new StringValue(StringPool.PERCENT + value + StringPool.PERCENT));

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = likeExpression;
                    } else {
                        queryExpression = new AndExpression(queryExpression, likeExpression);
                    }

                }

                if (EQ_CLASS_NAME.contains(className)) {
                    EqualsTo eq = new EqualsTo();
                    eq.setLeftExpression(new net.sf.jsqlparser.schema.Column(fieldName));
                    eq.setRightExpression(new StringValue(String.valueOf(value)));

                    //如果是第一个条件 直接赋值
                    if (ObjectUtil.isNull(queryExpression)) {
                        queryExpression = eq;
                    } else {
                        queryExpression = new AndExpression(queryExpression, eq);
                    }
                }

                if (TIME_CLASS_NAME.contains(className)) {
                    //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
                    String startTime = MapUtil.get(params, fieldName + GlobalConstant.START_TIME_SUFFIX, String.class);
                    String endTime = MapUtil.get(params, fieldName + GlobalConstant.END_TIME_SUFFIX, String.class);

                    if (startTime != null) {
                        GreaterThanEquals geq = new GreaterThanEquals(); // ">="
                        geq.setLeftExpression(new net.sf.jsqlparser.schema.Column(fieldName + GlobalConstant.START_TIME_SUFFIX));
                        geq.setRightExpression(new StringValue(startTime));

                        //如果是第一个条件 直接赋值
                        if (ObjectUtil.isNull(queryExpression)) {
                            queryExpression = geq;
                        } else {
                            queryExpression = new AndExpression(queryExpression, geq);
                        }
                    }

                    if (endTime != null) {
                        MinorThanEquals leq = new MinorThanEquals();// "<="
                        leq.setLeftExpression(new net.sf.jsqlparser.schema.Column(fieldName + GlobalConstant.END_TIME_SUFFIX));
                        leq.setRightExpression(new StringValue(endTime));

                        //如果是第一个条件 直接赋值
                        if (ObjectUtil.isNull(queryExpression)) {
                            queryExpression = leq;
                        } else {
                            queryExpression = new AndExpression(queryExpression, leq);
                        }
                    }
                }

            }
        }

        //判断是否存在删除标记字段  如果带有删除标记字段则进行删除标记字段的判断
        if (columns.stream().anyMatch(column -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName()))) {
            EqualsTo eq = new EqualsTo();
            eq.setLeftExpression(new net.sf.jsqlparser.schema.Column(GlobalConstant.DELETE_MARK));
            eq.setRightExpression(new LongValue(DeleteMark.NODELETE.getCode()));

            //如果是第一个条件 直接赋值
            if (ObjectUtil.isNull(queryExpression)) {
                queryExpression = eq;
            } else {
                queryExpression = new AndExpression(queryExpression, eq);
            }
        }


        Expression dataAuthExpression = AuthorityUtil.getDataAuthExpressionByTableName(tableName, null);

        if (ObjectUtil.isNotNull(dataAuthExpression)) {
            if (queryExpression == null) {
                queryExpression = dataAuthExpression;
            } else {
                queryExpression = new AndExpression(queryExpression, dataAuthExpression);
            }
        }
        plainSelect.setWhere(queryExpression);
        Db use = Db.use(datasource);
        use.setRunner(new XjrSqlConnRunner(DialectFactory.getDialect(datasource)));
        PageResult<Entity> pageResult = use.page(plainSelect.toString(), page);

        //将所有查询的数据id 转string
        for (Entity entity : pageResult) {
            entity.set(pkColumn.getName(), entity.get(pkColumn.getName()).toString());
        }

        PageOutput<Entity> pageOutput = new PageOutput<>();
        pageOutput.setPageSize(pageResult.getPageSize());
        pageOutput.setCurrentPage(pageResult.getPage());
        pageOutput.setTotal(pageResult.getTotal());
        pageOutput.setList(pageResult);

        return pageOutput;
    }

    /**
     * 根据配置信息获取分页列表数据
     *
     * @param tableName         主表名
     * @param fieldsList        列表所有字段名
     * @param formDesignConfig  表单配置
     * @param formReleaseConfig 表单发布配置
     * @param params            入参
     * @param page              分页参数
     * @return 列表数据
     */
    @SneakyThrows
    private PageOutput<Entity> getPageData(String tableName, List<String> fieldsList, FormDesignConfig formDesignConfig, FormReleaseConfig formReleaseConfig, Map<String, Object> params, Page page) {
        DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());
        //获取表里所有字段
        Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
        Collection<Column> columns = tableMeta.getColumns();

        Optional<Column> pkOptional = columns.stream().filter(Column::isPk).findFirst();
        Column pkColumn;

        if (pkOptional.isPresent()) {
            pkColumn = pkOptional.get();
            fieldsList.add(0, pkColumn.getName());
        } else {
            throw new MyException("主键不存在");
        }
        Entity where = Entity.create(tableName).setFieldNames(fieldsList);

        List<QueryConfig> queryConfigs = formReleaseConfig.getListConfig().getQueryConfigs();

        //如果有左侧树 需要把所选项目 where 条件加上
        if (formReleaseConfig.getListConfig().getIsLeftMenu()) {
            //如果已经包含此字段  就不添加了
            if (queryConfigs.stream().noneMatch(x -> StrUtil.equals(x.getFieldName(), formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName()))) {
                QueryConfig queryConfig = new QueryConfig();
                queryConfig.setFieldName(formReleaseConfig.getListConfig().getLeftMenuConfig().getListFieldName());
                queryConfig.setIsDate(false);
                queryConfigs.add(queryConfig);
            }

        }

        //遍历所有查询条件
        for (QueryConfig queryConfig : queryConfigs) {

            //如果是日期类型 默认设置查询参数为两个
            if (queryConfig.getIsDate()) {
                wrapperDateQuery(params, where, queryConfig);

            } else {

                Object value = params.get(queryConfig.getFieldName());
                //如果没有数据 则跳过
                if (value == null || StrUtil.isEmpty(String.valueOf(value))) {
                    continue;
                }

                //因为前端传入过来的key  默认都是驼峰命名  但是数据库里面的字段是下划线命名  需要转换一下 再判断是否存在
                Optional<Column> columnOptional = columns.stream().filter(column -> StrUtil.equalsIgnoreCase(column.getName(), queryConfig.getFieldName())).findFirst();

                //如果有这个字段 判断是属于什么java类型  然后设置查询参数
                columnOptional.ifPresent(column -> {
                    String className = JdbcToJavaUtil.getClassName(column);

                    wrapperPageQueryCondition(params, where, queryConfig, value, className);

                });


            }
        }

        //判断是否存在删除标记字段  如果带有删除标记字段则进行删除标记字段的判断
        if (columns.stream().anyMatch(column -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName()))) {
            where.set(GlobalConstant.DELETE_MARK, DeleteMark.NODELETE.getCode());
        }
        PageResult<Entity> pageResult = Db.use(datasource).page(where, page);

        //将所有查询的数据id 转string
        for (Entity entity : pageResult) {
            entity.set(pkColumn.getName(), entity.get(pkColumn.getName()).toString());
        }
        PageOutput<Entity> pageOutput = new PageOutput<>();
        pageOutput.setPageSize(pageResult.getPageSize());
        pageOutput.setCurrentPage(pageResult.getPage());
        pageOutput.setTotal(pageResult.getTotal());
        pageOutput.setList(pageResult);

        return pageOutput;
    }

    /**
     * 根据配置信息获取表单数据
     *
     * @param tableName        主表名
     * @param fieldsList       列表所有字段名
     * @param formDesignConfig 表单配置
     * @param keyValue         主键
     * @return 列表数据
     */
    @SneakyThrows
    private Entity getFormData(String tableName, List<String> fieldsList, FormDesignConfig formDesignConfig, String keyValue) {
        //获取表关系配置
        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //获取表结构配置 (因为要根据子表的字段配置 返回需要的数据)
        List<TableStructureConfig> tableStructureConfigs = formDesignConfig.getTableStructureConfigs();

        DataSource datasource = DatasourceUtil.getDataSource(formDesignConfig.getDatabaseId());


        //获取表里所有字段
        Table tableMeta = MetaUtil.getTableMeta(datasource, tableName);
        Collection<Column> columns = tableMeta.getColumns();
        Optional<Column> pk = columns.stream().filter(Column::isPk).findFirst();

        if (!pk.isPresent()) {
            throw new MyException("表" + tableName + "没有主键");
        }
        //把主键加入到查询项目
        fieldsList.add(pk.get().getName());
        Entity where = Entity.create(tableName).setFieldNames(fieldsList);
        // 转行id类型
        Object id = keyValue;
        if (StrUtil.equalsIgnoreCase(JdbcToJavaUtil.getClassName(pk.get()), "Long")) {
            id = Long.parseLong(keyValue);
        }
        where.set(pk.get().getName(), id);

        //判断是否存在删除标记字段  如果带有删除标记字段则进行删除标记字段的判断
        if (columns.stream().anyMatch(column -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName()))) {
            where.set(GlobalConstant.DELETE_MARK, DeleteMark.NODELETE.getCode());
        }
        GlobalDbConfig.setCaseInsensitive(false);
        Entity formData = Db.use(datasource).find(where.getFieldNames(), where, new XjrEntityHandler());

        //遍历所有子表
        List<TableConfig> tableConfigList = tableConfigs.stream().filter(x -> !x.getIsMain()).collect(Collectors.toList());

        for (TableConfig tableConfig : tableConfigList) {
            Optional<TableStructureConfig> tableStructureConfigOptional = tableStructureConfigs.stream().filter(y -> StrUtil.equalsIgnoreCase(y.getTableName(), tableConfig.getTableName())).findFirst();
            if (tableStructureConfigOptional.isPresent()) {
                TableStructureConfig tableStructureConfig = tableStructureConfigOptional.get();
                List<TableFieldConfig> tableFieldConfigs = tableStructureConfig.getTableFieldConfigs();
                String childTableName = tableStructureConfig.getTableName();
                List<String> childTableFields = tableFieldConfigs.stream().map(TableFieldConfig::getFieldName).collect(Collectors.toList());
                Entity childWhere = Entity.create(childTableName).setFieldNames(childTableFields);

                //获取子表关联主表的关联字段
                Object parentValue = formData.get(tableConfig.getRelationTableField());
                //默认新增条件 子表关联字段 = 主表的关联字段
                childWhere.set(tableConfig.getRelationField(), parentValue);

                //判断是否存在删除标记字段  如果带有删除标记字段则进行删除标记字段的判断
                Table childTableMeta = MetaUtil.getTableMeta(datasource, childTableName);
                Collection<Column> childColumns = childTableMeta.getColumns();

                if (childColumns.stream().anyMatch(column -> StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName()))) {
                    childWhere.set(GlobalConstant.DELETE_MARK, DeleteMark.NODELETE.getCode());
                }

                List<Entity> childList = Db.use(datasource).find(childWhere, new XjrEntityListHandler());

                formData.set(childTableName + "List", childList);
            }
        }

        return formData;
    }

    /**
     * 填充审计字段 新增
     *
     * @param entity
     * @param columns
     */
    private void putAuditEntityInsertData(Entity entity, Collection<Column> columns) {
        for (Column column : columns) {
            if (StrUtil.equalsIgnoreCase(GlobalConstant.CREATE_USER_ID, column.getName())) {
                entity.set(GlobalConstant.CREATE_USER_ID, StpUtil.getLoginIdAsLong());
            }
            if (StrUtil.equalsIgnoreCase(GlobalConstant.CREATE_DATE, column.getName())) {
                entity.set(GlobalConstant.CREATE_DATE, Timestamp.valueOf(LocalDateTime.now()));
            }
            if (StrUtil.equalsIgnoreCase(GlobalConstant.DELETE_MARK, column.getName())) {
                entity.set(GlobalConstant.DELETE_MARK, DeleteMark.NODELETE.getCode());
            }
            if (StrUtil.equalsIgnoreCase(GlobalConstant.ENABLED_MARK, column.getName())) {
                entity.set(GlobalConstant.ENABLED_MARK, EnabledMark.ENABLED.getCode());
            }
            if (StrUtil.equalsIgnoreCase(GlobalConstant.AUTH_USER_ID, column.getName())) {
                entity.set(GlobalConstant.AUTH_USER_ID, StpUtil.getLoginIdAsLong());
            }
        }
    }

    /**
     * 填充审计字段 修改
     *
     * @param entity
     * @param columns
     */
    private void putAuditEntityUpdateData(Entity entity, Collection<Column> columns) {
        for (Column column : columns) {
            if (StrUtil.equalsIgnoreCase(GlobalConstant.MODIFY_USER_ID, column.getName())) {
                entity.set(GlobalConstant.MODIFY_USER_ID, StpUtil.getLoginIdAsLong());
            }
            if (StrUtil.equalsIgnoreCase(GlobalConstant.MODIFY_DATE, column.getName())) {
                entity.set(GlobalConstant.MODIFY_DATE, Timestamp.valueOf(LocalDateTime.now()));
            }
        }
    }

    /**
     * 新增数据时候 构建子表单Entity
     *
     * @param datasource
     * @param tableConfigList
     * @param childMaps
     * @param formData
     */
    private Map<String, List<Map<String, Object>>> wrapperChildEntity(DataSource datasource, List<TableConfig> tableConfigList,
                                                                      Map<String, List<Entity>> childMaps, Map<String, Object> formData,
                                                                      FormDesignConfig formDesignConfig, Object keyValue, List<String> autoCodeList) {

        Map<String, List<Map<String, Object>>> childFormData = new HashMap<>();

        for (TableConfig tableConfig : tableConfigList) {

            //获取表里所有字段
            Table childTableMeta = MetaUtil.getTableMeta(datasource, tableConfig.getTableName());
            Collection<Column> childColumns = childTableMeta.getColumns();

            Optional<Column> childPkOptional = childColumns.stream().filter(Column::isPk).findFirst();

            List<Map<String, Object>> childMap = new ArrayList<>();
            List<Map<String, Object>> resultMap = new ArrayList<>();

            Class<List<Map<String, Object>>> childMapClass = ClassUtil.getClass(childMap);
            //获取子表的数据
            childMap = MapUtil.get(formData, tableConfig.getTableName() + "List", childMapClass);

            List<Entity> childEntities = new ArrayList<>();
            for (Map<String, Object> stringObjectMap : childMap) {
                Map<String, Object> handedMap = handleFormDataForSave(stringObjectMap, formDesignConfig, tableConfig.getTableName(), autoCodeList);
                Entity entity = Entity.create(tableConfig.getTableName());
                entity.putAll(handedMap);

                //获取子表关联主表的关联字段
                Object parentValue = formData.get(tableConfig.getRelationTableField());
                //默认新增条件 子表关联字段 = 主表的关联字段
                entity.set(tableConfig.getRelationField(), parentValue);

                //填充子表主键
                childPkOptional.ifPresent(pk -> {
                    long snowflakeNextId = IdUtil.getSnowflakeNextId();
                    entity.put(pk.getName(), snowflakeNextId);
                    handedMap.put(pk.getName(), snowflakeNextId);

                    if (ObjectUtil.isNotEmpty(keyValue)) {
                        //将子表的parent_id,赋值为主表的主键值
                        entity.put(tableConfig.getRelationField(), keyValue);
                        handedMap.put(tableConfig.getRelationField(), keyValue);
                    }
                });
                resultMap.add(handedMap);


                //如果有审计字段  默认填充值
                putAuditEntityInsertData(entity, childColumns);

                childEntities.add(entity);
            }

            //获取到子表的所有数据
            childMaps.put(tableConfig.getTableName(), childEntities);
            childFormData.put(tableConfig.getTableName(), resultMap);

            //移除Map中 子表的数据  避免sql错误；
            MapUtil.removeAny(formData, tableConfig.getTableName() + "List");
        }

        return childFormData;
    }


    /**
     * 分页查询时间  构建查询条件
     *
     * @param params
     * @param where
     * @param queryConfig
     * @param value
     * @param className
     */
    private void wrapperPageQueryCondition(Map<String, Object> params, Entity where, QueryConfig queryConfig, Object value, String className) {
        if (LIKE_CLASS_NAME.contains(className)) {
            where.set(queryConfig.getFieldName(), new Condition(queryConfig.getFieldName(), String.valueOf(value), Condition.LikeType.Contains));
        }

        if (EQ_CLASS_NAME.contains(className)) {
            where.set(queryConfig.getFieldName(), new Condition(queryConfig.getFieldName(), String.valueOf(value), Condition.LikeType.Contains));
        }

        if (TIME_CLASS_NAME.contains(className)) {
            //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
            Object startTime = params.get(queryConfig.getFieldName() + "Start");
            Object endTime = params.get(queryConfig.getFieldName() + "End");

            if (startTime != null) {
                where.set(queryConfig.getFieldName() + "Start", new Condition(queryConfig.getFieldName(), ">=", startTime));
            }

            if (endTime != null) {
                where.set(queryConfig.getFieldName() + "End", new Condition(queryConfig.getFieldName(), "<=", startTime));
            }
        }
    }

    /**
     * 构建时间查询条件
     *
     * @param params
     * @param where
     * @param queryConfig
     */
    private void wrapperDateQuery(Map<String, Object> params, Entity where, QueryConfig queryConfig) {
        //根据查询配置的字段名 从参数里面找到对应的值  如果是时间类型 需要查询start 和 end
        Object startTime = params.get(queryConfig.getFieldName() + "Start");
        Object endTime = params.get(queryConfig.getFieldName() + "End");

        //如果全都没有数据 则跳过
        if (startTime == null && endTime == null) {
            return;
        }

        if (startTime != null) {
            where.set(queryConfig.getFieldName() + "Start", new Condition(queryConfig.getFieldName(), ">=", startTime));
        }

        if (endTime != null) {
            where.set(queryConfig.getFieldName() + "End", new Condition(queryConfig.getFieldName(), "<=", startTime));
        }
    }

    /**
     * 处理保存的表单数据
     *
     * @param formData
     * @param formDesignConfig
     */
    private Map<String, Object> handleFormDataForSave(Map<String, Object> formData, FormDesignConfig formDesignConfig,
                                                      String tableName, List<String> autoCodeList) {
        Map<String, Object> resultData = new HashMap<>(formData.size());
        Map<String, List<ComponentConfig>> componentListMap = GeneratorUtil.buildFormComponentList(formDesignConfig.getFormJson().getList());
        List<ComponentConfig> configList = componentListMap.get(tableName);
        Set<String> fieldNameList = formData.keySet();
        DbType dbType = DatasourceUtil.getDbType(formDesignConfig.getDatabaseId());
        for (ComponentConfig config : configList) {
            Map<String, Object> options = config.getOptions();
            if (MapUtils.getBoolean(options, "isSave", false)) {
                continue;
            }
            String bindField = config.getBindField();
            String bindStartTimeField = config.getBindStartTime();
            String bindEndTimeField = config.getBindEndTime();
            boolean isMatch = false;
            for (String fieldName : fieldNameList) {
                if (StrUtil.equalsIgnoreCase(fieldName, bindField)
                        || StrUtil.equalsIgnoreCase(fieldName, bindStartTimeField)
                        || StrUtil.equalsIgnoreCase(fieldName, bindEndTimeField)) {
                    resultData.put(fieldName, formData.get(fieldName));
                    isMatch = true;
                }
            }
            if (!isMatch) continue;
            String type = config.getType();
            String format = MapUtils.getString(options, "format");
            if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.TIME)) {
                Object timeObj = MapUtils.getObject(formData, bindField);
                if (timeObj instanceof String) {
                    resultData.put(bindField, LocalDateTimeUtil.parseDbTime(String.valueOf(timeObj), dbType));
                } else if (timeObj instanceof LocalTime) {
                    resultData.put(bindField, timeObj);
                } else {
                    resultData.put(bindField, null);
                }
            } else if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.TIME_RANGE)) {
                Object start = MapUtils.getObject(formData, bindStartTimeField);
                Object end = MapUtils.getObject(formData, bindEndTimeField);
                if (ObjectUtil.isNotEmpty(start)) {
                    if (start instanceof String) {
                        resultData.put(bindStartTimeField, LocalDateTimeUtil.parseDbTime(String.valueOf(start), dbType));
                    } else {
                        resultData.put(bindStartTimeField, start);
                    }
                } else {
                    resultData.put(bindStartTimeField, null);
                }
                if (ObjectUtil.isNotEmpty(end)) {
                    if (end instanceof String) {
                        resultData.put(bindEndTimeField, LocalDateTimeUtil.parseDbTime(String.valueOf(end), dbType));
                    } else {
                        resultData.put(bindEndTimeField, end);
                    }
                } else {
                    resultData.put(bindEndTimeField, null);
                }
            } else if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.DATE)) {
                Object valueStr = MapUtils.getObject(formData, bindField);
                if (ObjectUtil.isNotEmpty(valueStr)) {
                    resultData.put(bindField, valueStr instanceof LocalDateTime ? valueStr : DateTimeUtil.parseDate(LocalDateTimeUtil.parseDate(String.valueOf(valueStr), format).toString()));
                } else {
                    resultData.put(bindField, null);
                }
            } else if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.DATE_RANGE)) {
                Object start = MapUtils.getObject(formData, bindStartTimeField);
                Object end = MapUtils.getObject(formData, bindEndTimeField);
                if (ObjectUtil.isNotEmpty(start)) {
                    resultData.put(bindStartTimeField, start instanceof LocalDateTime ? start : DateTimeUtil.parseDate(LocalDateTimeUtil.parseDate(String.valueOf(start), format).toString()));
                } else {
                    resultData.put(bindStartTimeField, null);
                }
                if (ObjectUtil.isNotEmpty(end)) {
                    resultData.put(bindEndTimeField, end instanceof LocalDateTime ? end : DateTimeUtil.parseDate(LocalDateTimeUtil.parseDate(String.valueOf(end), format).toString()));
                } else {
                    resultData.put(bindEndTimeField, null);
                }
            } else if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.AUTO_CODE)) {
                if (autoCodeList != null)
                    autoCodeList.add(MapUtils.getString(options, ComponentTypeConstant.AUTO_CODE_RULE));
            }
        }
        return resultData;
    }


    public PageOutput<Entity> pageTrans(FormExecutePageDto dto) {

        FormRelease formRelease = formReleaseMapper.selectById(dto.getReleaseId());


        String configJson = formRelease.getConfigJson();

        //发布配置
        FormReleaseConfig formReleaseConfig = JSONUtil.toBean(configJson, FormReleaseConfig.class);

        //自定义表单数据
        FormTemplate template = formTemplateMapper.selectById(formRelease.getFormId());

        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);

        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();

        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();

            //构建分页参数
            Page page = new Page(dto.getLimit() - 1, dto.getSize());
            String field = dto.getField();
            String orderStr = dto.getOrder();
            ListConfig listConfig = formReleaseConfig.getListConfig();
            if (StrUtil.isBlank(field)) {
                field = StrUtil.emptyToDefault(listConfig.getOrderBy(), tableConfig.getPkField());
                orderStr = StrUtil.emptyToDefault(listConfig.getOrderType(), "desc");
            }
            if (StrUtil.isNotBlank(field)) {
                Order order = new Order();
                order.setDirection(StrUtil.equalsIgnoreCase(orderStr, "desc") ? Direction.DESC : Direction.ASC);
                order.setField(field);
                page.setOrder(order);
            }

            List<ColumnConfig> columnConfigs = listConfig.getColumnConfigs();
            Set<String> fieldsList = columnConfigs.stream().map(ColumnConfig::getColumnName).collect(Collectors.toSet());
            // 添加权限所属人字段返回
            if (BooleanUtils.isTrue(formDesignConfig.getIsDataAuth())) {
                fieldsList.add(GlobalConstant.AUTH_USER_ID);
            }

            PageOutput<Entity> pageData = getPageDataByExpression(tableName, fieldsList, formDesignConfig, formReleaseConfig, dto.getParams(), page);
            if (dto.getIsTrans()) {
                // 关联数据显示转换
                FormDataTransUtil.transDataOver(pageData.getList(), formDesignConfig);
            }
            return pageData;
        } else {
            throw new MyException("主表不存在");
        }
    }


    @Override
    public DeskTableInfoVo getTableInfo(Long formId) {
        FormTemplate template = formTemplateMapper.selectById(formId);
        String formJson = template.getFormJson();
        //自定义表单配置
        FormDesignConfig formDesignConfig = JSONUtil.toBean(formJson, FormDesignConfig.class);

        List<TableConfig> tableConfigs = formDesignConfig.getTableConfigs();
        //主表
        Optional<TableConfig> mainTable = tableConfigs.stream().filter(TableConfig::getIsMain).findFirst();
        DeskTableInfoVo deskTableInfoVo = new DeskTableInfoVo();
        List<DeskColumnsVo> myColumnInfos = new ArrayList<>();
        if (mainTable.isPresent()) {
            TableConfig tableConfig = mainTable.get();
            String tableName = tableConfig.getTableName();
            //获取字段名
            DataSource dataSource = DatasourceUtil.getDatasourceMaster();
            Table tableMeta = MetaUtil.getTableMeta(dataSource, tableName);
            Collection<Column> columns = tableMeta.getColumns();
            Optional<Column> pk = columns.stream().filter(Column::isPk).findFirst();
            if (!pk.isPresent()) {
                throw new MyException("表" + tableName + "没有主键");
            }
            deskTableInfoVo.setPkName(pk.get().getName());
            for (Column column : columns) {
                DeskColumnsVo myColumnInfo = new DeskColumnsVo();
                myColumnInfo.setLabel(column.getComment());
                myColumnInfo.setProp(column.getName());
                myColumnInfos.add(myColumnInfo);

                DeskColumnsVo myColumnInfo1 = new DeskColumnsVo();
                if (!column.getName().equals(pk.get().getName())) {
                    myColumnInfo1.setLabel(column.getComment() + StringPool.UNDERSCORE + "接口");
                    myColumnInfo1.setProp(column.getName() + StringPool.UNDERSCORE + "api");
                    myColumnInfos.add(myColumnInfo1);
                }

            }
            deskTableInfoVo.setDeskColumnsVoList(myColumnInfos);
        } else {
            throw new MyException("主表不存在");
        }
        return deskTableInfoVo;
    }

}
