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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.milvus.param.collection.GetCollectionStatisticsParam;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.bill.BillShowParameter;
import kd.bos.bill.OperationStatus;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.metadata.IDataEntityType;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.dataentity.metadata.dynamicobject.DynamicLocaleProperty;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.dataentity.metadata.dynamicobject.DynamicProperty;
import kd.bos.entity.*;
import kd.bos.entity.botp.runtime.BFRow;
import kd.bos.entity.datamodel.IDataModel;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.property.EntryProp;
import kd.bos.entity.property.MulBasedataProp;
import kd.bos.entity.report.CellStyle;
import kd.bos.form.*;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.events.AfterDoOperationEventArgs;
import kd.bos.form.events.BeforeDoOperationEventArgs;
import kd.bos.form.operate.FormOperate;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import yem.base.common.module.version.dynamic.VersionResumeBillInfoEdit;
import yem.base.common.module.version.helper.NewVersionHelper;
import yem.base.common.utils.DynamicObjectUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import java.util.Map;

/**
 * 创建新版本功能基类
 *
 * @author longh
 * @description:
 * @date 2021年9月7日 下午2:49:09
 */
public class AbstractVersionBillPlugIn extends AbstractBillPlugIn {
    public static final String key_effectchange = "yem_effectchange";//生效按钮标识
    public static final String KEY_REL = "yem_base_versionsrel";//【版本变更关联追踪表】单据标识-扩展开发库
    public static final String KEY_TPL = "yem_base_versionsetting";//【创建新版本方案维护】单据标识
    public static final String KEY_LIST = "yem_base_versionresume";//【变更履历】单据标识
    //定义变更功能的可见控件标识
    private static final String[] VCTRLS = {"yem_versionhistory", "yem_version", "yem_changeman", "yem_changedate", "yem_effector", "yem_effectdate"};
    //定义变更功能的仅需求单据可见控件标识
    private static final String[] S = {"yem_newversion"};
    private static final String[] D = {"yem_deletehistory"};
    //定义变更功能的仅变更单据可见控件标识
    private static final String[] V = {"yem_effective"};
    //定义变更功能的仅变更单据不可见控件标识
    private static final String[] UNV = {"bar_new", "bar_submitandnew", "bar_print", "bar_push", "bar_track", "bar_more"};

    /**
     * 变更操作生成变更单成功后，跳转到变更单
     *
     * @param e
     * @param view
     */
    /**
     * 当执行某个操作后，查看新版本的信息。
     * 此方法用于处理操作完成后，根据操作结果决定是否展示新版本的详情。
     *
     * @param e 事件参数，包含操作的结果信息。
     * @param view 形式视图接口，用于展示新版本的详细信息。
     */
    public static void viewNewVersion(AfterDoOperationEventArgs e, IFormView view) {
        // 获取操作结果
        OperationResult operationResult = e.getOperationResult();
        // 检查操作是否成功
        if (operationResult.isSuccess()) {
            // 获取操作结果的详细信息
            String message = operationResult.getMessage();
            // 将信息解析为JSON对象
            JSONObject parseObject = JSON.parseObject(message);
            // 检查解析是否成功
            if (parseObject != null) {
                // 初始化展示参数
                BillShowParameter showParameter = new BillShowParameter();
                // 设置相关参数，用于定位和展示新版本信息
                showParameter.setFormId(parseObject.getString("yem_changebill"));
                showParameter.setPkId(parseObject.getString("pkId"));
                showParameter.setStatus(OperationStatus.EDIT);
                // 设置展示方式为在新标签页中打开
                showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
                // 展示新版本信息
                view.showForm(showParameter);
            }
        } else {
            // 操作失败，此处可添加处理逻辑，如提示用户操作失败的原因
        }
    }

