package com.vci.web.service.impl; import com.vci.corba.common.PLException; import com.vci.corba.omd.stm.StatePool; import com.vci.dto.OsStatusDTO; import com.vci.model.OsStatusDO; import com.vci.pagemodel.OsStatusVO; import com.vci.po.OsStatusPO; 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.pagemodel.PageHelper; import com.vci.starter.web.util.*; import com.vci.starter.web.util.Lcm.Func; import com.vci.web.service.OsLifeCycleServiceI; import com.vci.web.service.OsStatusServiceI; import com.vci.web.service.WebBoServiceI; 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 java.io.File; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import static com.vci.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST; /** * 状态的服务 * @author weidy * @date 2021-2-14 */ @Service public class OsStatusServiceImpl implements OsStatusServiceI { /** * 日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * 平台的客户端 */ @Autowired private PlatformClientUtil platformClientUtil; /** * 业务 */ @Autowired private WebBoServiceI boService; /** * 生命周期的服务 */ @Autowired(required = false) @Lazy private OsLifeCycleServiceI lifeCycleService; /** * 必填列 */ private List ColumnNameisRed = new ArrayList(); /** * 加载自身 */ @Autowired(required = false) @Lazy private OsStatusServiceI self; /** * 数据对象转换为显示对象 * * @param statePool 状态池的数据对象 * @return 显示对象 */ @Override public OsStatusVO statusDO2VO(StatePool statePool) { OsStatusVO statusVO = new OsStatusVO(); if(statePool!=null){ statusVO.setOid(statePool.oid); statusVO.setCreator(statePool.creator); statusVO.setImagePath(statePool.imagePath); statusVO.setLastModifier(statePool.modifier); try { statusVO.setCreateTime(new Date(statePool.createTime)); statusVO.setLastModifyTime(new Date(statePool.modifyTime)); statusVO.setTs(VciDateUtil.str2Date(statePool.ts,VciDateUtil.DateTimeMillFormat)); } catch (Exception e) { e.printStackTrace(); } statusVO.setDescription(statePool.description); statusVO.setId(statePool.name); statusVO.setName(statePool.tag); } return statusVO; } /** * 数据对象转换为显示对象 * * @param statePools 状态池的数据对象 集合 * @return 显示对象 */ @Override public List statusDO2VOs(Collection statePools) { List statusVOS = new ArrayList<>(); if(!CollectionUtils.isEmpty(statePools)){ statePools.stream().forEach(statePool -> { OsStatusVO statusVO = statusDO2VO(statePool); statusVOS.add(statusVO); }); } return statusVOS; } /** * 查询所有的状态 * * @return 状态的显示对象 */ @Override @VciUnLog public List selectAllStatus() { try { return statusDO2VOs(Arrays.stream(platformClientUtil.getStatePoolService().getStatePools()).collect(Collectors.toList())); } catch (PLException vciError) { throw WebUtil.getVciBaseException(vciError); } } /** * 清除缓存 */ @Override public void clearCache(){ // } /** * 查询全部的状态映射 * @return key是状态的英文名称 */ @Override @VciUnLog public Map selectAllStatusMap(){ return Optional.ofNullable(self.selectAllStatus()).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getId(),t->t,(o1,o2)->o1)); } /** * 状态转换为显示文本 * * @param status 状态 * @return 显示文本 */ @Override public String getStatusTextByValue(String status) { if(StringUtils.isBlank(status)){ return ""; } return self.selectAllStatusMap().getOrDefault(status,new OsStatusVO()).getName(); } /** * 批量添加状态 * * @param statePoolList 状态内容 */ @Override public boolean batchAddStatus(List statePoolList) throws Exception{ if(!CollectionUtils.isEmpty(statePoolList)){ for(StatePool statePool : statePoolList) { try { platformClientUtil.getStatePoolService().addStatePool(statePool); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } } return true; } return false; } /** * 批量修改状态 * @param statePoolList 状态内容 */ @Override public boolean batchEditSave(List statePoolList) { if(!CollectionUtils.isEmpty(statePoolList)){ for(StatePool statePool : statePoolList) { try { platformClientUtil.getStatePoolService().modifyStatePool(statePool); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } } } return true; } /** * 状态列表 * * @param conditionMap 查询对象 * @param pageHelper 分页列表 * @return 显示对象 */ @Override public DataGrid gridStatus(Map conditionMap, PageHelper pageHelper) { BaseQueryObject baseQueryObject = new BaseQueryObject(); baseQueryObject.setConditionMap(conditionMap); if (pageHelper == null) { pageHelper = new PageHelper(-1); } baseQueryObject.setPage(pageHelper.getPage()); baseQueryObject.setLimit(pageHelper.getLimit()); baseQueryObject.setOrder(pageHelper.getOrder()); baseQueryObject.setSort(pageHelper.getSort()); return gridObject(baseQueryObject, OsStatusDO.class,self.selectAllStatusMap(),OsStatusVO.class); } /** * 使用主键获取显示对象 * * @param oid 主键 * @return 状态的显示对象 */ @Override public OsStatusVO getObjectByOid(String oid) { List statusVOList = self.selectAllStatusMap().values().stream().filter(status -> status.getOid().equalsIgnoreCase(oid)).collect(Collectors.toList()); if(CollectionUtils.isEmpty(statusVOList)){ throw new VciBaseException(DATA_OID_NOT_EXIST); } return statusVOList.get(0); } /** * 使用主键集合查询 * @param oidCollection 主键集合 * @return 状态的内容 */ @Override public List selectByOidCollection(Collection oidCollection){ List statusVOList = self.selectAllStatus().stream().filter(status -> oidCollection.contains(status.getOid())).collect(Collectors.toList()); if(CollectionUtils.isEmpty(statusVOList)){ throw new VciBaseException(DATA_OID_NOT_EXIST); } return statusVOList; } /** * 添加状态 * * @param statusDTO 状态的数据传输对象 */ @Override public boolean addSave(OsStatusDTO statusDTO) throws Exception { VciBaseUtil.alertNotNull( statusDTO,"状态的信息", statusDTO.getId(),"状态的英文名称" ); if (statusDTO.getId().length()>50) { throw new PLException("500",new String[]{"状态英文名称不能超过50个字符!"}); } // 状态池名称只能为英文字母 String regex = "[a-z A-Z]*"; if (!statusDTO.getId().matches(regex)) { throw new PLException("500",new String[]{"名称只能为英文!"}); } StatePool dbStatePool = platformClientUtil.getStatePoolService().getStatePool(statusDTO.getId()); if (Func.isNotEmpty(dbStatePool) && Func.isNotBlank(dbStatePool.oid)) { throw new PLException("500",new String[]{"名称重复请更换名称!"}); } //虽然会自动生成oid,但是这儿设置主键,避免放入缓存的数据是没有oid的 statusDTO.setOid(VciBaseUtil.getPk().toUpperCase(Locale.ROOT)); try { boolean res = batchAddStatus(Arrays.asList(statusDTO2DO(statusDTO))); self.selectAllStatusMap(); return res; }catch (Exception e){ e.printStackTrace(); logger.error(e.getMessage()); return false; } } /** * 编辑状态 * @param statusDTO 状态的数据传输对象 */ @Override public boolean editSave(OsStatusDTO statusDTO) throws Exception { VciBaseUtil.alertNotNull(statusDTO,"状态的信息", statusDTO.getId(),"状态的英文名称", statusDTO.getName(),"状态的中文名称", statusDTO.getOid(),"主键"); OsStatusVO statusVO = getObjectByOid(statusDTO.getOid()); if(Func.isEmpty(statusVO) || Func.isBlank(statusVO.getOid())){ throw new PLException("500",new String[]{"修改的状态对象不存在!"}); } StatePool pool = statusDTO2DO(statusDTO); pool.creator = statusVO.getCreator(); pool.createTime = VciDateUtil.getTime(statusVO.getCreateTime()); try { boolean res = batchEditSave(Arrays.asList(pool)); self.selectAllStatusMap(); return res; }catch (Exception e){ e.printStackTrace(); logger.error(e.getMessage()); return false; } } /** * 删除状态 * @param osStatusDTOS */ @Override public boolean deleteStatus(List osStatusDTOS) throws PLException { VciBaseUtil.alertNotNull(osStatusDTOS,"待删除的属性列表"); Set oids = osStatusDTOS.stream().map(OsStatusDTO::getOid).collect(Collectors.toSet()); List osStatusVOList = selectByOidCollection(oids); //判断枚举是否有被引用 if(osStatusVOList.stream().anyMatch(statusVO -> lifeCycleService.checkStatusUsed(statusVO))){ throw new VciBaseException("状态在生命周期中被使用,不能删除"); } //平台的deleteStatus方法必传三个参数,oid、name和ts List statePoolList = new ArrayList<>(); for(OsStatusDTO statusDTO : osStatusDTOS){ //oid和ts判空 String oid = statusDTO.getOid(); //id主要用来对缓存数据删除 String id = statusDTO.getId(); //后台会用ts进行数据一致性校验 Date ts = statusDTO.getTs(); if(Func.isBlank(oid) || Func.isBlank(id) || Func.isEmpty(ts)){ throw new PLException("500",new String[]{"待删除的状态列表中主键【oid】、调整时间【ts】、状态名称【name】不能为空!"}); } StatePool statePool = new StatePool(); statePool.oid = oid; statePool.name = id; statePool.ts = Func.format(ts,VciDateUtil.DateTimeMillFormat); statePoolList.add(statePool); } boolean res = platformClientUtil.getStatePoolService().deleteStatePools(statePoolList.toArray(new StatePool[statePoolList.size()])); //clearCache(); self.selectAllStatusMap(); return res; } /** * 状态的数据传输对象转换为数据对象 * @param statusDTO 数据传输对象 * @return 平台的数据对象 */ @Override public StatePool statusDTO2DO(OsStatusDTO statusDTO){ StatePool statePool = new StatePool(); statePool.oid = statusDTO.getOid(); statePool.id = ""; statePool.name = statusDTO.getId(); //statePool.imagePath = statusDTO.getImagePath(); statePool.description = statusDTO.getDescription()==null?"":statusDTO.getDescription(); String userId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(); long now = VciDateUtil.getNowTime(); statePool.creator = Func.isBlank(statusDTO.getCreator()) ? userId:statusDTO.getCreator(); statePool.createTime = now; statePool.modifier = userId; statePool.modifyTime = now; statePool.ts = statusDTO.getTs()==null?VciDateUtil.getNowString(VciDateUtil.DateTimeMillFormat):VciDateUtil.date2Str(statusDTO.getTs(),VciDateUtil.DateTimeMillFormat); statePool.tag = statusDTO.getName(); return statePool; } /** * 导出选中的状态 * @param exportFileName 导出的文件名 * @param statusOids 需要导出的属性名称 * @return */ @Override public String exportStatus(String exportFileName, String statusOids,boolean flag/*控制导出的列名是否和导入模板一致*/) throws PLException { if(Func.isBlank(statusOids)){ 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 statusOidList = Func.toStrList(statusOids); AtomicInteger i = new AtomicInteger(1); statusOidList.stream().forEach(oid->{ OsStatusVO osStatusVO = this.getObjectByOid(oid); excelDataList.add(new WriteExcelData(i.get(),0, osStatusVO.getId())); excelDataList.add(new WriteExcelData(i.get(),1, osStatusVO.getName())); //excelDataList.add(new WriteExcelData(i.get(),2, osStatusVO.getImagePath())); excelDataList.add(new WriteExcelData(i.get(),3, osStatusVO.getDescription())); i.getAndIncrement(); }); WriteExcelOption excelOption = new WriteExcelOption(excelDataList); ExcelUtil.writeDataToFile(excelPath, excelOption); return excelPath; } /** * 下载状态导入模板 * @param exportFileName * @return * @throws PLException */ @Override public String downloadStatusTemplate(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); //写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 flag 是否获取导入模板列名 * @return */ private List getCloumns(boolean flag){ if(flag){ return new ArrayList<>( Arrays.asList("名称(不能为空)", "标签(对名称的解释)"/*,"图片(路径)"*/, "描述(可以为空)") ); } return new ArrayList<>(Arrays.asList("名称", "标签"/*, "图片"*/, "描述")); } /** * 导入状态 * @param file * @return */ @Override public BaseResult importStatus(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, OsStatusPO.class,excelOption,(value, po, fieldName)->{}); //去除都是空的情况 if(CollectionUtils.isEmpty(poList)){ return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{}); } //excel判重,数据校验,dto对象转换,存储对象转换,执行保存 List statePoolList = new ArrayList<>(); //当前excel中是否重复用的判重Map:(key:判重属性,value:行号) Map excelReapeat = new HashMap<>(); poList.stream().forEach(osStatusPO -> { try { StatePool dbStatePool = platformClientUtil.getStatePoolService().getStatePool(osStatusPO.getId()); if(Func.isNotEmpty(dbStatePool) && Func.isNotBlank(dbStatePool.oid)){ throw new VciBaseException("第【"+osStatusPO.getRowIndex()+"】行,名称在系统中已经存在,请修改!"); } } catch (PLException e) { e.printStackTrace(); logger.error(e.getMessage()); throw new VciBaseException(VciBaseUtil.getExceptionMessage(e)); } if(Func.isBlank(osStatusPO.getId())){//状态名判空 throw new VciBaseException("第【"+osStatusPO.getRowIndex()+"】行,statusnameerror"); }else if(!osStatusPO.getId().matches("[a-z A-Z]*")){ // 状态池名称只能为英文字母 throw new VciBaseException("名称只能为英文!"); }else if(excelReapeat.containsKey(osStatusPO.getId())){//状态名表格中判重 throw new VciBaseException("第【"+excelReapeat.get(osStatusPO.getId())+"】行和第【"+osStatusPO.getRowIndex()+"】行数据,名称重复"); } //状态名excel中判重处理 excelReapeat.put(osStatusPO.getId(),osStatusPO.getRowIndex()); OsStatusDTO osStatusDTO = new OsStatusDTO(); osStatusDTO.setOid(VciBaseUtil.getPk().toUpperCase(Locale.ROOT)); osStatusDTO.setId(osStatusPO.getId()); osStatusDTO.setName(osStatusPO.getName()); //osStatusDTO.setImagePath(osStatusPO.getImagePath()); osStatusDTO.setDescription(osStatusPO.getDescription()); statePoolList.add(statusDTO2DO(osStatusDTO)); }); //执行保存操作 batchAddStatus(statePoolList); }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("状态导入成功!"); } /** * 状态的显示对象转换为DO对象 * @param statusVO 显示对象 * @return 数据对象 */ public StatePool statusVO2DO(OsStatusVO statusVO){ StatePool statePool = new StatePool(); statePool.oid = statusVO.getOid(); statePool.id = ""; statePool.name = statusVO.getId(); statePool.description = statusVO.getDescription()==null?"":statusVO.getDescription(); String userId = VciBaseUtil.getCurrentUserId(); String now = VciDateUtil.getNowString(VciDateUtil.DateTimeMillFormat); statePool.creator = statusVO.getCreator(); statePool.createTime = VciDateUtil.getTime(statusVO.getCreateTime()); statePool.modifier = statusVO.getLastModifier(); statePool.modifyTime = VciDateUtil.getTime(statusVO.getLastModifyTime()); statePool.ts = statusVO.getTs()==null?now:VciDateUtil.date2Str(statusVO.getTs(),VciDateUtil.DateTimeMillFormat); statePool.tag = statusVO.getName(); return statePool; } }