package com.vci.ubcs.omd.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.vci.ubcs.omd.constant.BtmTypeConstant; import com.vci.ubcs.omd.dto.LifeCycleDTO; import com.vci.ubcs.omd.dto.LifeCycleEdgeDTO; import com.vci.ubcs.omd.dto.LifeCycleLineEventDTO; import com.vci.ubcs.omd.dto.LifeCycleNodeDTO; import com.vci.ubcs.omd.entity.LifeCycleEdge; import com.vci.ubcs.omd.entity.LifeCycleLineEvent; import com.vci.ubcs.omd.entity.LifeCycleNode; import com.vci.ubcs.omd.entity.LifeCycleRule; import com.vci.ubcs.omd.mapper.LifeCycleEdgeMapper; import com.vci.ubcs.omd.mapper.LifeCycleLineEventMapper; import com.vci.ubcs.omd.mapper.LifeCycleMapper; import com.vci.ubcs.omd.mapper.LifeCycleNodeMapper; import com.vci.ubcs.omd.repeater.DomainRepeater; import com.vci.ubcs.omd.service.IBtmTypeService; import com.vci.ubcs.omd.service.ILifeCycleService; import com.vci.ubcs.omd.service.IStatusService; import com.vci.ubcs.omd.vo.BtmTypeVO; import com.vci.ubcs.omd.vo.LifeCycleVO; import com.vci.ubcs.omd.vo.StatusVO; import com.vci.ubcs.omd.wrapper.LifeCycleRuleWrapper; import com.vci.ubcs.starter.enumpack.NewAppConstantEnum; import com.vci.ubcs.starter.exception.VciBaseException; import com.vci.ubcs.starter.web.constant.RegExpConstant; import com.vci.ubcs.starter.web.util.BeanUtil; import com.vci.ubcs.starter.web.util.VciBaseUtil; import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import org.springblade.core.secure.utils.AuthUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; /** * 生命周期的服务 * @author weidy * @date 2023/6/20 */ @Service public class LifeCycleServiceImpl extends ServiceImpl implements ILifeCycleService{ /** * 节点的数据层 */ @Resource private LifeCycleNodeMapper nodeMapper; /** * 连接线数据层 */ @Resource private LifeCycleEdgeMapper edgeMapper; /** * 状态 */ @Autowired(required = false) @Lazy private IStatusService statusService; /** * 连接线的事件 */ @Resource private LifeCycleLineEventMapper lineEventMapper; /** * 业务类型的服务 */ @Autowired(required = false) @Lazy private IBtmTypeService btmTypeService; /** * 获取生命周期列表 * * @param conditionMap 查询条件 * @param query 分页 * @return 生命周期的显示对象 */ @Override public IPage listLife(Map conditionMap, Query query) { return LifeCycleRuleWrapper.build().pageVO(baseMapper.selectPage(Condition.getPage(query),Condition.getQueryWrapper(conditionMap,LifeCycleRule.class).lambda().orderByAsc(LifeCycleRule::getId))); } /** * 添加保存 * * @param lifeCycleDTO 数据传输对象 * @return 添加后的显示对象 */ @Override @Transactional public LifeCycleVO addSave(LifeCycleDTO lifeCycleDTO) { VciBaseUtil.alertNotNull(lifeCycleDTO,"生命周期信息",lifeCycleDTO.getId(),"生命周期的编号",lifeCycleDTO.getName(),"生命周期名称",lifeCycleDTO.getNodes(),"生命周期的节点",lifeCycleDTO.getStartStatus(),"起始状态"); //先查询是否存在 QueryWrapper wrapper = new QueryWrapper(LifeCycleRule.class); wrapper.eq("lower(id)",lifeCycleDTO.getId().toLowerCase(Locale.ROOT)); if(baseMapper.selectCount(wrapper)>0){ throw new VciBaseException("生命周期的编号不能重复"); } String lifeOid = addLifeCycle(lifeCycleDTO); return LifeCycleRuleWrapper.build().entityVO(baseMapper.selectById(lifeOid)); } /** * 添加生命周期 * @param lifeCycleDTO * @return 主键 */ private String addLifeCycle(LifeCycleDTO lifeCycleDTO){ //编号不能有特殊的内容 if(!lifeCycleDTO.getId().matches(RegExpConstant.LETTER)){ throw new VciBaseException("生命周期的编号只能是字母"); } LifeCycleRule life = LifeCycleRuleWrapper.build().copyDTO2DO(lifeCycleDTO); life.setOid(VciBaseUtil.getPk()); String creator = AuthUtil.getUserAccount(); Date now = new Date(); life.setBtmname(BtmTypeConstant.LIFE_CYCLE); life.setOwner(creator); life.setCreator(creator); life.setCreateTime(now); life.setLastModifier(creator); life.setLastModifyTime(now); life.setTs(now); List statusList = new ArrayList<>(); //处理节点 if(!CollectionUtils.isEmpty(lifeCycleDTO.getNodes())){ lifeCycleDTO.getNodes().stream().forEach(nodeDTO->{ addLifeCycleNode(nodeDTO,life.getOid(),creator,now); statusList.add(nodeDTO.getId()); }); } if(!statusList.contains(life.getStartStatus())){ throw new VciBaseException("起始状态不在生命周期的画布中"); } //判断所有的节点在系统里都存在 List existStatusIdList = statusService.listStatusByIdCollection(statusList).stream().map(StatusVO::getId).collect(Collectors.toList()); String unExistStatus = statusList.stream().filter(s -> !existStatusIdList.contains(s)).collect(Collectors.joining(",")); if(StringUtils.hasLength(unExistStatus)){ throw new VciBaseException(unExistStatus + "这些状态在状态池里不存在,不能添加到生命周期中"); } //处理边界和连接线 if(!CollectionUtils.isEmpty(lifeCycleDTO.getEdges())){ lifeCycleDTO.getEdges().stream().forEach(edgeDTO->{ String edgeOid = addLifeCycleEdge(edgeDTO,statusList,life.getOid(),creator,now); if(!CollectionUtils.isEmpty(edgeDTO.getEvents())){ //有事件 edgeDTO.getEvents().stream().forEach(eventDTO->{ addLifeCycleLineEvent(eventDTO,edgeOid,creator,now); }); } }); } baseMapper.insert(life); return life.getOid(); } /** * 添加生命周期的连接线上的事件 * @param eventDTO * @param edgeOid * @param creator * @param now */ private void addLifeCycleLineEvent(LifeCycleLineEventDTO eventDTO,String edgeOid,String creator,Date now){ VciBaseUtil.alertNotNull(eventDTO.getBizDomain(),"所属领域",eventDTO.getEventFullName(),"事件的全路径"); NewAppConstantEnum[] values = NewAppConstantEnum.values(); Boolean fined = false; for (int i = 0; i < values.length; i++) { NewAppConstantEnum value = values[i]; if(value.getName().equalsIgnoreCase(eventDTO.getBizDomain())){ fined = true; break; } } if(!fined){ throw new VciBaseException(eventDTO.getBizDomain() + "这个领域还没有开放,请让开发人员在NewAppConstantEnum类中添加"); } LifeCycleLineEvent event = org.springblade.core.tool.utils.BeanUtil.copy(eventDTO, LifeCycleLineEvent.class); event.setOid(VciBaseUtil.getPk()); event.setPkLifeCycleEdge(edgeOid); event.setBtmname(BtmTypeConstant.LIFE_CYCLE_LINE_EVENT); event.setOwner(creator); event.setCreator(creator); event.setCreateTime(now); event.setLastModifier(creator); event.setLastModifyTime(now); event.setTs(now); lineEventMapper.insert(event); } /** * 添加生命周期的节点 * @param nodeDTO * @param lifeOid * @param creator * @param now */ private void addLifeCycleNode(LifeCycleNodeDTO nodeDTO,String lifeOid,String creator,Date now){ VciBaseUtil.alertNotNull(nodeDTO.getId(),"状态标识",nodeDTO.getName(),"状态名称"); LifeCycleNode node = org.springblade.core.tool.utils.BeanUtil.copy(nodeDTO, LifeCycleNode.class); node.setOid(VciBaseUtil.getPk()); node.setLifeCycleOid(lifeOid); node.setBtmname(BtmTypeConstant.LIFE_CYCLE_NODE); node.setOwner(creator); node.setCreator(creator); node.setCreateTime(now); node.setLastModifier(creator); node.setLastModifyTime(now); node.setTs(now); nodeMapper.insert(node); } /** * 添加生命周期的连接线 * @param edgeDTO * @param statusList * @param lifeOid * @param creator * @param now * @return 连接线的主键 */ private String addLifeCycleEdge(LifeCycleEdgeDTO edgeDTO,List statusList,String lifeOid,String creator,Date now){ VciBaseUtil.alertNotNull(edgeDTO.getSource(),"来源状态",edgeDTO.getTarget(),"目标状态",edgeDTO.getName(),"连接线名称"); if(!statusList.contains(edgeDTO.getSource()) ||!statusList.contains(edgeDTO.getTarget())){ throw new VciBaseException("数据错误,[" + edgeDTO.getName() + "]连接线上中使用的状态没有找到"); } LifeCycleEdge edge = org.springblade.core.tool.utils.BeanUtil.copy(edgeDTO, LifeCycleEdge.class); edge.setOid(VciBaseUtil.getPk()); edge.setLifeCycleOid(lifeOid); edge.setBtmname(BtmTypeConstant.LIFE_CYCLE_EDGE); edge.setOwner(creator); edge.setCreator(creator); edge.setCreateTime(now); edge.setLastModifier(creator); edge.setLastModifyTime(now); edge.setTs(now); edgeMapper.insert(edge); return edge.getOid(); } /** * 批量添加内容 * * @param lifeCycleDTOs 数据传输对象 * @return 添加后的显示对象 */ @Override @Transactional public List batchAddSave(Collection lifeCycleDTOs) { VciBaseUtil.alertNotNull(lifeCycleDTOs,"生命周期的信息"); //先集体校验一下 if(lifeCycleDTOs.stream().anyMatch(s->!StringUtils.hasLength(s.getId()) || !StringUtils.hasLength(s.getName()) || CollectionUtils.isEmpty(s.getNodes()) || !StringUtils.hasLength(s.getStartStatus()))){ throw new VciBaseException("生命周期的编号,名称,起始状态,包含的节点不能为空"); } //统一校验重复 Map> dtoMap = lifeCycleDTOs.stream().collect(Collectors.groupingBy(s->s.getId().toLowerCase(Locale.ROOT))); dtoMap.forEach((id,dtos)->{ if(dtos.size()>1){ throw new VciBaseException("编号为【" + id + "】的生命周期重复"); } }); VciBaseUtil.switchCollectionForOracleIn(dtoMap.keySet()).stream().forEach( ids->{ QueryWrapper wrapper = new QueryWrapper(LifeCycleRule.class); ids.stream().forEach(id->{ wrapper.eq("lower(id)",id); wrapper.or(); }); wrapper.eq("1","2"); if(baseMapper.selectCount(wrapper)>0){ throw new VciBaseException("生命周期的编号不能重复"); } } ); //先循环处理下,因为现在当前用户没有处理为线程共享的,后面修改后,可以用并发流去处理 List oidList = new ArrayList<>(); lifeCycleDTOs.stream().forEach(dto->{ oidList.add(addLifeCycle(dto)); }); return LifeCycleRuleWrapper.build().listEntityVO(listByIds(oidList)); } /** * 修改保存 * * @param lifeCycleDTO 数据传输对象 * @return */ @Override public LifeCycleVO editSave(LifeCycleDTO lifeCycleDTO) { VciBaseUtil.alertNotNull(lifeCycleDTO,"生命周期信息",lifeCycleDTO.getId(),"生命周期的编号",lifeCycleDTO.getName(),"生命周期名称" ,lifeCycleDTO.getNodes(),"生命周期的节点",lifeCycleDTO.getStartStatus(),"起始状态", lifeCycleDTO.getOid(),"主键"); LifeCycleRule rule = selectByOid(lifeCycleDTO.getOid()); //查询重复 QueryWrapper wrapper = new QueryWrapper(LifeCycleRule.class); if(rule.getId().equals(lifeCycleDTO.getId())){ throw new VciBaseException("生命周期编号不能修改"); } wrapper.eq("lower(id)",lifeCycleDTO.getId().toLowerCase(Locale.ROOT)); wrapper.ne("oid",lifeCycleDTO.getOid()); if(baseMapper.selectCount(wrapper)>0){ throw new VciBaseException("生命周期的编号不能重复"); } editLifeCycle(lifeCycleDTO,rule); return LifeCycleRuleWrapper.build().entityVO(getById(rule.getOid())); } /** * 修改生命周期 * @param lifeCycleDTO * @param life */ private void editLifeCycle(LifeCycleDTO lifeCycleDTO,LifeCycleRule life){ if(!lifeCycleDTO.getId().matches(RegExpConstant.LETTER)){ throw new VciBaseException("生命周期的编号只能是字母"); } BeanUtil.convert(lifeCycleDTO,life); String creator = AuthUtil.getUserAccount(); Date now = new Date(); life.setLastModifier(creator); life.setLastModifyTime(now); life.setTs(now); //删除现在全部的数据,然后重新添加= List nodeList = selectNodeByLifeOid(life.getOid()); List edges = selectEdgeByLifeOid(life.getOid()); List eventList = selectEventByEdgeOids(Optional.ofNullable(edges).orElseGet(ArrayList::new).stream().map(LifeCycleEdge::getOid).collect(Collectors.toList())); if(!CollectionUtils.isEmpty(nodeList)){ nodeMapper.deleteBatchIds(nodeList.stream().map(LifeCycleNode::getOid).collect(Collectors.toList())); } if(!CollectionUtils.isEmpty(edges)){ edgeMapper.deleteBatchIds(edges.stream().map(LifeCycleEdge::getOid).collect(Collectors.toList())); } if(!CollectionUtils.isEmpty(eventList)){ lineEventMapper.deleteBatchIds(eventList.stream().map(LifeCycleLineEvent::getOid).collect(Collectors.toList())); } List statusList = new ArrayList<>(); //处理节点 if(!CollectionUtils.isEmpty(lifeCycleDTO.getNodes())){ lifeCycleDTO.getNodes().stream().forEach(nodeDTO->{ addLifeCycleNode(nodeDTO,life.getOid(),creator,now); statusList.add(nodeDTO.getId()); }); } if(!statusList.contains(life.getStartStatus())){ throw new VciBaseException("起始状态不在生命周期的画布中"); } //判断所有的节点在系统里都存在 List existStatusIdList = statusService.listStatusByIdCollection(statusList).stream().map(StatusVO::getId).collect(Collectors.toList()); String unExistStatus = statusList.stream().filter(s -> !existStatusIdList.contains(s)).collect(Collectors.joining(",")); if(StringUtils.hasLength(unExistStatus)){ throw new VciBaseException(unExistStatus + "这些状态在状态池里不存在,不能添加到生命周期中"); } //处理边界和连接线 if(!CollectionUtils.isEmpty(lifeCycleDTO.getEdges())){ lifeCycleDTO.getEdges().stream().forEach(edgeDTO->{ String edgeOid = addLifeCycleEdge(edgeDTO,statusList,life.getOid(),creator,now); if(!CollectionUtils.isEmpty(edgeDTO.getEvents())){ //有事件 edgeDTO.getEvents().stream().forEach(eventDTO->{ addLifeCycleLineEvent(eventDTO,edgeOid,creator,now); }); } }); } baseMapper.updateById(life); } /** * 使用主键查询 * @param oid * @return */ private LifeCycleRule selectByOid(String oid){ LifeCycleRule rule = null; try { rule = getById(oid); }catch (Throwable e){ throw new VciBaseException("使用主键获取对象出错,这个数据可能不存在,或者数据重复了"); } return rule; } /** * 批量修改保存 * * @param lifeCycleDTOs * @return */ @Override public List batchEditSave(Collection lifeCycleDTOs) { if(CollectionUtils.isEmpty(lifeCycleDTOs)){ return new ArrayList<>(); } if(lifeCycleDTOs.stream().anyMatch(s->!StringUtils.hasLength(s.getId()) || !StringUtils.hasLength(s.getName()) || CollectionUtils.isEmpty(s.getNodes()) || !StringUtils.hasLength(s.getStartStatus()))){ throw new VciBaseException("生命周期的编号,名称,起始状态,包含的节点不能为空"); } //统一校验重复 Map> dtoMap = lifeCycleDTOs.stream().collect(Collectors.groupingBy(s->s.getId().toLowerCase(Locale.ROOT))); dtoMap.forEach((id,dtos)->{ if(dtos.size()>1){ throw new VciBaseException("编号为【" + id + "】的生命周期重复"); } }); VciBaseUtil.switchCollectionForOracleIn(dtoMap.keySet()).stream().forEach( ids->{ QueryWrapper wrapper = new QueryWrapper(LifeCycleRule.class); ids.stream().forEach(id->{ wrapper.eq("lower(id)",id); wrapper.ne("oid",dtoMap.get(id).get(0).getOid()); wrapper.or(); }); wrapper.eq("1","2"); if(baseMapper.selectCount(wrapper)>0){ throw new VciBaseException("生命周期的编号不能重复"); } } ); List oidList = lifeCycleDTOs.stream().map(LifeCycleDTO::getOid).collect(Collectors.toList()); List rules = listByIds(oidList); if(!CollectionUtils.isEmpty(rules)){ rules.stream().forEach(life->{ editLifeCycle(dtoMap.get(life.getId().toLowerCase(Locale.ROOT)).get(0),life); }); } return LifeCycleRuleWrapper.build().listEntityVO(listByIds(oidList)); } /** * 删除生命周期 * * @param lifeCycleDTO 数据传输对象 */ @Override @Transactional public void delete(LifeCycleDTO lifeCycleDTO) { VciBaseUtil.alertNotNull(lifeCycleDTO,"数据传输对象",lifeCycleDTO.getOid(),"主键"); LifeCycleRule rule = selectByOid(lifeCycleDTO.getOid()); //检查被引用不能删除 Integer count = btmTypeService.countByLifeId(lifeCycleDTO.getId()); if(count !=null && count>0){ throw new VciBaseException("生命周期被使用,不能被删除"); } //我们查询全部node和edge,然后一起删除 List nodeList = selectNodeByLifeOid(rule.getOid()); List edges = selectEdgeByLifeOid(rule.getOid()); List eventList = selectEventByEdgeOids(Optional.ofNullable(edges).orElseGet(ArrayList::new).stream().map(LifeCycleEdge::getOid).collect(Collectors.toList())); if(!CollectionUtils.isEmpty(nodeList)){ nodeMapper.deleteBatchIds(nodeList.stream().map(LifeCycleNode::getOid).collect(Collectors.toList())); } if(!CollectionUtils.isEmpty(edges)){ edgeMapper.deleteBatchIds(edges.stream().map(LifeCycleEdge::getOid).collect(Collectors.toList())); } if(!CollectionUtils.isEmpty(eventList)){ lineEventMapper.deleteBatchIds(eventList.stream().map(LifeCycleLineEvent::getOid).collect(Collectors.toList())); } baseMapper.deleteById(rule); } /** * 查询链接线 * @param lifeOid * @return */ private List selectEdgeByLifeOid(String lifeOid){ if(!StringUtils.hasLength(lifeOid)){ return new ArrayList<>(); } LambdaQueryWrapper query = new LambdaQueryWrapper(); query.eq(LifeCycleEdge::getLifeCycleOid,lifeOid); return edgeMapper.selectList(query); } /** * 获取节点的信息 * @param lifeOids 生命周期的主键集合 * @return */ private List selectEdgeByLifeOids(Collection lifeOids){ if(!CollectionUtils.isEmpty(lifeOids)){ return new ArrayList<>(); } List edgeList = new ArrayList<>(); VciBaseUtil.switchCollectionForOracleIn(lifeOids).stream().forEach(lOids->{ LambdaQueryWrapper query = new LambdaQueryWrapper(); lOids.stream().forEach(lOid->{ query.eq(LifeCycleEdge::getLifeCycleOid,lOid); query.or(); }); query.eq(LifeCycleEdge::getLifeCycleOid,"-1"); edgeList.addAll(edgeMapper.selectList(query)); }); return edgeList; } /** * 查询链接线上的事件 * @param edgeOids * @return */ private List selectEventByEdgeOids(Collection edgeOids){ if(CollectionUtils.isEmpty(edgeOids)){ return new ArrayList<>(); } List eventList = new ArrayList<>(); VciBaseUtil.switchCollectionForOracleIn(edgeOids).stream().forEach(edgeOidList->{ LambdaQueryWrapper query = new LambdaQueryWrapper(); edgeOidList.stream().forEach(edgeOid->{ query.eq(LifeCycleLineEvent::getPkLifeCycleEdge,edgeOid); query.or(); }); query.eq(LifeCycleLineEvent::getPkLifeCycleEdge,"-1"); eventList.addAll(lineEventMapper.selectList(query)); }); return eventList; } /** * 获取节点的信息 * @param lifeOid * @return */ private List selectNodeByLifeOid(String lifeOid){ if(!StringUtils.hasLength(lifeOid)){ return new ArrayList<>(); } LambdaQueryWrapper query = new LambdaQueryWrapper(); query.eq(LifeCycleNode::getLifeCycleOid,lifeOid); return nodeMapper.selectList(query); } /** * 获取节点的信息 * @param lifeOids 生命周期的主键集合 * @return */ private List selectNodeByLifeOids(Collection lifeOids){ if(!CollectionUtils.isEmpty(lifeOids)){ return new ArrayList<>(); } List nodeList = new ArrayList<>(); VciBaseUtil.switchCollectionForOracleIn(lifeOids).stream().forEach(lOids->{ LambdaQueryWrapper query = new LambdaQueryWrapper(); lOids.stream().forEach(lOid->{ query.eq(LifeCycleNode::getLifeCycleOid,lOid); query.or(); }); query.eq(LifeCycleNode::getLifeCycleOid,"-1"); nodeList.addAll(nodeMapper.selectList(query)); }); return nodeList; } /** * 批量删除生命周期 * * @param lifeCycleDTOs 数据传输对象列表 */ @Override @Transactional public void batchDelete(List lifeCycleDTOs) { VciBaseUtil.alertNotNull(lifeCycleDTOs,"生命周期的信息"); if(lifeCycleDTOs.stream().anyMatch(s->!StringUtils.hasLength(s.getOid()))){ throw new VciBaseException("生命周期的主键不能为空"); } List oidList = lifeCycleDTOs.stream().map(LifeCycleDTO::getOid).collect(Collectors.toList()); List lifeList = baseMapper.selectBatchIds(oidList); //批量查询 String usedBtmTypeId = Optional.ofNullable(btmTypeService.selectByLifeIds(lifeList.stream().map(LifeCycleRule::getId).collect(Collectors.toList()))).orElseGet(ArrayList::new).stream().map(BtmTypeVO::getId).collect(Collectors.joining(",")); if(StringUtils.hasLength(usedBtmTypeId)){ throw new VciBaseException(usedBtmTypeId + "这些业务类型引用了生命周期,不能删除"); } List nodeList = selectNodeByLifeOids(oidList); List edgeList = selectEdgeByLifeOids(oidList); if(!CollectionUtils.isEmpty(nodeList)){ nodeMapper.deleteBatchIds(nodeList.stream().map(LifeCycleNode::getOid).collect(Collectors.toList())); } if(!CollectionUtils.isEmpty(edgeList)){ List edgeOids = edgeList.stream().map(LifeCycleEdge::getOid).collect(Collectors.toList()); edgeMapper.deleteBatchIds(edgeOids); List eventList = selectEventByEdgeOids(edgeOids); if(!CollectionUtils.isEmpty(eventList)){ lineEventMapper.deleteBatchIds(eventList.stream().map(LifeCycleLineEvent::getOid).collect(Collectors.toList())); } } baseMapper.deleteBatchIds(oidList); } /** * 显示引用范围 * * @param lifeCycleDTO 生命周期的数据传输对象 * @return 业务类型 */ @Override public List listUses(LifeCycleDTO lifeCycleDTO) { VciBaseUtil.alertNotNull(lifeCycleDTO,"数据传输对象",lifeCycleDTO.getOid(),"主键"); LifeCycleRule rule = selectByOid(lifeCycleDTO.getOid()); return btmTypeService.selectByLifeId(rule.getId()); } }