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.dto.*; import com.vci.pagemodel.*; import com.vci.po.OsLifeCyclePO; import com.vci.starter.poi.bo.ReadExcelOption; import com.vci.starter.poi.bo.WriteExcelData; import com.vci.starter.poi.bo.WriteExcelOption; import com.vci.starter.poi.constant.ExcelLangCodeConstant; import com.vci.starter.poi.util.ExcelUtil; import com.vci.starter.web.annotation.log.VciUnLog; import com.vci.starter.web.exception.VciBaseException; import com.vci.starter.web.pagemodel.BaseQueryObject; import com.vci.starter.web.pagemodel.BaseResult; import com.vci.starter.web.pagemodel.DataGrid; import com.vci.starter.web.util.*; import com.vci.model.OsLifeCycleDO; import com.vci.web.service.OsLifeCycleServiceI; import com.vci.web.service.OsStatusServiceI; import com.vci.web.service.WebBoServiceI; 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.apache.poi.hssf.util.HSSFColor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.swing.*; import java.io.File; 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; /** * 生命周期服务 * @author weidy * @date 2021-2-14 */ @Service public class OsLifeCycleServiceImpl implements OsLifeCycleServiceI { /** * 平台客户端 */ @Autowired private PlatformClientUtil platformClientUtil; /** * 状态的服务 */ @Autowired private OsStatusServiceI statusService; /** * 加载自身 */ @Autowired(required = false) @Lazy private OsLifeCycleServiceI self; /** * 业务对象服务 */ @Autowired private WebBoServiceI boService; /** * 必填列 */ private List ColumnNameisRed = new ArrayList(); /** * 日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /*** * 获取生命周期的状态对应的中文值 * @param status 状态 * @return 状态的显示名称 * @throws VciBaseException 不存在生命周期 */ @Override public String getStatusText(String status) throws VciBaseException { return statusService.selectAllStatusMap().getOrDefault(status,new OsStatusVO()).getName(); } /** * 跃迁生命周期状态,注意调用此方法就会被持久化,不受事务控制 * @param bo 业务类型的数据对象 * @param targetStatus 目标的生命周期状态,不区分大小 * @throws VciBaseException 如果目标生命周期和当前生命周期状态没有连接线时抛出异常 */ @Override public void transStatus(BusinessObject bo, String targetStatus) throws VciBaseException { WebUtil.alertNotNull(bo,"业务数据对象",bo.lctId,"生命周期编码",bo.lcStatus,"当前生命周期状态",targetStatus,"目标生命周期状态"); 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}); } } } /** * 批量跃迁生命周期状态,这些数据中的当前状态必须都是一样。或者是当前状态都可以连接到目标状态 * @param boList 业务类型对象数据 * @param targetStatus 目标状态,不区分大小写 * @throws VciBaseException 转换生命周期出错的时候抛出异常 */ @Override public void transStatus(List boList, String targetStatus) throws VciBaseException { WebUtil.alertNotNull(boList,"业务数据对象",targetStatus,"目标对象"); transStatus(boList.toArray(new com.vci.corba.omd.data.BusinessObject[0]), targetStatus); } /** * 批量跃迁生命周期状态,这些数据中的当前状态必须都是一样,或者是当前状态都可以连接到目标状态 * @param bos 业务类型对象数据 * @param targetStatus 目标状态,不区分大小写 * @throws VciBaseException 转换生命周期出错的时候抛出异常 */ @Override public void transStatus(BusinessObject[] bos, String targetStatus) throws VciBaseException { 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 cboList 业务类型对象数据 * @param targetStatus 目标状态,不区分大小写 * @throws VciBaseException 转换生命周期出错的时候抛出异常 */ @Override public void transCboStatus(List cboList, String targetStatus) throws VciBaseException { 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 lctId 生命周期编号 * @return 显示对象 */ @Override public OsLifeCycleVO getLifeCycleById(String lctId) { WebUtil.alertNotNull(lctId,"业务类型编号"); return self.selectAllLifeCycleMap().getOrDefault(lctId,null); } /** * 生命周期的数据对象转换为显示对象 * @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 = statusService.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++) { com.vci.corba.omd.lcm.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.tag); try { life.setTs(VciDateUtil.str2Date(lifeCycle.ts,VciDateUtil.DateTimeMillFormat)); } catch (Exception e) { e.printStackTrace(); } } return life; } /** * 生命周期显示对象转换为数据对象 * @param lifeCycleVO 显示对象 * @return 数据对象 */ @Override public LifeCycle lifeCycleVO2DO(OsLifeCycleVO lifeCycleVO) throws PLException { LifeCycle lifeCyle = new LifeCycle(); lifeCyle.name = lifeCycleVO.getId(); lifeCyle.tag = lifeCycleVO.getName(); lifeCyle.oid = lifeCycleVO.getOid(); String userId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(); lifeCyle.creator = Func.isBlank(lifeCycleVO.getCreator()) ? userId:lifeCycleVO.getCreator(); lifeCyle.description = lifeCycleVO.getDescription(); lifeCyle.modifier = Func.isBlank(lifeCycleVO.getLastModifier()) ? userId:lifeCycleVO.getLastModifier(); lifeCyle.modifyTime = System.currentTimeMillis(); lifeCyle.createTime = lifeCycleVO.getCreateTime() != null ? lifeCycleVO.getCreateTime().getTime():System.currentTimeMillis(); lifeCyle.startState =lifeCycleVO.getStartStatus(); lifeCyle.ts = VciDateUtil.date2Str(lifeCycleVO.getTs(),VciDateUtil.DateTimeMillFormat); if(lifeCycleVO.getBounds() !=null && lifeCycleVO.getBounds().length>0) { Bound[] bounds = new Bound[lifeCycleVO.getBounds().length]; for (int i = 0; i < lifeCycleVO.getBounds().length; i++) { OsLifeCycleLineBoundVO boundVO = lifeCycleVO.getBounds()[i]; Bound bound = new Bound(); bound.id = StringUtils.isBlank(boundVO.getId()) ? "" : boundVO.getId(); bound.name = boundVO.getName(); bound.cellx = boundVO.getCellx(); bound.celly = boundVO.getCelly(); bound.cellh = boundVO.getCellh(); bound.cellw = boundVO.getCellw(); bound.cellicon = StringUtils.isBlank(boundVO.getCellicon()) ? "" : boundVO.getCellicon(); bounds[i] = bound; } lifeCyle.bounds = bounds; }else{ lifeCyle.bounds = new Bound[0]; } //加连接线 List lines = new ArrayList<>(); for (int i = 0; i < lifeCycleVO.getLines().size(); i++) { OsLifeCycleLineVO lineVO = lifeCycleVO.getLines().get(i); lines.add(lifeCycleLineVO2DO(lineVO)); } lifeCyle.routes = lines.toArray(new TransitionVO[0]); return lifeCyle; } /** * 查询所有生命周期状态 * * @return 生命周期状态的对象 * @throws VciBaseException 查询的时候出错的时候 */ @Override @VciUnLog public List selectAllLifeCycle() throws VciBaseException { 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); } } /** * 查询生命周期的映射 * @return key是生命周期的编号, value是生命周期的对象 * @throws VciBaseException 查询出错的时候会抛出异常 */ @Override @VciUnLog public Map selectAllLifeCycleMap() throws VciBaseException{ return Optional.ofNullable(self.selectAllLifeCycle()).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getId(),t->t,(o1,o2)->o1)); } /** * 清除缓存 */ @Override public void clearCache() { } /** * 获取连接线 * @param lcid 生命周期的编号 * @param currentStatus 当前的状态 * @param targetStatus 目标的状态 * @return 连接线 * @throws VciBaseException 读取出错的时候会抛出异常 */ @Override public OsLifeCycleLineVO getTransVO(String lcid, String currentStatus, String targetStatus) throws VciBaseException { 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 lineVO 连接线对象 * @return 平台的连接线对象 */ private TransitionVO lifeCycleLineVO2DO(OsLifeCycleLineVO lineVO) throws PLException { com.vci.corba.omd.lcm.TransitionVO transitionVO = new com.vci.corba.omd.lcm.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 bos 业务类型数据 * @param vos 跃迁对象 * @throws VciBaseException 跃迁出错的是会抛出异常 */ @Override public void batchTransVo(BusinessObject[] bos,OsLifeCycleLineVO[] vos) throws VciBaseException{ batchTransVo(bos,vos,null); } /** * 使用生命周期的编号获取包含的状态显示对象 * * @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 = statusService.selectAllStatusMap(); List statusVOList = new ArrayList<>(); hasStatusIdSet.stream().forEach(statusId->{ statusVOList.add(statusVOMap.getOrDefault(statusId,new OsStatusVO())); }); return statusVOList; } /** * 使用多个编号获取生命周期的对象 * @param lcIdList 编号 * @return 显示对象 */ @Override public List getLifeCycleByIds(Collection lcIdList) { if(Func.isEmpty(lcIdList)){ return null; } Map lifeCycleVOMap = self.selectAllLifeCycleMap(); List lifeCycleVOList = new ArrayList<>(); lcIdList.stream().forEach(vrId->{ OsLifeCycleVO lifeCycleVO = lifeCycleVOMap.getOrDefault(vrId,null); if(lifeCycleVO != null){ lifeCycleVOList.add(lifeCycleVO); } }); return lifeCycleVOList; } /** * 批量添加生命周期 * * @param lifeCyleList 生命周期的内容 */ @Override public void batchAddLifeCycle(List lifeCyleList) { if(!CollectionUtils.isEmpty(lifeCyleList)){ lifeCyleList.stream().forEach(lifeCyle -> { try { //校验生命周期是否合规 this.checkLifeCycle(lifeCyle,true); platformClientUtil.getLifeCycleService().addLifeCycle(lifeCyle); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } }); } } /** * 批量修改生命周期 * * @param lifeCycleList 生命周期的内容 */ @Override public void batchEditLifeCycle(List lifeCycleList) { if(!CollectionUtils.isEmpty(lifeCycleList)){ lifeCycleList.stream().forEach(lifeCyle -> { try { //校验生命周期是否合规 this.checkLifeCycle(lifeCyle,false); platformClientUtil.getLifeCycleService().modifyLifeCycle(lifeCyle); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } }); } } /** * 状态在生命周期中使用的范围 * * @param statusOid 状态的主键 * @return 生命周期的信息 */ @Override public DataGrid listStatusUsed(String statusOid) { if(StringUtils.isBlank(statusOid)){ return new DataGrid<>("没有状态的信息"); } OsStatusVO statusVO = statusService.getObjectByOid(statusOid); List lifeCycleVOS = self.selectAllLifeCycleMap().values().stream().collect(Collectors.toList()); List exitLifeVOList = new ArrayList<>(); Optional.ofNullable(lifeCycleVOS).orElseGet(()->new ArrayList<>()).stream().forEach( lifeCycleVO -> { if(Optional.ofNullable(lifeCycleVO.getLines()).orElseGet(()->new ArrayList<>()).stream().anyMatch( lineVO->statusVO.getId().equalsIgnoreCase(lineVO.getSourceLifeStatus())|| statusVO.getId().equalsIgnoreCase(lineVO.getTargetLifeStatus()))){ exitLifeVOList.add(lifeCycleVO); } }); DataGrid dataGrid = new DataGrid<>(); dataGrid.setData(exitLifeVOList); dataGrid.setTotal(exitLifeVOList.size()); return dataGrid; } /** * 判断状态是否被引用 * * @param statusVO 状态的显示对象 * @return true表示被引用 */ @Override public boolean checkStatusUsed(OsStatusVO statusVO) { List lifeCycleVOS = self.selectAllLifeCycleMap().values().stream().collect(Collectors.toList()); return Optional.ofNullable(lifeCycleVOS).orElseGet(()->new ArrayList<>()).stream().anyMatch( lifeCycleVO -> Optional.ofNullable(lifeCycleVO.getLines()).orElseGet(()->new ArrayList<>()).stream().anyMatch( lineVO->statusVO.getId().equalsIgnoreCase(lineVO.getSourceLifeStatus())|| statusVO.getId().equalsIgnoreCase(lineVO.getTargetLifeStatus())) ); } /** * 生命周期列表 * * @param baseQueryObject 查询对象,分页对象 * @return 生命周期显示对象 */ @Override public DataGrid gridLifeCycle(BaseQueryObject baseQueryObject) { return gridObject(baseQueryObject,OsLifeCycleDO.class,self.selectAllLifeCycleMap(),OsLifeCycleVO.class); } /** * 新增单条生命周期 * @param osLifeCycleVO * @return */ @Override public boolean addLifeCycle(OsLifeCycleVO osLifeCycleVO) throws PLException { VciBaseUtil.alertNotNull(osLifeCycleVO,"生命周期模板"); LifeCycle lifeCycle = lifeCycleVO2DO(osLifeCycleVO); //生命周期合规校验 checkLifeCycle(lifeCycle,true); return platformClientUtil.getLifeCycleService().addLifeCycle(lifeCycle); } /** * 修改生命周期 * @param osLifeCycleVO * @return */ @Override public boolean updateLifeCycle(OsLifeCycleVO osLifeCycleVO) throws PLException { VciBaseUtil.alertNotNull(osLifeCycleVO,"生命周期模板"); //查询修改的生命周期是否存在 LifeCycle dbLifeCycle = platformClientUtil.getLifeCycleService().getLifeCycle(osLifeCycleVO.getId()); if(Func.isEmpty(dbLifeCycle) || Func.isBlank(dbLifeCycle.oid)){ throw new PLException("500",new String[]{"修改生命周期模板不存在!"}); } osLifeCycleVO.setCreator(dbLifeCycle.creator); osLifeCycleVO.setCreateTime(new Date(dbLifeCycle.createTime)); LifeCycle lifeCycle = lifeCycleVO2DO(osLifeCycleVO); //检查生命周期修改是否和规 checkLifeCycle(lifeCycle,false); return platformClientUtil.getLifeCycleService().modifyLifeCycle(lifeCycle); } /** * 删除生命周期 * @param lifeCycleDTOS * @return */ @Override public boolean deleteLifeCycles(List lifeCycleDTOS) throws PLException { VciBaseUtil.alertNotNull(lifeCycleDTOS,"待删除的生命周期列表"); //判断要删除的生命周期是否有被引用 lifeCycleDTOS.stream().forEach(item->{ String lifeCycleName = item.getId(); try { List> usedLifeCycleList = this.getUsedLifeCycleList(lifeCycleName); if(Func.isNotEmpty(usedLifeCycleList)){ throw new VciBaseException("该生命周期已被使用不允许删除"); } } catch (PLException e) { logger.error(e.getMessage()); e.printStackTrace(); throw new VciBaseException(e.getMessage()); } }); //平台的deleteStatus方法必传三个参数,oid、name和ts List lcList = new ArrayList<>(); for(OsLifeCycleDTO lcDTO : lifeCycleDTOS){ //oid和ts判空 String oid = lcDTO.getOid(); //id主要用来对缓存数据删除 String id = lcDTO.getId(); //后台会用ts进行数据一致性校验 Date ts = lcDTO.getTs(); if(Func.isBlank(oid) || Func.isBlank(id) || Func.isEmpty(ts)){ throw new PLException("500",new String[]{"待删除的生命周期列表中主键【oid】、调整时间【ts】、状态名称【name】不能为空!"}); } LifeCycle vr = new LifeCycle(); vr.oid = oid; vr.name = id; vr.ts = Func.format(ts,VciDateUtil.DateTimeMillFormat); lcList.add(vr); } return platformClientUtil.getLifeCycleService().deleteLifeCycles(lcList.toArray(new LifeCycle[lcList.size()])); } /** * 查看生命周期的使用范围 * @return */ @Override public List> getUsedLifeCycleList(String lifeCycleName) throws PLException { if(Func.isBlank(lifeCycleName)){ throw new PLException("500",new String[]{"请选择要查询使用范围的生命周期模板!"}); } String[] btNames = platformClientUtil.getBtmService().getBTNamesByLCName(lifeCycleName); if(Func.isEmpty(btNames)){ return new ArrayList<>(); } List> btmNameMapList = new ArrayList<>(); Arrays.stream(btNames).forEach(btName->{ Map itemMap = new HashMap<>(); itemMap.put("lifeCycleName",lifeCycleName); itemMap.put("source",btName); btmNameMapList.add(itemMap); }); return btmNameMapList; } /** * 导出选中的生命周期 * @param exportFileName 导出的文件名 * @param lcNames 需要导出的生命周期名称 * @param flag 控制导出的列名是否和导入模板一致 * @return */ @Override public String exportLifeCycles(String exportFileName, String lcNames, boolean flag) throws PLException { if(Func.isBlank(lcNames)){ throw new PLException("500",new String[]{"请勾选要导出的生命周期模板!"}); } //界面没传名称,使用默认导出名称 exportFileName = Func.isBlank(exportFileName) ? "版本规则导出_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):exportFileName; //设置列名 List columns = this.getCloumns(flag); //写excel String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + exportFileName + ".xls"; try { new File(excelPath).createNewFile(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e); } //设置列 List excelDataList = new ArrayList<>(); //设置列头 for (int index = 0; index < columns.size(); index++) { excelDataList.add(new WriteExcelData(0,index, columns.get(index))); } //按照版本规则名查询,然后处理版本规则导出 List lcIdList = Func.toStrList(lcNames); List lifeCycleVOList = this.getLifeCycleByIds(lcIdList); if(Func.isEmpty(lifeCycleVOList)){ excelDataList.add(new WriteExcelData(1,1, "根据名称未查询到生命周期信息,请刷新后尝试重新导出!")); }else{ int row = 1; for (int i = 0; i < lifeCycleVOList.size(); i++) { OsLifeCycleVO lifeCycleVO = lifeCycleVOList.get(i); List lines = lifeCycleVO.getLines(); if(Func.isNotEmpty(lines)){ for (int j = 0; j < lines.size(); j++) { int start = row + j; excelDataList.add(new WriteExcelData(start,0, lifeCycleVO.getId())); excelDataList.add(new WriteExcelData(start,1, lifeCycleVO.getName())); excelDataList.add(new WriteExcelData(start,2, lifeCycleVO.getStartStatus())); excelDataList.add(new WriteExcelData(start,3, lifeCycleVO.getDescription())); OsLifeCycleLineVO osLifeCycleLineVO = lines.get(j); //按照导出模板列填数据 if(!flag){ excelDataList.add(new WriteExcelData(start,4, osLifeCycleLineVO.getName())); excelDataList.add(new WriteExcelData(start,5, osLifeCycleLineVO.getSourceLifeStatus())); excelDataList.add(new WriteExcelData(start,6, osLifeCycleLineVO.getSourceLifeStatusName())); excelDataList.add(new WriteExcelData(start,7, osLifeCycleLineVO.getTargetLifeStatus())); excelDataList.add(new WriteExcelData(start,8, osLifeCycleLineVO.getTargetLifeStatusName())); //处理连接线包含的事件 OsLifeCycleLineEventVO[] events = osLifeCycleLineVO.getEvents(); if(events != null && events.length > 0){ String collect = Arrays.stream(events).map(OsLifeCycleLineEventVO::getOid).collect(Collectors.joining(";")); excelDataList.add(new WriteExcelData(start,9, collect)); } excelDataList.add(new WriteExcelData(start,10, Func.format(lifeCycleVO.getCreateTime(),"yyyy年MM月dd日 hh:mm:ss"))); }else{ excelDataList.add(new WriteExcelData(start,4, osLifeCycleLineVO.getSourceLifeStatus())); excelDataList.add(new WriteExcelData(start,5, osLifeCycleLineVO.getTargetLifeStatus())); } } row = row+lines.size(); }else{ excelDataList.add(new WriteExcelData(row,0, lifeCycleVO.getId())); excelDataList.add(new WriteExcelData(row,1, lifeCycleVO.getName())); excelDataList.add(new WriteExcelData(row,2, lifeCycleVO.getStartStatus())); excelDataList.add(new WriteExcelData(row,3, lifeCycleVO.getDescription())); if(!flag){ excelDataList.add(new WriteExcelData(row,10, Func.format(lifeCycleVO.getCreateTime(),"yyyy年MM月dd日 hh:mm:ss"))); } row++; } } } WriteExcelOption excelOption = new WriteExcelOption(excelDataList); ExcelUtil.writeDataToFile(excelPath, excelOption); return excelPath; } /** * 下载生命周期导入模板 * @param exportFileName * @return * @throws PLException */ @Override public String downloadLifeCycleTemplate(String exportFileName) throws Exception { //界面没传名称,使用默认导出名称 exportFileName = Func.isBlank(exportFileName) ? "生命周期导入模板_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):exportFileName; //设置列名 List columns = this.getCloumns(true); //设置必填列 ColumnNameisRed.clear(); ColumnNameisRed.add(0); ColumnNameisRed.add(2); //写excel String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + exportFileName + ".xls"; try { new File(excelPath).createNewFile(); } catch (Throwable e) { throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e); } //设置列 List excelDataList = new ArrayList<>(); //设置列头 for (int index = 0; index < columns.size(); index++) { //判断是否为必填列,给必填列设置颜色 if(ColumnNameisRed.contains(index)){ WriteExcelData excelData = new WriteExcelData(0, index, columns.get(index)); excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex())); excelDataList.add(excelData); }else{ excelDataList.add(new WriteExcelData(0,index, columns.get(index))); } } WriteExcelOption excelOption = new WriteExcelOption(excelDataList); ExcelUtil.writeDataToFile(excelPath, excelOption); return excelPath; } /** * 导入生命周期 * @param file * @return */ @Override public BaseResult importLifeCycles(File file) throws Exception { VciBaseUtil.alertNotNull(file,"excel文件"); if(!file.exists()){ throw new VciBaseException("导入的excel文件不存在,{0}",new String[]{file.getPath()}); } try{ //1、读取excel中的数据,组成对象 ReadExcelOption excelOption = new ReadExcelOption(); List poList = ExcelUtil.readDataObjectFromExcel(file, OsLifeCyclePO.class,excelOption,(value, po, fieldName)->{}); //去除都是空的情况 if(CollectionUtils.isEmpty(poList)){ return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{}); } //将枚举和枚举项处理成一对多关系的对象 Map groupPOMap = new HashMap<>(); //默认的生命周期图标的坐标和宽度等信息 List defaultBoundList = new ArrayList<>(); for (OsLifeCyclePO po : poList) { //拼接用来作为分组的key String key = po.getId() + "_" + po.getName() + "_" + po.getStartStatus(); OsLifeCyclePO group = groupPOMap.get(key); if (group == null) { group = new OsLifeCyclePO(); //拿出现的首行做后续的提示行 group.setRowIndex(po.getRowIndex()); group.setId(po.getId()); group.setName(po.getName()); group.setStartStatus(po.getStartStatus()); group.setDescription(po.getDescription()); groupPOMap.put(key, group); //第一行起始状态需要单独处理 if(po.getRowIndex().equals("1")){ OsLifeCycleLineBoundVO boundVO = new OsLifeCycleLineBoundVO(); boundVO.setName(po.getStartStatus()); boundVO.setCellh("30.0"); boundVO.setCellw("80.0"); boundVO.setCellx(String.valueOf(200+(Integer.parseInt(po.getRowIndex())*60))); boundVO.setCelly(String.valueOf(300+(Integer.parseInt(po.getRowIndex())*60))); boundVO.setCellicon(""); defaultBoundList.add(boundVO); } //处理生命周期图标的默认的坐标信息 OsLifeCycleLineBoundVO boundVO = new OsLifeCycleLineBoundVO(); boundVO.setName(po.getTargetLifeStatus()); boundVO.setCellh("30.0"); boundVO.setCellw("80.0"); boundVO.setCellx(String.valueOf(250+(Integer.parseInt(po.getRowIndex())*60))); boundVO.setCelly(String.valueOf(350+(Integer.parseInt(po.getRowIndex())*60))); boundVO.setCellicon(""); defaultBoundList.add(boundVO); } OsLifeCycleLineVO lineItemVO = new OsLifeCycleLineVO(); lineItemVO.setName("line"+po.getRowIndex()); lineItemVO.setSourceLifeStatus(po.getSourceLifeStatus()); lineItemVO.setTargetLifeStatus(po.getTargetLifeStatus()); //处理连接线包含的事件 String[] eventArr = po.getEvents().split(";"); if(eventArr != null & eventArr.length > 0){ List eventVOList = new ArrayList<>(); for (int i = 0; i < eventArr.length; i++) { OsLifeCycleLineEventVO osLCLineEventVO = new OsLifeCycleLineEventVO(); osLCLineEventVO.setOid(eventArr[i]); String lcEventValueByKey = platformClientUtil.getLifeCycleService().getLCEventValueByKey(eventArr[i]); osLCLineEventVO.setEventFullName(lcEventValueByKey); eventVOList.add(osLCLineEventVO); } lineItemVO.setEvents(eventVOList.toArray(new OsLifeCycleLineEventVO[eventVOList.size()])); } group.getLineItems().add(lineItemVO); } Collection newPOList = groupPOMap.values(); //数据库查询是否有已存在的生命周期名,方便后续做判重处理 List lifeCycleVOList = this.getLifeCycleByIds(poList.stream().map(OsLifeCyclePO::getId).collect(Collectors.toSet())); List repeatLCId = new ArrayList<>(); if(Func.isNotEmpty(lifeCycleVOList)){ repeatLCId = lifeCycleVOList.stream().map(OsLifeCycleVO::getId).collect(Collectors.toList()); } //当前excel中是否重复用的判重Map:(key:判重属性,value:行号) Map excelReapeat = new HashMap<>(); //判断必填属性是否为空等等 List finalRepeatLCId = repeatLCId; newPOList.stream().forEach(lcPO -> { if(Func.isBlank(lcPO.getId())){ throw new VciBaseException("第【"+lcPO.getRowIndex()+"】行,lcnameerror"); }else if(Func.isEmpty(lcPO.getStartStatus())){ throw new VciBaseException("第【"+lcPO.getRowIndex()+"】行,startstatuserror"); }else if(!lcPO.getId().matches("^[A-Za-z]+$")){ throw new VciBaseException("第【"+lcPO.getRowIndex()+"】行数据,名称只能为英文字母"); }else if(excelReapeat.containsKey(lcPO.getId())){//名称表格中判重 throw new VciBaseException("第【"+excelReapeat.get(lcPO.getId())+"】行和第【"+lcPO.getRowIndex()+"】行数据,名称重复"); }else if (Func.isNotEmpty(finalRepeatLCId) && finalRepeatLCId.contains(lcPO.getId())){//2、判断名称是否与系统中重复 throw new VciBaseException("第【"+lcPO.getRowIndex()+"】行,名称在系统中已经存在,请修改!"); } //先对枚举名excel中需要判重处理 excelReapeat.put(lcPO.getId(),lcPO.getRowIndex()); }); //保存逻辑 for (OsLifeCyclePO osLifeCyclePO : newPOList) { OsLifeCycleVO osLifeCycleVO = new OsLifeCycleVO(); //生成存储的DTO对象 osLifeCycleVO.setId(osLifeCyclePO.getId()); osLifeCycleVO.setName(osLifeCyclePO.getName()); osLifeCycleVO.setDescription(osLifeCyclePO.getDescription()); osLifeCycleVO.setStartStatus(osLifeCyclePO.getStartStatus()); osLifeCycleVO.setLines(osLifeCyclePO.getLineItems()); osLifeCycleVO.setBounds(defaultBoundList.toArray(new OsLifeCycleLineBoundVO[defaultBoundList.size()])); //调用新增枚举方法 boolean addBoolean = platformClientUtil.getLifeCycleService().addLifeCycle(lifeCycleVO2DO(osLifeCycleVO)); if(!addBoolean){ throw new PLException("500",new String[]{"保存生命周期名,为【" + osLifeCycleVO.getId() + "】的数据时出现错误!"}); } } }catch (Exception e){ if(logger.isErrorEnabled()){ logger.error("读取excel内容时或保存生命周期信息时出现了错误,具体原因:",VciBaseUtil.getExceptionMessage(e)); } e.printStackTrace(); return BaseResult.fail(VciBaseUtil.getExceptionMessage(e),new String[]{},e); } return BaseResult.success("生命周期导入成功!"); } /** * 获取导出或导入模板的列名 * @param flag 是否获取导入模板列名 * @return */ private List getCloumns(boolean flag){ if(flag){ return new ArrayList<>( Arrays.asList( "名称", "标签", "起始状态", "描述", "连接线起始状态", "连接线目标状态", "事件(;间隔)" ) ); } return new ArrayList<>( Arrays.asList( "名称", "标签", "起始状态", "描述", "连接线名称", "连接线起始状态英文名称","连接线起始状态中文名称", "连接线目标状态英文名称","连接线目标状态中文名称", "事件", "创建时间" ) ); } /** * 检查生命周期名称是否已存在 * @param name * @return */ public boolean checkLCExist(String name) { try { LifeCycle lc = platformClientUtil.getLifeCycleService().getLifeCycle(name); if (lc != null && !lc.name.equals("")) { return true; } } catch (PLException e) { // TODO Auto-generated catch block e.printStackTrace(); logger.error(VciBaseUtil.getExceptionMessage(e)); } return false; } /** * 检查生命周期是否合规 * @param lifeCycle * @param isAdd 是否为新增 * @throws PLException */ public void checkLifeCycle(LifeCycle lifeCycle,boolean isAdd) throws PLException { String name = lifeCycle.name; if (Func.isBlank(name)) { throw new PLException("500", new String[]{"请输入生命周期名称!"}); } if (!name.matches("[a-z A-Z]*")) { throw new PLException("500", new String[]{"生命周期名称只能为英文字母!"}); } if (isAdd && checkLCExist(name)) { throw new PLException("500", new String[]{"该生命周期名称已经存在!"}); } if (Func.isBlank(lifeCycle.startState)) { throw new PLException("500", new String[]{"请选择开始状态!"}); } } /** * 生命周期的链接线 * * @param id 编号 * @return ER图内容 */ @Override public OsERVO listLinesPic(String id) { if(StringUtils.isBlank(id)){ return null; } OsLifeCycleVO lifeCycleVO = self.selectAllLifeCycleMap().getOrDefault(id,null); if(lifeCycleVO == null){ return null; } List voLines = lifeCycleVO.getLines(); List statusVOS = listStatusById(lifeCycleVO.getId()); List nodeVOList = new ArrayList<>(); List relationVOList = new ArrayList<>(); Map statusVOMap = Optional.ofNullable(statusVOS).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t)); if(!CollectionUtils.isEmpty(statusVOS)){ statusVOS.stream().forEach(statusVO -> { OsERNodeVO nodeVO = new OsERNodeVO(); nodeVO.setKey(statusVO.getId() + " " + statusVO.getName()); nodeVOList.add(nodeVO); }); } if(!CollectionUtils.isEmpty(voLines)){ voLines.stream().forEach(line->{ OsERRelationVO relationVO = new OsERRelationVO(); OsStatusVO statusVO = statusVOMap.get(line.getSourceLifeStatus().toLowerCase(Locale.ROOT)); OsStatusVO targetStatusVO = statusVOMap.get(line.getTargetLifeStatus().toLowerCase(Locale.ROOT)); relationVO.setFrom(statusVO.getId() + " " + statusVO.getName()); relationVO.setTo(targetStatusVO.getId() + " " + targetStatusVO.getName()); relationVO.setToText(line.getName()); relationVOList.add(relationVO); }); } OsERVO ervo = new OsERVO(); ervo.setTabViewList(nodeVOList); ervo.setTabRelViewList(relationVOList); return ervo; } /** * 查询所有跃迁事件key * @return */ @Override public List getLCEventKeys() throws PLException { return Arrays.asList(platformClientUtil.getLifeCycleService().getLCEventKeys()); } /** * 批量执行跃迁操作,要求必须是同一个业务类型下的 * @param bos 业务类型数据对象 * @param lineVOs 跃迁对象 * @param releaseStatus 发布状态,如果目标状态是发布状态时传递这个值 * @throws VciBaseException 跃迁出错的是会抛出异常 */ @Override public void batchTransVo(BusinessObject[] bos,OsLifeCycleLineVO[] lineVOs,String[] releaseStatus) throws VciBaseException{ 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] = ""; } } com.vci.corba.omd.lcm.TransitionVO[] vos = new com.vci.corba.omd.lcm.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[]{"跃迁路由和业务类型数据长度不相同"}); } } } }