Source/UBCS/ubcs-service/ubcs-ddl/src/main/java/com/vci/ubcs/ddl/service/impl/DdlServiceImpl.java
@@ -7,16 +7,17 @@
import com.vci.ubcs.ddl.bo.DdlTableInDataBaseBO;
import com.vci.ubcs.ddl.enums.BusinessTypeEnum;
import com.vci.ubcs.ddl.enums.ModifyTableTaskEnum;
import com.vci.ubcs.ddl.processor.ddl.DdlMapperProcessStrategy;
import com.vci.ubcs.ddl.processor.ddl.DdlMapperProcessor;
import com.vci.ubcs.ddl.processor.dll.DllMapperProcessor;
import com.vci.ubcs.ddl.processor.dll.DllMapperProcessorStrategy;
import com.vci.ubcs.ddl.properties.DdlPropertise;
import com.vci.ubcs.ddl.service.IDdlService;
import com.vci.ubcs.omd.cache.BtmTypeCache;
import com.vci.ubcs.omd.constant.BtmTypeFieldConstant;
import com.vci.ubcs.omd.constant.BtmTypeLcStatusConstant;
import com.vci.ubcs.omd.dto.BtmAndLinkTypeDdlDTO;
import com.vci.ubcs.omd.dto.TableAddColumnDTO;
import com.vci.ubcs.omd.dto.TableCheckDTO;
import com.vci.ubcs.omd.dto.TableCheckResultDTO;
import com.vci.ubcs.omd.entity.ModifyAttributeInfo;
import com.vci.ubcs.omd.vo.*;
import com.vci.ubcs.starter.exception.VciBaseException;
@@ -32,6 +33,7 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@@ -61,13 +63,15 @@
   /**
    * ddl数据操作服务
    */
   private final DdlMapperProcessor ddlMapper = DdlMapperProcessStrategy.getProcessor();
   @Autowired
   private DdlMapperProcessor ddlMapper;
   /**
    * dll数据操作服务
    */
   private final DllMapperProcessor dllMapper = DllMapperProcessorStrategy.getProcessor();
   @Autowired
   private DllMapperProcessor dllMapper;
   private static final String YES = "Y";
