package yem.base.common.module.version.form;

import com.alibaba.fastjson.JSONObject;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.bill.OperationStatus;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.entity.*;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.datamodel.ListSelectedRow;
import kd.bos.entity.datamodel.ListSelectedRowCollection;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.property.EntryProp;
import kd.bos.entity.property.LinkEntryProp;
import kd.bos.entity.property.SubEntryProp;
import kd.bos.form.*;
import kd.bos.form.container.Tab;
import kd.bos.form.control.Control;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.form.events.ClosedCallBackEvent;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.ComboEdit;
import kd.bos.form.field.ComboItem;
import kd.bos.form.field.events.BeforeF7SelectEvent;
import kd.bos.form.field.events.BeforeF7SelectListener;
import kd.bos.lang.Lang;
import kd.bos.list.ListShowParameter;
import kd.bos.metadata.dao.MetaCategory;
import kd.bos.metadata.dao.MetadataDao;
import kd.bos.metadata.form.ControlAp;
import kd.bos.metadata.form.FormMetadata;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BillTypeDifferentialHelper;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import yem.base.common.module.meta.propselect.helper.MetaPropertyHelper;
import yem.base.common.module.version.helper.F7Helper;

import java.util.*;
import java.util.Map.Entry;

/**
 * 创建新版本方案维护-表单插件
 *
 * @author longh
 * @description:
 * @date 2021年11月8日 上午10:05:40
 */
public class NewVersionTplFormPlugIn extends AbstractBillPlugIn implements BeforeF7SelectListener {
    private static final String KEY_VCHECK = "yem_base_versioncheckrule";//版本变更【校验规则】单据标识
    private static final String KEY_CCHECK = "yem_base_versioncheckcols";//版本变更【校验字段】单据标识

    @Override
    public void afterLoadData(EventObject e) {
        super.afterLoadData(e);

    }

    @Override
    //这里进来为空没有进行操作，用于已经创建好的数据，列表中进入可以拿到数据
    public void afterBindData(EventObject e) {
        super.afterBindData(e);
        DynamicObject entityObj = (DynamicObject) this.getModel().getValue("yem_changebill");//变更单据
        if (entityObj != null) {
            String entityNumber = entityObj.getString("number");//编码
            this.fillEntityCombo(entityNumber);
        }
    }

    /**
     * 注册监听器。
     * 本方法在继承自父类的注册监听器基础上，进一步添加了特定事件的监听处理。
     * 特别地，它关注了点击事件和项点击事件，并为特定控件绑定了对应的监听器。
     * 此外，还为几个特定的编辑控件添加了前置F7选择监听器，以在进行选择操作前进行特定的逻辑处理。
     *
     * @param e 事件对象，用于向父类注册监听器。
     */
    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        // 添加点击事件监听器，关注特定的控件ID。
        this.addClickListeners(new String[]{"yem_checkrule", "yem_checkcols","yem_billcol"});//校验规则（提交校验），校验字段（删除校验）
        // 添加项点击事件监听器，关注特定的控件ID。
        this.addItemClickListeners(new String[]{"yem_tbtypes", "yem_advcontoolbarap1"});//单据映射面板，明细配置

