package com.vci.web.service.impl; import com.vci.client.mw.ClientSessionUtility; import com.vci.corba.common.PLException; import com.vci.corba.omd.stm.StatePool; import com.vci.corba.omd.vrm.VersionRule; import com.vci.dto.OsAttributeDTO; import com.vci.dto.OsRevisionRuleDTO; import com.vci.dto.OsStatusDTO; import com.vci.pagemodel.OsAttributeVO; import com.vci.pagemodel.OsEnumVO; import com.vci.pagemodel.OsStatusVO; import com.vci.po.OsAttributePO; import com.vci.po.OsEnumPO; import com.vci.po.OsRevisionRulePO; 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.BaseResult; import com.vci.starter.web.util.*; import com.vci.pagemodel.OsRevisionRuleVO; import com.vci.web.service.OsRevisionRuleServiceI; 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.awt.*; import java.io.File; import java.util.*; import java.util.List; import java.util.stream.Collectors; /** * 版本规则的服务 * @author weidy * @date 2021-2-15 */ @Service public class OsRevisionRuleServiceImpl implements OsRevisionRuleServiceI { /** * 平台调用客户端 */ @Autowired private PlatformClientUtil platformClientUtil; /** * 加载自身 */ @Autowired(required = false) @Lazy private OsRevisionRuleServiceI self; /** * 日志 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * 必填列 */ private List ColumnNameisRed = new ArrayList(); /** * 查询所有的版本规则 * * @return 版本对象 */ @Override public List selectAllRevision() { try { return revisionRuleDO2VOs(Arrays.stream(platformClientUtil.getVersionService().getVersionRules()).collect(Collectors.toList())); } catch (PLException e) { throw WebUtil.getVciBaseException(e); } } /** * 查询所有的版本规则映射 * * @return key 是版本的英文名称 */ @Override @VciUnLog public Map selectAllRevisionMap() { return Optional.ofNullable(self.selectAllRevision()).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.toMap(s->s.getId().toLowerCase(),t->t,(o1,o2)->o1)); } /** * 创建版本规则 * @param osRevisionRuleDTO * @return */ @Override public boolean addVersionRule(OsRevisionRuleDTO osRevisionRuleDTO) throws PLException { //判空 VciBaseUtil.alertNotNull(osRevisionRuleDTO,"版本规则对象",osRevisionRuleDTO.getId(),"版本规则名称"); //版本规则合规检验 this.checkVersionRule(osRevisionRuleDTO); //查重 VersionRule vr = platformClientUtil.getVersionService().getVersionRule(osRevisionRuleDTO.getId()); //name不为空 if(Func.isNotEmpty(vr) && !"".equals(vr.name)){ throw new PLException("500",new String[]{"名称重复请更换名称!"}); } return platformClientUtil.getVersionService().addVersionRule(this.dto2VersionRule(osRevisionRuleDTO)); } /** * 修改版本规则 * @param osRevisionRuleDTO * @return */ @Override public boolean updateVersionRule(OsRevisionRuleDTO osRevisionRuleDTO) throws PLException { //判空 VciBaseUtil.alertNotNull(osRevisionRuleDTO,"版本规则对象",osRevisionRuleDTO.getId(),"版本规则名称"); //判断是否在系统中存在 VersionRule vr = platformClientUtil.getVersionService().getVersionRule(osRevisionRuleDTO.getName()); //版本规则合规检验 this.checkVersionRule(osRevisionRuleDTO); //name不为空 if(Func.isEmpty(vr) && !"".equals(vr.name)){ throw new PLException("500",new String[]{"修改的版本规则在系统中不存在!"}); } return platformClientUtil.getVersionService().modifyVersionRule(this.dto2VersionRule(osRevisionRuleDTO)); } /** * 删除版本规则 * @param osRevisionRuleDTOS * @return */ @Override public boolean deleteVersionRule(List osRevisionRuleDTOS) throws PLException { VciBaseUtil.alertNotNull(osRevisionRuleDTOS,"待删除的属性列表"); //判断要删除的版本规则是否有被引用 osRevisionRuleDTOS.stream().forEach(item->{ String vrName = item.getId(); try { List> usedVersionRuleList = this.getUsedVersionRuleList(vrName); if(Func.isNotEmpty(usedVersionRuleList)){ throw new VciBaseException("该版本已被使用不允许删除"); } } catch (PLException e) { logger.error(e.getMessage()); e.printStackTrace(); throw new VciBaseException(e.getMessage()); } }); //平台的deleteStatus方法必传三个参数,oid、name和ts List vrList = new ArrayList<>(); for(OsRevisionRuleDTO vrDTO : osRevisionRuleDTOS){ //oid和ts判空 String oid = vrDTO.getOid(); //id主要用来对缓存数据删除 String id = vrDTO.getId(); //后台会用ts进行数据一致性校验 Date ts = vrDTO.getTs(); if(Func.isBlank(oid) || Func.isBlank(id) || Func.isEmpty(ts)){ throw new PLException("500",new String[]{"待删除的版本规则列表中主键【oid】、调整时间【ts】、状态名称【name】不能为空!"}); } VersionRule vr = new VersionRule(); vr.oid = oid; vr.name = id; vr.ts = Func.format(ts,VciDateUtil.DateTimeMillFormat); vrList.add(vr); } return platformClientUtil.getVersionService().deleteVersionRules(vrList.toArray(new VersionRule[vrList.size()])); } /** * 检查版本规则设置的是否合理 * @param dto */ private void checkVersionRule(OsRevisionRuleDTO dto) throws PLException { //版本规则名称只能为英文字母 String regex = "[a-z A-Z]*"; if (!dto.getId().matches(regex)) { throw new PLException("500",new String[]{"名称只能为英文!"}); } //跳跃字符只能为数字或者字母 String regex0 = "^[a-zA-Z0-9,]+$"; if(Func.isNotBlank(dto.getJumpCharacter()) && (!(dto.getJumpCharacter().matches(regex0)))){ throw new PLException("500",new String[]{"跳跃字符只能为数字或者字母!"}); } //初始值不能为空且只能为数字或者字母或英文状态下的符号 String regex1 = "[A-Za-z0-9!@#$%^&*()-_=+{}':|;,.?/]+$"; if(Func.isBlank(dto.getInitialValue()) || !dto.getInitialValue().matches(regex1)){ throw new PLException("500",new String[]{"初始值不能为空且只能为数字或者字母或英文状态下的符号!"}); } if(dto.getInitialValue().length() + dto.getInitialValue().length() > 32) { throw new PLException("500",new String[]{"初始值不能超过32个字符!"}); } //步长不能为空且必须为1-9的正整数 String regex2 = "[1-9]"; if(Func.isBlank(dto.getStepLength()) || (!dto.getStepLength().matches(regex2))){ throw new PLException("500",new String[]{"步长不能为空且必须为1-9的正整数"}); } //前缀相关判断 String regex3 = "^\\s+.*"; if(Func.isNotBlank(dto.getPrefixion()) && (dto.getPrefixion().matches(regex3))){ throw new PLException("500",new String[]{"前缀不能以空格开头"}); } if (Func.isNotBlank(dto.getPrefixion()) && dto.getPrefixion().length() > 32) { throw new PLException("500",new String[]{"前缀不能超过32个字符"}); } //后缀相关判断 String regex4 = "^*.\\s+$"; if(Func.isNotBlank(dto.getSuffix()) && (dto.getSuffix().matches(regex4))){ throw new PLException("500",new String[]{"后缀不能以空格结尾"}); } if (Func.isNotBlank(dto.getSuffix()) && dto.getSuffix().length() > 32) { throw new PLException("500",new String[]{"后缀不能超过32个字符"}); } if (dto.getId().length() > 255) { throw new PLException("500",new String[]{"名称不能超过255个字符"}); } } /** * dto对象转换为VersionRule对象 * @return */ private VersionRule dto2VersionRule(OsRevisionRuleDTO osRevisionRuleDTO){ VersionRule newVR = new VersionRule(); newVR.oid = osRevisionRuleDTO.getOid(); newVR.name = osRevisionRuleDTO.getId(); newVR.tag = osRevisionRuleDTO.getName(); newVR.description = osRevisionRuleDTO.getDescription(); newVR.jumpCharacter = osRevisionRuleDTO.getJumpCharacter(); newVR.initialValue = osRevisionRuleDTO.getInitialValue(); newVR.stepLength = osRevisionRuleDTO.getStepLength(); newVR.prefixion = osRevisionRuleDTO.getPrefixion(); newVR.suffix = osRevisionRuleDTO.getSuffix(); String userName = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId(); long timeMillis = System.currentTimeMillis(); newVR.ts = Func.format((Func.isNotEmpty(osRevisionRuleDTO.getTs()) ? osRevisionRuleDTO.getTs():new Date()),VciDateUtil.DateTimeMillFormat); newVR.creator = Func.isBlank(osRevisionRuleDTO.getCreator()) ? userName:osRevisionRuleDTO.getCreator(); newVR.createTime = Func.isEmpty(osRevisionRuleDTO.getCreateTime()) ? timeMillis:osRevisionRuleDTO.getCreateTime().getTime(); newVR.modifier = userName; newVR.modifyTime = timeMillis; return newVR; } /** * 数据对象转换为显示对象 * * @param versionRules 数据对象 * @return 显示对象 */ @Override public List revisionRuleDO2VOs(Collection versionRules) { List ruleVOS = new ArrayList<>(); Optional.ofNullable(versionRules).orElseGet(()->new ArrayList<>()).stream().forEach(versionRule -> { OsRevisionRuleVO ruleVO = revisionRuleDO2VO(versionRule); ruleVOS.add(ruleVO); }); return ruleVOS; } /** * 数据对象转换为显示对象 * * @param versionRule 数据对象 * @return 显示对象 */ @Override public OsRevisionRuleVO revisionRuleDO2VO(VersionRule versionRule) { OsRevisionRuleVO ruleVO = new OsRevisionRuleVO(); if(versionRule !=null){ ruleVO.setOid(versionRule.oid); ruleVO.setCreator(versionRule.creator); ruleVO.setLastModifier(versionRule.modifier); try { ruleVO.setCreateTime(VciDateUtil.long2Date(versionRule.createTime)); ruleVO.setLastModifyTime(VciDateUtil.long2Date(versionRule.modifyTime)); ruleVO.setTs(VciDateUtil.str2Date(versionRule.ts,VciDateUtil.DateTimeMillFormat)); } catch (Exception e) { e.printStackTrace(); } ruleVO.setDescription(versionRule.description); ruleVO.setId(versionRule.name); ruleVO.setName(versionRule.tag); ruleVO.setStepLength(WebUtil.getInt(versionRule.stepLength)); ruleVO.setJumpCharacter(versionRule.jumpCharacter); ruleVO.setPrefixion(versionRule.prefixion); ruleVO.setSuffix(versionRule.suffix); ruleVO.setInitialValue(versionRule.initialValue); //associated暂时没有使用 } return ruleVO; } /** * 使用编号获取规则的值 * * @param id 编号 * @return 显示对象 */ @Override public OsRevisionRuleVO getRevisionRuleById(String id) { if(StringUtils.isNotBlank(id)){ return self.selectAllRevisionMap().getOrDefault(id.toLowerCase().trim(),null); } return null; } /** * 使用多个编号获取规则的值 * @param vrIdList 编号 * @return 显示对象 */ @Override public List getRevisionRuleByIds(Collection vrIdList) { if(Func.isEmpty(vrIdList)){ return null; } Map revisionRuleVOMap = self.selectAllRevisionMap(); List versionRuleList = new ArrayList<>(); vrIdList.stream().forEach(vrId->{ OsRevisionRuleVO versionRuleVO = revisionRuleVOMap.getOrDefault(vrId.toLowerCase(Locale.ROOT),null); if(versionRuleVO!=null){ versionRuleList.add(versionRuleVO); } }); return versionRuleList; } /** * 查询应用范围 * @param vrName 版本规则英文名称 * @return */ @Override public List> getUsedVersionRuleList(String vrName) throws PLException { if(Func.isBlank(vrName)){ throw new PLException("500",new String[]{"请选择要查询应用范围的属性!"}); } String[] btNames = platformClientUtil.getBtmService().getBTNamesByVerName(vrName); if(Func.isEmpty(btNames)){ return new ArrayList<>(); } List> btmNameMapList = new ArrayList<>(); Arrays.stream(btNames).forEach(btName->{ Map itemMap = new HashMap<>(); itemMap.put("versionRuleName",vrName); itemMap.put("source",btName); btmNameMapList.add(itemMap); }); return btmNameMapList; } /** * 导出选中的版本规则 * @param exportFileName 导出的文件名 * @param vrNames 需要导出的版本规则名称 * @param flag 控制导出的列名是否和导入模板一致 * @return */ @Override public String exportVersionRule(String exportFileName, String vrNames, boolean flag) throws PLException { if(Func.isBlank(vrNames)){ 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 vrIdList = Func.toStrList(vrNames); List revisionRuleVOList = this.getRevisionRuleByIds(vrIdList); if(Func.isEmpty(revisionRuleVOList)){ excelDataList.add(new WriteExcelData(1,1, "根据名称未查询到版本规则信息,请刷新后尝试重新导出!")); }else{ for (int i = 0; i < revisionRuleVOList.size(); i++) { OsRevisionRuleVO revisionRuleVO = revisionRuleVOList.get(i); excelDataList.add(new WriteExcelData(i+1,0, revisionRuleVO.getId())); excelDataList.add(new WriteExcelData(i+1,1, revisionRuleVO.getName())); excelDataList.add(new WriteExcelData(i+1,2, revisionRuleVO.getJumpCharacter())); excelDataList.add(new WriteExcelData(i+1,3, revisionRuleVO.getInitialValue())); excelDataList.add(new WriteExcelData(i+1,4, revisionRuleVO.getStepLength())); excelDataList.add(new WriteExcelData(i+1,5, revisionRuleVO.getPrefixion())); excelDataList.add(new WriteExcelData(i+1,6, revisionRuleVO.getSuffix())); excelDataList.add(new WriteExcelData(i+1,7, revisionRuleVO.getDescription())); if(!flag){ excelDataList.add(new WriteExcelData(i+1,8, Func.format(revisionRuleVO.getCreateTime(),"yyyy年MM月dd日 hh:mm:ss"))); } } } WriteExcelOption excelOption = new WriteExcelOption(excelDataList); ExcelUtil.writeDataToFile(excelPath, excelOption); return excelPath; } /** * 下载版本规则导入模板 * @param exportFileName * @return * @throws PLException */ @Override public String downloadVersionRuleTemplate(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(3); ColumnNameisRed.add(4); //写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 importVersionRules(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, OsRevisionRulePO.class,excelOption,(value, po, fieldName)->{}); //去除都是空的情况 if(CollectionUtils.isEmpty(poList)){ return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{}); } //excel判重,数据校验,dto对象转换,存储对象转换,执行保存 List dtoList = new ArrayList<>(); //当前excel中是否重复用的判重Map:(key:判重版本规则名,value:行号) Map excelReapeat = new HashMap<>(); //数据库查询是否有已存在的枚举名,方便后续做判重处理 List versionRuleVOList = this.getRevisionRuleByIds(poList.stream().map(OsRevisionRulePO::getId).collect(Collectors.toSet())); List repeatVrId = new ArrayList<>(); if(Func.isNotEmpty(versionRuleVOList)){ repeatVrId = versionRuleVOList.stream().map(OsRevisionRuleVO::getId).collect(Collectors.toList()); } //判断必填属性是否为空和其他校验 List finalRepeatVrId = repeatVrId; poList.stream().forEach(vrPO -> { if(Func.isBlank(vrPO.getId())){//版本规则名判空 throw new VciBaseException("第【"+vrPO.getRowIndex()+"】行,versionrulenameerror"); }else if(excelReapeat.containsKey(vrPO.getId())){//版本规则名表格中判重 throw new VciBaseException("第【"+excelReapeat.get(vrPO.getId())+"】行和第【"+vrPO.getRowIndex()+"】行数据,名称重复"); }else if (Func.isNotEmpty(finalRepeatVrId) && finalRepeatVrId.contains(vrPO.getId())){//判断名称是否与系统中重复 throw new VciBaseException("第【"+vrPO.getRowIndex()+"】行,名称在系统中已经存在,请修改!"); } //版本规则名excel中判重处理 excelReapeat.put(vrPO.getId(),vrPO.getRowIndex()); OsRevisionRuleDTO revisionRuleDTO = new OsRevisionRuleDTO(); //revisionRuleDTO.setOid(VciBaseUtil.getPk().toUpperCase(Locale.ROOT)); revisionRuleDTO.setId(vrPO.getId()); revisionRuleDTO.setName(vrPO.getName()); revisionRuleDTO.setJumpCharacter(vrPO.getJumpCharacter()); revisionRuleDTO.setInitialValue(vrPO.getInitialValue()); revisionRuleDTO.setStepLength(vrPO.getStepLength()); revisionRuleDTO.setPrefixion(vrPO.getPrefixion()); revisionRuleDTO.setSuffix(vrPO.getSuffix()); revisionRuleDTO.setDescription(vrPO.getDescription()); try { //检查版本规则是否合规 checkVersionRule(revisionRuleDTO); } catch (PLException e) { e.printStackTrace(); throw new VciBaseException(VciBaseUtil.getExceptionMessage(e)); } dtoList.add(revisionRuleDTO); }); //执行保存操作 dtoList.stream().forEach(dto->{ try { boolean b = platformClientUtil.getVersionService().addVersionRule(dto2VersionRule(dto)); if(!b){ throw new VciBaseException("save and return false"); } } catch (PLException e) { e.printStackTrace(); throw new VciBaseException("执行保存时出现错误,错误版本规则对象名为:【" + dto.getId() + "】,原因:"+VciBaseUtil.getExceptionMessage(e)); } }); }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( "名称", "标签", "跳跃字符", "初始值", "步长", "前缀", "后缀", "描述", "创建时间" ) ); } /** * 清除缓存 */ @Override public void clearCache() { } }