@@ -77,25 +81,25 @@
   private final Map<String, LinkTypeVO> idLinkMap = new ConcurrentHashMap<>();
   private void putBtm(@NotNull BtmTypeVO... voList) throws ServiceException {
   private void putBtm(@NotNull BtmTypeVO... voList) throws Throwable {
      String collect = Arrays.stream(voList).map(BtmTypeVO::getId).filter(idBtmMap::containsKey).collect(Collectors.joining(","));
      if (StringUtils.isBlank(collect)) {
         Arrays.stream(voList).forEach(vo -> {
            idBtmMap.put(vo.getId(), vo);
         });
      } else {
         throw new ServiceException("业务类型:[" + collect + "]正在被其他用户操作");
         throw new Throwable("业务类型:[" + collect + "]正在被其他用户操作");
      }
   }
   private void putLink(@NotNull LinkTypeVO... voList) throws ServiceException {
   private void putLink(@NotNull LinkTypeVO... voList) throws Throwable {
      String collect = Arrays.stream(voList).map(LinkTypeVO::getId).filter(idLinkMap::containsKey).collect(Collectors.joining(","));
      if (StringUtils.isBlank(collect)) {
         Arrays.stream(voList).forEach(vo -> {
            idLinkMap.put(vo.getId(), vo);
         });
      } else {
         throw new ServiceException("链接类型:[" + collect + "]正在被其他用户操作");
         throw new Throwable("链接类型:[" + collect + "]正在被其他用户操作");
      }
   }
@@ -119,77 +123,6 @@
      }
   }
   /**
    * 校验业务类型的数据库表中是否有数据
    *
    * @param pkBtmType 业务类型的主键
    * @return true表示有数据,false表示没有数据
    * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
    */
   @Override
   public boolean checkTableHasData(String pkBtmType) throws VciBaseException {
      return checkTableHasDataByTableName(getTableNameByBtmTypeOid(pkBtmType));
   }
   /**
    * 根据业务类型或者链接类型的主键获取数据库表格的名称
    *
    * @param pkBtmType 业务类型或者链接类型的主键
    * @return 数据库表名称
    */
   @Override
   public String getTableNameByBtmTypeOid(String pkBtmType) {
      VciBaseUtil.alertNotNull(pkBtmType, "业务类型或者链接类型的主键");
      BtmTypeVO btmType = BtmTypeCache.getDetail(pkBtmType);
      String tableName = "";
      if (btmType == null || StringUtils.isBlank(btmType.getOid())) {
         /*OsLinkTypeDO linkTypeDO = linkTypeDOMapper.selectByPrimaryKey(pkBtmType.trim());
         if(linkTypeDO == null || StringUtils.isBlank(linkTypeDO.getOid()) ){
            throw new com.vci.starter.web.exception.VciBaseException("不是业务类型,也不是链接类型,请查证");
         }else{
            tableName = linkTypeService.getTableName(linkTypeDO.getId());
         }*/
      } else {
         tableName = btmType.getTableName();
      }
      return tableName;
   }
   /**
    * 根据业务类型获取链接类型的英文名称获取数据库表格的名称
    *
    * @param id 业务类型获取链接类型的英文名称
    * @return 数据库表名称
    */
   @Override
   public String getTableNameByBtmTypeId(String id) {
      VciBaseUtil.alertNotNull(id, "业务类型或者链接类型的英文名称");
      List<BtmTypeVO> btmTypeList = BtmTypeCache.selectByIdCollection(VciBaseUtil.str2List(id));
      String tableName = "";
      if (CollectionUtils.isEmpty(btmTypeList)) {
         /*List<OsLinkTypeDO> linkTypeDOList = linkTypeDOMapper.selectByIdCollection(VciBaseUtil.str2List(id));
         if(CollectionUtils.isEmpty(linkTypeDOList)){
            throw new com.vci.starter.web.exception.VciBaseException("不是业务类型,也不是链接类型,请查证");
         }else{
            tableName = linkTypeService.getTableName(linkTypeDOList.get(0).getId());
         }*/
      } else {
         tableName = btmTypeList.get(0).getTableName();
      }
      return tableName;
   }
   /**
    * 校验业务类型的数据库表中是否有数据
    *
    * @param id 业务类型的英文名称
    * @return true表示有数据,false表示没有数据
    * @throws VciBaseException 参数为空或者查询出错的时候会抛出异常
    */
   @Override
   public boolean checkTableHasDataById(String id) throws VciBaseException {
      return checkTableHasDataByTableName(getTableNameByBtmTypeId(id));
   }
   /**
    * 批量将业务类型创建数据库表
@@ -253,6 +186,26 @@
   }
   /**
    * 创建链接类型的表格
    *
    * @param linkTypeVO 链接类型的显示对象
    * @throws VciBaseException 执行出错的时候会抛出异常
    */
   private void createDbTableForLink(LinkTypeVO linkTypeVO) throws VciBaseException {
      VciBaseUtil.alertNotNull(linkTypeVO, "要创建表格所属的业务类型", linkTypeVO.getTableName(), "业务类型的表格名称");
      String tableName = linkTypeVO.getTableName();
      if (!checkTableExistByTableName(tableName)) {
         String attributeSql = getCreateSqlByAttributeForLink(linkTypeVO.getAttributes());
         dllMapper.createTableBySql(tableName, attributeSql);
         if (StringUtils.isNotBlank(linkTypeVO.getName())) {
            dllMapper.commentTable(tableName, linkTypeVO.getName());
         }
         linkTypeVO.getAttributes().forEach(s -> {
            dllMapper.commentColumnTable(tableName, s.getId(), s.getName());
         });
      }
   }
   /**
    * 获取创建的sql语句中属性部分
    *
    * @param attributeVOList 属性的立碑
@@ -264,7 +217,26 @@
      attributeVOList.forEach(a -> {
         sb.append(a.getId()).append(StringPool.SPACE);
         VciFieldTypeEnum fieldTypeEnum = VciFieldTypeEnum.forValue(a.getAttrDataType());
         sb.append(dllMapper.getColumnTypeSql(fieldTypeEnum, a));
         sb.append(dllMapper.getColumnTypeSql(fieldTypeEnum, a)).append(",");
      });
      return sb.substring(0, sb.lastIndexOf(","));
   }
   /**
    * 获取创建的sql语句中属性部分
    *
    * @param attributeVOList 属性的立碑
    * @return sql语句
    */
   @Override
   public String getCreateSqlByAttributeForLink(List<LinkTypeAttributeVO> attributeVOList) {
      StringBuilder sb = new StringBuilder();
      attributeVOList.forEach(a -> {
         BtmTypeAttributeVO attributeVO = Optional.ofNullable(BeanUtil.copy(a, BtmTypeAttributeVO.class)).orElseGet(BtmTypeAttributeVO::new);
         attributeVO.setPkBtmType(a.getPkLinkType());
         sb.append(a.getId()).append(StringPool.SPACE);
         VciFieldTypeEnum fieldTypeEnum = VciFieldTypeEnum.forValue(a.getAttrDataType());
         sb.append(dllMapper.getColumnTypeSql(fieldTypeEnum, attributeVO)).append(",");
      });
      return sb.substring(0, sb.lastIndexOf(","));
   }