    /**
     * 查看历史版本记录
     * 当用户在编辑页面点击“历史版本”按钮时，此方法被调用，用于显示指定实体的历史版本记录。
     *
     * @param e 事件参数，包含操作结果和相关数据。
     * @param view 表单视图接口，用于呈现历史版本记录的表单。
     */
    public static void viewVersionHistory(AfterDoOperationEventArgs e, IFormView view) {
        // 获取操作结果，检查操作是否成功。
        OperationResult operationResult = e.getOperationResult();
        if (operationResult.isSuccess()) {
            // 获取操作结果中的消息，该消息包含历史版本的数据。
            String message = operationResult.getMessage();
            // 将消息解析为JSON对象，以获取历史版本的数据。
            JSONObject parseObject = JSON.parseObject(message);
            if (parseObject != null) {
                // 创建表单展示参数对象，用于配置如何展示历史版本记录的表单。
                FormShowParameter showParameter = new FormShowParameter();
                // 设置表单ID，这里使用了一个常量KEY_LIST，表示展示历史版本的列表。
                showParameter.setFormId(KEY_LIST);
                // 设置表单状态为编辑状态，表示用户可以查看但不能修改历史版本。
                showParameter.setStatus(OperationStatus.EDIT);
                // 配置表单的打开方式，这里设置为在新标签页中以主表单形式展示。
                showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
                // 设置自定义参数，将历史版本的数据传递给表单，用于展示。
                showParameter.setCustomParam("data", parseObject);
                // 使用表单视图接口展示历史版本记录的表单。
                view.showForm(showParameter);
            }
        }
    }


    /**
     * 在绑定数据后执行初始化操作。
     * <p>
     * 本方法在继承的父类方法后，执行特定的初始化设置。这些设置包括新版本设置和高亮设置，
     * 旨在对已绑定数据的对象进行进一步的配置和状态初始化。
     *
     * @param e 事件对象，携带与绑定数据相关的事件信息。
     */
    @Override
    public void afterBindData(EventObject e) {
        super.afterBindData(e); // 调用父类的afterBindData方法，完成基本的绑定数据后的处理
        this.initNewVersionSetting(); // 初始化新版本设置，可能包括检查和提醒用户有新版本可用的配置
        this.initHighLightSetting(); // 初始化高亮设置，可能包括对特定数据或界面元素进行高亮显示的配置
    }

