Source/UBCS/ubcs-service/ubcs-omd/src/main/java/com/vci/ubcs/omd/service/impl/BtmTypeServiceImpl.java
@@ -1,25 +1,28 @@
package com.vci.ubcs.omd.service.impl;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.exception.NacosException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.omd.constant.BtmTypeConstant;
import com.vci.ubcs.omd.constant.BtmTypeFieldConstant;
import com.vci.ubcs.omd.dto.BtmAndLinkTypeDdlDTO;
import com.vci.ubcs.omd.entity.*;
import com.vci.ubcs.omd.repeater.DomainRepeater;
import com.vci.ubcs.omd.service.IBtmTypeAttributeService;
import com.vci.ubcs.omd.service.*;
import com.vci.ubcs.omd.vo.*;
import com.vci.ubcs.omd.wrapper.BtmTypeWrapper;
import com.vci.ubcs.omd.wrapper.ModifyAttributeWrapper;
import com.vci.ubcs.starter.web.constant.OmdRegExpConstant;
import com.vci.ubcs.omd.dto.BtmTypeDTO;
import com.vci.ubcs.omd.dto.BtmTypeLinkAttributesDTO;
import com.vci.ubcs.omd.entity.BtmType;
import com.vci.ubcs.omd.entity.BtmTypeAttribute;
import com.vci.ubcs.omd.entity.ModifyAttributeInfoDO;
import com.vci.ubcs.omd.mapper.BtmTypeMapper;
import com.vci.ubcs.omd.service.IBtmTypeService;
import com.vci.ubcs.omd.vo.BtmTypeVO;
import com.vci.ubcs.omd.vo.BtmTypeAttributeVO;
import com.vci.ubcs.omd.vo.LinkTypeVO;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.web.enumpck.BooleanEnum;
import com.vci.ubcs.starter.web.enumpck.VciFieldTypeEnum;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.starter.web.util.VciDateUtil;
import org.springblade.core.log.exception.ServiceException;
@@ -27,16 +30,19 @@
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;
import javax.validation.constraints.NotEmpty;
import java.util.*;
import java.util.stream.Collectors;
/**
 * Description: 业务类型服务的实现类
@@ -60,6 +66,35 @@
   private IBtmTypeAttributeService btmTypeAttributeService;
   /**
    * 字段修改信息的服务
    */
   @Autowired
   private IModifyAttributeService modifyAttributeService;
   /**
    * 版本规则的服务
    */
   @Autowired
   private IRevisionRuleService revisionRuleService;
   /**
    * 属性的服务
    */
   @Autowired
   private IAttributeService attributeService;
   /**
    * 生命周期的服务
    */
   @Autowired
   private ILifeCycleService lifeCycleService;
   /**
    * 表名前缀
    */
   public static final String PL = "PLBT";
   /**
    * 设置平台本身的业务类型
    *
    * @param platformBtmType 平台本身的业务类型
@@ -79,7 +114,11 @@
   @Override
   public BtmTypeVO getBtmTypeByOid(String pkBtmType) throws ServiceException {
      Func.requireNotNull(pkBtmType,"业务类型主键不能为空");
      BtmTypeVO btmTypeVO = BtmTypeWrapper.build().entityVO(baseMapper.selectOne(Wrappers.<BtmType>query().lambda().eq(BtmType::getOid, pkBtmType)));
      BtmType queryBtmType = baseMapper.selectOne(Wrappers.<BtmType>query().lambda().eq(BtmType::getOid, pkBtmType));
      if (queryBtmType == null){
         return null;
      }
      BtmTypeVO btmTypeVO = BtmTypeWrapper.build().entityVO(queryBtmType);
      btmTypeVO.setAttributes(btmTypeAttributeService.getAttributeByBtmTypeOid(pkBtmType));
      return btmTypeVO;
   }
@@ -93,7 +132,10 @@
    */
   @Override
   public List<BtmTypeVO> listBtmTypeByOids(String pkBtmTypes) throws ServiceException {
      return null;
      VciBaseUtil.alertNotNull(pkBtmTypes, "业务类型的主键");
      List<String> pkList = new ArrayList<>();
      Collections.addAll(pkList, pkBtmTypes.split(","));
      return listBtmTypeByOidCollection(pkList);
   }
   /**
@@ -105,6 +147,12 @@
    */
   @Override
   public List<BtmTypeVO> listBtmTypeByOidCollection(Collection<String> pkBtmTypeCollection) throws ServiceException {
      if (!CollectionUtils.isEmpty(pkBtmTypeCollection)) {
         List<BtmType> btmTypeDOList = listBtmTypeDOByOidCollection(pkBtmTypeCollection);
         if (!CollectionUtils.isEmpty(btmTypeDOList)) {
            return BtmTypeWrapper.build().listEntityVO(btmTypeDOList);
         }
      }
      return null;
   }
@@ -117,6 +165,11 @@
    */
   @Override
   public BtmTypeVO getBtmTypeById(String id) throws ServiceException {
      VciBaseUtil.alertNotNull(id, "业务类型的英文名称");
      List<BtmTypeVO> btmTypeVOList = listBtmTypeByIds(id);
      if (!CollectionUtils.isEmpty(btmTypeVOList)) {
         return btmTypeVOList.get(0);
      }
      return null;
   }
@@ -129,7 +182,8 @@
    */
   @Override
   public List<BtmTypeVO> listBtmTypeByIds(String ids) throws ServiceException {
      return null;
      Func.requireNotNull(ids,"英文名称不能为空");
      return listBtmTypeByIdCollection(Func.toStrList(",",ids));
   }
   /**
@@ -141,7 +195,7 @@
    */
   @Override
   public List<BtmTypeVO> listBtmTypeByIdCollection(Collection<String> idCollection) throws ServiceException {
      return null;
      return CollectionUtils.isEmpty(idCollection) ?  null : BtmTypeWrapper.build().listEntityVO(baseMapper.selectList(Wrappers.<BtmType>query().lambda().in(BtmType::getId,idCollection)));
   }
   /**
@@ -153,7 +207,7 @@
    */
   @Override
   public List<BtmType> listBtmTypeDOByIdCollection(Collection<String> idCollection) throws ServiceException {
      return null;
      return CollectionUtils.isEmpty(idCollection) ? null : baseMapper.selectByIdCollection(idCollection);
   }
   /**
@@ -165,6 +219,9 @@
    */
   @Override
   public List<BtmType> listBtmTypeDOByOidCollection(Collection<String> oidCollection) throws ServiceException {
      if (!CollectionUtils.isEmpty(oidCollection)) {
         return baseMapper.selectList(Wrappers.<BtmType>query().lambda().in(BtmType::getOid, oidCollection));
      }
      return null;
   }
