Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/UIDataServiceImpl.java
@@ -1,15 +1,19 @@
package com.vci.web.service.impl;
import com.vci.client.bof.ClientLinkObject;
import com.vci.client.bof.RevisionValueObject;
import com.vci.client.bof.VersionValueObject;
import com.vci.client.common.providers.ServiceProvider;
import com.vci.client.common.oq.OQTool;
import com.vci.common.qt.object.QueryTemplate;
import com.vci.corba.common.PLException;
import com.vci.corba.framework.data.UserInfo;
import com.vci.corba.omd.data.*;
import com.vci.corba.omd.lcm.LifeCycle;
import com.vci.file.pagemodel.VciFileObjectVO;
import com.vci.corba.omd.ltm.LinkType;
import com.vci.corba.omd.qtm.QTInfo;
import com.vci.corba.query.data.BOAndLO;
import com.vci.dto.*;
import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
import com.vci.frameworkcore.lcstatuspck.ReleaseDataLCStatus;
import com.vci.omd.utils.ObjectTool;
import com.vci.pagemodel.*;
import com.vci.starter.revision.bo.TreeWrapperOptions;
import com.vci.starter.web.annotation.bus.VciChangeDataAfter;
import com.vci.starter.web.annotation.bus.VciChangeDataBefore;
@@ -22,27 +26,29 @@
import com.vci.starter.web.pagemodel.*;
import com.vci.starter.web.util.*;
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
import com.vci.web.dto.*;
import com.vci.web.enumpck.DeleteTypeEnum;
import com.vci.web.enumpck.UIFieldTypeEnum;
import com.vci.web.enumpck.UITreeLoadTypeEnum;
import com.vci.web.pageModel.*;
import com.vci.web.query.UIDataGridQuery;
import com.vci.web.query.UIFormQuery;
import com.vci.web.query.UILinkTypeDataQuery;
import com.vci.web.query.UITreeQuery;
import com.vci.web.service.*;
import com.vci.web.util.Func;
import com.vci.web.util.PlatformClientUtil;
import com.vci.web.util.WebUtil;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.frameworkcore.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST;
import static com.vci.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST;
/**
 * UI上的数据查询
@@ -69,6 +75,11 @@
     */
    @Autowired
    private OsBtmServiceI btmService;
    /**
     * 属性服务
     */
    @Autowired
    private OsAttributeServiceI attrService;
    /**
     * 链接类型
@@ -130,11 +141,11 @@
     * @throws VciBaseException 查询出错的时候会抛出异常
     */
    @Override
    public DataGrid getDataForGrid(UIDataGridQuery dataGridQuery) throws VciBaseException {
    public DataGrid getDataForGrid(UIDataGridQuery dataGridQuery) throws VciBaseException, PLException {
        VciBaseUtil.alertNotNull(dataGridQuery,"查询对象",dataGridQuery.getBtmname(),"业务类型",dataGridQuery.getTableDefineId());
        //先判断查询模板
        UITableDefineVO tableDefineVO = uiEngineService.getComponentByOid(dataGridQuery.getComponentOid()).getTableDefineVO();
        String queryTemplate = !CollectionUtils.isEmpty(dataGridQuery.getSourceData())?dataGridQuery.getSourceData().getOrDefault("querytemplate",tableDefineVO.getQueryTemplateName()):tableDefineVO.getQueryTemplateName();
        UITableDefineVO tableDefineVO = uiEngineService.getComponentByOid(dataGridQuery.getComponentOid(),null).getTableDefineVO();
        String queryTemplate = !CollectionUtils.isEmpty(dataGridQuery.getSourceData())? (String) dataGridQuery.getSourceData().getOrDefault("querytemplate",tableDefineVO.getQueryTemplateName()) :tableDefineVO.getQueryTemplateName();
        if(StringUtils.isBlank(queryTemplate)){
            //说明没有设置查询模板,需要看看在这个表格所在的组件有没有设置
            tableDefineVO = uiEngineService.getTableById(dataGridQuery.getBtmname(), dataGridQuery.getTableDefineId());
@@ -171,14 +182,15 @@
            queryFieldList.addAll(linkTypeVO.getAttributes().stream().map(OsLinkTypeAttributeVO::getId).collect(Collectors.toList()));
            queryFieldList.addAll(WebLoServiceImpl.LO_BASE_FIELD_MAP.values());
        }else{
            btmTypeVO = btmService.getBtmById(dataGridQuery.getBtmname());
            //btmTypeVO = btmService.getBtmById(dataGridQuery.getBtmname());
            btmTypeVO = btmService.getBtmByName(dataGridQuery.getBtmname());
            queryFieldList.addAll(btmTypeVO.getAttributes().stream().map(OsBtmTypeAttributeVO::getId).collect(Collectors.toList()));
            queryFieldList.addAll(WebBoServiceImpl.BO_BASE_FIELD_MAP.values());
        }
        queryFieldList.add("creator_name");
        queryFieldList.add("lastmodifier_name");
        //我们在后台查询业务数据
        Map<String, String> replaceMap = wrapperReplaceMap( dataGridQuery.getSourceData());
        Map<String, Object> replaceMap = wrapperReplaceMap(dataGridQuery.getSourceData());
        if(dataGridQuery.isLinkTypeFlag()){
            UILinkTypeDataQuery linkTypeDataQuery = new UILinkTypeDataQuery();
@@ -192,8 +204,9 @@
            }
            return loService.queryGridByScheme(linkTypeDataQuery);
        }else {
            return boService.queryGridByScheme(queryTemplate,
            DataGrid dataGrid = boService.queryGridByScheme(queryTemplate,
                    dataGridQuery.getConditionMap(), replaceMap, dataGridQuery.getPageHelper(), queryFieldList.stream().collect(Collectors.toList()));
            return dataGrid;
        }
        //生命周期在其中查询后就会处理
        //枚举也会被处理了
@@ -207,10 +220,10 @@
     * @throws VciBaseException 查询出错的时候会抛出异常
     */
    @Override
    public UIFormDataVO getDataForForm(UIFormQuery formQuery) throws VciBaseException {
    public UIFormDataVO getDataForForm(UIFormQuery formQuery) throws VciBaseException, PLException {
        VciBaseUtil.alertNotNull(formQuery,"表单的查询对象",formQuery.getBtmname(),"业务类型的信息",formQuery.getOid(),"业务数据的主键",formQuery.getFormDefineId(),"表单的定义编号");
        UIFormDefineVO formDefineVO = uiEngineService.getFormById(formQuery.getBtmname(),formQuery.getFormDefineId());
        String queryTemplate = !CollectionUtils.isEmpty(formQuery.getSourceData())?formQuery.getSourceData().getOrDefault("querytemplate",formDefineVO.getQueryTemplateName()):formDefineVO.getQueryTemplateName();
        String queryTemplate = !CollectionUtils.isEmpty(formQuery.getSourceData())? (String) formQuery.getSourceData().getOrDefault("querytemplate",formDefineVO.getQueryTemplateName()) :formDefineVO.getQueryTemplateName();
        Set<String> queryFieldList = formDefineVO.getItems().stream().filter(s->!UIFieldTypeEnum.CUSTOM.getValue().equalsIgnoreCase(s.getType())).map(UIFormItemVO::getField).collect(Collectors.toSet());
        //获取参照
        List<UIFormItemVO> referFieldList = formDefineVO.getItems().stream().filter(s -> UIFieldTypeEnum.REFER.getValue().equalsIgnoreCase(s.getType())).collect(Collectors.toList());
@@ -237,17 +250,17 @@
            queryFieldList.addAll(linkTypeVO.getAttributes().stream().map(OsLinkTypeAttributeVO::getId).collect(Collectors.toList()));
            queryFieldList.addAll(WebLoServiceImpl.LO_BASE_FIELD_MAP.values());
        }else{
            btmTypeVO = btmService.getBtmById(formQuery.getBtmname());
            btmTypeVO = btmService.getBtmByName(formQuery.getBtmname());
            queryFieldList.addAll(btmTypeVO.getAttributes().stream().map(OsBtmTypeAttributeVO::getId).collect(Collectors.toList()));
        }
        queryFieldList.add("creator_name");
        queryFieldList.add("lastmodifier_name");
        Map<String,String> conditionMap = WebUtil.getOidQuery(formQuery.getOid());
        Map<String, String> replaceMap = wrapperReplaceMap(formQuery.getSourceData());
        Map<String, Object> replaceMap = wrapperReplaceMap(formQuery.getSourceData());
        UIFormDataVO formDataVO = new UIFormDataVO();
        replaceMap.put("oid", formQuery.getOid().trim());
        if(!formDefineVO.isLinkTypeFlag()) {
            List<com.vci.client.bof.ClientBusinessObject> cbos = null;
            List<BusinessObject> cbos = null;
            if (StringUtils.isNotBlank(queryTemplate)) {
                replaceMap.put("oid", formQuery.getOid().trim());
                cbos = boService.queryCBOByScheme(queryTemplate, conditionMap, replaceMap, null, queryFieldList.stream().collect(Collectors.toList()));
@@ -256,7 +269,7 @@
                cbos = boService.queryCBO(formQuery.getBtmname(), conditionMap, null, queryFieldList.stream().collect(Collectors.toList()));
            }
            if (!CollectionUtils.isEmpty(cbos)) {
                com.vci.client.bof.ClientBusinessObject cbo = cbos.get(0);
                BusinessObject cbo = cbos.get(0);
                formDataVO.setData(boService.cbo2Map(cbo));
            } else {
                throw new VciBaseException(DATA_OID_NOT_EXIST);
@@ -313,13 +326,14 @@
     * @param sourceDataMap 来源数据
     * @return 替换后的值
     */
    private Map<String,String> wrapperReplaceMap(Map<String,String> sourceDataMap){
        Map<String,String> replaceMap =!CollectionUtils.isEmpty(sourceDataMap)? sourceDataMap:new HashMap<>();
    private Map<String,Object> wrapperReplaceMap(Map<String,Object> sourceDataMap){
        Map<String,Object> replaceMap =!CollectionUtils.isEmpty(sourceDataMap)? sourceDataMap:new HashMap<>();
        if(!replaceMap.containsKey("f_oid")){
            replaceMap.put("f_oid",replaceMap.getOrDefault("oid",""));
        }
        if(replaceMap.get("f_oid").contains(TREE_NODE_ID_SEP)){
            replaceMap.put("f_oid",replaceMap.get("f_oid").split(TREE_NODE_ID_SEP)[1]);
        String fOid = replaceMap.get("f_oid").toString();
        if(fOid.contains(TREE_NODE_ID_SEP)){
            replaceMap.put("f_oid",fOid.split(TREE_NODE_ID_SEP)[1]);
        }
        return replaceMap;
    }
@@ -337,9 +351,10 @@
     * @throws VciBaseException 查询出错的时候会抛出异常
     */
    @Override
    public List<Tree> getDataForTree(UITreeQuery treeQuery) throws VciBaseException {
    public List<UIDataTree> getDataForTree(UITreeQuery treeQuery) throws Exception {
        VciBaseUtil.alertNotNull(treeQuery,"表单的查询对象",treeQuery.getBtmname(),"业务类型的信息",treeQuery.getComponentOid(),"树所在的组件的主键");
        UIComponentVO componentVO = uiEngineService.getComponentByOid(treeQuery.getComponentOid());
        Map<String, OsAttributeVO> attributeVOMap = attrService.selectAllAttributeMap();
        UIComponentVO componentVO = uiEngineService.getComponentByOid(treeQuery.getComponentOid(),attributeVOMap);
        if(componentVO == null || StringUtils.isBlank(componentVO.getOid())){
            throw new VciBaseException("树的配置信息没有获取到");
        }
@@ -351,14 +366,21 @@
        if(!treeQuery.isLinkTypeFlag() && StringUtils.isBlank(treeQuery.getParentBtmName())){
            treeQuery.setParentBtmName(treeQuery.getBtmname());
        }
        //TODO: 替换树定义上的正反向查询属性,因为正反向查询是由链接类型查询模板上控制的
        boolean isOrientation = false; //是否反向,使用模板上配置的
        String qtName = treeDefineVO.getQueryTemplateName();
        if(Func.isNotBlank(treeDefineVO.getLinkType()) && Func.isNotBlank(qtName)){
            QTInfo wrapper = platformClientUtil.getQTDService().getQT(qtName);
            QueryTemplate qt = OQTool.getQTByDoc(DocumentHelper.parseText(wrapper.qtText), qtName);
            isOrientation = qt.getDirection().equals("opposite");
        }
        if(treeQuery.getConditionMap() == null){
            treeQuery.setConditionMap(new HashMap<>());
        }
        if(treeQuery.getExtandParamsMap() != null){
            treeQuery.getConditionMap().putAll(treeQuery.getExtandParamsMap());
        }
        String parentFieldName = treeQuery.getParentFieldName();
       String parentFieldName = treeQuery.getParentFieldName();
        if(parentFieldName.contains(",")){
            parentFieldName = parentFieldName.split(",")[0];
        }
@@ -370,19 +392,19 @@
        if(StringUtils.isNotBlank(treeQuery.getParentOid()) && treeQuery.getParentOid().contains(TREE_NODE_ID_SEP)){
            treeQuery.setParentOid(treeQuery.getParentOid().split(TREE_NODE_ID_SEP)[1]);
        }
        String queryTemplate = StringUtils.isNotBlank(treeQuery.getQueryTemplate())?treeQuery.getQueryTemplate():(!CollectionUtils.isEmpty(treeQuery.getSourceData())?treeQuery.getSourceData().getOrDefault("querytemplate",treeDefineVO.getQueryTemplateName()):treeDefineVO.getQueryTemplateName());
        String valueField = treeQuery.isLinkTypeFlag()?(!treeDefineVO.isOrientation()?"${oid}" + TREE_NODE_ID_SEP + "${t_oid}":"${oid}" + TREE_NODE_ID_SEP + "${f_oid}"):(StringUtils.isNotBlank(treeQuery.getValueField())?treeQuery.getValueField():"oid");
        String queryTemplate = StringUtils.isNotBlank(treeQuery.getQueryTemplate())?treeQuery.getQueryTemplate():(!CollectionUtils.isEmpty(treeQuery.getSourceData())? (String) treeQuery.getSourceData().getOrDefault("querytemplate",treeDefineVO.getQueryTemplateName()) :treeDefineVO.getQueryTemplateName());
        String valueField = treeQuery.isLinkTypeFlag()?(!isOrientation?"${oid}" + TREE_NODE_ID_SEP + "${t_oid}":"${oid}" + TREE_NODE_ID_SEP + "${f_oid}"):(StringUtils.isNotBlank(treeQuery.getValueField())?treeQuery.getValueField():"oid");
        String textField = StringUtils.isNotBlank(treeDefineVO.getTreeNodeExpression())?treeDefineVO.getTreeNodeExpression():(StringUtils.isNotBlank(treeQuery.getTextField())?treeQuery.getTextField():"name");
        List<Tree> rootTreeList = new ArrayList<>();
        List<UIDataTree> rootTreeList = new ArrayList<>();
        List<String> queryFieldList = new ArrayList<>();
        queryFieldList.add("creator_name");
        queryFieldList.add("lastmodifier_name");
        String rootExpress = StringUtils.isNotBlank(treeQuery.getRootExpress())?treeQuery.getRootExpress():treeDefineVO.getRootContent();
        Map<String, String> replaceMap = wrapperReplaceMap(treeQuery.getSourceData());
        Map<String, Object> replaceMap = wrapperReplaceMap(treeQuery.getSourceData());
        if(StringUtils.isBlank(treeDefineVO.getLinkType())){
            //这个是业务类型的自参照
            //以前的平台没有对自参照这种有全部查询的
            OsBtmTypeVO btmTypeVO = btmService.getBtmById(treeDefineVO.getBtmType());
            OsBtmTypeVO btmTypeVO = btmService.getBtmByName(treeDefineVO.getBtmType());
            queryFieldList.addAll(btmTypeVO.getAttributes().stream().map(OsBtmTypeAttributeVO::getId).collect(Collectors.toList()));
            queryFieldList.addAll(WebBoServiceImpl.BO_BASE_FIELD_MAP.values());
@@ -391,7 +413,7 @@
            if(treeQuery.isQueryRoot()){
                //是查询根节点
                List<com.vci.client.bof.ClientBusinessObject> rootCbos = null;
                List<BusinessObject> rootCbos = null;
                if(StringUtils.isNotBlank(queryTemplate)){
                    //说明是菜单里定义了查询模板的
                    rootCbos = boService.queryCBOByScheme(queryTemplate, null, replaceMap);
@@ -401,7 +423,7 @@
                    if(StringUtils.isBlank(parentFieldNameAndValue) || !parentFieldNameAndValue.contains(",")){
                        throw new VciBaseException("配置的信息有误。在没有在菜单或者来源数据设置根节点的查询模板时,请在树的【参照树】上设置上级字段的名称和根节点的查询的值。比如xxxx,yyy。其中xxxx是上级字段英文名称");
                    }
                    parentFieldName= parentFieldNameAndValue.split(",")[0];
                    parentFieldName = parentFieldNameAndValue.split(",")[0];
                    String rootQueryValue = parentFieldNameAndValue.split(",")[1];
                    treeQuery.getConditionMap().put(parentFieldName,rootQueryValue);
                    replaceMap.put(parentFieldName,rootQueryValue);
@@ -427,7 +449,7 @@
                return rootTreeList;
            }else{
                //这个不是跟节点,但是一般只是增加一个逐级查询,因为全部查询的时候,在根节点已经全部查询完了
                List<com.vci.client.bof.ClientBusinessObject> thisChildren = null;
                List<BusinessObject> thisChildren = null;
                if (StringUtils.isNotBlank(queryTemplate)) {
                    thisChildren = boService.queryCBOByScheme(queryTemplate, treeQuery.getConditionMap(), replaceMap, null, queryFieldList);
                } else {
@@ -436,8 +458,10 @@
                return cbo2Trees(thisChildren, valueField, textField, parentFieldName, treeQuery.isShowCheckBox(), null);
            }
        }else{
            OsLinkTypeVO linkTypeVO = linkTypeService.getLinkTypeById(treeDefineVO.getLinkType());
            queryFieldList.addAll(linkTypeVO.getAttributes().stream().map(OsLinkTypeAttributeVO::getId).collect(Collectors.toList()));
            //OsLinkTypeVO linkTypeVO = linkTypeService.getLinkTypeById(treeDefineVO.getLinkType());
            LinkType linkType = platformClientUtil.getLinkTypeService().getLinkType(treeDefineVO.getLinkType());
            //queryFieldList.addAll(linkTypeVO.getAttributes().stream().map(OsLinkTypeAttributeVO::getId).collect(Collectors.toList()));
            queryFieldList.addAll(Arrays.asList(linkType.attributes));
            queryFieldList.addAll(WebLoServiceImpl.LO_BASE_FIELD_MAP.values());
            addQueryField(queryFieldList,valueField);
@@ -448,7 +472,7 @@
            linkTypeDataQuery.setConditionMap(treeQuery.getConditionMap());
            linkTypeDataQuery.setParentOid(treeQuery.getParentOid());
            linkTypeDataQuery.setClauseList(queryFieldList);
            linkTypeDataQuery.setDirection(treeDefineVO.isOrientation());
            linkTypeDataQuery.setDirection(isOrientation);
            linkTypeDataQuery.setToBtmType(treeDefineVO.getBtmType());
            linkTypeDataQuery.setLinkType(treeDefineVO.getLinkType());
            if(UITreeLoadTypeEnum.ALL.getValue().equalsIgnoreCase(treeDefineVO.getLoadType())){
@@ -456,7 +480,7 @@
            }
            if(treeQuery.isQueryRoot()){
                //查询根节点.我们需要判断是否设置了根节点的查询条件
                List<com.vci.corba.query.data.BOAndLO> rootCbos = null;
                List<BOAndLO> rootCbos = null;
                String parentFieldNameAndValue = treeDefineVO.getShowLinkAbs();
                if(StringUtils.isNotBlank(parentFieldNameAndValue)){
                    if(StringUtils.isNotBlank(queryTemplate)){
@@ -478,7 +502,7 @@
                    }
                    if(!CollectionUtils.isEmpty(rootCbos)){
                        if(StringUtils.isBlank(parentFieldName)){
                            if(treeDefineVO.isOrientation()){
                            if(isOrientation){
                                parentFieldName = "t_oid";
                            }else{
                                parentFieldName = "f_oid";
@@ -498,15 +522,15 @@
                    if(CollectionUtils.isEmpty(replaceMap)){
                        throw new VciBaseException("根节点没有配置查询条件,也没有来源数据");
                    }
                    Tree root = new Tree();
                    root.setOid(replaceMap.getOrDefault("oid",replaceMap.getOrDefault("t_oid","")));
                    UIDataTree root = new UIDataTree();
                    root.setOid((String) replaceMap.getOrDefault("oid",replaceMap.getOrDefault("t_oid","")));
                    root.setText(getValueByExpressForBOAndLO(new HashMap<>(),replaceMap,rootExpress));
                    root.setAttributes(replaceMap);
                    root.setIndex("0");
                    rootTreeList.add(root);
                    if(StringUtils.isBlank(parentFieldName)){
                        if(treeDefineVO.isOrientation()){
                        if(isOrientation){
                            parentFieldName = "t_oid";
                        }else{
                            parentFieldName = "f_oid";
@@ -526,11 +550,74 @@
                    if(linkTypeDataQuery.getReplaceMap() == null){
                        linkTypeDataQuery.setReplaceMap(new HashMap<>());
                    }
                    linkTypeDataQuery.getReplaceMap().put(treeDefineVO.isOrientation()?"t_oid":"f_oid",treeQuery.getParentOid());
                    linkTypeDataQuery.getReplaceMap().put(isOrientation?"t_oid":"f_oid",treeQuery.getParentOid());
                }
                return cloAndCbo2Trees(loService.queryCLOAndBoByLinkType(linkTypeDataQuery),valueField,textField,parentFieldName,treeQuery.isShowCheckBox(),treeQuery.getParentOid());
            }
        }
    }
    /**
     * 获取数据(根据查询模板查询对象,返回的结构按照ui定义,定义的模板类型返回)
     * @param treeQuery 树形查询条件
     * @return 树形数据
     * @throws VciBaseException 查询出错的时候会抛出异常
     */
    @Override
    public BaseResult getDataByTemp(UITreeQuery treeQuery) throws Exception {
        VciBaseUtil.alertNotNull(treeQuery,"表单的查询对象",treeQuery.getComponentOid(),"当前组件的主键");
        //1、先查询页面定义组件
        Map<String, OsAttributeVO> attributeVOMap = attrService.selectAllAttributeMap();
        UIComponentVO componentVO = uiEngineService.getComponentByOid(treeQuery.getComponentOid(),attributeVOMap);
        if(componentVO == null || StringUtils.isBlank(componentVO.getOid())){
            throw new VciBaseException("未获取到界面配置信息!");
        }
        // 2、根据配置的查询模板查询数据(需要考虑全面一点),
        // 这儿根据当前类型来获取是什么类型的查询模板,然后做对应的查询处理
        //TODO: 替换树定义上的正反向查询属性,因为正反向查询是由链接类型查询模板上控制的
        UITreeDefineVO treeDefineVO = componentVO.getTreeDefineVO();
        boolean isOrientation = false; //是否反向,使用模板上配置的
        String qtName = treeDefineVO.getQueryTemplateName();
        if(Func.isNotBlank(treeDefineVO.getLinkType()) && Func.isNotBlank(qtName)){
            QTInfo wrapper = platformClientUtil.getQTDService().getQT(qtName);
            QueryTemplate qt = OQTool.getQTByDoc(DocumentHelper.parseText(wrapper.qtText), qtName);
            isOrientation = qt.getDirection().equals("opposite");
        }
        String queryTemplate = StringUtils.isNotBlank(treeQuery.getQueryTemplate())?treeQuery.getQueryTemplate():(!CollectionUtils.isEmpty(treeQuery.getSourceData())? (String) treeQuery.getSourceData().getOrDefault("querytemplate",treeDefineVO.getQueryTemplateName()) :treeDefineVO.getQueryTemplateName());
        Map<String, Object> replaceMap = wrapperReplaceMap(treeQuery.getSourceData());
        List<String> queryFieldList = new ArrayList<>();
        String valueField = treeQuery.isLinkTypeFlag()?(!isOrientation?"${oid}" + TREE_NODE_ID_SEP + "${t_oid}":"${oid}" + TREE_NODE_ID_SEP + "${f_oid}"):(StringUtils.isNotBlank(treeQuery.getValueField())?treeQuery.getValueField():"oid");
        String textField = StringUtils.isNotBlank(treeDefineVO.getTreeNodeExpression())?treeDefineVO.getTreeNodeExpression():(StringUtils.isNotBlank(treeQuery.getTextField())?treeQuery.getTextField():"name");
        String rootExpress = StringUtils.isNotBlank(treeQuery.getRootExpress())?treeQuery.getRootExpress():treeDefineVO.getRootContent();
        String parentFieldName = treeQuery.getParentFieldName();
        if(parentFieldName.contains(",")){
            parentFieldName = parentFieldName.split(",")[0];
        }
        queryFieldList.add("creator_name");
        queryFieldList.add("lastmodifier_name");
        OsBtmTypeVO btmTypeVO = btmService.getBtmByName(treeDefineVO.getBtmType());
        queryFieldList.addAll(btmTypeVO.getAttributes().stream().map(OsBtmTypeAttributeVO::getId).collect(Collectors.toList()));
        queryFieldList.addAll(WebBoServiceImpl.BO_BASE_FIELD_MAP.values());
        addQueryField(queryFieldList,valueField);
        addQueryField(queryFieldList,textField);
        List<BusinessObject> rootCbos = boService.queryCBOByScheme(queryTemplate, null, replaceMap);
        //3、根据不同的组件返回不同的数据类型(树、列表、树表、自定义模板、表单等)
        List<UIDataTree> rootTreeList = null;
        if(!CollectionUtils.isEmpty(rootCbos)){
            rootTreeList = cbo2Trees(rootCbos,valueField,StringUtils.isBlank(rootExpress)?textField:rootExpress,parentFieldName,treeQuery.isShowCheckBox(),null);
            TreeQueryObject treeQueryObject = new TreeQueryObject();
            treeQueryObject.setValueField(valueField);
            treeQueryObject.setTextField(textField);
            treeQueryObject.setParentFieldName(parentFieldName);
            treeQueryObject.setShowCheckBox(treeQuery.isShowCheckBox());
            if(UITreeLoadTypeEnum.ALL.getValue().equalsIgnoreCase(treeDefineVO.getLoadType())){
                treeQueryObject.setQueryAllLevel(false);
            }
            //queryTreeForBO(rootTreeList,treeDefineVO.getQueryTemplateName(),queryFieldList,treeQueryObject);
        }
        return BaseResult.tree(rootTreeList);
    }
    /**
@@ -540,19 +627,19 @@
     * @param queryFieldList 查询的字段
     * @param treeQueryObject 树形查询对象,需要valueField和textField,还有parentFieldName,和checkBox
     */
    private void queryTreeForBO(List<Tree> rootTreeList, String queryTemplate,List<String> queryFieldList,TreeQueryObject treeQueryObject) {
        for (Tree rootTree : rootTreeList) {
            List<com.vci.client.bof.ClientBusinessObject> thisChildren = null;
            Map<String,String> sourceDataMap = rootTree.getAttributes();
    private void queryTreeForBO(List<UIDataTree> rootTreeList, String queryTemplate,List<String> queryFieldList,TreeQueryObject treeQueryObject) {
        for (UIDataTree rootTree : rootTreeList) {
            List<BusinessObject> thisChildren = null;
            Map<String,Object> sourceDataMap = rootTree.getAttributes();
            sourceDataMap.put("f_oid",rootTree.getOid());
            Map<String,String> conditionMap = new HashMap<>();
            conditionMap.put(treeQueryObject.getParentFieldName(),rootTree.getOid());
            if (StringUtils.isNotBlank(queryTemplate)) {
                thisChildren = boService.queryCBOByScheme(queryTemplate, conditionMap, sourceDataMap, null, queryFieldList);
            } else {
                thisChildren = boService.queryCBO(sourceDataMap.getOrDefault("btmname",sourceDataMap.getOrDefault("btmName",treeQueryObject.getParentBtmName())), conditionMap, null, queryFieldList);
                thisChildren = boService.queryCBO((String) sourceDataMap.getOrDefault("btmname",sourceDataMap.getOrDefault("btmName",treeQueryObject.getParentBtmName())), conditionMap, null, queryFieldList);
            }
            List<Tree> childrenTree = cbo2Trees(thisChildren, treeQueryObject.getValueField(), treeQueryObject.getTextField(), treeQueryObject.getParentFieldName(), treeQueryObject.isShowCheckBox(), null);
            List<UIDataTree> childrenTree = cbo2Trees(thisChildren, treeQueryObject.getValueField(), treeQueryObject.getTextField(), treeQueryObject.getParentFieldName(), treeQueryObject.isShowCheckBox(), null);
            rootTree.setChildren(childrenTree);
            if(treeQueryObject.isQueryAllLevel() && !CollectionUtils.isEmpty(childrenTree) ) {
                queryTreeForBO(childrenTree,queryTemplate,queryFieldList,treeQueryObject);
@@ -569,8 +656,8 @@
     * @param textField 显示表达式
     * @param showCheckBox 是否显示复选框
     */
    private void queryTreeForLO(List<Tree> rootTreeList, UILinkTypeDataQuery linkTypeDataQuery,String parentFieldName,String valueField,String textField,boolean showCheckBox) {
        for (Tree rootTree : rootTreeList) {
    private void queryTreeForLO(List<UIDataTree> rootTreeList, UILinkTypeDataQuery linkTypeDataQuery,String parentFieldName,String valueField,String textField,boolean showCheckBox) {
        for (UIDataTree rootTree : rootTreeList) {
            Map<String,String> conditionMap = new HashMap<>();
            conditionMap.put(linkTypeDataQuery.isDirection()?"t_oid":"f_oid",rootTree.getOid());
            linkTypeDataQuery.setConditionMap(conditionMap);
@@ -589,18 +676,21 @@
     * @param parentOid 上级的主键
     * @return 树
     */
    private List<Tree> cbo2Trees(Collection<com.vci.client.bof.ClientBusinessObject> cbos,String valueField,String textField,String parentFieldName,boolean showCheckBox,String parentOid){
    private List<UIDataTree> cbo2Trees(Collection<BusinessObject> cbos,String valueField,String textField,String parentFieldName,boolean showCheckBox,String parentOid){
        final int[] i = {0};
        List<Tree> rootList = new ArrayList<>();
        List<Tree> children = new ArrayList<>();
        List<UIDataTree> rootList = new ArrayList<>();
        List<UIDataTree> children = new ArrayList<>();
        cbos.stream().forEach(cbo->{
            Tree tree = new Tree();
            UIDataTree tree = new UIDataTree();
            tree.setOid(getValueByExpress(cbo,valueField));
            tree.setText(getValueByExpress(cbo,textField));
            if(StringUtils.isNotBlank(parentFieldName)){
                tree.setParentId(cbo.getAttributeValue(parentFieldName));
                tree.setParentId(ObjectTool.getBOAttributeValue(cbo,parentFieldName));
            }
            tree.setAttributes(boService.cbo2Map(cbo));
            Map<String,Object> cbo2Map = boService.cbo2Map(cbo);
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put((String) cbo2Map.get("btmname"),cbo2Map);
            tree.setAttributes(returnMap);
            tree.setIndex(i[0] + "");
            i[0]++;
            tree.setChecked(showCheckBox);
@@ -614,7 +704,7 @@
        if(rootList.size() == 0 && children.size() == 0){
            return rootList;
        }
        return Tree.getChildList(rootList,children);
        return UIDataTree.getChildList(rootList,children);
    }
    /**
@@ -627,36 +717,41 @@
     * @param parentOid 上级的值
     * @return 树形数据
     */
    public List<Tree> cloAndCbo2Trees(Collection<com.vci.corba.query.data.BOAndLO> boAndLOS,String valueField,String textField,String parentFieldName,boolean showCheckBox,String parentOid){
    public List<UIDataTree> cloAndCbo2Trees(Collection<BOAndLO> boAndLOS, String valueField, String textField, String parentFieldName, boolean showCheckBox, String parentOid){
        final int[] i = {0};
        List<Tree> rootList = new ArrayList<>();
        List<Tree> children = new ArrayList<>();
        List<UIDataTree> rootList = new ArrayList<>();
        List<UIDataTree> children = new ArrayList<>();
        boAndLOS.stream().forEach(boAndLO->{
            Tree tree = new Tree();
            com.vci.client.bof.ClientBusinessObject cbo = new com.vci.client.bof.ClientBusinessObject();
            cbo.setBusinessObject(boAndLO.bo);
            com.vci.client.bof.ClientLinkObject clo = new com.vci.client.bof.ClientLinkObject();
            clo.setLinkObject(boAndLO.lo);
            Map<String,String> cloMap = loService.clo2Map(clo);
            Map<String,String> cbo2Map = boService.cbo2Map(cbo);
            if(!CollectionUtils.isEmpty(cbo2Map)){
            UIDataTree tree = new UIDataTree();
            BusinessObject cbo = new BusinessObject();
            cbo = boAndLO.bo;
            LinkObject clo = new LinkObject();
            clo = boAndLO.lo;
            Map<String,Object> cloMap = loService.clo2Map(clo);
            Map<String,Object> cbo2Map = boService.cbo2Map(cbo);
            /*if(!CollectionUtils.isEmpty(cbo2Map)){
                cbo2Map.forEach((key,value)->{
                    cloMap.put(parentFieldName + "." + key,value);
                    //TODO: 这儿为啥要拼接上parentFieldName,导致后面freemarker表达式无法正确替换
                    cloMap.put(/*parentFieldName + "." + key,value);
                });
            }
            }*/
            tree.setOid(getValueByExpressForBOAndLO(cloMap,cbo2Map,valueField));
            tree.setText(getValueByExpressForBOAndLO(cloMap,cbo2Map,textField));
            if(StringUtils.isBlank(parentFieldName)){
                tree.setParentId(boAndLO.lo.oid + TREE_NODE_ID_SEP + boAndLO.lo.fromOid);
            }else {
                if (parentFieldName.contains(".")) {
                    tree.setParentId(cbo.getAttributeValue(parentFieldName));
                    tree.setParentId(ObjectTool.getBOAttributeValue(cbo,parentFieldName));
                } else {
                    tree.setParentId(clo.getAttributeValue(parentFieldName));
                    tree.setParentId(ObjectTool.getLOAttributeValue(clo,parentFieldName));
                }
            }
            tree.setAttributes(cbo2Map);
            //TODO:返回的数据改成按链接类型和业务类型为key:值为对应的属性集合形式返回
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put((String) cloMap.get("linktypename"),cloMap);
            returnMap.put((String) cbo2Map.get("btmname"),cbo2Map);
            tree.setAttributes(returnMap);
            tree.setIndex(i[0] + "");
            i[0]++;
            tree.setChecked(showCheckBox);
@@ -668,7 +763,7 @@
            }
        });
        return Tree.getChildList(rootList,children);
        return UIDataTree.getChildList(rootList,children);
    }
    /**
@@ -677,7 +772,7 @@
     * @param fieldExpress 表达式的值
     * @return 转换后的值
     */
    private String getValueByExpress(com.vci.client.bof.ClientBusinessObject cbo,String fieldExpress){
    private String getValueByExpress(BusinessObject cbo,String fieldExpress){
        if(StringUtils.isBlank(fieldExpress)){
            return "";
        }
@@ -688,7 +783,7 @@
            List<String> fieldList = VciBaseUtil.str2List(fieldExpress);
            StringBuilder sb = new StringBuilder();
            fieldList.stream().forEach(field->{
                sb.append(cbo.getAttributeValue(field)).append(" ");
                sb.append(ObjectTool.getBOAttributeValue(cbo,field)).append(" ");
            });
            return sb.toString().trim();
        }
@@ -700,17 +795,30 @@
     * @param fieldExpress 表达式
     * @return 替换后的值
     */
    private String getValueByExpressForBOAndLO(Map<String,String> valueMap,Map<String,String> boValueMap,String fieldExpress){
    private String getValueByExpressForBOAndLO(Map<String,Object> valueMap,Map<String,Object> boValueMap,String fieldExpress){
        if(fieldExpress.contains("${")){
            //使用freemarker处理
            return VciBaseUtil.replaceByFreeMarker(fieldExpress,valueMap);
            /*
            TODO:表达式存在T_OID.name这种形式时freemarker替换规则是从T_OID这个对象中招name属性,
                但是valueMap是一个String,String的Map所以需要将T_OID.或F_OID.去掉,因为不管是查询的
                form端还是to端都是平台查好放在业务属性boValueMap集合中的,所以直接替就可以
            */
            if(fieldExpress.contains(".")){
                //去除t_oid、T_OID以及f_oid、F_OID
                fieldExpress = fieldExpress
                        .replace("t_oid.","")
                        .replace("T_OID.","")
                        .replace("f_oid.","")
                        .replace("F_OID.","");
            }
            return VciBaseUtil.replaceByFreeMarker(fieldExpress,boValueMap);
        }else {
            List<String> fieldList = VciBaseUtil.str2List(fieldExpress);
            Map<String,String> valueLowMap = new HashMap<>();
            Map<String,Object> valueLowMap = new HashMap<>();
            valueMap.forEach((key,value)->{
                valueLowMap.put(key.toLowerCase(),value);
            });
            Map<String,String> boLowValueMap = new HashMap<>();
            Map<String,Object> boLowValueMap = new HashMap<>();
            if(!CollectionUtils.isEmpty(boValueMap)){
                boValueMap.forEach((key,value)->{
                    boLowValueMap.put(key.toLowerCase(),value);
@@ -718,7 +826,7 @@
            }
            StringBuilder sb = new StringBuilder();
            fieldList.stream().forEach(field->{
                sb.append(valueLowMap.getOrDefault(field,boLowValueMap.getOrDefault(field,""))).append(" ");
                sb.append(boLowValueMap.getOrDefault(field,valueLowMap.getOrDefault(field,""))).append(" ");
            });
            return sb.toString().trim();
        }
@@ -762,7 +870,7 @@
     * @throws VciBaseException 配置或者是调用不成功的时候,会抛出异常
     */
    @Override
    public BaseResult callPreEvent(BaseModelDTOList baseModelDTOList,BaseLinkModelDTOList baseLinkModelDTOList, String preEvent, VciChangeDocumentTypeEnum businessType) throws VciBaseException{
    public BaseResult callPreEvent(BaseModelDTOList baseModelDTOList, BaseLinkModelDTOList baseLinkModelDTOList, String preEvent, VciChangeDocumentTypeEnum businessType) throws VciBaseException{
        if((baseModelDTOList == null || CollectionUtils.isEmpty(baseModelDTOList.getDataList())) && (baseLinkModelDTOList == null || CollectionUtils.isEmpty(baseLinkModelDTOList.getDataList()))){
            return BaseResult.success();
        }
@@ -869,12 +977,12 @@
     * @throws VciBaseException 执行出错的会抛出异常,或者事件直接返回了异常
     */
    @Override
    public BaseResult callPostEvent(Collection<com.vci.client.bof.ClientBusinessObject> cbos, Collection<com.vci.client.bof.ClientLinkObject> clos, String postEvent, VciChangeDocumentTypeEnum businessType) throws VciBaseException{
    public BaseResult callPostEvent(Collection<BusinessObject> cbos, Collection<LinkObject> clos, String postEvent, VciChangeDocumentTypeEnum businessType) throws VciBaseException{
        if(CollectionUtils.isEmpty(cbos)){
            return BaseResult.success();
        }
        String btmType = !CollectionUtils.isEmpty(cbos)?cbos.stream().findFirst().get().getBtmName():null;
        String linkType = !CollectionUtils.isEmpty(clos)?clos.stream().findFirst().get().getLinkObject().ltName:null;
        String btmType = !CollectionUtils.isEmpty(cbos)?cbos.stream().findFirst().get().btName:null;
        String linkType = !CollectionUtils.isEmpty(clos)?clos.stream().findFirst().get().ltName:null;
        if(StringUtils.isNotBlank(postEvent)){
            //前置事件
            //bean的名字#方法; 或者全路径。最后一个是方法的名字
@@ -1048,7 +1156,7 @@
     * @throws VciBaseException 保存出错的时候会抛出异常
     */
    @Override
    public BaseResult<Map<String, Object>> addSave(FormDataDTO formDataDTO) throws VciBaseException {
    public BaseResult<Map<String, Object>> addSave(FormDataDTO formDataDTO) throws VciBaseException, PLException {
        //首先判断对象是否为空
        VciBaseUtil.alertNotNull(formDataDTO,"添加的数据对象",formDataDTO.getBtmname(),"业务类型的名称",formDataDTO.getFormDefineId(),"表单定义的编号");
        UIFormDefineVO formDefineVO = uiEngineService.getFormById(formDataDTO.getBtmname(), formDataDTO.getFormDefineId());
@@ -1060,35 +1168,32 @@
            return beforeResult;
        }
        //封装数据
        BaseResult<com.vci.client.bof.ClientBusinessObject> resultCbo = wrapperCbo(formDataDTO,formDefineVO,false,false,false);
        BaseResult<BusinessObject> resultCbo = wrapperCbo(formDataDTO,formDefineVO,false,false,false);
        if(!resultCbo.isSuccess()){
            return BaseResult.fail(resultCbo.getMsg(),resultCbo.getMsgObjs());
        }
        //执行保存
        BaseResult<Map<String,Object>> result = BaseResult.success();
        com.vci.client.bof.ClientBusinessObject afterCBO = null;
        BusinessObject afterCBO = null;
        try {
//            BusinessObject resultBO = platformClientUtil.getBOFactoryService().createBusinessObject(resultCbo.getObj().getBusinessObject(),false,false);
//            BusinessObject resultBO = ServiceProvider.getBOFService().createBusinessObject(resultCbo.getObj().getBusinessObject(),false,false);
            BusinessObject resultBO = ServiceProvider.getBOFService().createBusinessObject(resultCbo.getObj().getBusinessObject(),false,false);
            afterCBO = new com.vci.client.bof.ClientBusinessObject();
            afterCBO.setBusinessObject(resultBO);
            BusinessObject resultBO = platformClientUtil.getBOFService().createBusinessObject(resultCbo.getObj(),false,false);
            afterCBO = new BusinessObject();
            afterCBO = resultBO;
            result.setObj(boService.cbo2Map(afterCBO));
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        if(!CollectionUtils.isEmpty(formDataDTO.getReleaseFileOids())){
            fileObjectService.releasedFile(afterCBO.getBtmName(),afterCBO.getOid(),formDataDTO.getReleaseFileOids());
            fileObjectService.releasedFile(afterCBO.btName,afterCBO.oid,formDataDTO.getReleaseFileOids());
        }
        //后置事件
        String afterEvent = formDataDTO.getPostEvent();
        try {
            callPostEvent(Arrays.stream(new com.vci.client.bof.ClientBusinessObject[]{afterCBO}).collect(Collectors.toList()),null, afterEvent, VciChangeDocumentTypeEnum.ADD);
            callPostEvent(Arrays.stream(new BusinessObject[]{afterCBO}).collect(Collectors.toList()),null, afterEvent, VciChangeDocumentTypeEnum.ADD);
        }catch (Throwable e){
            //说明后置事件出现了错误,那么就需要删除以前的这条数据
            try {
//                platformClientUtil.getBOFactoryService().deleteBusinessObject(afterCBO.getBusinessObject(),1);
                ServiceProvider.getBOFService().deleteBusinessObject(afterCBO.getBusinessObject(),1);
                platformClientUtil.getBOFService().deleteBusinessObject(afterCBO,1);
            } catch (PLException vciError) {
                throw WebUtil.getVciBaseException(vciError);
            }
@@ -1107,7 +1212,7 @@
     * @param newVersion 新版次
     * @return  执行的结果
     */
    private BaseResult<com.vci.client.bof.ClientBusinessObject> wrapperCbo(FormDataDTO formDataDTO,UIFormDefineVO formDefineVO,boolean editFlag,boolean newRevision,boolean newVersion){
    private BaseResult<BusinessObject> wrapperCbo(FormDataDTO formDataDTO,UIFormDefineVO formDefineVO,boolean editFlag,boolean newRevision,boolean newVersion) throws PLException {
        //扩展属性的值
        Map<String, String> data = formDataDTO.getData();
        Map<String,String> dataLow = new HashMap<>();
@@ -1135,7 +1240,7 @@
        Map<String,String> baseDataMap = formDataDTO2MapLow(formDataDTO);
        Map<String,String> allDataMapLow = new HashMap<>();
        allDataMapLow.putAll(dataLow);
//        allDataMapLow.putAll(baseDataMap);
        allDataMapLow.putAll(baseDataMap);
        //判断必输项
        BaseResult result = checkRequired(formDefineVO,null,allDataMapLow);
        if(!result.isSuccess()){
@@ -1148,7 +1253,7 @@
        if(!result.isSuccess()){
            return result;
        }
        com.vci.client.bof.ClientBusinessObject cbo = createOrGetCbo(dataLow,baseDataMap,editFlag,newRevision,newVersion);
        BusinessObject cbo = createOrGetCbo(dataLow,baseDataMap,editFlag,newRevision,newVersion);
        return BaseResult.success(cbo);
    }
@@ -1158,41 +1263,41 @@
     * @return 基础对象
     */
    @Override
    public BaseModel cbo2BaseModel(com.vci.client.bof.ClientBusinessObject cbo){
    public BaseModel cbo2BaseModel(BusinessObject cbo){
        BaseModel baseModel = new BaseModel();
        baseModel.setOid(cbo.getOid());
        baseModel.setNameOid(cbo.getNameoid());
        baseModel.setRevisionOid(cbo.getRevisionid());
        baseModel.setBtmname(cbo.getBtmName());
        baseModel.setLastR(String.valueOf(cbo.getIsLastR()));
        baseModel.setLastV(String.valueOf(cbo.getIsLastV()));
        baseModel.setFirstR(String.valueOf(cbo.getIsFirstR()));
        baseModel.setFirstV(String.valueOf(cbo.getIsFirstV()));
        baseModel.setCreator(cbo.getCreator());
        baseModel.setOid(cbo.oid);
        baseModel.setNameOid(cbo.nameoid);
        baseModel.setRevisionOid(cbo.revisionid);
        baseModel.setBtmname(cbo.btName);
        baseModel.setLastR(String.valueOf(cbo.isLastR));
        baseModel.setLastV(String.valueOf(cbo.isLastV));
        baseModel.setFirstR(String.valueOf(cbo.isFirstR));
        baseModel.setFirstV(String.valueOf(cbo.isFirstV));
        baseModel.setCreator(cbo.creator);
        try {
            baseModel.setCreateTime(new Date(cbo.getCreateTime()));
            baseModel.setLastModifyTime(new Date(cbo.getLastModifyTime()));
            baseModel.setTs(new Date(cbo.getTs()));
            baseModel.setCreateTime(new Date(cbo.createTime));
            baseModel.setLastModifyTime(new Date(cbo.modifyTime));
            baseModel.setTs(new Date(cbo.ts));
//            baseModel.setCheckInTime(VciDateUtil.str2Date(cbo.getCheckinTime(), VciDateUtil.DateTimeFormat));
//            baseModel.setCheckOutTime(VciDateUtil.str2Date(cbo.getCheckoutTime(), VciDateUtil.DateTimeFormat));
        }catch (Throwable e){
        }
        baseModel.setLastModifier(cbo.getLastModifier());
        baseModel.setRevisionRule(cbo.getRevisionRule());
        baseModel.setVersionRule(cbo.getVersionRule());
        baseModel.setRevisionSeq(cbo.getRevisionSeq());
        baseModel.setRevisionValue(cbo.getRevisionValue());
        baseModel.setVersionSeq(cbo.getVersionSeq());
        baseModel.setVersionValue(cbo.getVersionValue());
        baseModel.setLcStatus(cbo.getLcStatus());
        baseModel.setId(cbo.getId());
        baseModel.setName(cbo.getName());
        baseModel.setDescription(cbo.getDescription());
        baseModel.setOwner(cbo.getOwner());
        baseModel.setLastModifier(cbo.modifier);
        baseModel.setRevisionRule(cbo.revisionRule);
        baseModel.setVersionRule(cbo.versionRule);
        baseModel.setRevisionSeq(cbo.revisionSeq);
        baseModel.setRevisionValue(cbo.revisionValue);
        baseModel.setVersionSeq(cbo.versionSeq);
        baseModel.setVersionValue(cbo.versionValue);
        baseModel.setLcStatus(cbo.lcStatus);
        baseModel.setId(cbo.id);
        baseModel.setName(cbo.name);
        baseModel.setDescription(cbo.description);
        baseModel.setOwner(cbo.owner);
//        baseModel.setCheckInBy(cbo.getCheckinBy());
//        baseModel.setCheckOutBy(cbo.getCheckoutBy());
        baseModel.setCopyFromVersion(cbo.getCopyFromVersion());
        baseModel.setCopyFromVersion(cbo.fromVersion);
        return baseModel;
    }
@@ -1240,12 +1345,12 @@
     * @return 版本的对象
     */
    @Override
    public RevisionValueObject getNextRevision(OsBtmTypeVO btmTypeVO, BaseModel baseModel){
    public RevisionDataInfo getNextRevision(OsBtmTypeVO btmTypeVO, BaseModel baseModel){
        try {
            if(baseModel.getRevisionValue() == null){
                baseModel.setRevisionValue("");
            }
            return  changeRevisionValueInfoToObject(platformClientUtil.getBOFactoryService().getNextRevisionValueObject(WebUtil.getTableName(btmTypeVO.getId()),baseModel.getNameOid(),btmTypeVO.getRevisionRuleId(),btmTypeVO.isInputRevisionFlag(),baseModel.getRevisionValue()));
            return  changeRevisionValueInfoToObject(platformClientUtil.getBOFactoryService().getNextRevisionValueObject(btmTypeVO.getId(),baseModel.getNameOid(),btmTypeVO.getRevisionRuleId(),btmTypeVO.isInputRevisionFlag(),baseModel.getRevisionValue()));
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
@@ -1256,10 +1361,10 @@
     * @param info corba对象
     * @return java对象
     */
    private RevisionValueObject changeRevisionValueInfoToObject(RevisionDataInfo info) {
        RevisionValueObject object = new RevisionValueObject();
        object.setRevisionVal(info.revisionVal);
        object.setRevisionSeq(info.revisionSeq);
    private RevisionDataInfo changeRevisionValueInfoToObject(RevisionDataInfo info) {
        RevisionDataInfo object = new RevisionDataInfo();
        object.revisionVal = info.revisionVal;
        object.revisionSeq = info.revisionSeq;
        return object;
    }
@@ -1270,7 +1375,7 @@
     * @return 版本的值对象
     */
    @Override
    public VersionValueObject getNextVersion(OsBtmTypeVO btmTypeVO, BaseModel baseModel){
    public VersionDataInfo getNextVersion(OsBtmTypeVO btmTypeVO, BaseModel baseModel){
        try{
            return changeRevisionValueInfoToObject(platformClientUtil.getBOFactoryService().getNextVersionValue(WebUtil.getTableName(btmTypeVO.getId()),baseModel.getRevisionOid(),baseModel.getNameOid(),WebUtil.getInt(btmTypeVO.getVersionRule())));
        }catch (PLException vciError){
@@ -1283,10 +1388,10 @@
     * @param info 版次的值
     * @return java对象
     */
    private VersionValueObject changeRevisionValueInfoToObject(VersionDataInfo info) {
        VersionValueObject object = new VersionValueObject();
        object.setVersionVal(info.versionVal);
        object.setVersionSeq(info.versionSeq);
    private VersionDataInfo changeRevisionValueInfoToObject(VersionDataInfo info) {
        VersionDataInfo object = new VersionDataInfo();
        object.versionVal = info.versionVal;
        object.versionSeq = info.versionSeq;
        return object;
    }
    /**
@@ -1316,7 +1421,7 @@
     * @throws VciBaseException 保存出错的时候会抛出异常
     */
    @Override
    public BaseResult<String> batchAddSave(FormDataDTOList formDataDTOList) throws VciBaseException {
    public BaseResult<String> batchAddSave(FormDataDTOList formDataDTOList) throws VciBaseException, PLException {
        VciBaseUtil.alertNotNull(formDataDTOList,"要添加的数据",formDataDTOList.getFormDataDTOS(),"要添加的数据");
        //首先判断对象是否为空
        FormDataDTO firstFormDataDTO = formDataDTOList.getFormDataDTOS().stream().findFirst().get();
@@ -1331,26 +1436,25 @@
        //封装数据
        List<BusinessObject> addBos = new ArrayList<>();
        List<BusinessObject> afterBOs = new ArrayList<>();
        List<com.vci.client.bof.ClientBusinessObject> afterCBOs = new ArrayList<>();
        List<BusinessObject> afterCBOs = new ArrayList<>();
        Map<String,List<String>> releasedFileOids = new HashMap<>();
        for(FormDataDTO formDataDTO:formDataDTOList.getFormDataDTOS()) {
            BaseResult<com.vci.client.bof.ClientBusinessObject> resultCbo = wrapperCbo(formDataDTO, formDefineVO, false, false, false);
            BaseResult<BusinessObject> resultCbo = wrapperCbo(formDataDTO, formDefineVO, false, false, false);
            if (!resultCbo.isSuccess()) {
                return BaseResult.fail(resultCbo.getMsg(), resultCbo.getMsgObjs());
            }
            addBos.add(resultCbo.getObj().getBusinessObject());
            addBos.add(resultCbo.getObj());
            //执行保存
            if (!CollectionUtils.isEmpty(formDataDTO.getReleaseFileOids())) {
                releasedFileOids.put(resultCbo.getObj().getOid(),formDataDTO.getReleaseFileOids());
                releasedFileOids.put(resultCbo.getObj().oid,formDataDTO.getReleaseFileOids());
            }
        }
        try {
//            BusinessObject[] resultBOs = platformClientUtil.getBOFactoryService().batchCreateBusinessObject(addBos.toArray(new BusinessObject[0]), false, false);
            BusinessObject[] resultBOs = ServiceProvider.getBOFService().batchCreateBusinessObject(addBos.toArray(new BusinessObject[0]), false, false);
            BusinessObject[] resultBOs = platformClientUtil.getBOFService().batchCreateBusinessObject(addBos.toArray(new BusinessObject[0]), false, false);
            afterBOs = Arrays.stream(resultBOs).collect(Collectors.toList());
            Arrays.stream(resultBOs).forEach(bo->{
                com.vci.client.bof.ClientBusinessObject cbo = new com.vci.client.bof.ClientBusinessObject();
                cbo.setBusinessObject(bo);
                BusinessObject cbo = new BusinessObject();
                cbo = bo;
                afterCBOs.add(cbo);
            });
        } catch (PLException vciError) {
@@ -1368,7 +1472,7 @@
        }catch (Throwable e){
            //说明后置事件出现了错误,那么就需要删除以前的这条数据
            try {
                platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(afterBOs.toArray(new BusinessObject[0]),1);
                platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(afterBOs.toArray(new BusinessObject[0]),DeleteTypeEnum.OID_AND_TS.getValue());
            } catch (PLException vciError) {
                throw WebUtil.getVciBaseException(vciError);
            }
@@ -1387,7 +1491,7 @@
     * @throws VciBaseException 保存出错的时候会抛出异常
     */
    @Override
    public BaseResult<Map<String, Object>> editSave(FormDataDTO formDataDTO) throws VciBaseException {
    public BaseResult<Map<String, Object>> editSave(FormDataDTO formDataDTO) throws VciBaseException, PLException {
        //首先判断对象是否为空
        VciBaseUtil.alertNotNull(formDataDTO,"修改的数据对象",formDataDTO.getBtmname(),"业务类型的名称",formDataDTO.getFormDefineId(),"表单定义的编号");
        UIFormDefineVO formDefineVO = uiEngineService.getFormById(formDataDTO.getBtmname(), formDataDTO.getFormDefineId());
@@ -1399,26 +1503,25 @@
            return beforeResult;
        }
        //封装数据
        BaseResult<com.vci.client.bof.ClientBusinessObject> resultCbo = wrapperCbo(formDataDTO,formDefineVO,true,false,false);
        BaseResult<BusinessObject> resultCbo = wrapperCbo(formDataDTO,formDefineVO,true,false,false);
        if(!resultCbo.isSuccess()){
            return BaseResult.fail(resultCbo.getMsg(),resultCbo.getMsgObjs());
        }
        //执行保存
         BaseResult<Map<String,Object>> result = BaseResult.success();
        try {
//            platformClientUtil.getBOFactoryService().updateBusinessObject(new BusinessObjectHolder(resultCbo.getObj().getBusinessObject()));
            ServiceProvider.getBOFService().updateBusinessObject(resultCbo.getObj().getBusinessObject());
            platformClientUtil.getBOFService().updateBusinessObject(resultCbo.getObj());
            result.setObj(boService.cbo2Map(resultCbo.getObj()));
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        if(!CollectionUtils.isEmpty(formDataDTO.getReleaseFileOids())){
            fileObjectService.releasedFile(resultCbo.getObj().getBtmName(),resultCbo.getObj().getOid(),formDataDTO.getReleaseFileOids());
            fileObjectService.releasedFile(resultCbo.getObj().btName,resultCbo.getObj().oid,formDataDTO.getReleaseFileOids());
        }
        //后置事件
        String afterEvent = formDataDTO.getPostEvent();
        try {
            callPostEvent(Arrays.stream(new com.vci.client.bof.ClientBusinessObject[]{resultCbo.getObj()}).collect(Collectors.toList()), null,afterEvent, VciChangeDocumentTypeEnum.EDIT);
            callPostEvent(Arrays.stream(new BusinessObject[]{resultCbo.getObj()}).collect(Collectors.toList()), null,afterEvent, VciChangeDocumentTypeEnum.EDIT);
        }catch (Throwable e){
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
        }
@@ -1433,7 +1536,7 @@
     * @throws VciBaseException 保存出错的时候会抛出异常
     */
    @Override
    public BaseResult<Map<String, Object>> upRevision(FormDataDTO formDataDTO) throws VciBaseException {
    public BaseResult<Map<String, Object>> upRevision(FormDataDTO formDataDTO) throws VciBaseException, PLException {
        //首先判断对象是否为空
        VciBaseUtil.alertNotNull(formDataDTO,"修改的数据对象",formDataDTO.getBtmname(),"业务类型的名称",formDataDTO.getFormDefineId(),"表单定义的编号",formDataDTO.getCopyFromVersion(),"老版本的主键");
        UIFormDefineVO formDefineVO = uiEngineService.getFormById(formDataDTO.getBtmname(), formDataDTO.getFormDefineId());
@@ -1444,29 +1547,40 @@
            //说明前置事件没有执行成功
            return beforeResult;
        }
        //封装数据
        BaseResult<com.vci.client.bof.ClientBusinessObject> resultCbo = wrapperCbo(formDataDTO,formDefineVO,false,formDataDTO.isUpVersion()?false:true,formDataDTO.isUpVersion());
        if(!resultCbo.isSuccess()){
            return BaseResult.fail(resultCbo.getMsg(),resultCbo.getMsgObjs());
        List<BusinessObject> businessObjects = null;
        Date ts = formDataDTO.getTs();
        Map<String,String> conditionMap = WebUtil.getOidQuery(formDataDTO.getCopyFromVersion());
        conditionMap.put("ts", VciDateUtil.date2Str(ts,VciDateUtil.DateTimeMillFormat));
        conditionMap.put("oid",formDataDTO.getCopyFromVersion());
        businessObjects = boService.queryCBO(formDataDTO.getBtmname(), conditionMap);
        if(businessObjects.size() ==0){
            throw new VciBaseException("数据不是最新的,建议您刷新后重新操作");
        }
        //扩展属性的值
        Map<String, String> data = formDataDTO.getData();
        Map<String,String> dataLow = new HashMap<>();
        data.forEach((key,value)->{
            dataLow.put(key.toLowerCase(),value);
        });
        Map<String,String> baseDataMap = formDataDTO2MapLow(formDataDTO);
        Map<String,String> allDataMapLow = new HashMap<>();
        allDataMapLow.putAll(dataLow);
        allDataMapLow.putAll(baseDataMap);
        //判断唯一项
        BaseResult baseResult = checkUnique(formDefineVO, null, allDataMapLow, true);
        if(!baseResult.isSuccess()){
            return baseResult;
        }
        BusinessObject businessObject = platformClientUtil.getBOFService()
                .revisionBusinessObject(businessObjects.get(0), null, !formDataDTO.isUpVersion(),true, false, false);
        //执行保存
        BaseResult<Map<String,Object>> result = BaseResult.success();
        try {
//            BusinessObject bo = platformClientUtil.getBOFactoryService().createBusinessObject(resultCbo.getObj().getBusinessObject(),formDataDTO.isUpVersion()?false:true,formDataDTO.isUpVersion());
            BusinessObject bo = ServiceProvider.getBOFService().createBusinessObject(resultCbo.getObj().getBusinessObject(),formDataDTO.isUpVersion()?false:true,formDataDTO.isUpVersion());
            com.vci.client.bof.ClientBusinessObject afterCbo = new com.vci.client.bof.ClientBusinessObject();
            afterCbo.setBusinessObject(bo);
            result.setObj(boService.cbo2Map(afterCbo));
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        if(!CollectionUtils.isEmpty(formDataDTO.getReleaseFileOids())){
            fileObjectService.releasedFile(resultCbo.getObj().getBtmName(),resultCbo.getObj().getOid(),formDataDTO.getReleaseFileOids());
        }
        BaseResult<Map<String, Object>> result = BaseResult.success();
        result.setObj(boService.cbo2Map(businessObject));
        //后置事件
        String afterEvent = formDataDTO.getPostEvent();
        try {
            callPostEvent(Arrays.stream(new com.vci.client.bof.ClientBusinessObject[]{resultCbo.getObj()}).collect(Collectors.toList()), null,afterEvent, VciChangeDocumentTypeEnum.EDIT);
            callPostEvent(Arrays.stream(new BusinessObject[]{businessObject}).collect(Collectors.toList()), null,afterEvent, VciChangeDocumentTypeEnum.EDIT);
        }catch (Throwable e){
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
        }
@@ -1481,7 +1595,7 @@
     * @throws VciBaseException 保存出错的时候会抛出异常
     */
    @Override
    public BaseResult<String> batchEditSave(FormDataDTOList formDataDTOList) throws VciBaseException {
    public BaseResult<String> batchEditSave(FormDataDTOList formDataDTOList) throws VciBaseException, PLException {
        VciBaseUtil.alertNotNull(formDataDTOList,"要修改的数据",formDataDTOList.getFormDataDTOS(),"要修改的数据");
        //首先判断对象是否为空
        FormDataDTO firstFormDataDTO = formDataDTOList.getFormDataDTOS().stream().findFirst().get();
@@ -1496,16 +1610,16 @@
        //封装数据
        List<BusinessObject> updateCBOS = new ArrayList<>();
        Map<String,List<String>> releasedFileOids = new HashMap<>();
        List<com.vci.client.bof.ClientBusinessObject> afterCBOs = new ArrayList<>();
        List<BusinessObject> afterCBOs = new ArrayList<>();
        for(FormDataDTO formDataDTO:formDataDTOList.getFormDataDTOS()) {
            BaseResult<com.vci.client.bof.ClientBusinessObject> resultCbo = wrapperCbo(formDataDTO, formDefineVO, true, false, false);
            BaseResult<BusinessObject> resultCbo = wrapperCbo(formDataDTO, formDefineVO, true, false, false);
            if (!resultCbo.isSuccess()) {
                return BaseResult.fail(resultCbo.getMsg(), resultCbo.getMsgObjs());
            }
            updateCBOS.add(resultCbo.getObj().getBusinessObject());
            updateCBOS.add(resultCbo.getObj());
            //执行保存
            if (!CollectionUtils.isEmpty(formDataDTO.getReleaseFileOids())) {
                releasedFileOids.put(resultCbo.getObj().getOid(),formDataDTO.getReleaseFileOids());
                releasedFileOids.put(resultCbo.getObj().oid,formDataDTO.getReleaseFileOids());
            }
        }
        try {
@@ -1538,15 +1652,15 @@
     * @throws VciBaseException 数据被引用的时候会抛出异常
     */
    @Override
    public BaseResult batchDelete(DeleteDataDTO deleteDataDTO) throws VciBaseException {
    public BaseResult batchDelete(DeleteDataDTO deleteDataDTO) throws VciBaseException, PLException {
        VciBaseUtil.alertNotNull(deleteDataDTO,"数据传输对象",deleteDataDTO.getDataList(),"数据传输对象");
        String btmName = deleteDataDTO.getDataList().get(0).getBtmname();
        List<String> oidList = deleteDataDTO.getDataList().stream().map(BaseModelDTO::getOid).collect(Collectors.toList());
        //看看级联删除。只有自己引用自己的时候可以级联删除
        List<com.vci.client.bof.ClientBusinessObject> cbo = null;
        List<BusinessObject> cbo = null;
        if(deleteDataDTO.isCascade()){
            //级联删除
            OsBtmTypeVO btmTypeVO = btmService.getBtmById(btmName);
            OsBtmTypeVO btmTypeVO = btmService.getBtmByName(btmName);
            OsBtmTypeAttributeVO parentAttributeVO = btmTypeVO.getAttributes().stream().filter(s -> s.getReferBtmTypeId().equalsIgnoreCase(btmName)).findFirst().orElseGet(null);
            if(parentAttributeVO != null){
                //页面分页不能显示超过1000
@@ -1562,8 +1676,8 @@
        if(CollectionUtils.isEmpty(cbo)){
            return BaseResult.fail("没有在系统中找到这些数据,未执行删除操作");
        }
        List<com.vci.client.bof.ClientBusinessObject> finalCbo = cbo;
        Collection<Collection<String>> oidCollections = WebUtil.switchCollectionForOracleIn(finalCbo.stream().map(com.vci.client.bof.ClientBusinessObject::getOid).collect(Collectors.toList()));
        List<BusinessObject> finalCbo = cbo;
        Collection<Collection<String>> oidCollections = WebUtil.switchCollectionForOracleIn(finalCbo.stream().map(bo -> bo.oid).collect(Collectors.toList()));
        List<OsUsedAttributeVO> usedAttributeVOS = null;
        boolean adminCascade = false;
        if("admin".equalsIgnoreCase(VciBaseUtil.getCurrentUserId()) && deleteDataDTO.isAdminCascade()){
@@ -1579,7 +1693,12 @@
                        conditionMap.put(usedAttributeVO.getId(),QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(oids.toArray(new String[0])) + ")");
                        if(StringUtils.isNotBlank(usedAttributeVO.getPkBtmType())) {
                            if (boService.queryCount(usedAttributeVO.getPkBtmType(), conditionMap) > 0) {
                                OsBtmTypeVO btmTypeVO = btmService.getBtmById(usedAttributeVO.getPkBtmType());
                                OsBtmTypeVO btmTypeVO = null;
                                try {
                                    btmTypeVO = btmService.getBtmById(usedAttributeVO.getPkBtmType());
                                } catch (PLException e) {
                                    e.printStackTrace();
                                }
                                throw new VciBaseException("数据在【" + btmTypeVO.getName() + "】中的字段[" + usedAttributeVO.getName() + "]里被引用.不能删除");
                            }
                        }else{
@@ -1598,7 +1717,7 @@
                        Map<String,String> conditionMap = new HashMap<>();
                        conditionMap.put(usedAttributeVO.getId(),QueryOptionConstant.IN + "(" + VciBaseUtil.toInSql(oids.toArray(new String[0])) + ")");
                        if(StringUtils.isNotBlank(usedAttributeVO.getPkBtmType())) {
                            List<com.vci.client.bof.ClientBusinessObject> tempCbos = boService.queryCBO(usedAttributeVO.getPkBtmType(), conditionMap);
                            List<BusinessObject> tempCbos = boService.queryCBO(usedAttributeVO.getPkBtmType(), conditionMap);
                            if(!CollectionUtils.isEmpty(tempCbos)){
                                finalCbo.addAll(tempCbos);
                            }
@@ -1611,13 +1730,11 @@
        }
        VciBaseUtil.switchCollectionForOracleIn(finalCbo).stream().forEach(cbos->{
            try {
//                platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(cbos.stream().map(s->s.getBusinessObject()).collect(Collectors.toList()).toArray(new BusinessObject[0]),1);
                ServiceProvider.getBOFService().batchDeleteBusinessObject(cbos.stream().map(s->s.getBusinessObject()).collect(Collectors.toList()).toArray(new BusinessObject[0]),1);
                platformClientUtil.getBOFService().batchDeleteBusinessObject(cbos.toArray(new BusinessObject[0]),1);
            } catch (PLException vciError) {
                throw WebUtil.getVciBaseException(vciError);
            }
        });
        System.out.println("zheshi shazi ");
        return BaseResult.success();
    }
@@ -1629,7 +1746,7 @@
     * @throws VciBaseException 参数为空,必输项缺失
     */
    @Override
    public BaseResult<String> linkAddSave(FormLinkDataDTO formLinkDataDTO) throws VciBaseException {
    public BaseResult<String> linkAddSave(FormLinkDataDTO formLinkDataDTO) throws VciBaseException, PLException {
        //首先判断对象是否为空
        VciBaseUtil.alertNotNull(formLinkDataDTO,"添加的数据对象",formLinkDataDTO.getLinkType(),"链接类型的名称",formLinkDataDTO.getFormDefineId(),"表单定义的编号");
        if(formLinkDataDTO.getData() ==null){
@@ -1653,7 +1770,7 @@
            //说明前置事件没有执行成功
            return beforeResult;
        }
        com.vci.client.bof.ClientLinkObject clo = null;
        LinkObject clo = null;
        String prefix = "";
        if(formLinkDataDTO.isDirection()){
            prefix = LO_FROM_PREFIX;
@@ -1680,14 +1797,6 @@
            throw new VciBaseException(formLinkDataDTO.isDirection()?"from端":"to端" + "的业务类型为空");
        }
        //查询from端的
        com.vci.client.bof.ClientBusinessObject fromCbo = new com.vci.client.bof.ClientBusinessObject();
        try {
//            fromCbo.setBusinessObject(platformClientUtil.getBOFactoryService().readBusinessObject(fromOid,fromBtmName));
            fromCbo.setBusinessObject(ServiceProvider.getBOFService().readBusinessObject(fromOid,fromBtmName));
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        String finalPrefix = prefix;
        formLinkDataDTO.getData().forEach((key, value)->{
            if(key.toLowerCase().startsWith(finalPrefix)){
@@ -1697,55 +1806,47 @@
            }
        });
        //封装to端的
        BaseResult<com.vci.client.bof.ClientBusinessObject> result = wrapperToCbo(formLinkDataDTO,formDefineVO,toOid,toBtmName,boData);
        BaseResult<BusinessObject> result = wrapperToCbo(formLinkDataDTO,formDefineVO,toOid,toBtmName,boData);
        if(!result.isSuccess()){
            return BaseResult.fail(result.getMsg(),result.getMsgObjs());
        }
        com.vci.client.bof.ClientBusinessObject toCbo = result.getObj();
        BusinessObject toCbo = result.getObj();
        //初始化链接类型的值
        BaseResult<com.vci.client.bof.ClientLinkObject> resultClo = wrapperOnlyCLO(formLinkDataDTO, loData, formDefineVO, false);
        BaseResult<LinkObject> resultClo = wrapperOnlyCLO(formLinkDataDTO, loData, formDefineVO, false);
        if(!resultClo.isSuccess()){
            return BaseResult.fail(resultClo.getMsg(),resultClo.getMsgObjs());
        }
        clo = resultClo.getObj();
        if(formLinkDataDTO.isDirection()){
            clo.setFromBO(toCbo);
            clo.setToBO(fromCbo);
        } else {
            clo.setFromBO(fromCbo);
            clo.setToBO(toCbo);
        if(StringUtils.isBlank(clo.toOid)){
            clo.toOid = toCbo.oid;
        }
        //执行保存
        BusinessObject[] bos = new BusinessObject[1];
        toCbo.dealBusinessObjectNullValue();
        clo.dealLinkObjectNullValue();
        bos[0] = toCbo.getBusinessObject();
        ObjectTool.dealBusinessObjectNullValue(toCbo);
        bos[0] = toCbo;
        try {
//            platformClientUtil.getBOFactoryService().createBusinessObjectWithLink(bosHolder,loHolder);
            ServiceProvider.getBOFService().createBusinessObjectWithLink(bos,clo.getLinkObject());
            platformClientUtil.getBOFService().createBusinessObjectWithLink(bos,clo);
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        if(!CollectionUtils.isEmpty(formLinkDataDTO.getReleaseFileOids())){
            fileObjectService.releasedFile(formLinkDataDTO.getLinkType(),clo.getOid(),formLinkDataDTO.getReleaseFileOids());
            fileObjectService.releasedFile(formLinkDataDTO.getLinkType(),clo.oid,formLinkDataDTO.getReleaseFileOids());
        }
        //后置事件
        String afterEvent = formLinkDataDTO.getPostEvent();
        try {
            callPostEvent(null,Arrays.stream(new com.vci.client.bof.ClientLinkObject[]{clo}).collect(Collectors.toList()), afterEvent, VciChangeDocumentTypeEnum.ADD);
            callPostEvent(null,Arrays.stream(new LinkObject[]{clo}).collect(Collectors.toList()), afterEvent, VciChangeDocumentTypeEnum.ADD);
        }catch (Throwable e){
            //说明后置事件出现了错误,那么就需要删除以前的这条数据
            try {
//                platformClientUtil.getBOFactoryService().deleteBusinessObject(toCbo.getBusinessObject(),1);
//                platformClientUtil.getBOFactoryService().deleteLinkObject(clo.getLinkObject());
                ServiceProvider.getBOFService().deleteBusinessObject(toCbo.getBusinessObject(),1);
                ServiceProvider.getBOFService().deleteLinkObject(clo.getLinkObject());
                platformClientUtil.getBOFService().deleteBusinessObject(toCbo,1);
                platformClientUtil.getBOFService().deleteLinkObject(clo);
            } catch (PLException vciError) {
                throw WebUtil.getVciBaseException(vciError);
            }
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
        }
        return BaseResult.success(clo.getOid());
        return BaseResult.success(clo.oid);
    }
    /**
@@ -1756,7 +1857,7 @@
     * @param editFlag 是否为编辑
     * @return 链接类型的内容
     */
    private BaseResult<com.vci.client.bof.ClientLinkObject> wrapperOnlyCLO(FormLinkDataDTO formLinkDataDTO,Map<String,String> loData,UIFormDefineVO formDefineVO,boolean editFlag){
    private BaseResult<LinkObject> wrapperOnlyCLO(FormLinkDataDTO formLinkDataDTO,Map<String,String> loData,UIFormDefineVO formDefineVO,boolean editFlag){
        Map<String,String> baseDataMap = formLinkDataDTO2MapLow(formLinkDataDTO);
        Map<String,String> allDataMap = new HashMap<>();
        allDataMap.putAll(loData);
@@ -1772,33 +1873,40 @@
            return result;
        }
        //处理业务类型得到数据
        ClientLinkObject clo ;
        LinkObject clo ;
        if(editFlag){
            try {
//                LinkObject linkObject = platformClientUtil.getBOFactoryService().readLinkObjectById(formLinkDataDTO.getOid(), formLinkDataDTO.getLinkType());
                LinkObject linkObject = ServiceProvider.getBOFService().readLinkObjectById(formLinkDataDTO.getOid(), formLinkDataDTO.getLinkType());
                clo = new ClientLinkObject();
                clo.setLinkObject(linkObject);
                LinkObject linkObject = platformClientUtil.getBOFService().readLinkObjectById(formLinkDataDTO.getOid(), formLinkDataDTO.getLinkType());
                clo = linkObject;
            } catch (PLException vciError) {
                throw WebUtil.getVciBaseException(vciError);
            }
        }else{
            clo = new ClientLinkObject();
            clo = new LinkObject();
            //处理初始化的数据
            clo.setOid(VciBaseUtil.getPk());
            clo.setCreator(VciBaseUtil.getCurrentUserId());
            clo.setCreateTime(System.currentTimeMillis());
            clo.setTs(System.currentTimeMillis());
            clo.setLoName(formLinkDataDTO.getLinkType());
            clo.oid = VciBaseUtil.getPk();
            clo.creator = VciBaseUtil.getCurrentUserId();
            clo.createTime = System.currentTimeMillis();
            clo.ts = System.currentTimeMillis();
            clo.ltName = formLinkDataDTO.getLinkType();
            clo.toOid = formLinkDataDTO.getToid();
            clo.toNameOid = formLinkDataDTO.getTnameoid();
            clo.toRevOid = formLinkDataDTO.getTrevisionoid();
            clo.toBTName = formLinkDataDTO.getTbtmname();
            clo.fromOid = formLinkDataDTO.getFoid();
            clo.fromBTName = formLinkDataDTO.getFbtmname();
            clo.fromNameOid = formLinkDataDTO.getFnameoid();
            clo.fromRevOid = formLinkDataDTO.getFrevisionoid();
        }
        //
        allDataMap.forEach((key,value)->{
        LinkObject finalClo = clo;
        allDataMap.forEach((key, value)->{
            if(editFlag&&("lastmodifier".equalsIgnoreCase(key) || "lastmodifytime".equalsIgnoreCase(key)
                    || "ts".equalsIgnoreCase(key)  || "creator".equalsIgnoreCase(key)
                    || "createtime".equalsIgnoreCase(key))){
                //平台不能传递这个
            }else{
                loService.setAttribute(clo,key,value);
                loService.setAttribute(finalClo,key,value);
            }
        });
        return BaseResult.success(clo);
@@ -1814,7 +1922,7 @@
     * @param boData to的数据
     * @return 包含的对象
     */
    private BaseResult<com.vci.client.bof.ClientBusinessObject> wrapperToCbo(FormLinkDataDTO formLinkDataDTO,UIFormDefineVO formDefineVO,String toOid,String toBtmName,Map<String,String> boData){
    private BaseResult<BusinessObject> wrapperToCbo(FormLinkDataDTO formLinkDataDTO,UIFormDefineVO formDefineVO,String toOid,String toBtmName,Map<String,String> boData) throws PLException {
        Map<String,String> dataLow = new HashMap<>();
        boData.forEach((key,value)->{
            dataLow.put(key.toLowerCase(),value);
@@ -1841,7 +1949,7 @@
        if(!result.isSuccess()){
            return result;
        }
        com.vci.client.bof.ClientBusinessObject cbo = createOrGetCbo(dataLow,baseDataMap,editFlag,formLinkDataDTO.isToUpRevision(),formLinkDataDTO.isToUpVersion());
        BusinessObject cbo = createOrGetCbo(dataLow,baseDataMap,editFlag,formLinkDataDTO.isToUpRevision(),formLinkDataDTO.isToUpVersion());
        return BaseResult.success(cbo);
    }
@@ -1934,141 +2042,140 @@
     * @param newVersion 是否升版次
     * @return cbo对象
     */
    public com.vci.client.bof.ClientBusinessObject createOrGetCbo(Map<String,String> dataLowMap,Map<String,String> baseDataMap,boolean editFlag,boolean newRevision,boolean newVersion){
    public BusinessObject createOrGetCbo(Map<String,String> dataLowMap,Map<String,String> baseDataMap,boolean editFlag,boolean newRevision,boolean newVersion) throws PLException {
        String btmName = baseDataMap.get("btmname");
        String oid = baseDataMap.get("oid");
//        ClientBusinessObject cbo = new ClientBusinessObject();
        com.vci.client.bof.ClientBusinessObject cbo = new com.vci.client.bof.ClientBusinessObject();
//        BusinessObject cbo = new BusinessObject();
        BusinessObject cbo = new BusinessObject();
        String copyfromversion = baseDataMap.get("copyfromversion");
        OsBtmTypeVO btmTypeVO = btmService.getBtmById(btmName);
        List<String> attributeList = btmTypeVO.getAttributes().stream().map(attribute -> attribute.getId()).collect(Collectors.toList());
        //OsBtmTypeVO btmTypeVO = btmService.getBtmById(btmName);
        OsBtmTypeVO btmTypeVO = btmService.getBtmByName(btmName);
        //List<String> attributeList = btmTypeVO.getAttributes().stream().map(attribute -> attribute.getId()).collect(Collectors.toList());
        if(editFlag || newRevision || newVersion){
            try {
//                cbo.setBusinessObject(platformClientUtil.getBOFactoryService().readBusinessObject(editFlag?oid:copyfromversion,btmName));
                cbo.setBusinessObject(ServiceProvider.getBOFService().readBusinessObject(editFlag?oid:copyfromversion,btmName));
                cbo = platformClientUtil.getBOFService().readBusinessObject(editFlag?oid:copyfromversion,btmName);
            } catch (PLException vciError) {
                throw new VciBaseException("使用主键在系统中没有查询到数据",new String[]{oid},vciError);
            }
            if(btmTypeVO.isRevisionFlag() && newRevision){
                cbo.setOid(VciBaseUtil.getPk());
                cbo.setCopyFromVersion(copyfromversion);
                cbo.oid = VciBaseUtil.getPk();
                cbo.fromVersion = copyfromversion;
                if(btmTypeVO.isInputRevisionFlag() && StringUtils.isNotBlank(baseDataMap.getOrDefault("revisionvalue",""))){
                    //手动的,所以不处理版本规则了
                    cbo.setRevisionValue(baseDataMap.get("revisionvalue"));
                    cbo.revisionValue = baseDataMap.get("revisionvalue");
                }else{
                    //说明是升版
                    BaseModel baseModel = cbo2BaseModel(cbo);
                    RevisionValueObject revisionValueObject = getNextRevision(btmTypeVO,baseModel);
                    cbo.setRevisionid(VciBaseUtil.getPk());
                    cbo.setRevisionSeq((short) revisionValueObject.getRevisionSeq());
                    cbo.setRevisionValue(revisionValueObject.getRevisionVal());
                    cbo.setIsLastR(true);
                    cbo.setIsFirstR(false);
                    RevisionDataInfo revisionValueObject = getNextRevision(btmTypeVO,baseModel);
                    cbo.revisionid = VciBaseUtil.getPk();
                    cbo.revisionSeq = revisionValueObject.revisionSeq;
                    cbo.revisionValue = revisionValueObject.revisionVal;
                    cbo.isLastR = true;
                    cbo.isFirstR = false;
                    //处理版次
                    cbo.setVersionValue(getFirstVersion(btmTypeVO.getVersionRule()));
                    cbo.setVersionRule(btmTypeVO.getVersionRule());
                    cbo.setVersionSeq((short) 0);
                    cbo.setIsLastV(true);
                    cbo.setIsFirstV(true);
                    cbo.versionValue = getFirstVersion(btmTypeVO.getVersionRule());
                    cbo.versionRule = btmTypeVO.getVersionRule();
                    cbo.versionSeq = (short) 0;
                    cbo.isLastV = true;
                    cbo.isFirstV = true;
                }
                //升版的时候,生命周期的状态需要改动到默认状态
                if(StringUtils.isNotBlank(btmTypeVO.getLifeCycleId())){
                    //查询生命周期
//                    OsLifeCycleVO lifeCycleVO = lifeCycleService.getLifeCycleById(btmTypeVO.getLifeCycleId());
                    LifeCycle lifeCycleVO = null;
                    try {
                        lifeCycleVO = ServiceProvider.getOMDService().getLifeCycleService().getLifeCycle(btmTypeVO.getLifeCycleId());
                        lifeCycleVO = platformClientUtil.getLifeCycleService().getLifeCycle(btmTypeVO.getLifeCycleId());
                    } catch (PLException e) {
                        throw new RuntimeException(e);
                    }
                    if(lifeCycleVO == null || StringUtils.isBlank(lifeCycleVO.oid)){
                        throw new VciBaseException("{0}里的生命周期设置得不正确,在系统中没有找到{1}这个生命周期",new String[]{btmTypeVO.getName(),btmTypeVO.getLifeCycleId()});
                    }
                    cbo.setLcStatus(lifeCycleVO.startState);
                    cbo.lcStatus = lifeCycleVO.startState;
                }
            }
            if(btmTypeVO.isRevisionFlag() && newVersion){
                cbo.setCopyFromVersion(copyfromversion);
                cbo.setOid(VciBaseUtil.getPk());
                cbo.fromVersion = copyfromversion;
                cbo.oid = VciBaseUtil.getPk();
                //这是升版次,不存在即升版本,又升版次的情况
                BaseModel baseModel = cbo2BaseModel(cbo);
                VersionValueObject versionValueObject = getNextVersion(btmTypeVO,baseModel);
                cbo.setVersionValue(versionValueObject.getVersionVal());
                cbo.setVersionSeq((short) versionValueObject.getVersionSeq());
                cbo.setIsLastV(true);
                cbo.setIsFirstV(false);
                VersionDataInfo versionValueObject = getNextVersion(btmTypeVO,baseModel);
                cbo.versionValue = versionValueObject.versionVal;
                cbo.versionSeq = versionValueObject.versionSeq;
                cbo.isLastV = true;
                cbo.isFirstV = false;
                //升版的时候,生命周期的状态需要改动到默认状态
                if(StringUtils.isNotBlank(btmTypeVO.getLifeCycleId())){
                    //查询生命周期
//                    OsLifeCycleVO lifeCycleVO = lifeCycleService.getLifeCycleById(btmTypeVO.getLifeCycleId());
                    LifeCycle lifeCycleVO = null;
                    try {
                        lifeCycleVO = ServiceProvider.getOMDService().getLifeCycleService().getLifeCycle(btmTypeVO.getLifeCycleId());
                        lifeCycleVO = platformClientUtil.getLifeCycleService().getLifeCycle(btmTypeVO.getLifeCycleId());
                    } catch (PLException e) {
                        throw new RuntimeException(e);
                    }
                    if(lifeCycleVO == null || StringUtils.isBlank(lifeCycleVO.oid)){
                        throw new VciBaseException("{0}里的生命周期设置得不正确,在系统中没有找到{1}这个生命周期",new String[]{btmTypeVO.getName(),btmTypeVO.getLifeCycleId()});
                    }
                    cbo.setLcStatus(lifeCycleVO.startState);
                    cbo.lcStatus = lifeCycleVO.startState;
                }
            }
        }else{
            //我们需要将属性初始化
            if(StringUtils.isBlank(cbo.getOid()) || (newRevision || newVersion)){
                cbo.setOid(VciBaseUtil.getPk());
            if(StringUtils.isBlank(cbo.oid) || (newRevision || newVersion)){
                cbo.oid = VciBaseUtil.getPk();
            }
            if(StringUtils.isBlank(cbo.getCreator())){
                cbo.setCreator(VciBaseUtil.getCurrentUserId());
            if(StringUtils.isBlank(cbo.creator)){
                cbo.creator = VciBaseUtil.getCurrentUserId();
            }
            if(cbo.getCreateTime() != 0){
                cbo.setCreateTime(System.currentTimeMillis());
            if(cbo.createTime != 0){
                cbo.createTime = System.currentTimeMillis();
            }
            if(StringUtils.isBlank(cbo.getOwner())){
                cbo.setOwner(cbo.getCreator());
            if(StringUtils.isBlank(cbo.owner)){
                cbo.owner = cbo.creator;
            }
            cbo.setTs(System.currentTimeMillis());
            if(StringUtils.isNotBlank(btmTypeVO.getLifeCycleId()) && (StringUtils.isBlank(cbo.getLcStatus()) || newRevision || newVersion)){
            cbo.ts = System.currentTimeMillis();
            if(StringUtils.isNotBlank(btmTypeVO.getLifeCycleId()) && (StringUtils.isBlank(cbo.lcStatus) || newRevision || newVersion)){
                //查询生命周期
                OsLifeCycleVO lifeCycleVO = lifeCycleService.getLifeCycleById(btmTypeVO.getLifeCycleId());
                if(lifeCycleVO == null || StringUtils.isBlank(lifeCycleVO.getOid())){
                    throw new VciBaseException("{0}里的生命周期设置得不正确,在系统中没有找到{1}这个生命周期",new String[]{btmTypeVO.getName(),btmTypeVO.getLifeCycleId()});
                }
                cbo.setLcStatus(lifeCycleVO.getStartStatus());
                cbo.setLctId(btmTypeVO.getLifeCycleId());
                cbo.lcStatus = lifeCycleVO.getStartStatus();
                cbo.lctId = btmTypeVO.getLifeCycleId();
            }
            if(StringUtils.isBlank(cbo.getBtmName())){
                cbo.setBtmName(btmTypeVO.getId());
            if(StringUtils.isBlank(cbo.btName)){
                cbo.btName = btmTypeVO.getId();
            }
            if(btmTypeVO.isRevisionFlag()){
                //要管理版本
                if(btmTypeVO.isInputRevisionFlag() && StringUtils.isNotBlank(baseDataMap.getOrDefault("revisionvalue",""))){
                    //手动的,所以不处理版本规则了
                    cbo.setRevisionValue(baseDataMap.get("revisionvalue"));
                    cbo.revisionValue = baseDataMap.get("revisionvalue");
                }else {
                    OsRevisionRuleVO ruleVO = revisionRuleServiceI.getRevisionRuleById(btmTypeVO.getRevisionRuleId());
                    if (ruleVO == null || StringUtils.isBlank(ruleVO.getOid())) {
                        throw new VciBaseException("{0}里的版本规则设置得不正确,在系统中没有找到{1}这个版本规则", new String[]{btmTypeVO.getName(), btmTypeVO.getRevisionRuleId()});
                    }
                    cbo.setRevisionValue(ruleVO.getStartCode());
                    cbo.revisionValue = ruleVO.getInitialValue();
                }
                if (StringUtils.isBlank(cbo.getNameoid())) {
                    cbo.setNameoid(VciBaseUtil.getPk());
                if (StringUtils.isBlank(cbo.nameoid)) {
                    cbo.nameoid = VciBaseUtil.getPk();
                }
                if (StringUtils.isBlank(cbo.getRevisionid())) {
                    cbo.setRevisionid(VciBaseUtil.getPk());
                if (StringUtils.isBlank(cbo.revisionid)) {
                    cbo.revisionid = VciBaseUtil.getPk();
                }
                cbo.setIsFirstR(true);
                cbo.setIsLastR(true);
                cbo.setRevisionRule(btmTypeVO.getRevisionRuleId());
                cbo.setRevisionSeq((short) 0);
                cbo.isFirstR = true;
                cbo.isLastR = true;
                cbo.revisionRule = btmTypeVO.getRevisionRuleId();
                cbo.revisionSeq = (short) 0;
                //看看是否需要处理版次
                cbo.setVersionValue(getFirstVersion(btmTypeVO.getVersionRule()));
                cbo.setVersionRule(btmTypeVO.getVersionRule());
                cbo.setVersionSeq((short) 0);
                cbo.setIsLastV(true);
                cbo.setIsFirstV(true);
                cbo.versionValue = getFirstVersion(btmTypeVO.getVersionRule());
                cbo.versionRule = btmTypeVO.getVersionRule();
                cbo.versionSeq = (short) 0;
                cbo.isLastV = true;
                cbo.isFirstV = true;
            }
        }
//        Iterator<Map.Entry<String, String>> iterator = baseDataMap.entrySet().iterator();
@@ -2079,7 +2186,16 @@
//            }
//        }
        setValueToCbo(dataLowMap,baseDataMap,cbo,editFlag);
//        cbo.setName(dataLowMap.get("name"));
        //TODO:默认属性需要放在cbo外层
        if(StringUtils.isNotBlank(baseDataMap.getOrDefault("id",""))){
            cbo.id = baseDataMap.getOrDefault("id","");
        }
        if(StringUtils.isNotBlank(baseDataMap.getOrDefault("name",""))){
            cbo.name = baseDataMap.getOrDefault("name","");
        }
        if(StringUtils.isNotBlank(baseDataMap.getOrDefault("description",""))){
            cbo.description = baseDataMap.getOrDefault("description","");
        }
        return cbo;
    }
@@ -2110,18 +2226,12 @@
     * @param editFlag 是否为编辑
     */
    @Override
    public void setValueToCbo(Map<String, String> dataLow, Map<String, String> baseDataLow, com.vci.client.bof.ClientBusinessObject cbo, boolean editFlag){
    public void setValueToCbo(Map<String, String> dataLow, Map<String, String> baseDataLow, BusinessObject cbo, boolean editFlag){
        dataLow.forEach((key,value)->{
            if(editFlag&&notSendOnEdit(key)){
                //平台不能传递这个
            }else{
                try {
//                    if(!SystemAttribute.bosysAttList().contains(key)){
                        cbo.setAttributeValueWithNoCheck(key, value, !editFlag);
//                    }
                } catch (PLException vciError) {
                    throw new VciBaseException("{0}的值不符合要求,当前是{1}", new String[]{key, value}, vciError);
                }
                ObjectTool.setBOAttributeValue(cbo,key,value);
            }
        });
        baseDataLow.forEach((key,value)->{
@@ -2130,23 +2240,11 @@
            }else{
                if(editFlag) {
                    //编辑的时候可以都设置
                    try {
//                        if(!SystemAttribute.bosysAttList().contains(key)){
                            cbo.setAttributeValueWithNoCheck(key, value, !editFlag);
//                        }
                    } catch (PLException vciError) {
                        throw new VciBaseException("{0}的值不符合要求,当前是{1}", new String[]{key, value}, vciError);
                    }
                    ObjectTool.setBOAttributeValue(cbo,key,value);
                }else{
                    //只需要处理id,name,description,密级即可,其余的都已经被设置了
                    if(basicFields.contains(key) &&StringUtils.isNotBlank(value)){
                        try {
//                            if(!SystemAttribute.bosysAttList().contains(key)){
                                cbo.setAttributeValueWithNoCheck(key, value, true);
//                            }
                        } catch (PLException vciError) {
                            throw new VciBaseException("{0}的值不符合要求,当前是{1}", new String[]{key, value}, vciError);
                        }
                        ObjectTool.setBOAttributeValue(cbo,key,value);
                    }
                }
            }
@@ -2161,7 +2259,7 @@
     * @throws VciBaseException 参数为空,必输项缺失
     */
    @Override
    public BaseResult linkEditSave(FormLinkDataDTO formLinkDataDTO) throws VciBaseException {
    public BaseResult linkEditSave(FormLinkDataDTO formLinkDataDTO) throws VciBaseException, PLException {
        VciBaseUtil.alertNotNull(formLinkDataDTO,"修改的数据对象",formLinkDataDTO.getLinkType(),"链接类型的名称",
                formLinkDataDTO.getFormDefineId(),"表单定义的编号",formLinkDataDTO.getOid(),"主键",
                formLinkDataDTO.getFoid(),"from端主键",formLinkDataDTO.getToid(),"to端主键");
@@ -2182,12 +2280,10 @@
            //说明前置事件没有执行成功
            return beforeResult;
        }
        com.vci.client.bof.ClientLinkObject clo = null;
        LinkObject clo = null;
        String prefix = formLinkDataDTO.isDirection()?LO_FROM_PREFIX:LO_TO_PREFIX;
        String toOid = formLinkDataDTO.isDirection()?formLinkDataDTO.getFoid():formLinkDataDTO.getToid();
        String toBtmName =  formLinkDataDTO.isDirection()?formLinkDataDTO.getFbtmname():formLinkDataDTO.getTbtmname();
        String fromOid = formLinkDataDTO.isDirection()?formLinkDataDTO.getToid():formLinkDataDTO.getFoid();
        String fromBtmName = formLinkDataDTO.isDirection()?formLinkDataDTO.getTbtmname():formLinkDataDTO.getFbtmname();
        Map<String,String> boData = new HashMap<>();
        Map<String,String> loData = new HashMap<>();
@@ -2200,10 +2296,10 @@
                }
            });
        }
        com.vci.client.bof.ClientBusinessObject toCbo =null;
        BusinessObject toCbo =null;
        if(!CollectionUtils.isEmpty(boData)) {
            //封装to端的
            BaseResult<com.vci.client.bof.ClientBusinessObject> result = wrapperToCbo(formLinkDataDTO, formDefineVO, toOid, toBtmName, boData);
            BaseResult<BusinessObject> result = wrapperToCbo(formLinkDataDTO, formDefineVO, toOid, toBtmName, boData);
            if (!result.isSuccess()) {
                return BaseResult.fail(result.getMsg(), result.getMsgObjs());
            }
@@ -2211,44 +2307,34 @@
        }
        //初始化链接类型的值
        BaseResult<com.vci.client.bof.ClientLinkObject> resultClo = wrapperOnlyCLO(formLinkDataDTO, loData, formDefineVO, true);
        BaseResult<LinkObject> resultClo = wrapperOnlyCLO(formLinkDataDTO, loData, formDefineVO, true);
        if(!resultClo.isSuccess()){
            return BaseResult.fail(resultClo.getMsg(),resultClo.getMsgObjs());
        }
        clo = resultClo.getObj();
        if(toCbo!=null) {
            if (formLinkDataDTO.isDirection()) {
                clo.setFromBO(toCbo);
            } else {
                clo.setToBO(toCbo);
            }
        }
//        LinkObjectHolder loHolder = new LinkObjectHolder();
//        loHolder.value = clo.getLinkObject();
        try {
//            platformClientUtil.getBOFactoryService().updateLinkObject(loHolder);
            ServiceProvider.getBOFService().updateLinkObject(clo.getLinkObject());
            platformClientUtil.getBOFService().updateLinkObject(clo);
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        //保存to端或者from端
        try{
            platformClientUtil.getBOFactoryService().updateBusinessObject(toCbo.getBusinessObject());
            platformClientUtil.getBOFactoryService().updateBusinessObject(toCbo);
        } catch (PLException vciError) {
            throw WebUtil.getVciBaseException(vciError);
        }
        if(!CollectionUtils.isEmpty(formLinkDataDTO.getReleaseFileOids())){
            fileObjectService.releasedFile(formLinkDataDTO.getLinkType(),clo.getOid(),formLinkDataDTO.getReleaseFileOids());
            fileObjectService.releasedFile(formLinkDataDTO.getLinkType(),clo.oid,formLinkDataDTO.getReleaseFileOids());
        }
        //后置事件
        String afterEvent = formLinkDataDTO.getPostEvent();
        try {
            callPostEvent(null,Arrays.stream(new com.vci.client.bof.ClientLinkObject[]{clo}).collect(Collectors.toList()), afterEvent, VciChangeDocumentTypeEnum.ADD);
            callPostEvent(null,Arrays.stream(new LinkObject[]{clo}).collect(Collectors.toList()), afterEvent, VciChangeDocumentTypeEnum.ADD);
        }catch (Throwable e){
            //后置事件有问题了就只能是这样了,没办法恢复
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
        }
        return BaseResult.success(clo.getOid());
        return BaseResult.success(clo.oid);
    }
    /**
@@ -2264,31 +2350,31 @@
        if(deleteLinkDataDTO.getDataList().stream().anyMatch(s->StringUtils.isBlank(s.getOid()) || StringUtils.isBlank(s.getLinkType()))){
            throw new VciBaseException("有数据的主键(或链接类型)没有值,无法删除");
        }
        List<ClientLinkObject> clos = new ArrayList<>();
        List<LinkObject> clos = new ArrayList<>();
        VciBaseUtil.switchListForOracleIn(deleteLinkDataDTO.getDataList()).stream().forEach(linkModelDTOs->{
            Map<String,String> conditionMap = new HashMap<>();
            conditionMap.put("oid",QueryOptionConstant.IN +"(" + VciBaseUtil.toInSql(linkModelDTOs.stream().map(BaseLinkModelDTO::getOid).toArray(String[]::new)) +")");
            List<ClientLinkObject> clientLinkObjects = loService.queryCLO(linkModelDTOs.get(0).getLinkType(), conditionMap);
            if(!CollectionUtils.isEmpty(clientLinkObjects)){
                clos.addAll(clientLinkObjects);
            List<LinkObject> LinkObjects = loService.queryCLO(linkModelDTOs.get(0).getLinkType(), conditionMap);
            if(!CollectionUtils.isEmpty(LinkObjects)){
                clos.addAll(LinkObjects);
            }
        });
        if(CollectionUtils.isEmpty(clos)){
            throw new VciBaseException("使用主键没有在系统中找到链接类型的数据");
        }
        Map<String,List<ClientLinkObject>> fromBtmGroups = clos.stream().collect(Collectors.groupingBy(s->s.getFromBTMName()));
        Map<String,List<ClientLinkObject>> toBtmGroups = clos.stream().collect(Collectors.groupingBy(s->s.getToBTMName()));
        Map<String,List<com.vci.client.bof.ClientBusinessObject>> fromBtmDataGroups = new HashMap<>();
        Map<String,List<com.vci.client.bof.ClientBusinessObject>> toBtmDataGroups = new HashMap<>();
        Map<String,List<LinkObject>> fromBtmGroups = clos.stream().collect(Collectors.groupingBy(s->s.fromBTName));
        Map<String,List<LinkObject>> toBtmGroups = clos.stream().collect(Collectors.groupingBy(s->s.toBTName));
        Map<String,List<BusinessObject>> fromBtmDataGroups = new HashMap<>();
        Map<String,List<BusinessObject>> toBtmDataGroups = new HashMap<>();
        if(!CollectionUtils.isEmpty(fromBtmGroups)){
            fromBtmGroups.forEach((btmType,cloList)->{
                List<com.vci.client.bof.ClientBusinessObject> cbos = boService.selectCBOByOidCollection(cloList.stream().map(ClientLinkObject::getFromOid).collect(Collectors.toList()), btmType);
                List<BusinessObject> cbos = boService.selectCBOByOidCollection(cloList.stream().map(clo -> clo.fromOid).collect(Collectors.toList()), btmType);
                fromBtmDataGroups.put(btmType,cbos);
            });
        }
        if(!CollectionUtils.isEmpty(toBtmGroups)){
            toBtmGroups.forEach((btmType,cloList)->{
                List<com.vci.client.bof.ClientBusinessObject> cbos = boService.selectCBOByOidCollection(cloList.stream().map(ClientLinkObject::getToOid).collect(Collectors.toList()), btmType);
                List<BusinessObject> cbos = boService.selectCBOByOidCollection(cloList.stream().map(clo -> clo.toOid).collect(Collectors.toList()), btmType);
                toBtmDataGroups.put(btmType,cbos);
            });
        }
@@ -2303,19 +2389,19 @@
                if(attr.toLowerCase().startsWith(LO_FROM_PREFIX)){
                    fromBtmDataGroups.forEach((btm,cbos)->{
                        String attrNotPrefix = attr.substring(LO_FROM_PREFIX.length());
                        if(!CollectionUtils.isEmpty(cbos) && cbos.stream().anyMatch(s->!attrValue.equalsIgnoreCase(s.getAttributeValue(attrNotPrefix)))){
                        if(!CollectionUtils.isEmpty(cbos) && cbos.stream().anyMatch(s->!attrValue.equalsIgnoreCase(ObjectTool.getBOAttributeValue(s, attrNotPrefix)))){
                            throw new VciBaseException("数据的内容不允许删除,{0}", new String[]{deleteLinkDataDTO.getCheckNotDeleteMsg()});
                        }
                    });
                }else if(attr.toLowerCase().startsWith(LO_TO_PREFIX)){
                    toBtmDataGroups.forEach((btm,cbos)->{
                        String attrNotPrefix = attr.substring(LO_TO_PREFIX.length());
                        if(!CollectionUtils.isEmpty(cbos) && cbos.stream().anyMatch(s->!attrValue.equalsIgnoreCase(s.getAttributeValue(attrNotPrefix)))){
                        if(!CollectionUtils.isEmpty(cbos) && cbos.stream().anyMatch(s->!attrValue.equalsIgnoreCase(ObjectTool.getBOAttributeValue(s, attrNotPrefix)))){
                            throw new VciBaseException("数据的内容不允许删除,{0}", new String[]{deleteLinkDataDTO.getCheckNotDeleteMsg()});
                        }
                    });
                }else {
                    if (clos.stream().anyMatch(s -> attrValue.equalsIgnoreCase(s.getAttributeValue(attr)))) {
                    if (clos.stream().anyMatch(s -> attrValue.equalsIgnoreCase(ObjectTool.getLOAttributeValue(s,attr)))) {
                        throw new VciBaseException("数据的内容不允许删除,{0}", new String[]{deleteLinkDataDTO.getCheckNotDeleteMsg()});
                    }
                }
@@ -2324,7 +2410,7 @@
        //链接类型本身一般不会有关联
        List<LinkObject> los = new ArrayList<>();
        clos.stream().forEach(clo->{
            los.add(clo.getLinkObject());
            los.add(clo);
        });
        try {
            platformClientUtil.getBOFactoryService().batchDeleteLinkObject(los.toArray(new LinkObject[0]));
@@ -2334,7 +2420,7 @@
        if(deleteLinkDataDTO.isDeleteFromData()){
            fromBtmDataGroups.forEach((btm,cbos)->{
                try{
                    platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(cbos.stream().map(com.vci.client.bof.ClientBusinessObject::getBusinessObject).toArray(BusinessObject[] :: new),1);
                    platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(cbos.toArray(new BusinessObject[0]), DeleteTypeEnum.OID_AND_TS.getValue());
                }catch (PLException vciError) {
                    throw WebUtil.getVciBaseException(vciError);
                }
@@ -2343,7 +2429,7 @@
        if(deleteLinkDataDTO.isDeleteToData()){
            toBtmDataGroups.forEach((btm,cbos)->{
                try{
                    platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(cbos.stream().map(com.vci.client.bof.ClientBusinessObject::getBusinessObject).toArray(BusinessObject[] :: new),1);
                    platformClientUtil.getBOFactoryService().batchDeleteBusinessObject(cbos.toArray(new BusinessObject[0]),DeleteTypeEnum.OID_AND_TS.getValue());
                }catch (PLException vciError) {
                    throw WebUtil.getVciBaseException(vciError);
                }
@@ -2360,10 +2446,10 @@
     * @return 列表数据
     */
    @Override
    public DataGrid referDataGrid(ReferConfigVO referConfigVO, PageHelper pageHelper) {
    public DataGrid referDataGrid(ReferConfigVO referConfigVO, PageHelper pageHelper) throws PLException {
        checkReferConfig(referConfigVO);
        //使用业务类型查询
        OsBtmTypeVO btmById = btmService.getBtmById(referConfigVO.getReferBo());
        OsBtmTypeVO btmById = btmService.getBtmByName(referConfigVO.getReferBo());
        if(referConfigVO.getConditionMap() == null){
            referConfigVO.setConditionMap(new HashMap<>());
        }
@@ -2417,7 +2503,7 @@
            referConfigVO.setConditionMap(new HashMap<>());
        }
        List<com.vci.client.bof.ClientBusinessObject> cbos = null;
        List<BusinessObject> cbos = null;
        String oidFieldName = StringUtils.isNotBlank(referConfigVO.getParentUsedField())?referConfigVO.getParentUsedField():referConfigVO.getValueField();
        if(referConfigVO.isSelectAllLevel()) {
            String parentOidSql = "";
@@ -2492,7 +2578,7 @@
    @Override
    public List<Map<String,String>> getDataAttr(String btmname, String oid) {
        VciBaseUtil.alertNotNull(btmname,"业务类型的信息",oid,"业务数据的主键");
        List<com.vci.client.bof.ClientBusinessObject> cbos = boService.queryCBO(btmname,WebUtil.getOidQuery(oid));
        List<BusinessObject> cbos = boService.queryCBO(btmname,WebUtil.getOidQuery(oid));
        List<Map<String,String>> dataMap = new ArrayList<>();
        if(!CollectionUtils.isEmpty(cbos)){
            cbos.stream().forEach(cbo->{
@@ -2503,4 +2589,73 @@
        }
        return dataMap;
    }
    /**
     * 数据升版本/次,前端使用JSON提交
     * @param btmname 业务类型的信息
     * @param oid 业务数据的主键
     * @param type 1:版次对象;2:版本对象;3:主对象
     * @return 执行的结果
     */
    @Override
    public BaseResult deleteBusinessObject(String btmname, String oid, int type) throws PLException {
        List<BusinessObject> cbos = boService.queryCBO(btmname,WebUtil.getOidQuery(oid));
        BaseResult<Object> objectBaseResult = new BaseResult<>();
        if(cbos.size() == 0){
            objectBaseResult.setSuccess(false);
            throw new PLException("500", new String[]{"没有获取到数据的主键"});
        }
        for (BusinessObject cbo : cbos) {
            if(StringUtils.isBlank(cbo.revisionid)){
                String revisionoid = Arrays.stream(cbo.hisAttrValList).filter(e -> e.attrName.equals("REVISIONOID")).findFirst().map(e -> e.attrVal).orElse("");
                cbo.revisionid = revisionoid;
            }
            boolean b = platformClientUtil.getBOFService().deleteBusinessObject(cbo,type);
            if(!b){
                throw new PLException("500", new String[]{"数据删除失败!!"});
            }
        }
        return BaseResult.success();
    }
    /**
     * 变更所有者
     * @param btmname 业务类型
     * @param oid 主键
     * @return 执行的结果
     */
    @Override
    public BaseResult changeBusinessObjectOwner(String btmname, String oid) throws PLException {
        List<BusinessObject> cbos = boService.queryCBO(btmname,WebUtil.getOidQuery(oid));
        BaseResult<Object> objectBaseResult = new BaseResult<>();
        if(cbos.size() == 0){
            objectBaseResult.setSuccess(false);
            throw new PLException("500", new String[]{"没有获取到数据的主键"});
        }
        UserInfo userInfo = platformClientUtil.getFrameworkService().getUserObjectByUserName(WebUtil.getCurrentUserId());
        for (BusinessObject cbo : cbos) {
            platformClientUtil.getBOFService().changeBusinessObjectOwner(cbo,userInfo);
        }
        return BaseResult.success();
    }
    /**
     * 变更所有者
     * @param btmname 业务类型
     * @param oid 主键
     * @param releaseStatus 发布状态
     * @return 执行的结果
     */
    @Override
    @Transactional
    public BaseResult transferBusinessObject(String btmname, String oid, String toStatus,String releaseStatus) throws PLException {
        List<BusinessObject> cbos = boService.queryCBO(btmname,WebUtil.getOidQuery(oid));
        BaseResult<Object> objectBaseResult = new BaseResult<>();
        if(cbos.size() == 0){
            objectBaseResult.setSuccess(false);
            throw new PLException("500", new String[]{"没有获取到数据的主键"});
        }
        for (BusinessObject cbo : cbos) {
            platformClientUtil.getBOFService().transferBusinessObjectAndRelease(cbo, toStatus, releaseStatus);
        }
        return BaseResult.success();
    }
}