        // 为特定控件添加前置F7选择监听器，用于在选择操作执行前进行干预。
        ((BasedataEdit) this.getControl("yem_requirebill")).addBeforeF7SelectListener(this);
        ((BasedataEdit) this.getControl("yem_changebill")).addBeforeF7SelectListener(this);
        ((BasedataEdit) this.getControl("yem_changebilltype")).addBeforeF7SelectListener(this);
    }


    @Override
    public void click(EventObject evt) {
        super.click(evt);
        String key = ((Control) evt.getSource()).getKey();
        switch (key) {
            case "yem_checkrule"://校验规则
                this.clickCheckRule(evt, key);
                break;
            case "yem_checkcols"://校验字段
                this.clickCheckCols(evt, key);
                break;
            case "yem_billcol"://明细的选择
                this.clickBillcol(evt, key);
                break;
        }
    }

    private void clickBillcol(EventObject evt, String key) {
        MetaPropertyHelper.showPropertySelect(this, key, "yem_cm_htdemobill", true);
    }
    private void callBack4FieldSelector(ClosedCallBackEvent e) {
        IDataModel model = this.getModel();
        MetaPropertyHelper.callBackEntryData( model, e,"yem_colsmap", "yem_billcolno", "yem_billcol", true);
        //默认给是否启用赋值为true
        model.setValue("yem_enable", true);
    }
    /**
     * 根据事件对象和关键字点击检查规则。
     * 此方法用于在特定事件触发时，检查并显示或编辑检查规则的详细信息。
     * 它通过获取当前行的数据，并使用这些数据来显示一个模态对话框，其中包含检查规则的详细信息。
     *
     * @param evt 事件对象，用于触发此方法的操作。
     * @param key 关键字，用于特定的检查规则标识。
     */
    private void clickCheckRule(EventObject evt, String key) {
        // 获取当前视图
        IFormView view = this.getView();
        // 获取当前模型
        IDataModel model = this.getModel();
        // 获取当前“yem_checkmap”表中选定行的索引
        int rowIndex = model.getEntryCurrentRowIndex("yem_checkmap");
        // 根据索引获取“yem_checkmap”表中选定行的实体对象
        DynamicObject entryRow = model.getEntryRowEntity("yem_checkmap", rowIndex);

        // 创建用于显示表单的参数对象
        FormShowParameter showParameter = new FormShowParameter();
        // 设置表单操作状态为新增
        showParameter.setStatus(OperationStatus.ADDNEW);
        // 设置表单打开方式为模态对话框
        showParameter.getOpenStyle().setShowType(ShowType.Modal);
        // 设置要显示的表单的ID
        showParameter.setFormId(KEY_VCHECK);
        // 从视图中获取“yem_changebill”对象，并检查其是否存在
        DynamicObject yem_changebill = MetaPropertyHelper.getAndCheckF7Value(view, "yem_changebill");
        if (yem_changebill == null) {
            // 处理yem_changebill为null的情况
            return;
        }else{
            // 设置自定义参数“entityNumber”为“yem_changebill”的编号
            showParameter.setCustomParam("entityNumber", yem_changebill.getString("number"));
        }
        // 设置自定义参数“data”为当前选定行的实体对象
        showParameter.setCustomParam("data", entryRow);
        // 设置关闭回调，用于在关闭表单时执行特定操作
        showParameter.setCloseCallBack(new CloseCallBack(this, KEY_VCHECK));
        // 使用配置的参数显示表单
        view.showForm(showParameter);
    }

    /**
     * 处理点击检查列的事件。
     * 当用户点击检查列时，此方法将被调用以显示一个模态对话框，其中包含与所选行相关的信息。
     *
     * @param evt 事件对象，代表触发此方法的事件。
     * @param key 用于标识操作的关键字。
     */
    private void clickCheckCols(EventObject evt, String key) {
        // 获取当前视图
        IFormView view = this.getView();
        // 获取当前模型
        IDataModel model = this.getModel();
        // 获取当前选中行的索引
        int rowIndex = model.getEntryCurrentRowIndex("yem_checkdelrow");//删行校验分录
        // 获取当前选中行的对象
        DynamicObject entryRow = model.getEntryRowEntity("yem_checkdelrow", rowIndex);

        // 创建用于显示表单的参数对象
        FormShowParameter showParameter = new FormShowParameter();
        // 设置表单操作状态为新增
        showParameter.setStatus(OperationStatus.ADDNEW);
        // 设置表单打开方式为模态对话框
        showParameter.getOpenStyle().setShowType(ShowType.Modal);
        // 设置表单的ID
        showParameter.setFormId(KEY_CCHECK);
        // 从视图中获取变更单号，并设置为自定义参数
        DynamicObject yem_changebill = MetaPropertyHelper.getAndCheckF7Value(view, "yem_changebill");
        if(yem_changebill == null){
            return;
        }else{
            // 设置自定义参数“entityNumber”为“yem_changebill”的编号
            showParameter.setCustomParam("entityNumber", yem_changebill.getString("number"));
        }
        // 设置当前选中行的数据作为自定义参数
        showParameter.setCustomParam("data", entryRow);
        // 设置关闭回调，用于处理对话框关闭后的逻辑
        showParameter.setCloseCallBack(new CloseCallBack(this, KEY_CCHECK));
        // 显示表单
        view.showForm(showParameter);
    }

    @Override
    public void itemClick(ItemClickEvent evt) {
        super.itemClick(evt);
        String itemKey = evt.getItemKey();
        switch (itemKey) {
            case "yem_updatebt"://重置
                this.initBilltypes();
                break;
//            case "yem_updatecols": //更新列
//                this.updateTreeCols();
//                break;
            default:
                break;
        }
    }

    /**
     * 更新树形列信息。
     * 该方法用于根据实体对象中的变更单信息，更新树形列的显示。它首先从模型中获取变更单实体对象，
     * 然后根据变更单号获取相应的控制信息。接着，它遍历模型中的列映射集合，移除已经存在的列控制信息。
     * 最后，将剩余的列控制信息添加到模型中，以更新树形列的显示。
     */
    private void updateTreeCols() {
        // 获取数据模型
        IDataModel model = this.getModel();
        // 从数据模型中获取变更单实体对象
        DynamicObject entityObj = model.getDataEntity().getDynamicObject("yem_changebill");
        // 如果变更单实体对象存在
        if (entityObj != null) {
            // 从变更单实体对象中获取变更单号
            String entityNumber = entityObj.getString("number");
            // 根据变更单号获取全部控制信息
            Map<String, BillTypeControlInfo> ctlInfos = BillTypeDifferentialHelper.getFullControlInfos(entityNumber);

            // 从数据模型中获取列映射集合
            DynamicObjectCollection yem_colsmap = model.getEntryEntity("yem_colsmap");
            // 遍历列映射集合，移除已存在的列控制信息
            for (DynamicObject row : yem_colsmap) {
                String yem_billcolno = row.getString("yem_billcolno");
                if (ctlInfos.containsKey(yem_billcolno)) {
                    ctlInfos.remove(yem_billcolno);
                }
            }
            // 遍历剩余的列控制信息，为每条信息在模型中创建新行，并初始化树形列页面
            for (Entry<String, BillTypeControlInfo> ctlInfo : ctlInfos.entrySet()) {

                int rowIndex = this.getModel().createNewEntryRow("yem_colsmap");
                this.initColsTreePage(ctlInfo.getValue(), rowIndex);
            }
        }
    }


    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        super.propertyChanged(e);
        String name = e.getProperty().getName();
        switch (name) {
            case "yem_requirebill"://需求单据
                this.requireBillChanged(e, name);
                break;
            case "yem_changebill"://变更单据
                this.changeBillChanged(e, name);
                break;
            //监控校验实体的变化，如果校验实体发生变化了，直接将表示存入校验父实体中
            case "yem_checkdelentity"://删行校验的校验实体
                this.checkDelRowChanged(e, name);
                break;
        }
    }