@@ -177,7 +234,7 @@
    */
   @Override
   public String getNameByOid(String oid) throws ServiceException {
      return null;
      return Objects.requireNonNull(baseMapper.selectOne(Wrappers.<BtmType>query().lambda().eq(BtmType::getOid,oid))).getName();
   }
   /**
@@ -189,7 +246,7 @@
    */
   @Override
   public String getNameById(String id) throws ServiceException {
      return null;
      return Objects.requireNonNull(baseMapper.selectOne(Wrappers.<BtmType>query().lambda().eq(BtmType::getId,id))).getName();
   }
   /**
@@ -213,6 +270,16 @@
    */
   @Override
   public List<BtmTypeAttributeVO> listHasAttributeById(String id) throws ServiceException {
      VciBaseUtil.alertNotNull(id,"业务类型英文名称");
      List<String> ids = Func.toStrList(",", id);
      Map<String, List<BtmTypeAttributeVO>> attributeMap = batchListHasAttributesByIdCollection(ids);
      if (!CollectionUtils.isEmpty(attributeMap)) {
         List<BtmTypeAttributeVO> attributeVOList = new ArrayList<>();
         attributeMap.forEach((k, v) -> {
            attributeVOList.addAll(v);
         });
         return attributeVOList;
      }
      return null;
   }
