package com.vci.web.service.impl; import com.vci.corba.common.PLException; import com.vci.corba.omd.data.BusinessObject; import com.vci.corba.omd.lcm.Bound; import com.vci.corba.omd.lcm.LifeCycle; import com.vci.corba.omd.lcm.TransitionVO; import com.vci.corba.omd.lcm.TransitionVOEvent; import com.vci.pagemodel.*; import com.vci.starter.web.annotation.log.VciUnLog; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.util.Lcm.Func; import com.vci.starter.web.util.VciDateUtil; import com.vci.web.service.WebLifeCycleServiceI; import com.vci.web.service.WebStatusServiceI; import com.vci.web.util.PlatformClientUtil; import com.vci.web.util.WebUtil; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; import static com.vci.constant.FrameWorkBusLangCodeConstant.DATA_ID_NOT_EXIST; import static com.vci.constant.WebLangCodeConstant.LIFE_CYCLE_ROUTER_NULL; import static com.vci.constant.WebLangCodeConstant.LIFE_CYCLE_TRANS_ERROR; /** * @Description 生命周期服务 * @Author dangsn * @Date 2024/11/28 10:39 */ @Service public class WebLifeCycleServiceImpl implements WebLifeCycleServiceI { /** * 日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * 平台客户端 */ @Resource private PlatformClientUtil platformClientUtil; /** * 生命周期服务 */ @Resource private WebStatusServiceI statusServiceI; /** * 跃迁生命周期状态,注意调用此方法就会被持久化,不受事务控制 * @param bo 业务类型的数据对象 * @param targetStatus 目标的生命周期状态,不区分大小 * @throws VciBaseException 如果目标生命周期和当前生命周期状态没有连接线时抛出异常 */ @Override public void transStatus(BusinessObject bo, String targetStatus) { WebUtil.alertNotNull(bo,"业务数据对象",bo.lctId,"生命周期编码",bo.lcStatus,"当前生命周期状态",targetStatus,"目标生命周期状态"); try { OsLifeCycleLineVO transVO = getTransVO(bo.lctId, bo.lcStatus, targetStatus); if(transVO!=null) { doTransVO(bo, transVO); }else{ if(!targetStatus.equalsIgnoreCase(bo.lcStatus)){ //状态相同的时候。,不抛出异常 throw new VciBaseException(LIFE_CYCLE_ROUTER_NULL,new String[]{bo.lcStatus,targetStatus}); } } } catch (Exception e) { throw new VciBaseException("跃迁生命周期状态失败!", new Object[]{}, e); } } /** * 批量跃迁生命周期状态,这些数据中的当前状态必须都是一样,或者是当前状态都可以连接到目标状态 * @param cboList 业务类型对象数据 * @param targetStatus 目标状态,不区分大小写 * @throws VciBaseException 转换生命周期出错的时候抛出异常 */ @Override public void transCboStatus(List cboList,String targetStatus){ WebUtil.alertNotNull(cboList,"业务数据对象",targetStatus,"目标对象"); BusinessObject[] bos = new BusinessObject[cboList.size()]; for(int i = 0 ; i < cboList.size() ; i ++){ bos[i] = cboList.get(i); } transStatus(bos, targetStatus); } /** * 批量跃迁生命周期状态,这些数据中的当前状态必须都是一样,或者是当前状态都可以连接到目标状态 * @param bos 业务类型对象数据 * @param targetStatus 目标状态,不区分大小写 * @throws VciBaseException 转换生命周期出错的时候抛出异常 */ @Override public void transStatus(BusinessObject[] bos, String targetStatus){ WebUtil.alertNotNull(bos,"业务数据对象",targetStatus,"目标对象"); List transVOList = new ArrayList<>(); List transBOs = new ArrayList<>(); for(int i = 0 ; i < bos.length ; i ++){ BusinessObject bo = bos[i]; WebUtil.alertNotNull(bo,"业务数据对象",bo.lctId,"生命周期编码",bo.lcStatus,"当前生命周期状态"); OsLifeCycleLineVO transVO = getTransVO(bo.lctId, bo.lcStatus, targetStatus); if(transVO!=null){ transVOList.add(transVO); transBOs.add(bo); }else{ if(!targetStatus.equalsIgnoreCase(bo.lcStatus)){ throw new VciBaseException("不存在从【{0}】状态到【{1}】状态的生命周期连接线,请联系管理员进行配置",new String[]{bo.lcStatus, targetStatus} ); } } } if(!CollectionUtils.isEmpty(transBOs)) { batchTransVo(transBOs.toArray(new BusinessObject[0]), transVOList.toArray(new OsLifeCycleLineVO[0])); } } /** * 获取连接线 * @param lcid 生命周期的编号 * @param currentStatus 当前的状态 * @param targetStatus 目标的状态 * @return 连接线 * @throws VciBaseException 读取出错的时候会抛出异常 */ @Override public OsLifeCycleLineVO getTransVO(String lcid, String currentStatus,String targetStatus){ WebUtil.alertNotNull(lcid,"生命周期编码",currentStatus,"当前状态",targetStatus,"目标状态"); OsLifeCycleVO life = getLifeCycleById(lcid); if(life == null ){ throw new VciBaseException(DATA_ID_NOT_EXIST,new String[]{lcid}); } if(CollectionUtils.isEmpty(life.getLines())){ throw new VciBaseException(LIFE_CYCLE_ROUTER_NULL,new String[]{lcid}); } return Optional.ofNullable(life.getLines()).orElseGet(()->new ArrayList<>()).stream().filter(s->s.getSourceLifeStatus().equalsIgnoreCase(currentStatus) && s.getTargetLifeStatus().equalsIgnoreCase(targetStatus)).findFirst().orElseGet(()->null); } /** * 跃迁业务类型的生命周期状态 * @param obj 业务类型数据对象 * @param lineVO 跃迁路由 * @throws VciBaseException 跃迁出错的是会抛出异常 */ @Override public void doTransVO(BusinessObject obj,OsLifeCycleLineVO lineVO) throws VciBaseException { if(lineVO!=null){ try { TransitionVO transitionVO = lifeCycleLineVO2DO(lineVO); platformClientUtil.getBOFService().transferBusinessObject(obj, transitionVO.destination); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } }else{ throw new VciBaseException(LIFE_CYCLE_ROUTER_NULL); } } /** * 批量执行跃迁操作 * @param bos 业务类型数据 * @param vos 跃迁对象 * @throws VciBaseException 跃迁出错的是会抛出异常 */ @Override public void batchTransVo(BusinessObject[] bos,OsLifeCycleLineVO[] vos){ batchTransVo(bos,vos,null); } /** * 批量执行跃迁操作,要求必须是同一个业务类型下的 * @param bos 业务类型数据对象 * @param lineVOs 跃迁对象 * @param releaseStatus 发布状态,如果目标状态是发布状态时传递这个值 * @throws VciBaseException 跃迁出错的是会抛出异常 */ @Override public void batchTransVo(BusinessObject[] bos,OsLifeCycleLineVO[] lineVOs,String[] releaseStatus){ if(bos!=null && lineVOs != null && lineVOs.length == bos.length){ try { if(releaseStatus == null){ releaseStatus = new String[lineVOs.length]; for(int i = 0 ; i < lineVOs.length ; i ++ ){ releaseStatus[i] = ""; } } TransitionVO[] vos = new TransitionVO[lineVOs.length]; for(int i = 0 ; i < lineVOs.length; i ++){ vos[i] = lifeCycleLineVO2DO(lineVOs[i]); } platformClientUtil.getBOFService().batchTransferBusinessObjectAndRelease( bos, vos, releaseStatus); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } }else{ if(bos == null){ throw new VciBaseException(LIFE_CYCLE_TRANS_ERROR,new String[]{"业务类型数据为空"}); }else if(lineVOs ==null){ throw new VciBaseException(LIFE_CYCLE_TRANS_ERROR,new String[]{"跃迁路由为空"}); }else{ throw new VciBaseException(LIFE_CYCLE_TRANS_ERROR,new String[]{"跃迁路由和业务类型数据长度不相同"}); } } } /** * 连接线转换为平台的对象 * @param lineVO 连接线对象 * @return 平台的连接线对象 */ private TransitionVO lifeCycleLineVO2DO(OsLifeCycleLineVO lineVO) throws PLException { TransitionVO transitionVO = new TransitionVO(); transitionVO.id = lineVO.getOid(); transitionVO.source = lineVO.getSourceLifeStatus(); transitionVO.destination = lineVO.getTargetLifeStatus(); transitionVO.connect = lineVO.getName() == null?"":lineVO.getName(); //加事件 TransitionVOEvent[] events; if(lineVO.getEvents() == null || lineVO.getEvents().length == 0){ events = new TransitionVOEvent[0]; }else{ events = new TransitionVOEvent[lineVO.getEvents().length]; for (int j = 0; j < lineVO.getEvents().length; j++) { OsLifeCycleLineEventVO eventVO = lineVO.getEvents()[j]; TransitionVOEvent event = new TransitionVOEvent(); event.id = eventVO.getOid(); event.name = Func.isBlank(eventVO.getEventFullName()) ? platformClientUtil.getLifeCycleService().getLCEventValueByKey(eventVO.getOid()):eventVO.getEventFullName(); events[j] = event; } } transitionVO.transitionVOEvents = events; return transitionVO; } /** * 通过编号获取生命周期状态对象, * * @param lctId 生命周期编号 * @return 显示对象 */ @Override public OsLifeCycleVO getLifeCycleById(String lctId){ WebUtil.alertNotNull(lctId,"业务类型编号"); return selectAllLifeCycleMap().getOrDefault(lctId,null); } /** * 查询生命周期的映射 * @return key是生命周期的编号, value是生命周期的对象 * @throws VciBaseException 查询出错的时候会抛出异常 */ @Override @VciUnLog public Map selectAllLifeCycleMap(){ return Optional.ofNullable(selectAllLifeCycle()).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getId(), t->t,(o1, o2)->o1)); } /** * 查询所有生命周期状态 * * @return 生命周期状态的对象 * @throws VciBaseException 查询的时候出错的时候 */ @Override @VciUnLog public List selectAllLifeCycle(){ try { LifeCycle[] lifeCyles = platformClientUtil.getLifeCycleService().getLifeCycles(); return lifeCycleDO2VOs(Arrays.stream(lifeCyles).collect(Collectors.toList())); } catch (PLException vciError) { if(logger.isErrorEnabled()){ logger.error(vciError.code,vciError); } throw WebUtil.getVciBaseException(vciError); } } /** * 生命周期的数据对象转换为显示对象 * @param lifeCycles 数据对象 * @return 显示对象 */ @Override public List lifeCycleDO2VOs(Collection lifeCycles){ List lifeCycleVOS = new ArrayList<>(); Optional.ofNullable(lifeCycles).orElseGet(()->new ArrayList<>()).stream().forEach(lifeCyle -> { OsLifeCycleVO lifeCycleVO = lifeCycleDO2VO(lifeCyle); lifeCycleVOS.add(lifeCycleVO); }); return lifeCycleVOS; } /** * 生命周期的数据对象转换为显示对象 * @param lifeCycle 数据对象 * @return 显示对象 */ @Override public OsLifeCycleVO lifeCycleDO2VO(LifeCycle lifeCycle){ OsLifeCycleVO life = new OsLifeCycleVO(); Map statusVOMap = statusServiceI.selectAllStatusMap(); if(lifeCycle !=null) { try { life.setCreateTime(new Date(lifeCycle.createTime)); } catch (Exception e) { e.printStackTrace(); } life.setCreator(lifeCycle.creator); life.setDescription(lifeCycle.description); life.setId(lifeCycle.name); life.setLastModifier(lifeCycle.modifier); try { life.setLastModifyTime(new Date(lifeCycle.modifyTime)); } catch (Exception e) { e.printStackTrace(); } life.setOid(lifeCycle.oid); Bound[] bounds = lifeCycle.bounds; if(bounds != null && bounds.length>0){ List boundVOList = new ArrayList<>(); Arrays.stream(bounds).forEach(bound->{ OsLifeCycleLineBoundVO boundVO = new OsLifeCycleLineBoundVO(); boundVO.setId(bound.id); boundVO.setName(bound.name); boundVO.setCellx(bound.cellx); boundVO.setCelly(bound.celly); boundVO.setCellh(bound.cellh); boundVO.setCellw(bound.cellw); boundVO.setCellicon(bound.cellicon); boundVOList.add(boundVO); }); life.setBounds(boundVOList.toArray(new OsLifeCycleLineBoundVO[boundVOList.size()])); }else{ life.setBounds(new OsLifeCycleLineBoundVO[0]); } List lineVOS = new ArrayList<>(); if(lifeCycle.routes!=null && lifeCycle.routes.length>0){ Arrays.stream(lifeCycle.routes).forEach(route->{ OsLifeCycleLineVO lineVO = new OsLifeCycleLineVO(); lineVO.setSourceLifeStatus(route.source); lineVO.setSourceLifeStatusName(statusVOMap.getOrDefault(route.source,new OsStatusVO()).getName()); lineVO.setTargetLifeStatus(route.destination); lineVO.setTargetLifeStatusName(statusVOMap.getOrDefault(route.destination,new OsStatusVO()).getName()); lineVO.setOid(route.id); lineVO.setName(route.connect); if(route.transitionVOEvents ==null || route.transitionVOEvents.length == 0){ lineVO.setEvents(new OsLifeCycleLineEventVO[0]); }else { OsLifeCycleLineEventVO[] eventVOs = new OsLifeCycleLineEventVO[route.transitionVOEvents.length]; for (int i = 0; i < route.transitionVOEvents.length; i++) { TransitionVOEvent event = route.transitionVOEvents[i]; OsLifeCycleLineEventVO eventVO = new OsLifeCycleLineEventVO(); eventVO.setOid(event.id); eventVO.setEventFullName(event.name); eventVOs[i] = eventVO; } lineVO.setEvents(eventVOs); } lineVOS.add(lineVO); }); } life.setLines(lineVOS); life.setStartStatus(lifeCycle.startState); life.setStartStatusName(statusVOMap.getOrDefault(lifeCycle.startState,new OsStatusVO()).getName()); life.setName(lifeCycle.label); try { life.setTs(VciDateUtil.str2Date(lifeCycle.ts,VciDateUtil.DateTimeMillFormat)); } catch (Exception e) { e.printStackTrace(); } } return life; } /** * 使用生命周期的编号获取包含的状态显示对象 * * @param lifeCycleId 生命周期的编号 * @return 状态的显示对象 */ @Override public List listStatusById(String lifeCycleId) { OsLifeCycleVO lifeCycleVO = getLifeCycleById(lifeCycleId); if(lifeCycleVO == null || StringUtils.isBlank(lifeCycleVO.getOid())){ return new ArrayList<>(); } Set hasStatusIdSet = new HashSet<>(); lifeCycleVO.getLines().stream().forEach(lineVO->{ hasStatusIdSet.add(lineVO.getSourceLifeStatus()); hasStatusIdSet.add(lineVO.getTargetLifeStatus()); }); Map statusVOMap = statusServiceI.selectAllStatusMap(); List statusVOList = new ArrayList<>(); hasStatusIdSet.stream().forEach(statusId->{ statusVOList.add(statusVOMap.getOrDefault(statusId,new OsStatusVO())); }); return statusVOList; } }