/**
 * 检查删除行是否发生变化。
 * 当前方法的目的是根据变更单的编号，获取变更单的实体类型，进而获取该实体类型的表单元数据，以此来判断删除行是否有变化。
 * @param e PropertyChangedArgs对象，携带属性改变的事件信息。
 * @param name 变更的属性名。
 */
    private void checkDelRowChanged(PropertyChangedArgs e, String name) {
        ChangeData changeData = e.getChangeSet()[0];
        int rowIndex = changeData.getRowIndex();
        String name3 = (String) this.getModel().getValue("yem_checkdelentity", rowIndex);
        // 获取变更单对象
         DynamicObject yemChangebill = (DynamicObject) this.getModel().getValue("yem_changebill");
         // 判断变更单对象是否存在
         if (yemChangebill != null) {
             // 根据变更单编号获取实体类型
             MainEntityType entityType = EntityMetadataCache.getDataEntityType(yemChangebill.getString("number"));
             // 获取实体类型的属性集合
             DataEntityPropertyCollection entryTypes = entityType.getProperties();

             IDataEntityProperty property = entityType.findProperty(name3);
             if (property != null && property instanceof SubEntryProp) {
                 this.getModel().setValue("yem_parentdelentity", property.getParent().getName(), rowIndex);
             }else{
                 this.getModel().setValue("yem_parentdelentity", null, rowIndex);
             }
         }
    }

    private void requireBillChanged(PropertyChangedArgs e, String name) {
        this.initBilltypes();
    }

    /**
     * 初始化单据类型。
     * 此方法用于在特定条件下删除并重新加载单据类型的映射数据。它首先从当前模型中删除所有现有的单据类型映射数据，
     * 然后根据特定条件从数据库中加载新的单据类型数据，并将这些数据添加到模型中。
     * 这个过程对于确保单据类型的准确性和时效性是非常重要的。
     */
    private void initBilltypes() {
        // 获取当前模型实例
        IDataModel model = this.getModel();
        // 删除现有的单据类型映射数据
        model.deleteEntryData("yem_billtypes");

        // 从模型中获取需求单据对象
        DynamicObject yem_requirebill = (DynamicObject) model.getValue("yem_requirebill");
        // 如果需求单据存在
        if (yem_requirebill != null) {
            // 根据条件查询符合状态为'C'，启用状态为'1'，且单据形式与需求单据匹配的单据类型
            DynamicObject[] billtypes = BusinessDataServiceHelper.load("bos_billtype", "id", new QFilter[]{new QFilter("status", QCP.equals, "C"), new QFilter("enable", QCP.equals, "1"), new QFilter("billformid", QCP.equals, yem_requirebill.getPkValue())});
            // 遍历查询结果，为每个单据类型创建新的映射条目
            for (DynamicObject billtype : billtypes) {
                // 在模型中创建一个新的映射条目行
                int index = model.createNewEntryRow("yem_billtypes");
                // 将当前单据类型设置为映射的源单据类型
                model.setValue("yem_srcbilltype", billtype, index);
            }
        }
    }


    private void changeBillChanged(PropertyChangedArgs e, String name) {
        IDataModel model = this.getModel();
        model.deleteEntryData("yem_colsmap");//明细分录
        model.deleteEntryData("yem_checkmap");//提交校验分录
        model.deleteEntryData("yem_checkdelrow");//删行校验分录

        DynamicObject entityObj = model.getDataEntity().getDynamicObject(name);
        if (entityObj != null) {
            String entityNumber = entityObj.getString("number");
//            this.initColsTreePages(entityNumber);
            this.fillEntityCombo(entityNumber);
//            this.initCheckDelRowEntity(model, entityNumber);
        }
    }

    /**
     * 初始化列树页面。
     * 此方法用于根据给定的实体编号，初始化与之相关的列树页面。它通过获取实体编号对应的全部控制信息，
     * 遍历这些信息来创建新的列树页面条目，并对每个条目进行初始化配置。
     *
     * @param entityNumber 实体编号，用于检索特定实体的控制信息。
     */
    private void initColsTreePages(String entityNumber) {
        // 通过实体编号获取完整的控制信息映射。
        Map<String, BillTypeControlInfo> ctlInfos = BillTypeDifferentialHelper.getFullControlInfos(entityNumber);

        // 遍历控制信息映射，对每个控制信息进行列树页面初始化。
        for (Entry<String, BillTypeControlInfo> ctlInfo : ctlInfos.entrySet()) {
            // 在模型中创建一个新的条目行，用于列树页面。
            int rowIndex = this.getModel().createNewEntryRow("yem_colsmap");//明细分录
            // 对新创建的条目行进行列树页面初始化。
            this.initColsTreePage(ctlInfo.getValue(), rowIndex);
        }
    }


    /**
     * 初始化列树页面。
     * 此方法用于在特定行索引处设置模型的两个属性，用于显示列号和列名。
     * 它是私有的，说明它只应该在类的内部使用。
     *
     * @param ctlInfo 控制信息对象，包含列的键和名。
     * @param rowIndex 行索引，用于指定在数据模型中的位置。
     */
    private void initColsTreePage(BillTypeControlInfo ctlInfo, int rowIndex) {
        // 获取当前的数据模型
        IDataModel model = this.getModel();
        // 设置列号
        model.setValue("yem_billcolno", ctlInfo.getFieldKey(), rowIndex);//标识
        // 设置列名
        model.setValue("yem_billcol", ctlInfo.getFieldName(), rowIndex);//名称
    }


    /**
     * 处理关闭事件的回调函数。
     * 当特定的关闭操作发生时，此方法将被调用，以执行相应的后续处理。
     * 通过检查操作ID来决定执行哪项具体后续行动。
     *
     * @param e 事件对象，包含关闭操作的相关信息。
     */
    @Override
    public void closedCallBack(ClosedCallBackEvent e) {
        // 调用父类的关闭回调函数，处理通用的关闭逻辑
        super.closedCallBack(e);

        // 获取关闭操作的唯一标识符
        String key = e.getActionId();
        switch (key) {
            case KEY_VCHECK://版本变更【校验规则】单据标识
                this.callBack4CheckRule(e);
                break;
            case KEY_CCHECK://版本变更【校验字段】单据标识
                this.callBack4CheckCols(e);
                break;
            case "yem_billcol":
                this.callBack4FieldSelector(e);
                break;
        }
    }

    /**
     * 处理检查规则的回调事件。
     * 当检查规则的查询操作完成时，此方法被调用，用于处理返回的数据并更新模型。
     *
     * @param e 回调事件对象，包含操作ID和返回的数据。
     */
    private void callBack4CheckRule(ClosedCallBackEvent e) {
        // 获取操作ID和返回的数据
        String actionId = e.getActionId();
        Object returnData = e.getReturnData();

        // 检查操作ID和返回数据是否都不为空
        if (actionId != null && returnData != null) {
            // 获取数据模型
            IDataModel model = this.getModel();
            // 将返回的数据转换为JSONObject
            JSONObject jsonObj = (JSONObject) returnData;

            // 获取当前检查映射的行索引
            int rowIndex = model.getEntryCurrentRowIndex("yem_checkmap");

            // 更新检查规则描述和检查规则JSON数据
            model.setValue("yem_checkrule", jsonObj.getString("yem_desc"), rowIndex);//校验规则
            model.setValue("yem_checkjson", jsonObj.toJSONString(), rowIndex);//序列化校验条件(json字符串)
        }
    }


    /**
     * 处理列检查回调事件。
     * 当列检查操作完成时，此方法被调用以处理返回的数据，更新模型中的相关列信息。
     *
     * @param e 回调事件对象，包含操作ID和返回的数据。
     */
    private void callBack4CheckCols(ClosedCallBackEvent e) {
        // 获取操作ID和返回的数据
        String actionId = e.getActionId();
        Object returnData = e.getReturnData();

        // 检查操作ID和返回数据是否都不为空
        if (actionId != null && returnData != null) {
            // 获取当前的数据模型
            IDataModel model = this.getModel();
            // 将返回的数据转换为JSONObject
            JSONObject jsonObj = (JSONObject) returnData;

            // 获取当前行索引，用于后续在模型中更新数据
            int rowIndex = model.getEntryCurrentRowIndex("yem_checkdelrow");

            // 将返回的列信息更新到模型中，分别存储列的显示信息和编号信息
            model.setValue("yem_checkcols", jsonObj.getJSONArray("yem_col").toString(), rowIndex);//校验字段

            model.setValue("yem_checkcolsjson", jsonObj.getJSONArray("yem_colno").toString(), rowIndex);//序列化校验字段
        }
    }


    @Override
    public void beforeF7Select(BeforeF7SelectEvent e) {
        String key = e.getProperty().getName();
        switch (key) {
            case "yem_requirebill":
            case "yem_changebill":
                this.beforeF7SelectBill(e);
                break;
            case "yem_changebilltype"://单据类型映射（变更单据类型）
                this.beforeF7BillType(e);
                break;
        }
    }

    /**
     * 在选择单据前执行的事件处理方法。
     * 该方法主要用于设置F7查询过滤条件，确保在选择单据前应用正确的筛选条件。
     *
     * @param e 事件对象，包含关于即将进行的单据选择的信息。
     */
    private void beforeF7SelectBill(BeforeF7SelectEvent e) {
        // 创建一个过滤器集合，用于指定查询时的过滤条件。
        // 这里指定了查询的模型类型为"BillFormModel"，以筛选出符合特定条件的单据。
        QFilter fs = F7Helper.getMetaTypeFs(new String[]{"BillFormModel"});//, "BaseFormModel"

        // 将创建的过滤器应用到即将进行的F7查询中。
        // 这一步确保了查询结果只包含符合条件的单据。
        F7Helper.addF7Filter(e, fs);
    }


    /**
     * 在选择F7类型之前处理事件。
     * 此方法用于在进行F7选择之前，根据当前的“yem_changebill”值设置过滤条件，
     * 以确保选择的F7类型与当前的“yem_changebill”相关联。
     *
     * @param e 事件对象，包含F7选择之前的上下文信息。
     */
    private void beforeF7BillType(BeforeF7SelectEvent e) {
        // 获取“yem_changebill”字段的值，它是一个动态对象
        DynamicObject yem_changebill = (DynamicObject) this.getModel().getValue("yem_changebill");

        // 如果“yem_changebill”不存在，则使用0作为billformid的值，否则获取“yem_changebill”的主键值
        Object billformid = yem_changebill == null ? 0L : yem_changebill.getPkValue();

        // 创建一个过滤条件，用于过滤billformid与当前“yem_changebill”主键值相同的F7类型
        QFilter fs = new QFilter("billformid", QCP.equals, billformid);

        // 将过滤条件添加到F7选择事件中，以影响F7类型的筛选
        F7Helper.addF7Filter(e, fs);
    }

    /**
     * 根据实体编号填充实体组合框。
     * 此方法用于在用户界面的两个组合框中填充相同的实体选项。这两个组合框分别用于选择实体和选择待删除的实体。
     * @param entityNumber 实体的编号，用于查询实体类型。
     */
    private void fillEntityCombo(String entityNumber) {
        // 根据实体编号获取实体类型
        MainEntityType mainType = EntityMetadataCache.getDataEntityType(entityNumber);
        // 根据实体类型构建实体选项列表
        List<ComboItem> entryItems = this.buildEntryComboItems(mainType,"yem_checkentity");
        // 获取用于选择实体的组合框控件，并设置实体选项
        ComboEdit entryEditor = this.getView().getControl("yem_checkentity");//提交校验实体
        entryEditor.setComboItems(entryItems);
        List<ComboItem> entryItems1 = this.buildEntryComboItems(mainType,"yem_checkdelentity");
        // 获取用于选择待删除实体的组合框控件，并设置相同的实体选项
        ComboEdit entryEditor1 = this.getView().getControl("yem_checkdelentity");//删除校验实体
        entryEditor1.setComboItems(entryItems1);
    }


    /**
     * 根据主实体类型构建下拉选项列表。
     *
     * @param mainType 主实体类型，用于获取关联的实体类型信息。
     * @return 包含空白项、主实体类型项和其他实体类型项的列表。
     */
    private List<ComboItem> buildEntryComboItems(MainEntityType mainType,String entryKey) {
        // 初始化一个列表用于存储下拉选项项
        ArrayList<ComboItem> entryItems = new ArrayList<>();
        // 获取当前语言环境ID
        String currLCId = Lang.get().toString();

        // 创建一个空白选项，用于用户不选择任何实体类型的情况
        ComboItem blankItem = new ComboItem();
        blankItem.setValue("");
        blankItem.setCaption(new LocaleString());
        entryItems.add(blankItem);

        // 如果主实体类型不为空
        if (mainType != null) {
            // 获取所有实体类型
            Map<String, EntityType> entitys = mainType.getAllEntities();


            // 创建一个代表主实体类型的选项
            ComboItem headItem = new ComboItem();
            headItem.setValue(mainType.getName());
            headItem.setCaption(new LocaleString(currLCId, "单据头"));
            if("yem_checkentity".equals(entryKey)){
                entryItems.add(headItem);
            }
            // 遍历所有实体类型，添加除链接实体类型外的实体类型选项
            for (EntityType entity : entitys.values()) {
                // 排除链接实体类型，只处理普通实体类型
                if (!(entity instanceof LinkEntryType) && entity instanceof EntryType) {
                    ComboItem entryItem = new ComboItem();
                    entryItem.setValue(entity.getName());
                    entryItem.setCaption(entity.getDisplayName());
                    entryItems.add(entryItem);
                }
            }
        }
        return entryItems;
    }


    /**
     * 初始化检查删除行实体。
     * 根据给定的实体编号，从实体元数据缓存中获取主要实体类型，并根据该类型及其子实体类型初始化检查删除行。
     * 此方法主要用于在数据模型中为可删除的实体类型创建一个新的检查行，用于后续的删除操作检查。
     *
     * @param model 数据模型，用于创建新的行并设置值。
     * @param entityNumber 实体编号，用于从缓存中获取实体类型。
     */
    private void initCheckDelRowEntity(IDataModel model, String entityNumber) {
        // 从实体元数据缓存中获取指定编号的主实体类型
        MainEntityType mainType = EntityMetadataCache.getDataEntityType(entityNumber);
        // 如果主实体类型存在
        if (mainType != null) {
            // 获取主实体类型下的所有子实体类型
            Map<String, EntityType> entitys = mainType.getAllEntities();
            // 遍历所有子实体类型
            for (EntityType entity : entitys.values()) {
                // 排除链接实体类型，仅处理普通实体类型
                if (!(entity instanceof LinkEntryType) && entity instanceof EntryType) {
                    // 在数据模型中创建一个新的检查删除行
                    int index = model.createNewEntryRow("yem_checkdelrow");//删行校验分录
                    // 设置该行的实体名称
                    model.setValue("yem_checkdelentity", entity.getName(), index);//校验实体
                }
            }
        }
    }


}