@@ -225,7 +292,7 @@
    */
   @Override
   public Map<String, List<BtmTypeAttributeVO>> batchListHasAttributesByOidCollection(Collection<String> oidCollection) throws ServiceException {
      return null;
      return btmTypeAttributeService.batchListHasAttributesByBtmTypeOidCollection(oidCollection).stream().collect(Collectors.groupingBy(BtmTypeAttributeVO::getPkBtmType));
   }
   /**
@@ -237,7 +304,8 @@
    */
   @Override
   public Map<String, List<BtmTypeAttributeVO>> batchListHasAttributesByIdCollection(Collection<String> idCollection) throws ServiceException {
      return null;
      List<String> btmTypeOidList = baseMapper.selectList(Wrappers.<BtmType>query().lambda().in(BtmType::getId, idCollection)).stream().map(BtmType::getOid).collect(Collectors.toList());
      return btmTypeAttributeService.batchListHasAttributesByBtmTypeOidCollection(btmTypeOidList).stream().collect(Collectors.groupingBy(BtmTypeAttributeVO::getPkBtmType));
   }
   /**
@@ -261,7 +329,8 @@
    */
   @Override
   public boolean checkBtmTypeUsed(String pkBtmType) throws ServiceException {
      return false;
      VciBaseUtil.alertNotNull(pkBtmType, "业务类型主键");
      return checkBtmTypeUseds(VciBaseUtil.str2List(pkBtmType));
   }
   /**
@@ -273,113 +342,41 @@
    */
   @Override
   public boolean checkBtmTypeUseds(Collection<String> oidCollection) throws ServiceException {
      VciBaseUtil.alertCollectionNotNull("校验是否引用的业务类型对象的主键", oidCollection);
      //检查链接类型
      //因为链接类型中fromBtmType和toBtmType都是逗号分隔的,所以直接查询所有的链接类型中的使用的业务类型名称
      List<BtmType> btmTypeDOList = listBtmTypeDOByOidCollection(oidCollection);
      if (CollectionUtils.isEmpty(btmTypeDOList)) {
         return false;
      }
      /*Set<String> usedBtmTypeSet = linkTypeServiceI.listUsedBtmType();
      if (btmTypeDOList.stream().anyMatch(s -> usedBtmTypeSet.contains(s.getId().trim().toLowerCase()))) {
         return true;
      }*/
      return false;
   }
   /**
    * 添加业务类型
    *
    * @param btmTypeDTO      业务类型数据传输对象
    * @param autoCreateTable 是否自动创建表格
    * @return 添加后的业务类型
    * @throws ServiceException 添加出错的时候会抛出异常
    * 添加默认的字段
    * @param attributes 字段集
    * @param fieldMap 默认字段集
    * @return 添加后的字段集
    */
   @Override
   public BtmTypeDTO addSave(BtmTypeDTO btmTypeDTO, boolean autoCreateTable) throws ServiceException {
      TransactionStatus transaction = null;
      DefaultTransactionDefinition def = null;
      if (autoCreateTable) {
         def = new DefaultTransactionDefinition();
         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
         // 事物隔离级别,开启新事务,这样会比较安全些。
         transaction = dataSourceTransactionManager.getTransaction(def);
         // 获得事务状态
      }
      BtmType btmTypeDO = new BtmType();
      try {
         VciBaseUtil.alertNotNull(btmTypeDTO, "要添加的业务类型", btmTypeDTO.getId(), "业务类型的英文名称", btmTypeDTO.getName(), "业务类型中文名称");
         if (btmTypeDTO.isViewFlag() && (StringUtils.isBlank(btmTypeDTO.getViewCreateSql())
            || StringUtils.isBlank(btmTypeDTO.getTableName()))) {
            throw new VciBaseException("如果当前是业务类型是视图的时候,请必须输入视图的创建语句和视图名称");
   private List<BtmTypeLinkAttributesDTO> addAttributeByFieldMap(List<BtmTypeLinkAttributesDTO> attributes, Map<String, String> fieldMap) {
      Map<String, BtmTypeLinkAttributesDTO> existFieldMap = attributes.stream().collect(Collectors.toMap(BtmTypeLinkAttributesDTO::getId, t -> t, (o1, o2) -> o1));
      fieldMap.forEach((k,v) -> {
         if (!existFieldMap.containsKey(k)){
            BtmTypeLinkAttributesDTO attr = new BtmTypeLinkAttributesDTO();
            attr.setId(k);
            attr.setName(v);
            attr.setAttrDataType(VciFieldTypeEnum.VTString.name());
            attr.setAttributeLength(50);
            attr.setNullableFlag(false);
            attr.setDescription(v);
            attributes.add(attr);
         }
         if (!btmTypeDTO.isViewFlag()) {
            VciBaseUtil.alertCollectionNotNull("属性", btmTypeDTO.getAttributesDTOList());
         }
         if (!btmTypeDTO.getId().matches(OmdRegExpConstant.LETTER)) {
            throw new VciBaseException("业务类型英文名称只能是纯英文,目前为{0}", new Object[]{btmTypeDTO.getId()});
         }
         if (btmTypeDTO.getId().length() > 24) {
            throw new VciBaseException("业务类型英文名称不能超过18,目前长度为{0}", new Object[]{btmTypeDTO.getId().length()});
         }
         List<BtmType> btmTypeDOList = listBtmTypeDOByIdCollection(VciBaseUtil.str2List(btmTypeDTO.getId()));
         if (!CollectionUtils.isEmpty(btmTypeDOList) && btmTypeDOList.size() > 0) {
            BtmType existBtmType = btmTypeDOList.get(0);
            throw new VciBaseException("业务类型英文名称已经存在(不区分大小写),这个英文名称对应的中文名称为{0},创建人{1},创建时间{2}"
               , new Object[]{existBtmType.getName(), existBtmType.getCreator(), VciDateUtil.date2Str(existBtmType.getCreateTime(), VciDateUtil.DateFormat)});
         }
         /*
         //检查使用的版本规则是否存在
         if (StringUtils.isNotBlank(btmTypeDTO.getRevisionRuleId())) {
            if (revisionRuleServiceI.checkRevisionRuleExist(btmTypeDTO.getRevisionRuleId())) {
               throw new VciBaseException("版本规则{0}[{1}]在系统中不存在,请先查证",
                  new Object[]{btmTypeDTO.getRevisionRuleId(), btmTypeDTO.getRevisionRuleName()});
            }
         }
         //检查使用的生命周期是否存在
         if (StringUtils.isNotBlank(btmTypeDTO.getLifeCycleId())
            && !FrameWorkLcStatusConstant.EMTYPE_LIFE_CYCLE.equalsIgnoreCase(btmTypeDTO.getLifeCycleId())) {
            if (lifeCycleServiceI.checkLifeCycleExist(btmTypeDTO.getLifeCycleId())) {
               throw new VciBaseException("生命周期{0}[{1}]在系统中不存在,请先查证",
                  new Object[]{btmTypeDTO.getLifeCycleId(), btmTypeDTO.getLifeCycleName()});
            }
         }
         if (StringUtils.isNotBlank(btmTypeDTO.getSubLifeCycleId())) {
            if (lifeCycleServiceI.checkLifeCycleExist(btmTypeDTO.getSubLifeCycleId())) {
               throw new VciBaseException("备用生命周期{0}[{1}]中其中有某些在系统中不存在,请先查证",
                  new Object[]{btmTypeDTO.getSubLifeCycleId(), btmTypeDTO.getSubLifeCycleName()});
            }
         }
         */
         if (StringUtils.isBlank(btmTypeDTO.getOid())) {
            btmTypeDTO.setOid(VciBaseUtil.getPk());
         }
         BeanUtil.copy(btmTypeDTO, btmTypeDO);
         String creator = AuthUtil.getUserAccount();
         Date now = new Date();
         btmTypeDO.setCreator(creator);
         btmTypeDO.setCreateTime(now);
         btmTypeDO.setOwner(creator);
         btmTypeDO.setBtmname(BtmTypeConstant.OMD_BTMTYPE);
         btmTypeDO.setTs(now);
         if (StringUtils.isBlank(btmTypeDO.getTableName())) {
            btmTypeDO.setTableName(getTableName(btmTypeDO.getId()));
         }
         //处理属性
         addAttributeForBtm(btmTypeDTO, creator, now);
         baseMapper.insert(btmTypeDO);
         if (autoCreateTable) {
            dataSourceTransactionManager.commit(transaction);
         }
      } catch (ServiceException e) {
         if (autoCreateTable) {
            dataSourceTransactionManager.rollback(transaction);
         }
         throw e;
      } catch (Throwable e) {
         if (autoCreateTable) {
            dataSourceTransactionManager.rollback(transaction);
         }
         throw e;
      }
      if (autoCreateTable) {
         BtmTypeVO btmTypeVO = BtmTypeWrapper.build().entityVO(btmTypeDO);
         btmTypeVO.setAttributes(listHasAttributesByOid(btmTypeDO.getOid()));
         checkTableSame(btmTypeVO);
      }
      return btmTypeDTO;
      });
      return attributes;
   }
   /**
@@ -388,43 +385,44 @@
    * @param btmTypeVO 业务类型的显示对象
    */
   private void checkTableSame(BtmTypeVO btmTypeVO) {
      /*List<OmdBtmTypeVO> btmTypeVOList = new ArrayList<>();
      List<BtmTypeVO> btmTypeVOList = new ArrayList<>();
      btmTypeVOList.add(btmTypeVO);
      List<OsModifyAttributeInfoDO> modifyAttributeInfoDOList = ddlServiceI.checkDifferent(btmTypeVOList, null);
      BtmAndLinkTypeDdlDTO ddlDTO = new BtmAndLinkTypeDdlDTO();
      ddlDTO.setBtmTypeList(btmTypeVOList);
      try {
         modifyAttributeServiceI.batchAddSave(modifyAttributeInfoDOList);
      } catch (Throwable e) {
         if (logger.isErrorEnabled()) {
            logger.error("保存【修改属性】数据", e);
         // 将以前的checkDifferent和reflexDifferent结合了
         R result = DomainRepeater.checkDifferent(ddlDTO,btmTypeVO.getBizDomain());
         if (result.isSuccess()){
            List<ModifyAttributeInfo> infoList = new ArrayList<>();
            Object data = result.getData();
            if (data instanceof List){
               List dataList = (List) data;
               dataList.forEach(s -> {
                  if (s instanceof ModifyAttributeInfo){
                     ModifyAttributeInfo info = (ModifyAttributeInfo) s;
                     infoList.add(info);
                  }
               });
               modifyAttributeService.saveBatch(ModifyAttributeWrapper.build().listEntityBeforeSave(infoList));
            }
         }
      } catch (NacosException e) {
         if (log.isDebugEnabled()) {
            log.error("保存【修改属性】数据", e);
         }
         throw new RuntimeException(e);
      }
      ddlServiceI.reflexDifferent(modifyAttributeInfoDOList);
      modifyAttributeServiceI.finishModify(modifyAttributeInfoDOList);*/
//      modifyAttributeServiceI.finishModify(modifyAttributeInfoList);
   }
   /**
    * 添加属性到业务类型中
    *
    * @param btmTypeDTO 业务类型的数据传输对象
    * @param creator    创建人
    * @param now        当前时间
    */
   private void addAttributeForBtm(BtmTypeDTO btmTypeDTO, String creator, Date now) throws VciBaseException{
      List<BtmTypeLinkAttributesDTO> attributesDTOList = btmTypeDTO.getAttributesDTOList();
      btmTypeAttributeService.checkAndInsert(btmTypeDTO.getOid(),attributesDTOList,creator,now);
   }
   /**
    * 修改业务类型
    *
    * @param btmTypeDTO    业务类型数据传输对象
    * @param autoEditTable 是否自动更新表格
    * @return 修改后的业务类型
    * @throws ServiceException 修改出错的时候会抛出异常
    */
   @Override
   public BtmTypeDTO editSave(BtmTypeDTO btmTypeDTO, boolean autoEditTable) throws ServiceException {
      return null;
   private List<BtmTypeAttributeVO> addAttributeForBtm(BtmTypeDTO btmTypeDTO) throws VciBaseException{
      List<BtmTypeLinkAttributesDTO> attributesDTOList = btmTypeDTO.getAttributes();
      return btmTypeAttributeService.checkAndInsert(btmTypeDTO.getOid(),attributesDTOList,AuthUtil.getUserAccount(),new Date());
   }
   /**
@@ -459,7 +457,7 @@
    * @throws ServiceException 参数为空或者查询出错时会抛出异常
    */
   @Override
   public List<ModifyAttributeInfoDO> checkDbTableSame(String pkBtmType) throws ServiceException {
   public List<ModifyAttributeInfo> checkDbTableSame(String pkBtmType) throws ServiceException {
      return null;
   }
@@ -471,102 +469,14 @@
    * @throws ServiceException 参数为空的时候会抛出异常
    */
   @Override
   public String getTableName(String id) throws ServiceException {
      return null;
   }
   /**
    * 将业务类型使用的属性的传输对象转换为数据对象
    *
    * @param attributesDTO 属性的数据传输对象
    * @param pkBtmType     业务类型的主键
    * @param creator       创建人
    * @param now           当前时间
    * @return 属性的数据对象
    */
   @Override
   public BtmTypeAttribute btmTypeAttributeDTO2DO(BtmTypeLinkAttributesDTO attributesDTO, String pkBtmType, String creator, Date now) {
      return null;
   }
   /**
    * 业务类型的属性显示对象转换为数据对象
    *
    * @param thisBtmTypeHasAttributeVOList 业务类型属性显示对象
    * @return 数据对象
    */
   @Override
   public List<BtmTypeAttribute> btmTypeAttributeVO2DO(List<BtmTypeAttributeVO> thisBtmTypeHasAttributeVOList) {
      return null;
   }
   /**
    * 批量将业务类型的数据对象转换为显示对象
    *
    * @param attributeDOList 属性的数据对象列表
    * @return 属性的显示对象列表
    */
   @Override
   public List<BtmTypeAttributeVO> batchBtmTypeAttributeDO2VO(List<BtmTypeAttribute> attributeDOList) {
      return null;
   }
   /**
    * 批量将业务类型的数据对象转换为显示对象
    *
    * @param attributesDO 属性的数据对象
    * @return 属性的显示对象列表
    */
   @Override
   public BtmTypeAttributeVO btmTypeAttributeDO2VO(BtmTypeAttribute attributesDO) {
      return null;
   }
   /**
    * 获取业务类型的指定属性
    *
    * @param id                    链接类型的英文名称
    * @param attributeIdCollection 属性的集合,如果为空则获取全部
    * @return 属性的显示对象
    */
   @Override
   public List<BtmTypeAttribute> listAttributeDOByIdsForBtm(String id, Collection<String> attributeIdCollection) {
      return null;
   }
   /**
    * 根据业务类型的编号获取属性
    *
    * @param id 业务类型的编号
    * @return 属性的显示对象
    */
   @Override
   public List<BtmTypeAttributeVO> listAttributeByBtmTypeId(String id) {
      return null;
   }
   /**
    * 根据业务类型的主键获取属性
    *
    * @param oid 业务类型的主键
    * @return 属性的显示对象
    */
   @Override
   public List<BtmTypeAttributeVO> listAttributeByBtmTypeOid(String oid) {
      return null;
   }
   /**
    * 批量根据业务类型编号或者主键获取包含的属性
    *
    * @param oidsOrIds 主键或者编号集合
    * @param queryById 是否使用编号查询
    * @return key是业务类型的主键或者编号,值是包含的属性的信息
    * @throws ServiceException 参数为空或者查询出错会抛出异常
    */
   @Override
   public List<BtmTypeAttributeVO> batchListAttributeByBtmType(Collection<String> oidsOrIds, boolean queryById) throws ServiceException {
      return null;
   public String getTableName(String id,String domain) throws VciBaseException {
      VciBaseUtil.alertNotNull(id,"业务类型英文名称",domain,"领域名称");
      if (domain.contains("ubcs-")){
         domain = domain.split("ubcs-")[1];
      }else {
         throw new VciBaseException("领域名称不符合规则");
      }
      return PL + StringPool.UNDERSCORE + domain + StringPool.UNDERSCORE + id;
   }
   /**
@@ -576,16 +486,167 @@
    * @return 执行结果
    */
   @Override
   public boolean submit(BtmTypeDTO btmTypeDTO) {
      addSave(btmTypeDTO,false);
      try {
         R result = DomainRepeater.submitBtmType(btmTypeDTO.getDomain(), Objects.requireNonNull(BeanUtil.copy(btmTypeDTO, BtmTypeVO.class)));
         return result.isSuccess();
      } catch (NacosException e) {
         throw new RuntimeException(e);
   @Transactional(rollbackFor = Exception.class)
   public R submit(BtmTypeDTO btmTypeDTO, boolean autoCreateTable) throws ServiceException {
      /*TransactionStatus transaction = null;
      DefaultTransactionDefinition def = null;
      if (autoCreateTable) {
         def = new DefaultTransactionDefinition();
         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
         // 事物隔离级别,开启新事务,这样会比较安全些。
         transaction = dataSourceTransactionManager.getTransaction(def);
         // 获得事务状态
      }*/
      //checkBtmTypeBeforeSave(btmTypeDTO);
      BtmType btmTypeDO = Optional.ofNullable(BeanUtil.copy(btmTypeDTO, BtmType.class)).orElseGet(BtmType::new);
      btmTypeDO.setBizDomain(btmTypeDTO.getBizDomain());
      List<BtmTypeLinkAttributesDTO> attributes = btmTypeDTO.getAttributes();
      List<BtmTypeAttributeVO> afterAttributes;
      if (StringUtils.isBlank(btmTypeDO.getOid())){
         btmTypeDO = BtmTypeWrapper.build().entityBeforeInsert(btmTypeDO);
         if (StringUtils.isBlank(btmTypeDO.getTableName())) {
            btmTypeDO.setTableName(getTableName(btmTypeDO.getId(),btmTypeDO.getBizDomain()));
         }
         // 添加属性
         btmTypeDTO.setOid(btmTypeDO.getOid());
         afterAttributes = addAttributeForBtm(btmTypeDTO);
         baseMapper.insert(btmTypeDO);
      }else {
         BtmTypeVO btmTypeByOid = getBtmTypeByOid(btmTypeDO.getOid());
         List<BtmTypeAttributeVO> beforeAttributes = btmTypeByOid.getAttributes();
         // 处理属性,多余的删除,不存在的添加
         afterAttributes = updateAttributeForBtm(btmTypeByOid.getOid(),beforeAttributes, attributes);
         baseMapper.updateByPrimaryKey(btmTypeDO);
      }
      BtmTypeVO btmTypeVO = BtmTypeWrapper.build().entityVO(btmTypeDO);
      //在创建表的时候还需要把默认的字段带上。
      List<BtmTypeAttributeVO> defaultAttribute = btmTypeAttributeService.getDefaultAttribute(btmTypeVO);
      afterAttributes.addAll(defaultAttribute);
      btmTypeVO.setAttributes(afterAttributes);
      try {
         if (autoCreateTable) {
            // checkTableSame(btmTypeVO);
            R result = DomainRepeater.submitBtmType(btmTypeDTO.getBizDomain(), btmTypeVO);
            if (result.isSuccess()){
               List<ModifyAttributeInfo> infoList = new ArrayList<>();
               Object data = result.getData();
               if (data instanceof List){
                  List dataList = (List) data;
                  dataList.forEach(s -> {
                     if (s instanceof ModifyAttributeInfo){
                        ModifyAttributeInfo info = (ModifyAttributeInfo) s;
                        infoList.add(info);
                     }
                  });
                  modifyAttributeService.saveBatch(ModifyAttributeWrapper.build().listEntityBeforeSave(infoList));
               }
               // dataSourceTransactionManager.commit(transaction);
            }else {
               // dataSourceTransactionManager.rollback(transaction);
               // 创建表报错,抛出异常让该方法回滚
               throw new VciBaseException(result.getMsg());
               // return R.fail(result.getMsg());
            }
         }
      } catch (Throwable e) {
         if (autoCreateTable) {
//            dataSourceTransactionManager.rollback(transaction);
            throw new VciBaseException(e.getMessage());
         }
      }
      return R.data(btmTypeVO);
   }
   /**
    * 更新业务类型的属性
    * @param oid 逐渐
    * @param beforeAttr 更新前的属性
    * @param afterAttr 更新后的属性
    */
   private List<BtmTypeAttributeVO> updateAttributeForBtm(String oid, List<BtmTypeAttributeVO> beforeAttr, List<BtmTypeLinkAttributesDTO> afterAttr) {
      List<BtmTypeAttributeVO> deleteList = beforeAttr.stream().filter(before -> afterAttr.stream().noneMatch(after -> StringUtils.equals(before.getId(), after.getId()))).collect(Collectors.toList());
      List<BtmTypeLinkAttributesDTO> addList = afterAttr.stream().filter(after -> beforeAttr.stream().noneMatch(before -> StringUtils.equals(before.getId(), after.getId()))).collect(Collectors.toList());
      List<BtmTypeLinkAttributesDTO> modifyList = new ArrayList<>();
      Map<String, BtmTypeAttributeVO> beforeAttrMap = beforeAttr.stream().collect(Collectors.toMap(BtmTypeAttributeVO::getId, t -> t, (o1, o2) -> o1));
      Map<String, BtmTypeLinkAttributesDTO> afterAttrMap = afterAttr.stream().collect(Collectors.toMap(BtmTypeLinkAttributesDTO::getId, t -> t, (o1, o2) -> o1));
      afterAttrMap.forEach((k,v) -> {
         if (beforeAttrMap.containsKey(k)){
            modifyList.add(v);
         }
      });
      btmTypeAttributeService.checkAndRemove(deleteList.stream().map(BtmTypeAttributeVO::getOid).collect(Collectors.toList()));
      List<BtmTypeAttributeVO> voListAdd = btmTypeAttributeService.checkAndInsert(oid, addList, AuthUtil.getUserAccount(), new Date());
      List<BtmTypeAttributeVO> voListUpdate = btmTypeAttributeService.checkAndUpdate(oid, modifyList, AuthUtil.getUserAccount(), new Date());
      List<BtmTypeAttributeVO> returnList = new ArrayList<>();
      if(!CollectionUtils.isEmpty(voListAdd)) {
         returnList.addAll(Objects.requireNonNull(voListAdd));
      }
      if(!CollectionUtils.isEmpty(voListUpdate)) {
         returnList.addAll(Objects.requireNonNull(voListUpdate));
      }
      return returnList;
   }
   /**
    * 检查业务类型符合规范
    * @param btmTypeDTO 业务类型页面传输对象
    */
   private void checkBtmTypeBeforeSave(BtmTypeDTO btmTypeDTO) {
      VciBaseUtil.alertNotNull(btmTypeDTO, "要添加的业务类型", btmTypeDTO.getId(), "业务类型的英文名称", btmTypeDTO.getName(), "业务类型中文名称");
      if (btmTypeDTO.isViewFlag() && (StringUtils.isBlank(btmTypeDTO.getViewCreateSql())
         || StringUtils.isBlank(btmTypeDTO.getTableName()))) {
         throw new VciBaseException("如果当前是业务类型是视图的时候,请必须输入视图的创建语句和视图名称");
      }
      if (!btmTypeDTO.isViewFlag()) {
         VciBaseUtil.alertCollectionNotNull("属性", btmTypeDTO.getAttributes());
      }
      if (!btmTypeDTO.getId().matches(OmdRegExpConstant.LETTER)) {
         throw new VciBaseException("业务类型英文名称只能是纯英文,目前为{0}", new Object[]{btmTypeDTO.getId()});
      }
      if (btmTypeDTO.getId().length() > 24) {
         throw new VciBaseException("业务类型英文名称不能超过18,目前长度为{0}", new Object[]{btmTypeDTO.getId().length()});
      }
      List<BtmType> btmTypeDOList = listBtmTypeDOByIdCollection(VciBaseUtil.str2List(btmTypeDTO.getId().toLowerCase(Locale.ROOT)));
      if (!CollectionUtils.isEmpty(btmTypeDOList) && btmTypeDOList.size() > 0) {
         boolean exist = btmTypeDOList.stream().filter(btm -> StringUtils.isNotBlank(btm.getOid())).anyMatch(btm -> !StringUtils.equals(btmTypeDTO.getOid(), btm.getOid()));
         BtmType existBtmType = btmTypeDOList.get(0);
         if (exist) {
            throw new VciBaseException("业务类型英文名称已经存在(不区分大小写),这个英文名称对应的中文名称为{0},创建人{1},创建时间{2}"
               , new Object[]{existBtmType.getName(), existBtmType.getCreator(), VciDateUtil.date2Str(existBtmType.getCreateTime(), VciDateUtil.DateFormat)});
         }
      }
      if (btmTypeDTO.isRevisionFlag()){
         // 需要控制版本
         // 检查使用的版本规则是否存在
         if (StringUtils.isNotBlank(btmTypeDTO.getRevisionRuleId())) {
            if (!revisionRuleService.checkRevisionRuleExist(btmTypeDTO.getRevisionRuleId())) {
               throw new VciBaseException("版本规则{0}[{1}]在系统中不存在,请先查证",
                  new Object[]{btmTypeDTO.getRevisionRuleId(), btmTypeDTO.getRevisionRuleName()});
            }
         }
      }
      if (btmTypeDTO.isLifeCycleFlag()){
         // 需要控制生命周期
         //检查使用的生命周期是否存在
            if (StringUtils.isNotBlank(btmTypeDTO.getLifeCycleId())
//               && !FrameWorkLcStatusConstant.EMTYPE_LIFE_CYCLE.equalsIgnoreCase(btmTypeDTO.getLifeCycleId())
            ) {
               if (lifeCycleService.getOne(Wrappers.<LifeCycleRule>query().lambda().eq(LifeCycleRule::getId,btmTypeDTO.getLifeCycleId())) == null) {
                  throw new VciBaseException("生命周期{0}[{1}]在系统中不存在,请先查证",
                     new Object[]{btmTypeDTO.getLifeCycleId(), btmTypeDTO.getLifeCycleName()});
               }
            }
//            if (StringUtils.isNotBlank(btmTypeDTO.getSubLifeCycleId())) {
//               if (lifeCycleServiceI.checkLifeCycleExist(btmTypeDTO.getSubLifeCycleId())) {
//                  throw new VciBaseException("备用生命周期{0}[{1}]中其中有某些在系统中不存在,请先查证",
//                     new Object[]{btmTypeDTO.getSubLifeCycleId(), btmTypeDTO.getSubLifeCycleName()});
//               }
//            }
      }
      if (btmTypeDTO.isSecretFlag()){
         // 需要控制密级
      }
   }
   @Override
   public boolean deleteLogic(@NotEmpty List<Long> ids) {
      return false;
@@ -595,4 +656,317 @@
   public boolean changeStatus(@NotEmpty List<Long> ids, Integer status) {
      return false;
   }
   /**
    * 按domain分组,查询业务类型属性结构
    *
    * @return 查询结果
    */
   @Override
   public List<BtmTreeVO> treeDomain() {
      try {
         Map<String, String> domain = Optional.ofNullable(DomainRepeater.getDomain()).orElseGet(ArrayList::new).stream().collect(Collectors.toMap(DomainVO::getValue, DomainVO::getLabel));
         List<BtmTypeVO> vos = BtmTypeWrapper.build().listEntityVO(baseMapper.selectAll());
         if (CollectionUtils.isEmpty(vos)){
            return new ArrayList<>();
         }
         Map<String, List<BtmTypeVO>> domainMap = Optional.ofNullable(vos).orElseGet(ArrayList::new).stream().sorted(Comparator.comparing(BtmTypeVO::getId)).collect(Collectors.groupingBy(BtmTypeVO::getBizDomain));
         List<BtmTreeVO> treeList = new ArrayList<>();
         domainMap.forEach((k,v)-> {
            if (domain.containsKey(k)){
               String label = domain.get(k);
               BtmTreeVO parent = new BtmTreeVO();
               parent.setName(label);
               parent.setLabel(label);
               parent.setId(k);
               parent.setLevel(1);
               parent.setChildList(v.stream().map(s -> {
                  BtmTreeVO child = new BtmTreeVO();
                  child.setOid(s.getOid());
                  child.setName(s.getName());
                  child.setId(s.getId());
                  child.setLevel(2);
                  child.setLabel(s.getId() +  (s.getName() == null ? "" : "(" + s.getName() + ")"));
                  return child;
               }).collect(Collectors.toList()));
               treeList.add(parent);
            }
         });
         return treeList;
      } catch (NacosException e) {
         throw new RuntimeException(e);
      }
   }
   /**
    * 从数据库表中获取
    *
    * @param domain 领域值
    * @return 读取结果
    */
   @Override
   public List<BtmTypeVO> getFromTable(String domain) {
      VciBaseUtil.alertNotNull(domain,"领域值");
      try {
         if (!DomainRepeater.getDomain().stream().collect(Collectors.toMap(DomainVO::getValue, DomainVO::getLabel)).containsKey(domain)){
            return null;
         }
         R result = DomainRepeater.getFromTable(domain);
         if (result.isSuccess()){
            List<BtmTypeVO> list = new ArrayList<>();
            Object dataList = result.getData();
            if (dataList instanceof  List){
               ((List<?>) dataList).forEach(data -> {
                  JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(data));
                  list.add(BeanUtil.copy(jsonObject,BtmTypeVO.class));
               });
            }
            return list;
         }else {
            return new ArrayList<>();
         }
      } catch (NacosException e) {
         throw new RuntimeException(e);
      }
   }
   /**
    * 选择数据库表保存为业务类型
    *
    * @param btmTypeDTOList 页面传输对象
    * @param domain 领域
    * @return 执行结果
    */
   @Override
   @Transactional
   public List<BtmTypeVO> saveFromTable(List<BtmTypeDTO> btmTypeDTOList,String domain) {
      // 之前已经做过重复校验了,这边直接执行保存逻辑即可
      List<BtmType> btmList = new ArrayList<>();
      List<BtmTypeAttribute> btmTypeAttributes = new ArrayList<>();
      Map<String,Attribute> idAttrMap = new HashMap<>();
      // 校验属性是否存在
      Set<String> attributeIds = new HashSet<>();
      Date now = new Date();
      String user = AuthUtil.getUserAccount();
      btmTypeDTOList.stream().forEach(dto -> {
         BtmType btmType = Objects.requireNonNull(BeanUtil.copy(dto, BtmType.class));
         btmType.setOid(VciBaseUtil.getPk());
         btmType.setTs(now);
         btmType.setCreator(user);
         btmType.setBtmName(BtmTypeConstant.BTMTYPE);
         btmType.setCreateTime(now);
         btmType.setBizDomain(domain);
         btmType.setLastModifyTime(now);
         btmType.setLastModifier(user);
         btmType.setName(dto.getDescription());
         Set<String> ids = dto.getAttributes().stream().filter(s -> {
            return ! (BtmTypeFieldConstant.BASIC_FIELD_MAP.containsKey(s.getId())
            || BtmTypeFieldConstant.LIFECYCLE_MANAGE_FIELD_MAP.containsKey(s.getId())
            || BtmTypeFieldConstant.SECRET_MANAGE_FIELD_MAP.containsKey(s.getId())
            || BtmTypeFieldConstant.REVISION_MANAGE_FIELD_MAP.containsKey(s.getId())
            );
         }).map(attr -> {
            // 添加属性,1是校验,2是添加
            Attribute attribute = new Attribute();
            attribute.setId(attr.getId());
            attribute.setName(attr.getName());
            attribute.setTypeCode("attributeType");
            attribute.setTypeKey(attr.getAttrDataType());
//            attribute.setDictKey(attr.getAttrDataType());
            attribute.setMaxLength(attr.getAttributeLength());
            attribute.setPrecision(attr.getPrecisionLength());
            attribute.setDescription(attr.getDescription());
            attribute.setDefaultValue(attr.getDefaultValue());
            attribute.setNullable(String.valueOf(attr.isNullableFlag()));
            attribute.setHashtag(attr.getDescription());
            attribute.setReferToId(attr.getReferBtmTypeId());
            attribute.setReferToName(attr.getReferBtmTypeName());
            attribute.setTs(now);
            attribute.setOwner(user);
            attribute.setCreateTime(now);
            attribute.setLastModifier(user);
            attribute.setLastModifyTime(now);
            attribute.setBtmName(BtmTypeConstant.ATTRIBUTE);
            attribute.setCreator(user);
            attribute.setOid(VciBaseUtil.getPk());
            idAttrMap.put(attribute.getId(),attribute);
            // 在这里给业务类型设置版本控制、生命周期控制、密级控制相关的信息
            // 添加业务类型和属性的关系
            BtmTypeAttribute btmTypeAttribute = Objects.requireNonNull(BeanUtil.copy(attr, BtmTypeAttribute.class));
            btmTypeAttribute.setPkBtmType(btmType.getOid());
            btmTypeAttribute.setCreator(user);
            btmTypeAttribute.setCreateTime(now);
            btmTypeAttribute.setLastModifier(user);
            btmTypeAttribute.setLastModifyTime(now);
            btmTypeAttribute.setOid(VciBaseUtil.getPk());
            btmTypeAttribute.setBtmName(btmType.getId());
            btmTypeAttribute.setOwner(user);
            btmTypeAttributes.add(btmTypeAttribute);
            return attr;
         }).map(BtmTypeLinkAttributesDTO::getId).collect(Collectors.toSet());
         attributeIds.addAll(ids);
         btmType.setLifeCycleFlag(String.valueOf(ids.stream().anyMatch(BtmTypeFieldConstant.LIFECYCLE_MANAGE_FIELD_MAP::containsKey)));
         btmType.setRevisionFlag(String.valueOf(ids.stream().anyMatch(BtmTypeFieldConstant.REVISION_MANAGE_FIELD_MAP::containsKey)));
         btmType.setSecretFlag(String.valueOf(ids.stream().anyMatch(BtmTypeFieldConstant.SECRET_MANAGE_FIELD_MAP::containsKey)));
         btmType.setConsistence(BooleanEnum.TRUE.getValue());
         btmList.add(btmType);
      });
      List<Attribute> existAttr = attributeService.list(Wrappers.<Attribute>query().lambda().in(Attribute::getId, attributeIds));
      if (!CollectionUtils.isEmpty(btmList)){
         baseMapper.batchInsert(btmList);
      }
      if (!CollectionUtils.isEmpty(btmTypeAttributes)){
         btmTypeAttributeService.saveBatch(btmTypeAttributes);
      }
      BtmTypeFieldConstant.BASIC_FIELD_MAP.forEach((k,v) -> {
         idAttrMap.remove(k);
      });
      BtmTypeFieldConstant.LIFECYCLE_MANAGE_FIELD_MAP.forEach((k,v) -> {
         idAttrMap.remove(k);
      });
      BtmTypeFieldConstant.SECRET_MANAGE_FIELD_MAP.forEach((k,v) -> {
         idAttrMap.remove(k);
      });
      BtmTypeFieldConstant.REVISION_MANAGE_FIELD_MAP.forEach((k,v) -> {
         idAttrMap.remove(k);
      });
      if (CollectionUtils.isEmpty(existAttr)){
         attributeService.saveBatch(idAttrMap.values());
      }else {
         List<Attribute> addList = idAttrMap.values().stream().filter(a -> existAttr.stream().noneMatch(b -> StringUtils.equals(a.getId(), b.getId()))).collect(Collectors.toList());
         if (!CollectionUtils.isEmpty(addList)) {
            attributeService.saveBatch(addList);
         }
      }
      return BtmTypeWrapper.build().listEntityVO(btmList);
   }
   /**
    * 按照业务类型id获取默认属性
    *
    * @param btmTypeId 业务类型id
    * @return 业务类型
    */
   @Override
   public BtmTypeVO getDefaultAttrByBtmId(String btmTypeId) {
      BtmTypeVO btmType = getBtmTypeById(btmTypeId);
      if (btmType == null){
         return null;
      }
      btmType.setAttributes(btmTypeAttributeService.getDefaultAttribute(btmType));
      return btmType;
   }
   /**
    * 按照业务类型id获取所有的属性
    *
    * @param btmTypeId 业务类型id
    * @return 业务类型
    */
   @Override
   public BtmTypeVO getAllAttributeByBtmId(String btmTypeId) {
      BtmTypeVO btmType = getBtmTypeById(btmTypeId);
      if (btmType == null){
         return null;
      }
      btmType.setAttributes(btmTypeAttributeService.getAllAttribute(btmType));
      return btmType;
   }
   /**
    * 按照业务类型主键获取所有的属性
    *
    * @param btmTypeOid 业务类型主键
    * @return 业务类型
    */
   @Override
   public BtmTypeVO getAllAttributeByBtmOid(String btmTypeOid) {
      BtmTypeVO btmType = getBtmTypeByOid(btmTypeOid);
      if (btmType == null){
         return null;
      }
      btmType.setAttributes(btmTypeAttributeService.getAllAttribute(btmType));
      return btmType;
   }
   /**
    * 获取引用某个生命周期的业务类型
    *
    * @param lifeId 生命周期的编号
    * @return 业务类型显示对象
    */
   @Override
   public List<BtmTypeVO> selectByLifeId(String lifeId) {
      if(StringUtils.isBlank(lifeId)){
         return new ArrayList<>();
      }
      LambdaQueryWrapper<BtmType> query = new LambdaQueryWrapper<BtmType>();
      query.eq(BtmType::getLifeCycleId,lifeId);
      return BtmTypeWrapper.build().listEntityVO(getBaseMapper().selectList(query));
   }
   /**
    * 获取引用某些生命周期的业务类型
    *
    * @param lifeIds 生命周期的编号集合
    * @return 业务类型显示对象
    */
   @Override
   public List<BtmTypeVO> selectByLifeIds(Collection<String> lifeIds) {
      if(CollectionUtils.isEmpty(lifeIds)){
         return new ArrayList<>();
      }
      List<BtmType> btmTypeList = new ArrayList<>();
      VciBaseUtil.switchCollectionForOracleIn(lifeIds).stream().forEach(ids->{
         LambdaQueryWrapper<BtmType> query = new LambdaQueryWrapper<BtmType>();
         ids.stream().forEach(id->{
            query.eq(BtmType::getLifeCycleId,id);
            query.or();
         });
         query.eq(BtmType::getLifeCycleId,"-1");
         btmTypeList.addAll(baseMapper.selectList(query));
      });
      return BtmTypeWrapper.build().listEntityVO(btmTypeList);
   }
   /**
    * 统计引用某个生命周期的业务类型
    *
    * @param lifeId 生命周期的编号
    * @return 个数
    */
   @Override
   public Integer countByLifeId(String lifeId) {
      if(StringUtils.isBlank(lifeId)){
         return 0;
      }
      LambdaQueryWrapper<BtmType> query = new LambdaQueryWrapper<BtmType>();
      query.eq(BtmType::getLifeCycleId,lifeId);
      return baseMapper.selectCount(query).intValue();
   }
   /**
    * 统计引用某些生命周期的业务类型
    *
    * @param lifeIds 生命周期的编号集合
    * @return 个数
    */
   @Override
   public Integer countByLifeIds(Collection<String> lifeIds) {
      if(CollectionUtils.isEmpty(lifeIds)){
         return 0;
      }
      final Integer[] total = {0};
      VciBaseUtil.switchCollectionForOracleIn(lifeIds).stream().forEach(ids->{
         LambdaQueryWrapper<BtmType> query = new LambdaQueryWrapper<BtmType>();
         ids.stream().forEach(id->{
            query.eq(BtmType::getLifeCycleId,id);
            query.or();
         });
         query.eq(BtmType::getLifeCycleId,"-1");
         total[0] += baseMapper.selectCount(query).intValue();
      });
      return total[0];
   }
}