    /**
     * 初始化新版本设置，根据模板配置来调整界面的显示和控件的启用状态。
     * 此功能主要用于根据不同的单据类型（变更单或非变更单），来动态显示和启用/禁用界面元素。
     * 它通过查询模板配置来获取显示和启用状态的规则，并据此调整界面状态。
     */
    private void initNewVersionSetting() {
        // 获取当前模型和视图对象
        IDataModel model = this.getModel();
        IFormView view = this.getView();
        // 获取当前操作的实体类型名称
        String entityNumber = model.getDataEntityType().getName();
        // 根据实体类型名称查询对应的模板配置
        DynamicObject tplObj = NewVersionHelper.queryTemplate(entityNumber);
        if (tplObj != null) {
            // 根据模板配置，设置界面整体可见性
            //设置控件可见（变更单/非变更单）
            view.setVisible(true, VCTRLS);
            // 分别获取变更单和非变更单的模板配置项
            String yem_requirebill = tplObj.getString("yem_requirebill.number");
            String yem_changebill = tplObj.getString("yem_changebill.number");
            // 根据当前实体类型，分别处理变更单和非变更单的显示和启用状态
            if (entityNumber.equals(yem_requirebill)) {
                // 设置非变更单相关控件的可见性
                //设置控件可见（非变更单）
                view.setVisible(true, S);
                view.setVisible(tplObj.getBoolean("yem_enabledelete"), D);
            } else if (entityNumber.equals(yem_changebill)) {
                view.setVisible(false, D);
                // 获取并处理变更单的详细配置
                //设置字段可用（变更单）
                String billstatus = (String) model.getValue("billstatus");
                if ("A".equals(billstatus)) {
                    // 根据配置，启用或禁用特定的表头和分录字段
                    List<String> ableList = new ArrayList<>();
                    List<String> unableList = new ArrayList<>();
                    DynamicObjectCollection colsmap = tplObj.getDynamicObjectCollection("yem_colsmap");
                    for (DynamicObject colmap : colsmap) {
                        if (colmap.getBoolean("yem_enable")) {
                            ableList.add(colmap.getString("yem_billcolno"));
                        } else {
                            unableList.add(colmap.getString("yem_billcolno"));
                        }
                    }
                    // 应用表头字段的启用/禁用状态
                    //表头处理
                    view.setEnable(true, ableList.toArray(new String[0]));
                    view.setEnable(false, unableList.toArray(new String[0]));
                    // 应用分录字段的启用/禁用状态
                    // 分录处理
                    int size = 0;
                    DynamicObject dataEntity = model.getDataEntity(true);
                    DynamicObjectType dyObjType = dataEntity.getDynamicObjectType();
                    DataEntityPropertyCollection properties = dyObjType.getProperties();
                    for (IDataEntityProperty property : properties) {
                        String name = property.getName();
                        if (property instanceof EntryProp) {
                            DynamicObjectCollection dyObjCollection = dataEntity.getDynamicObjectCollection(name);
                            size = dyObjCollection.size() > size ? dyObjCollection.size() : size;
                        }
                    }
                    for (int i = 0; i < size; i++) {
                        view.setEnable(true, i, ableList.toArray(new String[0]));
                        view.setEnable(false, i, unableList.toArray(new String[0]));
                    }
                }
                // 设置变更单相关控件的可见性
                //设置控件可见（变更单）
                view.setVisible(true, V);
                // 根据配置，决定是否显示某些特定的控件
                String effectOption = tplObj.getString("yem_effectoption");
                if (!"audit".equals(effectOption)) {
                    view.setVisible(true, key_effectchange);
                }
                // 隐藏某些在变更单中不应显示的控件
                //设置控件不可见（变更单）
                view.setVisible(false, UNV);
            }
        }
    }


    @Override
    public void afterDoOperation(AfterDoOperationEventArgs e) {
        super.afterDoOperation(e);
        IFormView view = this.getView();
        String operateKey = e.getOperateKey();
        switch (operateKey) {
            case "newversion":
                viewNewVersion(e, view);
                break;
            case "versionhistory":
                viewVersionHistory(e, view);
                break;
            case "audit":
            case "effectchange":
                OperationResult operationResult = e.getOperationResult();
                if (operationResult.isSuccess()) {
                    view.invokeOperation("refresh");
                }
                break;
            case "deletehistory"://删除历史版本
                //刷新页面
                OperationResult operationResult1 = e.getOperationResult();
                if (operationResult1.isSuccess()) {
                    view.invokeOperation("refresh");
                }
                break;
            default:
                break;
        }
    }