@@ -278,19 +250,10 @@
   @Override
   public void createDbTablesById(String ids) throws VciBaseException {
      VciBaseUtil.alertNotNull(ids, "业务类型/链接类型的英文集合");
      List<BtmTypeVO> btmTypeVOList = BtmTypeCache.selectByIdCollection(VciBaseUtil.str2List(ids));
//      List<OsLinkTypeVO> linkTypeVOList = linkTypeService.listLinkTypeByIdCollection(VciBaseUtil.str2List(ids));
      if (!CollectionUtils.isEmpty(btmTypeVOList)) {
         //说明是业务类型
         btmTypeVOList.forEach(this::createDbTableForBtm);
      }
      /*//试试链接类型
      if(!CollectionUtils.isEmpty(linkTypeVOList)){
         //的确是链接类型
         linkTypeVOList.stream().forEach( s -> {
            createDbTableForLink(s);
         });
      }*/
      // 业务类型
      Func.toStrList(",",ids).stream().filter(idBtmMap::containsKey).map(idBtmMap::get).forEach(this::createDbTableForBtm);
      // 链接类型
      Func.toStrList(",",ids).stream().filter(idLinkMap::containsKey).map(idLinkMap::get).forEach(this::createDbTableForLink);
   }
   /**
@@ -480,16 +443,6 @@
      ddlMapper.dropTableColumn(tableName, columnName);
   }
   /**
    * 校验业务类型或者链接类型的对应的表格是否存在
    *
    * @param pkBtmType 业务类型或者链接类型的表格
    * @return true表示存在,false表示不存在
    */
   @Override
   public boolean checkTableExist(String pkBtmType) {
      return checkTableExistByTableName(getTableNameByBtmTypeOid(pkBtmType));
   }
   /**
    * 根据表格的名称判断表格是否存在
@@ -502,16 +455,6 @@
      return ddlMapper.checkTableExist(tableName) > 0;
   }
   /**
    * 校验业务类型或者链接类型所对应的表格是否存在
    *
    * @param id 业务类型或者链接类型的英文名称
    * @return true表示存在,false表示不存在
    */
   @Override
   public boolean checkTableExistById(String id) {
      return checkTableExistByTableName(getTableNameByBtmTypeId(id));
   }
   /**
    * 获取数据库和业务类型中的不同的地方
@@ -532,7 +475,7 @@
      if (!CollectionUtils.isEmpty(linkTypeVOList)) {
         modifyAttributeInfoList.addAll(checkLinkType(linkTypeVOList));
      }
      if (CollectionUtils.isEmpty(modifyAttributeInfoList)) {
      if (!CollectionUtils.isEmpty(modifyAttributeInfoList)) {
         reflexDifferent(modifyAttributeInfoList, btmTypeVOList, linkTypeVOList);
      }
      return modifyAttributeInfoList;
@@ -628,6 +571,7 @@
               modifyAttributeInfo.setBeforeModifyAttributes(String.join(",", beforeList));
            }
         }
         modifyAttributeInfoDOList.add(modifyAttributeInfo);
      });
      return modifyAttributeInfoDOList;
   }
@@ -729,6 +673,7 @@
               }
            }
            modifyAttributeInfoDOList.add(modifyAttributeInfo);
      });
      return modifyAttributeInfoDOList;
   }
@@ -807,8 +752,8 @@
   @Override
   public void reflexDifferent(List<ModifyAttributeInfo> differentAttributeList, List<BtmTypeVO> btmTypeVOList, List<LinkTypeVO> linkTypeVOList) throws VciBaseException {
      VciBaseUtil.alertNotNull(differentAttributeList, "要清理的数据库的信息为空");
      Map<String, BtmTypeVO> idBtmTypeMap = btmTypeVOList.stream().collect(Collectors.toMap(BtmTypeVO::getId, t -> t, (o1, o2) -> o1));
      Map<String, LinkTypeVO> idLinkTypeMap = linkTypeVOList.stream().collect(Collectors.toMap(LinkTypeVO::getId, t -> t, (o1, o2) -> o1));
      Map<String, BtmTypeVO> idBtmTypeMap = Optional.ofNullable(btmTypeVOList).orElseGet(ArrayList::new).stream().collect(Collectors.toMap(BtmTypeVO::getId, t -> t, (o1, o2) -> o1));
      Map<String, LinkTypeVO> idLinkTypeMap = Optional.ofNullable(linkTypeVOList).orElseGet(ArrayList::new).stream().collect(Collectors.toMap(LinkTypeVO::getId, t -> t, (o1, o2) -> o1));
      differentAttributeList.forEach(s -> {
//         BtmTypeVO btmType = idBtmTypeMap.get(id);
         if (ModifyTableTaskEnum.CREATE.getValue().equalsIgnoreCase(s.getTaskName())) {
@@ -1031,7 +976,7 @@
    * @return 执行结果
    */
   @Override
   public R<List<ModifyAttributeInfo>> submit(BtmAndLinkTypeDdlDTO ddlDTO) {
   public R<List<ModifyAttributeInfo>> submit(BtmAndLinkTypeDdlDTO ddlDTO) throws Throwable {
      try {
         List<ModifyAttributeInfo> changedList = new ArrayList<>();
         if (!CollectionUtils.isEmpty(ddlDTO.getBtmTypeList())) {
@@ -1046,11 +991,23 @@
            changedList.addAll(checkDifferent(null,linkTypeList));
            removeLink(linkTypeList.toArray(new LinkTypeVO[0]));
         }
         R<List<ModifyAttributeInfo>> result = R.success("数据库操作成功");
         String msg = changedList.isEmpty() ? "数据库操作成功" : changedList.get(0).getHandleResult();
         R<List<ModifyAttributeInfo>> result = R.success(msg);
         result.setData(changedList);
         return result;
      } catch (ServiceException e) {
         throw new RuntimeException(e.getMessage());
      } catch (Exception e) {
         try {
            // 建表失败有异常,捕获后返回,并释放线程中的内容
            if (!CollectionUtils.isEmpty(ddlDTO.getBtmTypeList())) {
               removeBtm(ddlDTO.getBtmTypeList().toArray(new BtmTypeVO[0]));
            }
            if (!CollectionUtils.isEmpty(ddlDTO.getLinkTypeList())) {
               removeLink(ddlDTO.getLinkTypeList().toArray(new LinkTypeVO[0]));
            }
            return R.fail(e.getMessage());
         }catch (ServiceException e2){
            return R.fail(e.getMessage());
         }
      }
   }
@@ -1104,21 +1061,24 @@
         List<BtmTypeVO> btmTypeVOList = new ArrayList<>();
         allTableBO.forEach(table -> {
            BtmTypeVO vo = new BtmTypeVO();
            vo.setTableName(table.getTableName());
            vo.setTableName(table.getTableName().toLowerCase());
            vo.setDescription(table.getTableDesc());
            List<DdlTableInDataBaseBO> columns = selectTableColumnInfo(table.getTableName());
            List<BtmTypeAttributeVO> attributes = new ArrayList<>();
            columns.forEach(col -> {
               BtmTypeAttributeVO attributeVO = new BtmTypeAttributeVO();
               attributeVO.setId(col.getId());
               attributeVO.setId(col.getId().toLowerCase());
               attributeVO.setName(col.getName());
               attributeVO.setNullableFlag(col.getNullableFlag());
               attributeVO.setNullableFlag(StringUtils.equals(col.getNullableFlag(), BooleanEnum.TRUE.getValue()));
               attributeVO.setAttributeLength(col.getAttributeLength());
               attributeVO.setPrecisionLength(col.getPrecisionLength());
               attributeVO.setScaleLength(col.getScaleLength());
               VciFieldTypeEnum field = dllMapper.getFieldTypeByColumnStr(col.getAttrDataType(), col.getAttributeLength());
               if (field != null){
                  attributeVO.setAttrDataType(field.name());
               }
               if(col.getPrecisionLength() != null){
                  attributeVO.setAttrDataType(VciFieldTypeEnum.VTDouble.name());
               }
               attributes.add(attributeVO);
            });
@@ -1129,4 +1089,55 @@
      }
      return new ArrayList<>();
   }
   /**
    * 检查数据表是否存在数据,不存在则删除
    *
    * @param tableCheckDTOList 需要检查的表集合
    * @return 检查结果
    */
   @Override
   public TableCheckResultDTO checkTableHasDataThenDelete(List<TableCheckDTO> tableCheckDTOList) {
      TableCheckResultDTO resultDTO = new TableCheckResultDTO();
      List<TableCheckDTO> successList = new ArrayList<>();
      List<TableCheckDTO> failList = new ArrayList<>();
      tableCheckDTOList.forEach(table -> {
         VciBaseUtil.alertNotNull(table.getTableName(),"数据表名称");
         TableCheckDTO checkDTO = new TableCheckDTO();
         boolean hasDataFlag = checkTableHasDataByTableName(table.getTableName());
         if (hasDataFlag){
            table.setDone(false);
            failList.add(checkDTO);
         }else {
            dropTableByName(table.getTableName());
            table.setDone(true);
            successList.add(table);
         }
      });
      if (!CollectionUtils.isEmpty(successList)){
         resultDTO.setSuccessList(successList);
      }
      if (!CollectionUtils.isEmpty(failList)){
         resultDTO.setFailList(failList);
      }
      return resultDTO;
   }
   /**
    * 为表添加字段
    *
    * @param addColumnDTO 添加的对象
    * @return 执行结果标识
    */
   @Override
   public Boolean addColumnForTable(TableAddColumnDTO addColumnDTO) {
      VciBaseUtil.alertNotNull(addColumnDTO,"添加字段的对象");
      if (!CollectionUtils.isEmpty(addColumnDTO.getLinkTypeAttributeVOList())){
         addColumn2TableForLink(addColumnDTO.getLinkTypeAttributeVOList());
      }
      if(!CollectionUtils.isEmpty(addColumnDTO.getBtmTypeAttributeVOList())){
         addColumn2TableForBtm(addColumnDTO.getBtmTypeAttributeVOList());
      }
      return true;
   }
}