package org.example.Utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.bytedeco.flycapture.FlyCapture2.TimeStamp;
import org.example.Entity.Control.Container.FieldSet;
import org.example.Entity.Control.Container.RowColumn;
import org.example.Entity.Control.Data.DataStore;
import org.example.Entity.Control.Fields.*;
import org.example.Entity.System.BaseModule;
import org.example.Entity.System.LoginUserInfo;
import org.example.Entity.System.ModuleEntity;
import org.example.Enums.SystemEnums;
import org.example.Enums.SystemTypeEnums;
import org.example.Impl.BaseImpl;
import org.example.Impl.DataImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.example.Utils.NativeExtensionUtils.*;

/* ==============================================================================
 * 功能描述：公共逻辑业务
 * 修改人：
 * 修改日期：
 * 修改备注：无
 * 版本：1.0.0.0
 * ==============================================================================*/
@Component
public class IPublicUtil extends BaseImpl {
    private static final Logger log = LoggerFactory.getLogger(IPublicUtil.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public IPublicUtil() {
    }

    @Autowired
    public IPublicUtil(JdbcTemplate jdbcTemplate) {
        setJdbcTemplate(jdbcTemplate);
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        super.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void setDbOperator(DbOperator dbOperator) {
        super.setDbOperator(dbOperator);
        if (dbOperator != null) {
            setJdbcTemplate(dbOperator.getJdbcTemplate());
        }
    }

    /**
     * /// <summary>
     * /// 创建具体控件
     * /// </summary>
     * /// <param name="row">控件行数据</param>
     * /// <param name="dlltab">The dlltab</param>
     * /// <returns>Component</returns>
     * /// <remarks>
     * /// </remarks>
     **/
    public Field createControl(Map<String, Object> row, ModuleEntity module, Boolean createEditor) {
        Field myControl = new Field(row);
        Boolean disabled = NativeExtensionUtils.toBoolean(DataTableUtil.getRowVal(row, "Disabled2", false));
        Map<String, Object> leftRecord = module != null ? module.getLeftRecord() : null;
        ModuleEntity parentModuel = module != null ? module.ParentModule : null;
        if (module != null && module.PopPms != null) {
            if (leftRecord == null) {
                leftRecord = module.PopPms;
            } else if (!leftRecord.equals(module.PopPms)) {
                // 合并 PopPms 到 leftRecord
                Map<String, Object> pms = module.PopPms;
                Map<String, Object> leftRecordMap = leftRecord;
                for (Map.Entry<String, Object> entry : pms.entrySet()) {
                    leftRecordMap.put(entry.getKey().toLowerCase(), entry.getValue());
                }
                leftRecord = leftRecordMap;
            }
        }

        String fieldTypeId = DataTableUtil.getRowVal(row, "FieldType", "0") + "";
        SystemEnums.ControlType fieldType = null;
        try {
            int typeValue = Integer.parseInt(fieldTypeId);
            fieldType = SystemEnums.ControlType.fromValue(typeValue);
        } catch (IllegalArgumentException e) {
            // 处理无法解析的枚举值
            log.warn(String.valueOf("无法解析的 ControlType: " + fieldTypeId));
        }

        if (fieldType == null) {
            // 若无法解析枚举值，可返回空 Map 或抛出异常，这里返回空 Map
            return null;
        }

        String format = NativeExtensionUtils.getStringValue(row, "dataformat", "0");
        if (format.isEmpty()) {
            format = PublicUtil.GetFormatByCType(fieldType);
        }
//        out.println(fieldType + " fieldTypeId= " + fieldTypeId);
        ComboBox _myControl = null;
        switch (fieldType) {
            case LabComboxValue: // 下拉框控件  获取Value值
            case LabComboxText:  // 下拉框控件  获取Text值
            case LabAutoCompleteValue: //自动筛选框 获取Value值
            case LabAutoCompleteText: // 自动筛选框 获取Text值
            case LabComboxValueParam://搜索框返回ID-带参数
            case LabComboxTextParam://搜索框返回文本-带参数
            case LabMultiSelectValue://多选，获取Value
            case LabMultiSelectText://多选，获取Text
            case LabCheckAutoSeacherValue://搜索框返回文本-带复选框参数
            case LabCheckAutoSeacherText://搜索框返回文本-带复选框参数
            case LabAutoCompleteValueParam://搜索框返回文本-带参数
            case LabAutoCompleteTextParam://搜索框返回文本-带参数
            case LabMultiSelectValueParam:// 多选 获取Value值,需要带参数
            case LabMultiSelectTextParam:// 多选 获取Text值,需要带参数
            case LabCheckComboxValue: // 下拉框控件带复选框  获取Value值
            case LabCheckComboxText:  // 下拉框控件带复选框  获取Text值
            case LabSmartQueryReturnID://智能搜索返回ID
            case LabSmartQueryReturnName://智能搜索返回Name
            case LabSmartQueryReturnIDWithParam://智能搜索返回ID 带参数
            case LabSmartQueryReturnNameWithParam://智能搜索返回Name 带参数
            case LabComboxModuleValueParam://智能搜索返回ID 带参数
            case LabComboxModuleTextParam://智能搜索返回Name 带参数
            case LabComTreeboxValue: // 下拉树返回value
            case LabComTreeboxText: // 下拉树返回text
            case LabComTreeboxValueParam: // 下拉树返回value带参数
            case LabComTreeboxTextParam: // 下拉树返回text带参数
            case LabComTreeboxLeafValue: // 下拉树返回末级value
            case LabComTreeboxLeafText: // 下拉树返回末级text带
            case LabComTreeboxLeafValueParam: // 下拉树返回末级value带参数
            case LabComTreeboxLeafTextParam: // 下拉树返回末级text带参数
            case LabMultiComTreeboxLeafValue: // 下拉树多返回末级value
            case LabMultiComTreeboxLeafText: // 下拉树多返回末级text带
            case LabMultiComTreeboxLeafValueParam: // 下拉树多返回末级value带参数
            case LabMultiComTreeboxLeafTextParam: // 下拉树多返回末级text带参数
            case LabMultiComTreeboxValue: // 下拉树多返回value
            case LabMultiComTreeboxText: // 下拉树多返回text
            case LabMultiComTreeboxValueParam: // 下拉树多返回value带参数
            case LabMultiComTreeboxTextParam: // 下拉树多返回text带参数
            case LabRadioGroupValue: //单选框组数
            case LabRadioGroupText: //单选框组
            case CheckboxGroupValue: //多选框组
            case CheckboxGroupText: //多选框组
            case LabWinBtnsValue: //单选框组数
            case LabWinBtnsText: //单选框组
            case LabWinMultiBtnsValue: //多选框组
            case LabWinMultiBtnsText: //多选框组
            case LabWinGridValue: //单选框组数
            case LabWinGridText: //单选框组
            case LabWinMultiGridValue: //多选框组
            case LabWinMultiGridText: //多选框组
            case LabComStarValueParam: //多选框组
            case LabComStarTextParam: //多选框组
            case LabModuleSelectValues:
            case LabModuleMultiSelectValues:
                _myControl = new ComboBox(row);
//                myControl.putAll(row);
//                myControl.put("xtype", "combobox");
                String dataSource = _myControl.getDataSource();
                String displayField = _myControl.getDisplayField();
                String valueField = _myControl.getValueField();
                if (dataSource == null || dataSource.isEmpty() || (displayField == null && valueField == null)) {
                    myControl = new TextField(row);
                    break;
                }
                if (module != null && module.PopPms != null) {
                    _myControl.setPopPms(module.PopPms);
                }
                myControl = SetBoxPro(_myControl, row, fieldType, module);
                break;
            case LabTreeType:// 树控件
                if (!isWindowsDirver()) {
                    _myControl = new ComboBox(row);
                    dataSource = _myControl.getDataSource();
                    displayField = _myControl.getDisplayField();
                    valueField = _myControl.getValueField();
                    log.debug(String.valueOf("LabTreeType" + (isNullOrEmpty(dataSource) || (isNullOrEmpty(displayField) && isNullOrEmpty(valueField)))));
                    if (isNullOrEmpty(dataSource) || (isNullOrEmpty(displayField) && isNullOrEmpty(valueField))) {
                        myControl = new Hidden(row);
                        break;
                    }
                    _myControl.setPopPms(module != null ? module.PopPms : null);//右键参数
                    myControl = SetBoxPro(_myControl, row, fieldType, module);
                    log.debug(String.valueOf(myControl + " LabTreeType"));
                    break;
                }
                myControl = new Hidden(row);
                String dataSourceStr = myControl.getDataSource();
                if (dataSourceStr != null && dataSourceStr.indexOf("0 _hidden") > -1) {
                    myControl = new TextField(row);
                }
                break;
            case LabDate:   // 日期控件
            case LabCheckDateEx:
            case LabDateTime:
            case LabCheckDateTimeShort:
            case LabDateTimeShort:
            case LabTime:
            case LabCheckTime:
            case LabShortTime:
            case LabCheckShortTime:
            case LabYearTime:
                if (format.equals("0") || format.isEmpty()) {
                    format = GetFormatByCType(fieldType);
                }
                myControl = new DateField(row);
                myControl.setFormat(format);
                break;
            case LabPassword:    // 数字控件
                myControl = new TextField(row);
                ((TextField) myControl).setType("password");
                break;
            case LabTextInt:    // 数字控件
                myControl = new NumberField(row);
                break;
            case LabMemoEdit: // 多文本框控件
                myControl = new TextField(row);
                ((TextField) myControl).setType("triggertextarea");
                break;
            case LabRemark: // 多文本框控件
                myControl = new TextareaField(row);
                ((TextareaField) myControl).setAutoHeight(true);
                break;
            case LabJointRemark: // 多文本框控件
                myControl = new TextareaField(row);
                ((TextareaField) myControl).setType("jointTextAreaField");
                break;
            case LabRichEdit: // 富文本框控件
                myControl = new TextareaField(row);
                ((TextareaField) myControl).setType("textareaEditor");
                break;
            case LabMap: // 地图控件
                myControl = new MapLocationField(row);
                ((MapLocationField) myControl).setGlyph("xf041@FontAwesome");
                if (module != null && module.getMasterTable() != null && !module.getMasterTable().isEmpty()) {
                    updateMapField(module.getMasterTable(), myControl.getName());
                }
                myControl = new MapLocationField(row);
                break;
            case LabCheckBox:
                myControl = new Checkbox(row);
                break;
            case LabPic:   // 文件控件
            case LabPicEx:   // 图片控件
                myControl = new ImageFiled(row);
                myControl.setXtype("field.upload");
                break;
            case LabCalcText:
                myControl = new Field(row);
                myControl.setXtype("calculatorField");
                break;
            case LabVPhone:
                myControl = new Field(row);
                myControl.setXtype("vphonefield");
                break;
            case LabPhone:
                myControl = new Field(row);
                myControl.setXtype("field.phone");
                break;
            case LabOSacn:
            case LabTSacn:
                myControl = new Field(row);
                myControl.setXtype("scanfield");
                break;
            case LabSignature:
                myControl = new Field(row);
                myControl.setXtype("signaturefield");
                break;
            case LabEleScale:
                myControl = new Field(row);
                myControl.setXtype("eleScale");
                break;
            case ApiLabText:
                myControl = new TextField(row);
                myControl.setXtype("apifield");
                dataSource = myControl.getDataSource();
                if (dataSource != null && (dataSource.startsWith("http") || dataSource.startsWith("/"))) {
                    myControl.store = new DataStore();
                    myControl.store.url = (dataSource);
                    String defaultSource = myControl.getDefaultsource();
                    if (defaultSource != null && defaultSource.startsWith("{") && defaultSource.endsWith("}")) {
                        myControl.store.ApiDataNode = (defaultSource.substring(1, defaultSource.length() - 1));
                    }
                }
                break;
            default:  // 文本框控件
                myControl = new TextField(row);
                myControl.setXtype("textfield");
                break;
        }

//        out.println("myControl1 " + JSON.Encode(myControl));

        Field field = myControl;
        // 处理默认值和其他属性
        String defaultSource = field.getDefaultsource();

        if (isNullOrEmpty(defaultSource)
                && fieldType == SystemEnums.ControlType.LabTreeType
                && field.getDataSource() != null && !field.getDataSource().isEmpty()
                && module != null && module.getLeftRecord() != null) {
            // 假设 GetTreeSpecNo 方法存在
//            out.println("GetTreeSpecNo 1");
            field.setDefaultval(GetTreeSpecNo(module.getMasterTable(), field.getName(), field.getValueField(), field.getDataSource(), Objects.toString(leftRecord.get(field.getValueField()), ""), null, 0));
//            out.println("GetTreeSpecNo 2");

        } else {
            // 假设 GetDefaultValue 方法存在
            field.setDefaultval(GetDefaultValue(defaultSource, module, SystemTypeEnums.PmType.store));
        }


        if (module != null) {
            if (module instanceof BaseModule) {
                BaseModule baseModule = (BaseModule) module;
                field.PopupHeight = baseModule.getPopupHeight();
                field.PopupWidth = baseModule.getPopupWidth();
            }
            field.setPopPms(module.PopPms);
            if (module.getLeftRecord() != null && field.getDefaultval() == null) {
                if ("speciesname".equals(field.getName())) {
                }
            }
            if (module.Updrow != null) {
                // 假设 SetDefaultVal 方法存在
                field.setDefaultVal(module.Updrow);
//                2026.2.27
                if (isNullOrEmpty(module.IdValue) && isNullOrEmpty(field.getDefaultval()))
                    field.setDefaultval(GetDefaultValue(defaultSource, null, module == null ? null : module.getLeftRecord(), SystemTypeEnums.PmType.store));

                String labelColor = field.getLabelColor();
                if (labelColor != null && !labelColor.isEmpty()) {
                    field.setLabelColor(GetDefaultValue(labelColor, module, SystemTypeEnums.PmType.sql));
                }
            } else if (!isNullOrEmpty(field.getLabelColor())) {
                String labelColor = field.getLabelColor();
                if (labelColor != null && labelColor.indexOf("{") > -1) {
                    field.setLabelColor("");
                }
            }
        }

        myControl.setUtil(this);
        myControl.setDbOperator(jdbcTemplate);

        if (myControl instanceof ComboBox) {
            // 假设 SetBoxStore 方法存在
            setBoxStore((ComboBox) myControl, false, module);
        }
        if (fieldType.toString().contains("LabCheck")
                && !"LabCheckBox".equals(fieldType.toString())) {
//            out.println("if判断");
            myControl = new LabelCheckBox(row, myControl);
        }

        myControl.setUtil(this);
        myControl.setDbOperator(jdbcTemplate);
//        out.println("myControl " + JSON.Encode(myControl));
        return myControl;
    }

    /**
     * 创建具体控件列表
     *
     * @param tab     控件数据列表（对应C#的DataTable）
     * @param module  模块实体
     * @param order   是否排序
     * @param formKey 表单键
     * @return 控件列表
     */
    public List<Field> createControl(List<Map<String, Object>> tab, ModuleEntity module, boolean order, String formKey) {
        if (tab == null || tab.isEmpty()) {
            return null;
        }

        Map<String, Object> datas = new HashMap<>();
        List<Field> enabalCondField = new ArrayList<>(); // 带有条件的控件，可用受条件影响
        List<Field> coms = tab.stream()
                .map(row -> {
//                    out.println("createControl.row" + row);
                    Field field = createControl(row, module, false);// 调整参数
//                    out.println("createControl.field" + field);
                    datas.put(field.getName().toLowerCase(), field.getValue());
                    if (field.getEnableCond() != null && !field.getEnableCond().isEmpty()) {
                        enabalCondField.add(field);
                    }
                    return field;
                })
                .collect(Collectors.toList());

//        out.println("COMs" + JSON.Encode(coms));
        // 合并模块的LeftRecord数据到datas
        if (module != null && module.getLeftRecord() != null) {
            datas.putAll(module.getLeftRecord());
        }
        // 处理带有启用条件的控件
        if (!enabalCondField.isEmpty()) {
            for (Field field : enabalCondField) {
                boolean disabled = !toBoolean(evalCond(field.getEnableCond(), datas, null));
                if (field.getCondEnableType() == 1) {
                    field.setHidden(disabled);
                } else {
                    field.disabled = disabled;
                    field.enableDisValue = disabled;
                }
            }
        }

        // 移除重复name且隐藏的控件
        Map<String, List<Field>> nameGroups = coms.stream()
                .filter(field -> field instanceof Field || field.getClass().isAssignableFrom(Field.class))
                .collect(Collectors.groupingBy(Field::getName));

        List<Field> toRemove = new ArrayList<>();
//        for (List<Field> group : nameGroups.values()) {
//            if (group.size() > 1) {
//                // 收集组中隐藏的控件
//                List<Field> hiddenInGroup = group.stream()
//                        .filter(field -> field.getHidden() != null && field.getHidden())
//                        .collect(Collectors.toList());
//                toRemove.addAll(hiddenInGroup);
//            }
//        }
//        coms.removeAll(toRemove);

//        2026.2.27
        List<List<Field>> repetition = nameGroups.values().stream()
                // 对应 C#: Where(group => group.Count() > 1)
                .filter(group -> group.size() > 1)
                // 对应 C#: Select(group => group.ToList()/* 无hidden筛选 */)
                .map(ArrayList::new) // 转为ArrayList，和C#的ToList()一致
                .collect(Collectors.toList());

// 3. 遍历每组，按规则删除元素（逻辑完全复刻C#）
        for (List<Field> list : repetition) {
            int i = 0; // 对应 C# 的 int i = 0;
            // 对应 C#: list.Where(_com => _com.hidden == false).FirstOrDefault()
            Field noHide = list.stream()
                    .filter(_com -> Boolean.FALSE.equals(_com.getHidden())) // hidden==false（处理null，null不会匹配）
                    .findFirst()
                    .orElse(null); // 无匹配时返回null，对应FirstOrDefault()

            // 遍历组内每个元素，按条件删除
            for (Field com : list) {
                // 对应 C#: if(noHide==null&&i >0||com!=noHide)coms.Remove(com);
                if ((noHide == null && i > 0) || (com != noHide)) {
                    coms.remove(com); // 对应 C# 的 coms.Remove(com)（注意：有并发修改异常风险）
                }
                i++; // 索引自增，和C#完全一致
            }
        }

        // 设置下拉框联动字段（上级值改变时影响下级）
        List<Field> finalComs = coms;
        coms.forEach(field -> {
            if (field != null && field.getName() != null) {
                List<String> linkNames = finalComs.stream()
                        .filter(com -> com instanceof ComboBox)
                        .map(com -> (ComboBox) com)
                        .filter(combobox -> {
                            String dataSource = combobox.getDataSource();
                            return dataSource != null && dataSource.toLowerCase()
                                    .contains("{" + field.getName().toLowerCase() + "}");
                        })
                        .map(ComboBox::getName)
                        .collect(Collectors.toList());
                field.linknames = linkNames.toArray(new String[0]);
            }
        });

//        out.println("1: " + coms);
        // 添加分组控件
        if (module != null) {
            formKey = (formKey == null || formKey.isEmpty()) ? module.getFromkey() : formKey;
            coms = addGroupControl(formKey, coms);
        }

        // 处理隐藏控件和排序
        List<Field> finalComs1 = coms;
        List<Field> hiddens = coms.stream()
                .filter(field -> field instanceof Hidden)
                .peek(field -> field.setTabIndex(finalComs1.size()))
                .collect(Collectors.toList());

        List<Field> notHiddens = coms.stream()
                .filter(field -> !(field instanceof Hidden))
                .collect(Collectors.toList());

//        out.println("2: " + notHiddens);

        // 排序非隐藏控件
        if (order) {
            notHiddens = orderTabFields(notHiddens);
//            out.println("3: " + notHiddens);
        }

        // 设置tabIndex
        for (int i = 0; i < notHiddens.size(); i++) {
            notHiddens.get(i).setTabIndex(i);
        }

        // 合并隐藏控件和非隐藏控件（隐藏控件放前面）
        hiddens.addAll(notHiddens);
        coms = hiddens;
//        out.println("4: " + coms);
        return coms;
    }

    // 重载方法，处理order默认值为true的情况
    public List<Field> createControl(List<Map<String, Object>> tab, ModuleEntity module, String formKey) {
        return createControl(tab, module, true, formKey);
    }

    // 重载方法，处理formKey默认值为空的情况
    public List<Field> createControl(List<Map<String, Object>> tab, ModuleEntity module, boolean order) {
        return createControl(tab, module, order, "");
    }

    // 重载方法，处理所有默认参数
    public List<Field> createControl(List<Map<String, Object>> tab, ModuleEntity module) {
        return createControl(tab, module, true, "");
    }

    /**
     * 根据控件类型获取默认的日期/时间格式
     *
     * @param ctype 控件类型枚举
     * @return 对应的日期/时间格式字符串，如果不匹配则返回 null
     */
    public static String GetFormatByCType(int ctype) {
        try {
            // 根据整数值获取对应的 ControlType 枚举实例
            SystemEnums.ControlType fieldType = SystemEnums.ControlType.fromValue(ctype);
            return GetFormatByCType(fieldType);
        } catch (IllegalArgumentException e) {
            // 处理无法解析的枚举值
            log.warn(String.valueOf("无法解析的 ControlType 值: " + ctype));
            return null;
        }
    }

    public static String GetFormatByCType(SystemEnums.ControlType ctype) {
        String format = null;

        switch (ctype) {
            case LabDate:   // 日期控件
                format = (format == null || format.isEmpty()) ? "yyyy-MM-dd" : format;
                break;
            case LabDateTime:
            case LabCheckDateTimeShort:
                format = (format == null || format.isEmpty()) ? "yyyy-MM-dd HH:mm:ss" : format;
                break;
            case LabDateTimeShort:
                format = (format == null || format.isEmpty()) ? "yyyy-MM-dd HH:mm" : format;
                break;
            case LabTime:
            case LabCheckTime:
                format = (format == null || format.isEmpty()) ? "HH:mm:ss" : format;
                break;
            case LabShortTime:
            case LabCheckShortTime:
                format = (format == null || format.isEmpty()) ? "HH:mm" : format;
                break;
            case LabYearTime:
            case LabLabYearTime:
                format = (format == null || format.isEmpty()) ? "yyyy-MM" : format;
                break;
            default:
                format = null;
                break;
        }

        return format;
    }

    /**
     * 设置组合框控件的属性
     *
     * @param myControl 组合框控件（Map形式）
     * @param row       数据行
     * @param ctype     控件类型
     * @param module    模块信息
     * @return 设置后的控件
     */
    public static Field SetBoxPro(ComboBox myControl, Map<String, Object> row, SystemEnums.ControlType ctype, ModuleEntity module) {
        String ftypeName = ctype.toString();

        if (ftypeName.contains("Text") || ftypeName.contains("ReturnName")) {
            myControl.setValueField(myControl.getDisplayField());
        }

        if (ftypeName.contains("RadioGroup")) {
            myControl.setXtype("radiogroup");
        } else if (ftypeName.contains("CheckboxGroup")) {
            myControl.setXtype("CheckboxGroup");
        }

        if (ftypeName.contains("AutoComplete") || ftypeName.contains("AutoSeacher")) {
            myControl.editable = true; // 可以输入筛选
        }

        if (ftypeName.contains("Multi")) {
            myControl.multiSelect = true; // 多选
        }

        if (ftypeName.contains("Param")) {
            myControl.parmbox = true; // 多选
            myControl.editable = true; // 可以输入筛选
        }

        if (ftypeName.contains("Module") && myControl.getAddModule() != null && !myControl.getAddModule().isEmpty()) {
            // 弹窗模块选择
            myControl.pickxtype = "Ywp.widget.ModuleSelect";
            myControl.setXtype("WinCombobox");
        }

        if (ftypeName.contains("Win")) {
            // 弹窗模块选择
            myControl.setXtype("WinCombobox");
            if (ftypeName.contains("Grid")) {
                myControl.pickxtype = "picker.GridPanel";
            }
            if (ftypeName.contains("Btns")) {
                myControl.pickxtype = "picker.Btns";
            }
        }

        if (ftypeName.contains("Star")) {
            // 弹窗模块选择
            myControl.setXtype("Yw.form.field.Star");
        }

        if (ftypeName.contains("Tree") ||
                (myControl.getDataSource()) != null &&
                        (myControl.getDataSource().toLowerCase().contains("_parentid") ||
                                myControl.getDataSource().toLowerCase().contains(" pid"))) {
            myControl.pickxtype = "picker.TreePanel";
            if (ftypeName.contains("Leaf")) {
                // 设置选择器配置
                Map<String, Object> pickerCfg = new HashMap<>();
                pickerCfg.put("selectLeaf", true);
                myControl.pickerCfg = pickerCfg;
            }
        }

        // 当数据源是本表，数据字段查询为本表
        if (module != null &&
                myControl.getDisplayField() != null &&
                myControl.getDisplayField().equals(myControl.getValueField()) &&
                module.getMasterTable() != null &&
                !module.getMasterTable().isEmpty() &&
                myControl.getDataSource() != null &&
                myControl.getDataSource().toLowerCase().contains(module.getMasterTable().toLowerCase()) &&
                myControl.getName() != null &&
                myControl.getDataSource().toLowerCase().contains(myControl.getName().toLowerCase())) {
            myControl.MValue = false;
        }

        return myControl;
    }

    /**
     * 检查表中是否存在特定列，不存在则添加
     *
     * @param tableName  表名
     * @param columnName 列名
     * @param columnType 列类型
     */
    private void checkAndAddColumn(String tableName, String columnName, String columnType) {
        // 查询 INFORMATION_SCHEMA 检查表中是否存在该列
        String checkSql = "SELECT COUNT(*) FROM DBA_TAB_COLUMNS " +
                "WHERE TABLE_NAME = ? AND COLUMN_NAME = ?";

        Integer count = jdbcTemplate.queryForObject(
                checkSql,
                new Object[]{tableName, columnName},
                Integer.class
        );

        // 如果列不存在，则添加
        if (count != null && count == 0) {
            String alterSql = "ALTER TABLE " + tableName + " ADD " + columnName + " " + columnType;
            jdbcTemplate.execute(alterSql);
        }
    }

    /**
     * 更新地图字段：添加经纬度相关列
     *
     * @param tabname   表名
     * @param fieldname 字段名前缀
     */
    public void updateMapField(String tabname, String fieldname) {
        // 检查并添加 _itude 列
        checkAndAddColumn(tabname, fieldname + "_itude", "VARCHAR(100)");

        // 检查并添加 _longitude 列
        checkAndAddColumn(tabname, fieldname + "_longitude", "VARCHAR(50)");

        // 检查并添加 _latitude 列
        checkAndAddColumn(tabname, fieldname + "_latitude", "VARCHAR(50)");
    }


    /**
     * 获取树形的特殊编号
     */
    public String GetTreeSpecNo(String tabName, String fieldName, String valueField,
                                String treeSql, String parentNo, Type fieldType, int batchIndex) {
        // 检查treeSql中是否包含表名
        if (treeSql.toLowerCase().indexOf((tabName + "").toLowerCase()) < 0) {
            return parentNo;
        }

        // 确定字段类型
        if (fieldType == null) {
            fieldType = GetTableColumnType(tabName, fieldName);
        }

        // 如果是值类型，直接返回parentNo
        if (fieldType != null && isValueType(fieldType)) {
            return parentNo;
        }

        // 检查必要参数
        if (valueField == null || valueField.isEmpty() || treeSql == null || treeSql.isEmpty()) {
            return "";
        }

        String defaultValue = "";
        // 正则表达式检查parentNo是否只包含数字、点和减号
        Pattern pattern = Pattern.compile("[^\\d\\.-]");
        if (!pattern.matcher(parentNo == null ? "" : parentNo).find()) {
            // 构建查询命令
            SqlAnalyzer sqlAnalyzer = new SqlAnalyzer(treeSql);
            String queryCmd = sqlAnalyzer.BuildTopText();

            // 构建查询SQL
            String sql = String.format(
                    "select max(cast(%s as bigint))+1 from (%s) temp where %s like '%s__'",
                    valueField, queryCmd, valueField, parentNo == null ? "" : parentNo
            );

            // 执行查询
            String sqlWithParams = PublicUtil.ReqSqlPms(null, null, sql, SystemTypeEnums.PmType.sql, getUser());
            Object result = jdbcTemplate.queryForObject(sqlWithParams, Object.class);
            defaultValue = result != null ? result.toString() : "";

            int spLen = 2;
            // 根据parentNo前缀调整长度
            if (parentNo != null && !parentNo.isEmpty()) {
                if (parentNo.startsWith("000")) {
                    spLen = 4;
                } else if (parentNo.startsWith("00")) {
                    spLen = 3;
                }
            }

            String bw = "0000".substring(0, spLen - 1);

            // 处理默认值
            if (defaultValue == null || defaultValue.isEmpty()) {
                defaultValue = String.format("%s%s1", parentNo == null ? "" : parentNo, bw);
            } else {
                defaultValue = bw + defaultValue;
            }

            // 处理批量索引
            if (batchIndex > 0) {
                try {
                    long value = Long.parseLong(defaultValue);
                    defaultValue = bw + (value + batchIndex);
                } catch (NumberFormatException e) {
                    // 如果转换失败，保持原有值
                }
            }

            return defaultValue;
        }

        return parentNo;
    }

    public String GetTreeSpecNo(String tabName, String fieldName, String valueField,
                                String treeSql, String parentNo) {
        return GetTreeSpecNo(tabName, fieldName, valueField, treeSql, parentNo, null, 0);
    }

    /**
     * 判断类型是否为值类型
     */
    private boolean isValueType(Type type) {
        if (type instanceof Class<?>) {
            Class<?> clazz = (Class<?>) type;
            return clazz.isPrimitive() ||
                    Number.class.isAssignableFrom(clazz) ||
                    Boolean.class.isAssignableFrom(clazz) ||
                    Character.class.isAssignableFrom(clazz);
        }
        return false;
    }

    /**
     * 使用静态 JdbcTemplate 查询表结构信息
     */
    public Type GetTableColumnType(String tabName, String colName) {
        if (jdbcTemplate == null) {
            throw new IllegalStateException("JdbcTemplate 未初始化，请确保 Spring 上下文已启动");
        }

        String tbName = null;
        tbName = GetOtherDbOper(tabName, tbName);

        try {
            // 查询 syscolumns 系统表获取列的 xtype
            String sql = String.format("SELECT xtype FROM syscolumns WHERE ID=OBJECT_ID('%s') AND name='%s'", tbName, colName);
            Object result = jdbcTemplate.queryForObject(sql, Object.class);

            if (result != null) {
                int xtype = Integer.parseInt(result.toString());
                if (xtype > 0) {
                    // 将 SQL Server 的 xtype 转换为 Java 类型
                    return NativeExtensionUtils.SqlxtypeToProType(xtype);
                }
            }
        } catch (Exception e) {
            // 处理异常，记录日志等
            log.error("Exception caught", e);
        }

        return null;
    }

    /**
     * 根据表名获取对应的数据库操作对象
     *
     * @param tablename 表名
     * @param tbname    处理后的表名（通过数组引用返回）
     * @return 数据库操作对象
     */
    public String GetOtherDbOper(String tablename, String tbname) {
        tbname = tablename;
        if (tablename == null || tablename.isEmpty()) {
            return null;
        }

        if (tablename.contains(".") && tablename.split("\\.").length <= 3) {
            String[] parts = tablename.split("\\.");
            String newDbName = parts[0].replace("[", "").replace("]", "");
            tbname = tablename.replace(parts[0] + ".", "");
        }

        return tbname;
    }

    /**
     * 使用正则表达式替换连接字符串中的数据库名
     */
    public String replaceDatabaseName(String connectionString, String newDbName) {
        // 匹配 "Database=数据库名;" 部分，不区分大小写
        Pattern pattern = Pattern.compile("Database=([^;]+);", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(connectionString);

        if (matcher.find()) {
            return matcher.replaceFirst("Database=" + newDbName + ";");
        }

        return connectionString;
    }


    public String GetDefaultValue(String defaultValue, ModuleEntity module, SystemTypeEnums.PmType pmType) {
        Object row = null;
        if (module != null) {
            if (module.Updrow != null) {
                row = module.Updrow;
            } else {
                row = module.getLeftRecord();
            }
        }
        Map<String, Object> lere = null;
        if (module != null && module.getLeftRecord() != null) {
            // 创建Hashtable并复制HashMap中的所有键值对
            Map<String, Object> temp = new Hashtable<>();
            temp.putAll(module.getLeftRecord()); // 利用Map接口的putAll方法复制数据
            lere = temp;
        } else {
            lere = null;
        }
        // 假设这里有一个重载的 GetDefaultValue 方法
        return GetDefaultValue(defaultValue, (Map<String, Object>) row, lere, pmType);
    }

    /**
     * 获取默认值，处理各种特殊格式的默认值表达式
     */
    public String GetDefaultValue(String defaultValue, Map<String, Object> row, Map<String, Object> leftRecord, SystemTypeEnums.PmType pmType) {
        if (defaultValue == null || defaultValue.isEmpty()) {
            return defaultValue;
        }

        // 去除前后空格、制表符等
        defaultValue = defaultValue.replaceAll("^[\\r\\n]+", "");

        // 处理 GUID
        if ("guid".equalsIgnoreCase(defaultValue)) {
            return UUID.randomUUID().toString();
        }

        // 处理以 @ 开头的 SQL 表达式
        if (defaultValue.startsWith("@")) {
            if ("@select getdate()".equalsIgnoreCase(defaultValue.trim())) {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            }

            pmType = SystemTypeEnums.PmType.sql;

            // 解析 SQL 参数
            if (row instanceof Map<String, Object>) {
                defaultValue = PublicUtil.ReqSqlPmsByRow(row, leftRecord, defaultValue, pmType, getUser());
            } else if (row instanceof Map) {
                defaultValue = PublicUtil.ReqSqlPms(row, leftRecord, defaultValue, pmType, getUser());
            } else {
                defaultValue = PublicUtil.ReqSqlPms(null, leftRecord, defaultValue, pmType, getUser());
            }

            boolean isDm = ConfigUtil.getProviderName().equals("dm");
            if (isDm) defaultValue.replace("db_name()", "(SELECT SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') FROM DUAL)");
            // 执行 SQL 查询
            // 替换你原来的 queryForObject 代码段
            List<Object> resultList = jdbcTemplate.queryForList(
                    defaultValue.replace("@", ""),  // 你的动态SQL（去掉@符号）
                    Object.class                    // 返回类型保持不变
            );

// 处理结果：空列表返回null，有结果取第一条（符合原逻辑“取单个值”的诉求）
            Object val = resultList.isEmpty() ? null : resultList.get(0);

            if (val instanceof Date || val instanceof TimeStamp) {
                return formatDateTime((Date) val);
            }

            return val != null ? val.toString() : "";
        }

        // 处理 {parentkey} 占位符
        if (defaultValue.toLowerCase().contains("{parentkey}")) {
            defaultValue = defaultValue.toLowerCase().replace("{parentkey}", "");
        }

        // 处理 {parent.key} 占位符
        if (defaultValue.toLowerCase().contains("{parent.key}")) {
            defaultValue = defaultValue.toLowerCase().replace("{parent.key}", "{parent.speciesno}");
        }

        // 替换 {# 为 {parent.
        defaultValue = defaultValue.replace("{#", "{parent.");

        // 再次解析参数
        if (row instanceof java.sql.ResultSet) {
            defaultValue = PublicUtil.ReqSqlPmsByRow(row, leftRecord, defaultValue, pmType, getUser());
        } else if (row instanceof Map) {
            defaultValue = PublicUtil.ReqSqlPms(row, leftRecord, defaultValue, pmType, getUser());
        } else {
            defaultValue = PublicUtil.ReqSqlPms(null, leftRecord, defaultValue, pmType, getUser());
        }

        // 处理以 ! 开头的存储过程调用
        if (defaultValue.startsWith("!")) {
            String procSql = "exec " + defaultValue.replace("!", "").replace("(", " ").replace(")", "");
            try {
                // 直接执行SQL语句
                Object val = jdbcTemplate.queryForObject(procSql, Object.class);
//                out.println("val: " + val + (val != null ? val.getClass() : "null"));
                if (val instanceof Date) {
                    return formatDateTime((Date) val);
                }
                return val != null ? val.toString() : "";
            } catch (EmptyResultDataAccessException e) {
                // 处理查询无结果的情况
                log.debug(String.valueOf("存储过程未返回结果: " + e.getMessage()));
                return "";
            } catch (Exception e) {
                log.debug(String.valueOf("执行存储过程出错: " + e.getMessage()));
//                e.printStackTrace();
                return "";
            }
        }

        return defaultValue;
    }

    /**
     * 格式化日期时间，去除时间部分的 00:00:00
     */
    public String formatDateTime(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formatted = sdf.format(date);
        return formatted.replace(" 00:00:00", "");
    }

    /**
     * 获取操作数据库对象
     */
    public JdbcTemplate GetOperater() {
        return jdbcTemplate;
    }

    /**
     * 处理数据库查询语句
     * 参数10个
     */
    public String dealQuerySql(String querySql, Map<String, Object> record, Map<String, Object> leftRecord, Map<String, Object> pms, String keyField, String keyValue, boolean precise, boolean readOnly, boolean convertStr, boolean doNotSpelling) {
        List<String> keyWhere = new ArrayList<>();
        StringBuilder sqlBuder = new StringBuilder();
        querySql = querySql == null ? "" : querySql;

        if (querySql.contains("#")) {
            querySql = querySql.replaceAll("#\\s*and\\s*", "and #");

            if (record == null || record.isEmpty()) {
                if (readOnly || precise) {
                    querySql = querySql.replace("{#", "{").replaceAll("(#)(.|\\n)*?(#)", keyValue == null || keyValue.isEmpty() ? "1!=1" : "1=1");
                } else {
                    querySql = querySql.replace("{#", "{").replaceAll("(#)(.|\\n)*?(#)", "1=1");
                }
            } else {
                if (keyValue != null && !keyValue.isEmpty() && (readOnly || precise)) {
                    // querySql = querySql.replace("{#", "{").replaceAll("(#)(.|\\n)*?(#)", "1=1");
                    // 获取两个#号之间存在{}替换字符则去掉 两个#
                    String pattern = "#(.*?)#";
// Pattern.DOTALL 等价于 C# 的 RegexOptions.Singleline
                    java.util.regex.Pattern regex = java.util.regex.Pattern.compile(pattern, java.util.regex.Pattern.DOTALL);
                    java.util.regex.Matcher match = regex.matcher(querySql);
                    String val = "";
                    boolean isMatchSuccess = match.find();
                    if (isMatchSuccess) { // 等价于 C# 的 match.Success
                        val = match.group(1); // 等价于 C# 的 Groups[1].Value
                    }

                    if (isMatchSuccess && val.indexOf("{") > -1) { // 保持和原代码一致的判断逻辑
                        querySql = querySql.replace("#" + val + "#", val); // 替换 #{val}# 为 val
                    } else {
                        // 先替换 {# 为 {，再用正则替换 #...# 为 1=1
                        String tempSql = querySql.replace("{#", "{");
                        java.util.regex.Pattern replaceRegex = java.util.regex.Pattern.compile("(#)(.|\\n)*?(#)");
                        querySql = replaceRegex.matcher(tempSql).replaceAll("1=1");
                    }
                } else {
                    querySql = querySql.replace("\\n", "\n"); // 处理转义的换行符

                    // 2. 使用更稳定的正则，兼容跨行和#前后的空格
                    // 正则：#\\s*(.+?)\\s*#，并启用Pattern.DOTALL模式
                    Pattern pattern = Pattern.compile("#\\s*(.+?)\\s*#", Pattern.DOTALL);
                    Matcher matcher = pattern.matcher(querySql);
//                    Pattern pattern = Pattern.compile("(#)(.|\\n)*?(#)");
//                    Matcher matcher = pattern.matcher(querySql);
                    List<String> matchList = new ArrayList<>();
                    while (matcher.find()) {
                        matchList.add(matcher.group()); // 收集所有#...#内容（基于原始SQL）
                    }
                    // 2. 遍历替换（和C# foreach一致）
                    for (String match : matchList) {
                        // 用C#的Trim('#')等价逻辑：仅去掉首尾#
                        String cleanMatch = match.trim().replaceAll("^#|#$", "");
                        querySql = querySql.replace(match, cleanMatch);
                    }
                }
            }
        }

        if (leftRecord != null) {
            if (record == null) {
                record = new HashMap<>();
            }
            for (Map.Entry<String, Object> entry : leftRecord.entrySet()) {
                if (!record.containsKey(entry.getKey())) {
                    record.put(entry.getKey(), entry.getValue());
                }
            }
        }

        boolean isInner = keyField != null && !keyField.isEmpty() && querySql.toLowerCase().contains("{" + keyField + "}");

        if (isInner) {
            return PublicUtil.ReqSqlPms(record, leftRecord, querySql, SystemTypeEnums.PmType.sql, getUser());
        }

        if (keyValue != null && !keyValue.isEmpty() && keyField != null && !keyField.isEmpty()) {
            if (keyValue.contains(",")) {
                if (precise || readOnly) {
                    keyValue = keyValue.replace("'", "").replace(",", "','");
                    keyWhere.add(buildKVWhere(keyField, keyValue, precise || readOnly, convertStr, doNotSpelling));
                } else {
                    String[] vs = keyValue.replace("'", "").split(",");
                    for (String s : vs) {
                        String w = buildKVWhere(keyField, s.replace("%2C", ","), precise || readOnly, convertStr, doNotSpelling);
                        if (w != null && !w.isEmpty()) {
                            keyWhere.add(w);
                        }
                    }
                }
            } else {
                keyWhere.add(buildKVWhere(keyField, keyValue.replace("%2C", ","), precise || readOnly, convertStr, doNotSpelling));
            }

            if (keyField != null && !keyField.isEmpty()) {
                // 完全等价于 C# 的 (\ ){1,}
                boolean hasTop = Pattern.compile("select +top +", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE)
                        .matcher(querySql)
                        .find();
                int maxVal = 200, i = 0;
                if (keyWhere.size() > maxVal) {
                    String kw = "1!=1";
                    for (String w : keyWhere) {
                        kw = String.format("%s or %s", kw, w);
                        i++;
                        if (i % maxVal == 0) {
                            Map<String, String> wd = new HashMap<>();
                            wd.put(keyField, String.format(" And (%s)", kw));
                            SqlAnalyzer sqlAnalyzer = new SqlAnalyzer(querySql);
                            sqlBuder.append(sqlAnalyzer.InsertWhere(wd, false, true, !hasTop && (precise || readOnly)));
                            sqlBuder.append(";");
                            kw = "1!=1";
                        }
                    }
                    return sqlBuder.toString();
                } else {
                    Map<String, String> wd = new HashMap<>();
                    wd.put(keyField, String.format(" And (%s)", String.join(" or ", keyWhere)));
                    SqlAnalyzer sqlAnalyzer = new SqlAnalyzer(querySql);
                    querySql = sqlAnalyzer.InsertWhere(wd, false, true, !hasTop && (precise || readOnly));
                }
            }
        }

        return PublicUtil.ReqSqlPms(record, leftRecord, querySql, SystemTypeEnums.PmType.sql, getUser());
    }

    //专门给附件的
    public String DealQuerySql(String querySql, Map<String, Object> record, Map<String, Object> leftRecord, Map<String, Object> pms, String keyField, String keyValue, boolean precise, boolean readOnly, boolean convertStr, boolean doNotSpelling) {
        List<String> keyWhere = new ArrayList<>();
        StringBuilder sqlBuder = new StringBuilder();
        querySql = querySql == null ? "" : querySql;

        if (querySql.contains("#")) {
            // 对齐C#的正则替换：# 空格 and 空格 → # and
            querySql = querySql.replaceAll("#\\s*and\\s*", "# and ");

            if (record == null || record.isEmpty()) {
                if (readOnly || precise) {
                    querySql = querySql.replace("{#", "{").replaceAll("(#)(.|\\n)*?(#)", keyValue == null || keyValue.isEmpty() ? "1!=1" : "1=1");
                } else {
                    querySql = querySql.replace("{#", "{").replaceAll("(#)(.|\\n)*?(#)", "1=1");
                }
            } else {
                if (keyValue != null && !keyValue.isEmpty() && (readOnly || precise)) {
                    // 获取两个#号之间存在{}替换字符则去掉 两个#
                    String pattern = "#(.*?)#";
                    // Pattern.DOTALL 等价于 C# 的 RegexOptions.Singleline
                    java.util.regex.Pattern regex = java.util.regex.Pattern.compile(pattern, java.util.regex.Pattern.DOTALL);
                    java.util.regex.Matcher match = regex.matcher(querySql);
                    String val = "";
                    boolean isMatchSuccess = match.find();
                    if (isMatchSuccess) { // 等价于 C# 的 match.Success
                        val = match.group(1); // 等价于 C# 的 Groups[1].Value
                    }

                    if (isMatchSuccess && val.indexOf("{") > -1) { // 保持和原代码一致的判断逻辑
                        querySql = querySql.replace("#" + val + "#", val); // 替换 #{val}# 为 val
                    } else {
                        // 先替换 {# 为 {，再用正则替换 #...# 为 1=1
                        String tempSql = querySql.replace("{#", "{");
                        java.util.regex.Pattern replaceRegex = java.util.regex.Pattern.compile("(#)(.|\\n)*?(#)");
                        querySql = replaceRegex.matcher(tempSql).replaceAll("1=1");
                    }
                } else {
                    // ========== 关键修改1：删除转义换行符的逻辑（C#无此逻辑） ==========
                    // 删掉：querySql = querySql.replace("\\n", "\n");

                    // ========== 关键修改2：使用和C#完全一致的正则 ==========
                    // C#原正则：(@"(#)(.|\n)*?(#)")
                    Pattern pattern = Pattern.compile("(#)(.|\\n)*?(#)", Pattern.DOTALL);
                    Matcher matcher = pattern.matcher(querySql);
                    List<String> matchList = new ArrayList<>();
                    while (matcher.find()) {
                        matchList.add(matcher.group()); // 收集所有#...#内容（基于原始SQL）
                    }
                    // 遍历替换（和C# foreach一致）
                    for (String match : matchList) {
                        // ========== 关键修改3：仅去掉首尾#，不trim（对齐C#的Trim('#')） ==========
                        // C#: m.Value.Trim('#') → Java: 仅替换首尾的#，保留中间所有空格/换行/字符
                        String cleanMatch = match.replaceAll("^#|#$", "");
                        querySql = querySql.replace(match, cleanMatch);
                    }
                }
            }
        }

        if (leftRecord != null) {
            if (record == null) {
                record = new HashMap<>();
            }
            for (Map.Entry<String, Object> entry : leftRecord.entrySet()) {
                if (!record.containsKey(entry.getKey())) {
                    record.put(entry.getKey(), entry.getValue());
                }
            }
        }

        boolean isInner = keyField != null && !keyField.isEmpty() && querySql.toLowerCase().contains("{" + keyField + "}");

        if (isInner) {
            return PublicUtil.ReqSqlPms(record, leftRecord, querySql, SystemTypeEnums.PmType.sql, getUser());
        }

        if (keyValue != null && !keyValue.isEmpty() && keyField != null && !keyField.isEmpty()) {
            // ========== 关键修改4：对齐C#的逗号判断逻辑（IndexOf(',') > 0） ==========
            if (keyValue.indexOf(',') > 0) {
                if (precise || readOnly) {
                    keyValue = keyValue.replace("'", "").replace(",", "','");
                    keyWhere.add(buildKVWhere(keyField, keyValue, precise || readOnly, convertStr, doNotSpelling));
                } else {
                    String[] vs = keyValue.replace("'", "").split(",");
                    for (String s : vs) {
                        String w = buildKVWhere(keyField, s.replace("%2C", ","), precise || readOnly, convertStr, doNotSpelling);
                        if (w != null && !w.isEmpty()) {
                            keyWhere.add(w);
                        }
                    }
                }
            } else {
                keyWhere.add(buildKVWhere(keyField, keyValue.replace("%2C", ","), precise || readOnly, convertStr, doNotSpelling));
            }

            if (keyField != null && !keyField.isEmpty()) {
                // 完全等价于 C# 的 (\ ){1,}
                boolean hasTop = Pattern.compile("select +top +", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE)
                        .matcher(querySql)
                        .find();
                int maxVal = 200, i = 0;
                if (keyWhere.size() > maxVal) {
                    String kw = "1!=1";
                    for (String w : keyWhere) {
                        kw = String.format("%s or %s", kw, w);
                        i++;
                        if (i % maxVal == 0) {
                            Map<String, String> wd = new HashMap<>();
                            wd.put(keyField, String.format(" And (%s)", kw));
                            SqlAnalyzer sqlAnalyzer = new SqlAnalyzer(querySql);
                            sqlBuder.append(sqlAnalyzer.InsertWhere(wd, false, true, !hasTop && (precise || readOnly)));
                            sqlBuder.append(";");
                            kw = "1!=1";
                        }
                    }
                    return sqlBuder.toString();
                } else {
                    Map<String, String> wd = new HashMap<>();
                    wd.put(keyField, String.format(" And (%s)", String.join(" or ", keyWhere)));
                    SqlAnalyzer sqlAnalyzer = new SqlAnalyzer(querySql);
                    querySql = sqlAnalyzer.InsertWhere(wd, false, true, !hasTop && (precise || readOnly));
                }
            }
        }

        return PublicUtil.ReqSqlPms(record, leftRecord, querySql, SystemTypeEnums.PmType.sql, getUser());
    }


    //    dealQuerySql方法重载,参数9个
    public String dealQuerySql(String querySql, Map<String, Object> record, Map<String, Object> leftRecord, Map<String, Object> pms, String keyField, String keyValue, boolean precise, boolean readOnly, boolean convertStr) {
        boolean doNotSpelling = false;
        return dealQuerySql(querySql, record, leftRecord, pms, keyField, keyValue, precise, readOnly, convertStr, doNotSpelling);
    }

    /**
     * 处理某些地方大小写的问题
     */
    public String buildKVWhere(String keyField, String keyValue, boolean precise, boolean convertStr, boolean doNotSpelling) {
        String v = Trim(keyValue);
        String keyWhere = "";

        if (keyField.indexOf(",") > -1) {
            ArrayList<String> pms = new ArrayList<>();
            String[] keys = keyField.split(",");
            for (String key : keys) {
                if (key != null && !key.trim().isEmpty()) {
                    pms.add(buildKVWhere(key, keyValue, precise, convertStr, doNotSpelling));
                }
            }
            if (!pms.isEmpty()) {
                return "(" + String.join(" or ", pms) + ")";
            }
        }

        String _keyField = convertStr ? String.format("convert(varchar(100), %s)", keyField) : keyField;

        if (precise) {
            if (v.indexOf("','") > -1) {
                keyWhere = String.format("%s in ('%s')", _keyField, keyValue);
            } else {
                keyWhere = String.format("%s = '%s'", _keyField, v);
            }
        } else if (RegexUtil.ENOnlyReg.matcher(v).matches() && !doNotSpelling) {
            keyWhere = String.format("%s like '%%%s%%' OR dbo.P_GetPy(%s) like '%%%s%%'", _keyField, v, _keyField, v);
        } else {
            keyWhere = String.format("%s like '%%%s%%'", _keyField, v);
        }

        return keyWhere;
    }

    /**
     * <summary>
     * /// 设置combobox 的store以及porxy
     * /// </summary>
     * /// <param name="_myControl">The _my control</param>
     * /// <param name="isinidata">是否初始化一个store的data</param>
     * /// <returns>ComboBox</returns>
     * /// </remarks>
     */
    public ComboBox setBoxStore(ComboBox myControl, boolean isIniData, ModuleEntity module) {
        DataStore store = new DataStore();
        String val = "";
        if (module == null || module.Updrow == null) {
            val = String.valueOf(myControl.getDefaultval());
        } else {
            val = String.valueOf(module.Updrow.get(myControl.getName()));
        }

        // 处理默认值逻辑
        String valueField = myControl.getValueField();
        String displayField = myControl.getDisplayField();
        if (valueField != null && !valueField.isEmpty()
                && module != null
                && !val.isEmpty()
                && !valueField.equals(displayField)) {

            String xtype = myControl.getXtype();
            if (!"radiogroup".equals(xtype) && !"CheckboxGroup".equals(xtype)) {
//                boolean prise = myControl.getDataSource().indexOf("dbo.P_BaseMixInfoTab") < 0;
                boolean prise = myControl.getDataSource().indexOf("P_BaseMixInfoTab") < 0;
                String sql = dealQuerySql(
                        myControl.getDataSource(),
                        module.Updrow != null ? module.Updrow : null,
                        null,
                        null,
                        valueField + "," + displayField,
                        myControl.multiSelect ? val : val.replace(",", "%2C"),
                        prise,
                        prise, false, false
                );

                try {
                    // 假设dbOperator存在于当前类中，用于执行SQL查询
                    store.data = (jdbcTemplate.queryForList(sql));
                } catch (Exception e) {

                }
            }
        }

        var c = myControl.getColumns();
        // 设置查询参数
        myControl.queryParam = myControl.getDisplayField();
        Map<String, Object> extraParams = new HashMap<>();
        extraParams.put("moduleId", module != null ? module.getModuleId() : null);
        extraParams.put("fdtype", myControl.getFieldDataType());
        extraParams.put("id", myControl.getFieldId());
        extraParams.put("_fId", myControl.getFieldId());
        extraParams.put("textField", displayField);
        extraParams.put("popPms", JSON.Encode(myControl.getPopPms())); // 假设使用Jackson或FastJSON
        store.extraParams = (extraParams);
        myControl.store = (store);
        return myControl;
    }

    /**
     * 评估条件表达式（带row和leftRecord参数）
     *
     * @param cond       条件表达式
     * @param row        数据行
     * @param leftRecord 左侧记录哈希表
     * @return 评估结果（布尔值）
     */
    public Object evalCond(String cond, Map<String, Object> row, Map<String, Object> leftRecord) {
        // 获取处理后的条件值
        String _cond = GetDefaultValue(cond, row, leftRecord, SystemTypeEnums.PmType.sql);

        // 处理特殊前缀条件
        if ((cond.startsWith("@") || cond.startsWith("!")) && (_cond == null || _cond.isEmpty())) {
            return "";
        }

        // 转换SQL条件为可执行代码
        String code = PublicUtil.SqlToCode(_cond);

        // 执行条件评估并转换为布尔值
        Object evalResult = PublicUtil.EvalCond(code, (input, e) -> new DataImpl(new DbOperator()).EvalCond(_cond), true);
        return evalResult;
    }

    /**
     * 评估条件表达式（带Module参数，支持默认值）
     *
     * @param cond   条件表达式
     * @param module 模块实体（可为null）
     * @return 评估结果（对象类型）
     */
    public Object evalCond(String cond, ModuleEntity module) {
        // 获取处理后的条件值，使用ignorenull类型
        String _cond = GetDefaultValue(cond, module, SystemTypeEnums.PmType.ignorenull);

        // 包含占位符时直接返回原始条件
        if (_cond != null && _cond.indexOf("{") > -1) {
            return _cond;
        }

        // 处理特殊前缀条件
        if (cond.startsWith("@") || cond.startsWith("!")) {
            return DataTableUtil.toBoolean(_cond);
        }

        // 转换SQL条件为可执行代码并评估
        String code = PublicUtil.SqlToCode(_cond);
        return DataTableUtil.toBoolean(PublicUtil.EvalCond(code, (input, e) -> new DataImpl(new DbOperator()).EvalCond(_cond), true));
    }

    /**
     * 重载方法，默认module为null
     */
    public Object evalCond(String cond) {
        return evalCond(cond, null);
    }

    /**
     * 为控件添加分组信息
     *
     * @param formKey  表单标识
     * @param controls 原始控件列表
     * @return 包含分组的控件列表
     */
    public List<Field> addGroupControl(String formKey, List<Field> controls) {
        // 查询分组信息（对应C#的DataTable）
//        String sql = "select * from T_SystemFieldGroupTab where unionkey = ?";
//        String sql = "select * from dbo.p_systemaddgroup where formkey= ? ";
        String sql = "select * from p_systemaddgroup where formkey= ? ";
        List<Map<String, Object>> groupRows = jdbcTemplate.queryForList(sql, formKey);

        if (!groupRows.isEmpty()) {
            List<Field> groups = new ArrayList<>();

            // 遍历分组数据，创建FieldSet
            for (Map<String, Object> row : groupRows) {
                // 使用带util参数的构造方法，对应C#的FieldSet(item, this)
                FieldSet group = new FieldSet(row, this);
                group.setXtype("fieldset"); // 设置xtype属性
                groups.add(group);
            }
            // 将原有控件添加到分组列表后
            groups.addAll(controls);
            return groups;
        }
        // 无分组时返回原始控件列表
        return controls;
    }

    /**
     * 对控件列表按位置排序，确保Tab键顺序正确
     *
     * @param list 待排序的Field列表
     */
    public List<Field> orderTabFields(List<Field> list) {
        int length = list.size();

        // 选择排序算法（保持与原C#代码一致的排序逻辑）
        for (int i = 0; i < length - 1; i++) {
            Field field = list.get(i);
            Field min = field;
            int minIndex = i;

            // 寻找从i开始的最小值
            for (int j = i + 1; j < length; j++) {
                Field other = list.get(j);
                if (other == null) {
                    continue;
                }

                // 原C#代码中的"other > min"对应Java的compareTo方法
                // 这里假设compareTo返回正数表示other大于min
                if (org.example.Entity.Control.Base.Component.isGreater(other, min)) {
                    minIndex = j;
                    min = other;
                }
            }

            // 交换位置
            if (minIndex != i) {
                list.set(minIndex, field);
                list.set(i, min);
            }
        }

        return list;
    }

    /**
     * 根据控件类型，获取ext控件
     *
     * @param gridcolumn 表格列对象
     * @param dr         数据行（对应C#的DataRow，Java中常用Map表示）
     * @param module     模块对象
     * @param isValeqkey 输出参数：下拉菜单时，是否为key等于val（通过数组传递以实现类似out效果）
     * @return 控件对象
     */
    public Object getGridColumnEditType(RowColumn gridcolumn, Map<String, Object> dr, ModuleEntity module, boolean[] isValeqkey) {
        // 初始化输出参数（默认key等于val）
        isValeqkey[0] = true;

        // 创建控件（第三个参数对应C#的createEditor=true）
        Field component = createControl(dr, module, true);

//        out.println(component.getClass());
        // 处理下拉框类型控件
        if (component != null && component.getClass() == ComboBox.class) {
            ComboBox box = (ComboBox) component;
            // 判断valueField是否等于displayField
            isValeqkey[0] = (box.getValueField() == (box.getDisplayField()));
//            out.println("isValeqkey[0] + " + isValeqkey[0]);
        }

        // 清空字段标签
        if (component != null) {
            component.setFieldLabel("");
        }

        return component;
    }

    /**
     * 检查权限
     *
     * @param kcPurview 用户权限值
     * @param menuid    模块id
     * @return 权限标识（"AllPurview"：所有权限；"ReadPurview"：只读权限；""：无权限）
     */
    public String CheckPurview(String kcPurview, String menuid) {
        // 管理员拥有所有权限
        LoginUserInfo user = getUser();
        if (user != null && "管理员".equals(user.UserName)) {
            return "AllPurview";
        }

        // 权限值或模块ID为空时无权限
        if (NativeExtensionUtils.isNullOrEmpty(kcPurview) || NativeExtensionUtils.isNullOrEmpty(menuid)) {
            return "";
        }

        // 格式化权限字符串，前后加逗号便于精确匹配
        String formattedKcPurview = String.format(",%s,", kcPurview);
        String allPurview = String.format(",%s,", menuid);       // 所有权限标识
        String readPurview = String.format(",%s|,", menuid);     // 只读权限标识

        // 检查权限级别
        if (formattedKcPurview.contains(allPurview)) {
            return "AllPurview";
        } else if (formattedKcPurview.contains(readPurview)) {
            return "ReadPurview";
        } else {
            return "";
        }
    }
}