    @Override
    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
        super.beforeDoOperation(args);
        FormOperate formOperate = (FormOperate) args.getSource();
        switch (formOperate.getType()) {//操作类型
            case "newentry"://新增分录
            case "copyentryrow"://复制分录
            case "insertentry"://插入分录
                this.checkAddRow(args, formOperate);
                break;
            case "deleteentry"://删除分录
                this.checkDeleteRow(args, formOperate);
                break;
            default:
                break;
        }
    }

    /**
     * 在添加行之前进行检查，以确定是否应该阻止添加行操作。
     * 该方法主要用于验证当前操作的行是否已经在其他地方存在，特别是对于那些不应该重复添加的行。
     * 它通过查询相应的模板和数据实体来确定是否存在相应的行记录，并根据检查结果决定是否取消添加行操作。
     *
     * @param args 事件参数，用于操作前的检查。
     * @param formOperate 表单操作对象，包含当前的操作信息。
     */
    private void checkAddRow(BeforeDoOperationEventArgs args, FormOperate formOperate) {
        // 获取当前视图和模型对象
        IFormView view = this.getView();
        IDataModel model = this.getModel();

        // 获取当前操作的数据实体类型名称
        String entityNumber = model.getDataEntityType().getName();

        // 根据实体类型名称查询对应的模板信息，以确定是否为变更单
        DynamicObject tplObj = NewVersionHelper.queryTemplate(entityNumber);//校验是否变更单
        if (tplObj != null && entityNumber.equals(tplObj.getString("yem_changebill.number"))) {
            // 从模板中获取相关单据的类型名称
            String yem_requirebill = tplObj.getString("yem_requirebill.number");

            // 根据相关单据类型和主数据ID查询具体的单据信息
            // 查询主数据分录内码
            List<Long> entryIds = new ArrayList<>();
            DynamicObject requirebill = BusinessDataServiceHelper.loadSingle(model.getValue("yem_masterid"), yem_requirebill);

            // 从操作参数中获取当前操作的行标识
            String entryKey = (String) formOperate.getParameter().get("entryId");//分录标识

            // 根据单据类型获取数据实体类型，进而获取实体定义
            MainEntityType dataType = EntityMetadataCache.getDataEntityType(yem_requirebill);
            Map<String, EntityType> allEntities = dataType.getAllEntities();
            EntityType entityType = allEntities.get(entryKey);

            // 根据实体类型的不同，采取不同的处理策略，以收集相关的行ID
            if (entityType instanceof EntryType && !(entityType instanceof SubEntryType)) {
                // 如果是普通分录类型，则直接查询并收集ID
                // 分录处理
                for (DynamicObject obj : requirebill.getDynamicObjectCollection(entryKey)) {
                    long id = obj.getLong("id");
                    entryIds.add(id);
                }
            } else if (entityType instanceof SubEntryType) {
                // 如果是子分录类型，则先查询父分录，再收集子分录的ID
                // 子分录处理
                IDataEntityType parent = entityType.getParent();
                String parentKey = parent.getName();
                for (DynamicObject obj : requirebill.getDynamicObjectCollection(parentKey)) {
                    for (DynamicObject subObj : obj.getDynamicObjectCollection(entryKey)) {
                        entryIds.add(subObj.getLong("id"));
                    }
                }
            }

            // 如果收集到的行ID数量大于0，则进一步检查这些行是否已经被其他地方引用
            if (entryIds.size() > 0) {
                // 查询分录是否由上游携带，是则阻断增行并提示
                @SuppressWarnings("deprecation")
                List<BFRow> loadSourceRowIds = BFTrackerServiceHelper.loadSourceRowIds(yem_requirebill, entryKey, entryIds.toArray(new Long[0]));
                // 如果找到相关引用，则取消添加行操作，并给出提示
                if (loadSourceRowIds.size() > 0) {
                    args.setCancel(true);//阻断增行
                    view.showTipNotification("该分录为上游关联数据，不允许增行。");
                }
            }
        }
    }


    /**
     * 删行前校验：查询分录字段是否满足条件，不满足则阻断删行并提示
     *
     * @param args
     * @param formOperate
     */
    private void checkDeleteRow(BeforeDoOperationEventArgs args, FormOperate formOperate) {
        // 获取当前视图和模型对象，用于后续操作。
        IFormView view = this.getView();
        IDataModel model = this.getModel();

        // 获取当前模型的数据实体类型名称。
        String entityNumber = model.getDataEntityType().getName();

        // 通过实体类型名称查询对应的模板对象，用于检查删除条件。
        DynamicObject tplObj = NewVersionHelper.queryTemplate(entityNumber);//校验是否变更单
        // 如果模板对象存在，并且模板对象标识与当前实体类型匹配，则进行删除检查。
        if (tplObj != null && entityNumber.equals(tplObj.getString("yem_changebill.number"))) {
            // 获取待删除行的标识。
            String entryKey = (String) formOperate.getParameter().get("entryId");//分录标识
            // 获取当前行的索引。
            int index = model.getEntryCurrentRowIndex(entryKey);
            // 根据标识和索引获取待删除的具体行对象。
            DynamicObject entryRow = model.getEntryRowEntity(entryKey, index);

            // 用于累计错误消息的字符串构建器。
            StringBuilder errorMsg = new StringBuilder();

            // 从模板对象中获取用于检查删除条件的配置集合。
            DynamicObjectCollection yem_checkdelrow = tplObj.getDynamicObjectCollection("yem_checkdelrow");
            // 遍历检查配置，检查每行是否存在不允许删除的条件。
            for (DynamicObject row : yem_checkdelrow) {
                //获取校验父实体标识
                String yemParentdelentity = row.getString("yem_parentdelentity");
                if(yemParentdelentity!=null && !yemParentdelentity.isEmpty()){
                    //获取子单据标识
                    String yemCheckdelentity = row.getString("yem_checkdelentity");
                    //详细提示，操作第几行的数据
                    int index1 = model.getEntryCurrentRowIndex(yemCheckdelentity);
                    String yem_checkcolsjson = row.getString("yem_checkcolsjson");
                    DynamicObjectCollection yemCheckdelentity1 = entryRow.getDynamicObjectCollection(yemCheckdelentity);
                    for (DynamicObject dynamicObject : yemCheckdelentity1) {
                        // 解析列配置，用于后续的列值检查。
                        JSONArray parseArray = JSON.parseArray(yem_checkcolsjson);
                        if (parseArray != null) {
                            for (Object obj : parseArray) {
                                // 获取列号。
                                String colno = obj.toString();
                                BigDecimal bigDecimal = dynamicObject.getBigDecimal(colno);
                                if (bigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                                    // 获取列的显示名称，用于错误消息。
                                    DynamicProperty property = dynamicObject.getDynamicObjectType().getProperty(colno);
                                    String displayName = property.getDisplayName() == null ? "" : "第"+(++index1)+"行的"+property.getDisplayName().getLocaleValue();
                                    // 累加错误消息。
                                    if (errorMsg.length() > 0) {
                                        errorMsg.append("、");
                                    }
                                    errorMsg.append(displayName);
                                }
                            }
                        }
                    }

                }
                // 如果当前行标识与检查配置匹配。
                if (entryKey.equals(row.getString("yem_checkdelentity"))) {
                    // 获取检查列的配置。
                    String yem_checkcolsjson = row.getString("yem_checkcolsjson");
                    // 解析列配置，用于后续的列值检查。
                    JSONArray parseArray = JSON.parseArray(yem_checkcolsjson);
                    // 如果列配置存在，则进行列值检查。
                    if (parseArray != null) {
                        for (Object obj : parseArray) {
                            // 获取列号。
                            String colno = obj.toString();
                            // 获取列值，并检查是否为零。
                            BigDecimal bigDecimal = entryRow.getBigDecimal(colno);
                            // 如果列值不为零，则认为该列存在不允许删除的条件。
                            if (bigDecimal.compareTo(BigDecimal.ZERO) != 0) {
                                // 获取列的显示名称，用于错误消息。
                                DynamicProperty property = entryRow.getDynamicObjectType().getProperty(colno);
                                String displayName = property.getDisplayName() == null ? "" : property.getDisplayName().getLocaleValue();
                                // 累加错误消息。
                                if (errorMsg.length() > 0) {
                                    errorMsg.append("、");
                                }
                                errorMsg.append(displayName);
                            }
                        }
                    }
                }
            }
            // 如果存在不允许删除的条件，则取消删除操作，并显示错误消息。
            if (errorMsg.length() > 0) {
                args.setCancel(true);//阻断删行
                errorMsg.insert(0, "【").append("】").append("不为零，不允许删行。");
                view.showTipNotification(errorMsg.toString());
            }
        }
    }


    /**
     * 初始化高亮设置，用于在比较两个版本的差异时，突出显示变更的部分。
     * 此方法主要用于配置和加载比较所需的数据显示和样式。
     */
    private void initHighLightSetting() {
        // 获取当前模型的数据
        IDataModel model = this.getModel();
        // 获取当前视图
        IFormView view = this.getView();
        // 获取视图代理，用于后续的比较操作
        IClientViewProxy proxy = this.getView().getService(IClientViewProxy.class);
        // 获取表单显示参数，其中可能包含比较的ID信息
        FormShowParameter formShowParameter = view.getFormShowParameter();
        // 从表单显示参数中获取比较ID
        Object compareId = formShowParameter.getCustomParam(VersionResumeBillInfoEdit.HighLight);

        // 如果没有比较ID，则不执行后续操作
        if (compareId == null) {
            return;
        }

        // 加载当前选中的数据实体
        DynamicObject selectData = model.getDataEntity(true);
        // 获取选中数据的类型
        DynamicObjectType selectType = selectData.getDynamicObjectType();
        // 根据比较ID和数据类型，加载比较的对象数据
        DynamicObject compareData = BusinessDataServiceHelper.loadSingle(compareId, selectType);

        // 查询变更方案的模板信息
        // 查询变更方案
        DynamicObject queryTemplate = NewVersionHelper.queryTemplate(selectType.getName());
        // 构建过滤条件，用于加载关联数据
        // 查询关联表数据
        QFilter qFilter = new QFilter("yem_tplid", QCP.equals, queryTemplate.getPkValue());
        qFilter.and(new QFilter("yem_masterid", QCP.equals, selectData.getLong("yem_masterid")));
        qFilter.and(new QFilter("yem_xmasterid", QCP.in, new Object[]{selectData.getPkValue(), compareData.getPkValue()}));
        // 定义加载字段
        String selectFields = DynamicObjectUtil.getSelectfields(KEY_REL, false);
        // 加载关联数据
        DynamicObject[] rels = BusinessDataServiceHelper.load(KEY_REL, selectFields, new QFilter[]{qFilter});

        // 执行动态对象的比较操作，突出显示差异部分
        this.compareDynamicObject(proxy, selectData, compareData, rels);

    }


    private void compareDynamicObject(IClientViewProxy proxy, DynamicObject selectData, DynamicObject compareData, DynamicObject[] rels) {
        compareDynamicObject(proxy, selectData, compareData, rels, null, null);
    }

    private void compareDynamicObject(IClientViewProxy proxy, DynamicObject selectData, DynamicObject compareData, DynamicObject[] rels, String entryKey, Integer rowIndex) {
        ArrayList<CellStyle> csList = new ArrayList<>();
        boolean isEntry = false;
        if (entryKey != null && !entryKey.isEmpty()) {
            isEntry = true;
        }

        DynamicObjectType selectType = selectData.getDynamicObjectType();
        DataEntityPropertyCollection selectProperties = selectType.getProperties();
        for (IDataEntityProperty selectProperty : selectProperties) {
            String name = selectProperty.getName();
            //分录处理
            if (selectProperty instanceof EntryProp) {
                //分录对象
                DynamicObjectCollection compareDynamicObjectCollection = compareData.getDynamicObjectCollection(name);
                DynamicObjectCollection selectDynamicObjectCollection = selectData.getDynamicObjectCollection(name);
                for (int i = 0; i < selectDynamicObjectCollection.size(); i++) {
                    DynamicObject selectObj = selectDynamicObjectCollection.get(i);
                    String src_selectEntryPk = null;
                    String selectEntryPk = selectObj.getPkValue() == null ? "" : selectObj.getPkValue().toString();
                    DynamicObject dynamicObject = null;
                    boolean isadd = false;//是追加的行
                    if (selectEntryPk.length() > 0) {
                        for (DynamicObject compareObj : compareDynamicObjectCollection) {
                            String src_compareEntryPk = null;
                            String compareEntryPk = compareObj.getPkValue() == null ? "" : compareObj.getPkValue().toString();//原始分录ID
                            if (compareEntryPk.length() > 0) {
                                //关联处理
                                for (DynamicObject rel : rels) {
                                    String yem_entitykey = rel.getString("yem_entitykey");//单据体标识
                                    String yem_pkid = rel.getString("yem_pkid");//原始主键
                                    String yem_xpkid = rel.getString("yem_xpkid");//变更单主键
                                    if (name.equals(yem_entitykey) && selectEntryPk.equals(yem_xpkid)) {
                                        src_selectEntryPk = yem_pkid;
                                    }
                                    if (name.equals(yem_entitykey) && compareEntryPk.equals(yem_xpkid)) {
                                        src_compareEntryPk = yem_pkid;
                                    }
                                }
                                if (src_selectEntryPk == null) {
                                    isadd = true;
                                } else if (src_selectEntryPk.equals(src_compareEntryPk)) {
                                    dynamicObject = compareObj;
                                }
                            }
                        }
                    }
                    if (isadd) {
                        ClientActions.createRowStyleBuilder()
                                .setRows(new int[]{i})
                                .setBackColor(VersionResumeBillInfoEdit.HighLightColor)
                                .buildStyle()
                                .build()
                                .invokeControlMethod(proxy, name);
                    } else if (dynamicObject != null) {
                        compareDynamicObject(proxy, selectObj, dynamicObject, rels, name, i);
                    }
                }
            }//多选基础资料类处理
            else if (selectProperty instanceof MulBasedataProp) {/*
				MulBasedataProp mulBasedataProp = ((MulBasedataProp) selectProperty);
				
				IDataEntityType itemType = mulBasedataProp.getItemType();
				ISimpleProperty primaryKey = itemType.getPrimaryKey();
				DynamicObjectCollection compareColls = (DynamicObjectCollection)compareData.get(name);
				compareColls.clear();
				DynamicObjectType toDynamicObjectType = compareColls.getDynamicObjectType();
				
				DynamicObjectCollection selectColls = (DynamicObjectCollection)selectData.get(name);
				for (DynamicObject coll : selectColls) {
					DynamicObject mulBaseData = new DynamicObject(toDynamicObjectType);
					compareDynamicObject(proxy, coll, mulBaseData);
					primaryKey.resetValue(mulBaseData);
					compareColls.add(mulBaseData);
				}
			*/
            }//多语言表处理
            else if (selectProperty instanceof DynamicLocaleProperty) {/*
				DynamicLocaleProperty localeProperty = ((DynamicLocaleProperty) selectProperty);
				
				IDataEntityType itemType = localeProperty.getItemType();
				ISimpleProperty primaryKey = itemType.getPrimaryKey();	
				DynamicObjectCollection compareColls = (DynamicObjectCollection)compareData.get(name);
				compareColls.clear();
				DynamicObjectType toDynamicObjectType = compareColls.getDynamicObjectType();
				
				DynamicObjectCollection selectColls = (DynamicObjectCollection)selectData.get(name);
				for (DynamicObject coll : selectColls) {
					DynamicObject mulBaseData = new DynamicObject(toDynamicObjectType);
					compareDynamicObject(proxy, coll, mulBaseData);
					primaryKey.resetValue(mulBaseData);
					compareColls.add(mulBaseData);
				}
			*/
            }//字段处理
            else {
                String selectCol = selectData.get(name) == null ? "null" :
                        selectData.get(name).toString() == null ? "null" : selectData.get(name).toString();
                String compareCol = compareData.get(name) == null ? "null" :
                        compareData.get(name).toString() == null ? "null" : compareData.get(name).toString();
                if (selectCol.equals(compareCol)) {
                    continue;
                }
                if (!isEntry) {
                    ClientActions.createControlStyleBuilder().setBackColor(VersionResumeBillInfoEdit.HighLightColor).build(proxy, name);
                } else {
                    CellStyle cs = new CellStyle();
                    cs.setBackColor(VersionResumeBillInfoEdit.HighLightColor);//外边框颜色
                    cs.setFieldKey(name);//列标识
                    cs.setRow(rowIndex);//行索引
                    csList.add(cs);
                }
            }
        }
        if (isEntry) {
            EntryGrid grid = this.getView().getControl(entryKey);//获取分录表体
            if (grid != null) {
                grid.setCellStyle(csList);//设置单元格样式
            }
        }
    }

}
