Index: ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/device/service/XinHuaDataManagerImpl.java =================================================================== diff -u -r40924 -r40941 --- ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/device/service/XinHuaDataManagerImpl.java (.../XinHuaDataManagerImpl.java) (revision 40924) +++ ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/device/service/XinHuaDataManagerImpl.java (.../XinHuaDataManagerImpl.java) (revision 40941) @@ -50,15 +50,18 @@ import com.forgon.disinfectsystem.entity.basedatamanager.rinser.Rinser; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizationrecord.SterilizationRecord; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.LowTempSterilizerRecord; +import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.XinhuaCleanH101513; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.SterilizerFileName; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.SterilizerRecord; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.Ps100gxpStageDetails; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.Ps100gxpSterilizerRecord; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.CommonStageDetails; import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.CommonSterilizerRecord; import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData.BelimedV2WashDataPDF; +import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData.XinHuaSuper6000Data; import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData.WashData; import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData.XinHuaDataPDF; +import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData.XinHuaSuper6000Details; import com.forgon.disinfectsystem.entity.washanddisinfectmanager.washanddisinfectrecord.WashAndDisinfectRecord; import com.forgon.disinfectsystem.filemanager.CommonFileManager; import com.forgon.disinfectsystem.filemanager.FtpFileManager; @@ -221,7 +224,7 @@ continue; } } - String cycles = name.split("-")[2].replace(".pdf", ""); + //String cycles = name.split("-")[2].replace(".pdf", ""); // 从PDF文档中提取文本 int index = 0; if(name.contains("WS")){ @@ -230,52 +233,12 @@ index = name.indexOf("ST"); } String machineNumber = name.substring(0, index); + if(!StringUtils.equals(machineNumber, machineNo)){ + continue; + } String ymd = "20" + name.substring(index + 2 , index + 8); - XinHuaDataPDF xinHuaDataPDF = dataRead(smbForm,deviceInterface, remoteType, ftp, ftpFile, enableDetailedDeviceInformation, loginUserData, ymd); - if(xinHuaDataPDF != null){ - xinHuaDataPDF.setMachineNumber(machineNumber); - } - //判断pdf文件是否有效 - if(validateWashDataPDF(xinHuaDataPDF)){ - boolean isParsedFile = isParsedFile(xinHuaDataPDF); - if(isParsedFile){ - logger.debug(name+"该文件已经解析过"); - }else{ - if(name.contains("WS")){ - //更新清洗机的温度压力数据 - Long wdId = washAndDisinfectRecordManager.refreshWashRecordAmounts(deviceInterface, Long.parseLong(cycles), machineNo, xinHuaDataPDF.getStartDate(), 1L, WashAndDisinfectRecord.WASHDATATYPE_XINHUA_WSPDF); - if(DatabaseUtil.isPoIdValid(wdId)){ - xinHuaDataPDF.setRecordId(wdId); - } - }else{ - String beginStartTimeStr = null; - String endStartTimeStr = null; - if(!DeviceInterface.PARAMATCHINGMETHOD_CYCLECOUNTER.equals(deviceInterface.getParaMatchingMethod())){ - Date beginStartTime = new Date(xinHuaDataPDF.getStartDate().getTime() - 10*60*1000); - Date endStartTime = new Date(xinHuaDataPDF.getStartDate().getTime() + 10*60*1000); - beginStartTimeStr = ForgonDateUtils.safelyFormatDate(beginStartTime,ForgonDateUtils.SIMPLEDATEFORMAT_YYYYMMDDHHMMSS,""); - endStartTimeStr = ForgonDateUtils.safelyFormatDate(endStartTime,ForgonDateUtils.SIMPLEDATEFORMAT_YYYYMMDDHHMMSS,""); - } - Long sterilizationRecordId = sterilizationRecordManager.findMatchingSterilizationRecordId(beginStartTimeStr, endStartTimeStr, deviceInterface.getId(), cycles, machineNumber); - if(enableDetailedDeviceInformation){ - appLogManager.saveLog(loginUserData, Log.MODEL_DEVICE_INTERFACE, Log.TYPE_QUERY, String.format("机器号[%s],文件中的循环次数 [%s],需要更新温度压力数据的灭菌记录id[%s]",machineNumber,cycles,sterilizationRecordId)); - } - if(DatabaseUtil.isPoIdValid(sterilizationRecordId)){ - xinHuaDataPDF.setRecordId(sterilizationRecordId); - objectDao.excuteSQL("update "+SterilizationRecord.class.getSimpleName() + " set sterilizationParaType="+SterilizationRecord.STERILIZATIONPARATYPE_XINHUA_PDF - + " where id="+sterilizationRecordId); - } - } - //复制PDF到服务器 - copyFile(smbForm, deviceInterface, remoteType, ftp, ftpFile, enableDetailedDeviceInformation, loginUserData); - } - if(xinHuaDataPDF != null){ - objectDao.saveOrUpdate(xinHuaDataPDF); - } - commonFileManager.moveFile(remoteType, name, ftp, ftpFileManager.getCurrentPath(ftp), backUpPath, session, smbForm,false); - }else{ - logger.debug(name + ",该文件为无效文件"); - } + dataRead(smbForm,deviceInterface, remoteType, ftp, ftpFile, enableDetailedDeviceInformation, loginUserData, ymd, machineNumber); + commonFileManager.moveFile(remoteType, name, ftp, ftpFileManager.getCurrentPath(ftp), backUpPath, session, smbForm,false); } } catch (Exception e) { logger.warn(e.getMessage()); @@ -402,113 +365,306 @@ return false; } - /** - * 检查清洗参数pdf文件记录是否合法 - * @param belimedV2WashDataPDF - * @return - */ - private boolean validateWashDataPDF(XinHuaDataPDF belimedV2WashDataPDF) { - if(belimedV2WashDataPDF == null){ - return false; - } - if(!DatabaseUtil.isPoIdValid(belimedV2WashDataPDF.getDeviceInterfaceID())){ - return false; - } - if(StringUtils.isBlank(belimedV2WashDataPDF.getMachineNumber())){ - return false; - } - if(belimedV2WashDataPDF.getStartDate() == null){ - return false; - } - if(belimedV2WashDataPDF.getCycleCounter() == null){ - return false; - } - if(StringUtils.isBlank(belimedV2WashDataPDF.getFileName())){ - return false; - } - return true; - } -private XinHuaDataPDF dataRead(SmbFile remoteFile, + private void dataRead(SmbFile remoteFile, DeviceInterface deviceInterface, String remoteType, FTPClient ftp, FTPFile ftpFile, boolean enableDetailedDeviceInformation, - LoginUserData loginUserData, String ymd) { + LoginUserData loginUserData, String ymd, String machineNumber) { - InputStream inputStream = null; - ByteArrayOutputStream out = null; - InputStreamReader isr = null; - String fileName = null; - XinHuaDataPDF xinHuaDataPDF = new XinHuaDataPDF(); - PDDocument document = null; - try { - Date da = null; - if(DeviceInterface.INTERFACETYPE_FTP.equals(remoteType)){ - da = ftpFile.getTimestamp().getTime(); - fileName = ftpFile.getName(); - }else{ - da = new Date(); - da.setTime(remoteFile.getDate()); - fileName = remoteFile.getName(); - } - inputStream = commonFileManager.getInputStream(remoteType, ftp, fileName, remoteFile, out,false); - isr = new InputStreamReader(inputStream,"GBK"); - document = PDDocument.load(inputStream); - String cycles = fileName.split("-")[2].replace(".pdf", ""); - // 创建PDFTextStripper对象 - PDFTextStripper pdfStripper = new PDFTextStripper(); - // 从PDF文档中提取文本 - String text = pdfStripper.getText(document); - String regex = "\\d{2}:\\d{2}:\\d{2}"; - String startDateStr = getDateStr(text, regex); - if(StringUtils.isNotBlank(startDateStr)){ - startDateStr = ymd + " "+ startDateStr; - DateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); - Date startTime = sdf.parse(startDateStr); - if(startTime != null){ - xinHuaDataPDF.setFileName(fileName); - xinHuaDataPDF.setDeviceInterfaceID(deviceInterface.getId()); - xinHuaDataPDF.setCycleCounter(Long.parseLong(cycles)); - xinHuaDataPDF.setStartDate(startTime); - } - } - } catch (FileNotFoundException e) { - logger.warn(e.getMessage()); - e.printStackTrace(); - } catch (IOException e) { - logger.warn(e.getMessage()); - e.printStackTrace(); - if(enableDetailedDeviceInformation){ - appLogManager.saveLog(loginUserData, - Log.MODEL_DEVICE_INTERFACE, Log.TYPE_ADD, - deviceInterface.getName() + "设备接口连接异常," + e.getMessage()); - } - } catch(Exception e){ - logger.warn(e.getMessage()); - e.printStackTrace(); - }finally{ - FileSystemHelper.closeInputStream(inputStream, null, isr, out); - if(document != null){ - try { - document.close(); - } catch (IOException e) { - e.printStackTrace(); + InputStream inputStream = null; + ByteArrayOutputStream out = null; + InputStreamReader isr = null; + String fileName = null; + PDDocument document = null; + try { + Date da = null; + if(DeviceInterface.INTERFACETYPE_FTP.equals(remoteType)){ + da = ftpFile.getTimestamp().getTime(); + fileName = ftpFile.getName(); + }else{ + da = new Date(); + da.setTime(remoteFile.getDate()); + fileName = remoteFile.getName(); } + inputStream = commonFileManager.getInputStream(remoteType, ftp, fileName, remoteFile, out,false); + isr = new InputStreamReader(inputStream,"GBK"); + document = PDDocument.load(inputStream); + + String cycles = fileName.split("-")[2].replace(".pdf", ""); + // 创建PDFTextStripper对象 + PDFTextStripper pdfStripper = new PDFTextStripper(); + // 从PDF文档中提取文本 + String text = pdfStripper.getText(document); + System.out.println(text); + //boolean isParsedFile = isParsedFile(xinHuaDataPDF); + /*if(isParsedFile){ + logger.debug(name+"该文件已经解析过"); + }*/ + if(fileName.contains("WS")){ + XinHuaSuper6000Data data = parseText(text); + if(data.getStartDate() == null || StringUtils.isBlank(data.getTotalRunTime())){ + logger.debug(fileName + ",该文件为无效文件"); + return; + } + data.setMachineNumber(machineNumber); + data.setDeviceInterfaceID(deviceInterface.getId()); + long time = data.getStartDate().getTime(); + Date beginStartTime = new Date(time - 10*60*1000); + Date endStartTime = new Date(time + 10*60*1000); + String beginStartTimeStr = ForgonDateUtils.safelyFormatDate(beginStartTime,ForgonDateUtils.SIMPLEDATEFORMAT_YYYYMMDDHHMMSS,""); + String endStartTimeStr = ForgonDateUtils.safelyFormatDate(endStartTime,ForgonDateUtils.SIMPLEDATEFORMAT_YYYYMMDDHHMMSS,""); + String queryString = " and " + dateQueryAdapter.dateAreaSql("po.startDate", beginStartTimeStr, endStartTimeStr, false); + //判断是否已经读取过文件 + String sql = String.format("select count(1) from %s po " + + "where po.deviceInterfaceID = %s " + + "and po.machineNumber = '%s' " + + " and po.runCount= %s " + + queryString, + XinHuaSuper6000Data.class.getSimpleName(), + data.getDeviceInterfaceID(), + data.getMachineNumber(), + data.getRunCount()); + if(objectDao.countBySql(sql) > 0){ + logger.debug(fileName+"该文件已经解析过"); + return; + } + //更新清洗机的温度压力数据 + Long washAndDisinfectRecordId = washAndDisinfectRecordManager.refreshWashRecordAmounts(deviceInterface + , Long.parseLong(cycles), machineNumber + , data.getStartDate(), 1L, WashAndDisinfectRecord.WASHDATATYPE_XINHUA_WSPDF); + if(DatabaseUtil.isPoIdValid(washAndDisinfectRecordId)){ + data.setWashAndDisinfectRecordId(washAndDisinfectRecordId); + } + if(data != null){ + objectDao.saveOrUpdate(data); + } + }else{ + XinhuaCleanH101513 data = SterilizationDataParser.parseText(text); + if(data.getStartDate() == null || StringUtils.isBlank(data.getTotalRunTime())){ + logger.debug(fileName + ",该文件为无效文件"); + return; + } + data.setMachineNumber(machineNumber); + data.setDeviceInterfaceID(deviceInterface.getId()); + + long time = data.getStartDate().getTime(); + Date beginStartTime = new Date(time - 10*60*1000); + Date endStartTime = new Date(time + 10*60*1000); + String beginStartTimeStr = ForgonDateUtils.safelyFormatDate(beginStartTime,ForgonDateUtils.SIMPLEDATEFORMAT_YYYYMMDDHHMMSS,""); + String endStartTimeStr = ForgonDateUtils.safelyFormatDate(endStartTime,ForgonDateUtils.SIMPLEDATEFORMAT_YYYYMMDDHHMMSS,""); + String queryString = " and " + dateQueryAdapter.dateAreaSql("po.startDate", beginStartTimeStr, endStartTimeStr, false); + //判断是否已经读取过文件 + String sql = String.format("select count(1) from %s po " + + "where po.deviceInterfaceID = %s " + + "and po.machineNumber = '%s' " + + " and po.operationCount= %s " + + queryString, + XinhuaCleanH101513.class.getSimpleName(), + data.getDeviceInterfaceID(), + data.getMachineNumber(), + data.getOperationCount()); + if(objectDao.countBySql(sql) > 0){ + logger.debug(fileName+"该文件已经解析过"); + return; + } + + if(DeviceInterface.PARAMATCHINGMETHOD_CYCLECOUNTER.equals(deviceInterface.getParaMatchingMethod())){ + beginStartTimeStr = null; + endStartTimeStr = null; + } + Long sterilizationRecordId = sterilizationRecordManager.findMatchingSterilizationRecordId(beginStartTimeStr, endStartTimeStr, deviceInterface.getId(), cycles, machineNumber); + if(enableDetailedDeviceInformation){ + appLogManager.saveLog(loginUserData, Log.MODEL_DEVICE_INTERFACE, Log.TYPE_QUERY, String.format("机器号[%s],文件中的循环次数 [%s],需要更新温度压力数据的灭菌记录id[%s]",machineNumber,cycles,sterilizationRecordId)); + } + if(DatabaseUtil.isPoIdValid(sterilizationRecordId)){ + data.setSterilizationRecordId(sterilizationRecordId); + objectDao.excuteSQL("update "+SterilizationRecord.class.getSimpleName() + " set sterilizationParaType="+SterilizationRecord.STERILIZATIONPARATYPE_XINHUA_PDF + + " where id="+sterilizationRecordId); + } + if(data != null){ + objectDao.saveOrUpdate(data); + } + } + + } catch (FileNotFoundException e) { + logger.warn(e.getMessage()); + e.printStackTrace(); + } catch (IOException e) { + logger.warn(e.getMessage()); + e.printStackTrace(); + if(enableDetailedDeviceInformation){ + appLogManager.saveLog(loginUserData, + Log.MODEL_DEVICE_INTERFACE, Log.TYPE_ADD, + deviceInterface.getName() + "设备接口连接异常," + e.getMessage()); + } + } catch(Exception e){ + logger.warn(e.getMessage()); + e.printStackTrace(); + }finally{ + FileSystemHelper.closeInputStream(inputStream, null, isr, out); + if(document != null){ + try { + document.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } } - return xinHuaDataPDF; -} -private String getDateStr(String text, String regex){ - if(StringUtils.isBlank(text)){ - return null; + public XinHuaSuper6000Data parseText(String text) { + XinHuaSuper6000Data data = new XinHuaSuper6000Data(); + String[] lines = text.split("\n"); + + // 解析头部信息 + parseHeaderInfo(lines, data); + + // 解析过程数据 + parseXinHuaSuper6000Details(lines, data); + + // 解析尾部信息 + parseFooterInfo(lines, data); + + return data; } - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(text); - String a = null; - while (matcher.find()) { - a = matcher.group(); - break; - } - return a; + + private void parseHeaderInfo(String[] lines, XinHuaSuper6000Data data) { + for (int i = 0; i < Math.min(5, lines.length); i++) { + String line = lines[i].trim(); + + // 解析程序名称、批次等信息 + if (line.contains("程序名称:")) { + Pattern pattern = Pattern.compile("程序名称:([^\\s]+)\\s+批次:([^\\s]+)\\s+锅号-锅次:([^\\s]+)\\s+运行次数:(\\d+)"); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + data.setProgramName(matcher.group(1)); + data.setRunCount(Integer.parseInt(matcher.group(4))); + } + + } + if(line.contains("工作日期")){ + // 定义正则表达式模式 + String datePattern = "工作日期:(\\d{4}-\\d{2}-\\d{2})"; + + // 提取工作日期 + Pattern p3 = Pattern.compile(datePattern); + Matcher m3 = p3.matcher(line); + if (m3.find()) { + data.setWorkDate(m3.group(1)); + } + } + } } + + private void parseXinHuaSuper6000Details(String[] lines, XinHuaSuper6000Data data) { + boolean inDataSection = false; + //List columnHeaders = Arrays.asList("时间", "阶段", "内室温度", "空气温度", "低温水箱温度", "高温水箱温度", "A0值"); + String ymd = data.getWorkDate(); + Date endDate = null; + for (String line : lines) { + String trimmedLine = line.trim(); + + // 检查是否进入数据区域 + if (trimmedLine.contains("时间") && trimmedLine.contains("阶段") && trimmedLine.contains("内室温度")) { + inDataSection = true; + continue; + } + + // 跳过空行和页眉页脚 + if (trimmedLine.isEmpty() || trimmedLine.contains("第") || trimmedLine.contains("页") || trimmedLine.contains("签名")) { + continue; + } + + // 处理数据行 + if (inDataSection && !trimmedLine.contains("时间") && !trimmedLine.contains("阶段")) { + // 使用正则表达式匹配数据行 + Pattern pattern = Pattern.compile("(\\d{2}:\\d{2}:\\d{2})\\s+([^\\s]+(?:\\s[^\\s]+)*?)\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)\\s+([\\d-]+)"); + Matcher matcher = pattern.matcher(trimmedLine); + + if (matcher.find()) { + XinHuaSuper6000Details processData = new XinHuaSuper6000Details(); + String time = matcher.group(1); + processData.setTime(time); + Date thisendDate = null; + try { + thisendDate = DateTools.YMDHMSFORMAT.get().parse(ymd + " " + time); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(data.getStartDate() == null){ + data.setStartDate(thisendDate); + } + if(endDate != null && endDate.after(thisendDate)){//跨天 + Calendar c = Calendar.getInstance(); + c.setTime(thisendDate); + c.add(Calendar.DAY_OF_MONTH, 1); + endDate = c.getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + ymd = sdf.format(endDate); + thisendDate = endDate; + }else{ + endDate = thisendDate; + } + processData.setDateTime(thisendDate); + processData.setStage(matcher.group(2).trim()); + processData.setInnerTemperature(Double.parseDouble(matcher.group(3))); + processData.setAirTemperature(Double.parseDouble(matcher.group(4))); + processData.setLowTempWaterTank(Double.parseDouble(matcher.group(5))); + processData.setHighTempWaterTank(Double.parseDouble(matcher.group(6))); + processData.setA0Value(Integer.parseInt(matcher.group(7))); + + data.getXinHuaSuper6000DetailsList().add(processData); + } + } + + // 检查是否离开数据区域 + if (inDataSection && (trimmedLine.contains("打印时间") || trimmedLine.contains("运行结果"))) { + inDataSection = false; + } + } + data.setEndDate(endDate); +} + + private void parseFooterInfo(String[] lines, XinHuaSuper6000Data data) { + for (int i = lines.length - 5; i < lines.length; i++) { + if (i >= 0) { + String line = lines[i].trim(); + + // 解析总运行时间和A0值 + //38分49秒 正常结束运行结果:总运行时间:A0值:4771 + if (line.contains("总运行时间")) { + + if(line.contains("A0值:")){ + String[] parts = line.split("A0值:"); + if (parts.length >= 2) { + // 提取A0值 + line = parts[0]; + String a0Value = parts[1].trim(); + try { + data.setA0Value(Integer.parseInt(a0Value)); + } catch (NumberFormatException e) { + // 忽略转换错误 + } + } + } + // 提取运行时间 + if (line.contains("秒")) { + int end = line.indexOf("秒") + 1; + data.setTotalRunTime(line.substring(0, end)); + }else if(line.contains("分")){//只有分没有秒 + int end = line.indexOf("分") + 1; + data.setTotalRunTime(line.substring(0, end)); + } + line = line.replace(data.getTotalRunTime(), StringUtils.EMPTY); + line = line.replace("运行结果:", StringUtils.EMPTY); + line = line.replace("总运行时间:", StringUtils.EMPTY); + if(StringUtils.isNotBlank(line)){ + data.setRunResult(line.trim()); + } + } + } + } +} + /** * 读取保存新华 PS-100GXP数据 * @param devInterface 设备接口 Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/sterilizationmanager/sterilizerrecord/XinhuaCleanH101513.java =================================================================== diff -u --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/sterilizationmanager/sterilizerrecord/XinhuaCleanH101513.java (revision 0) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/sterilizationmanager/sterilizerrecord/XinhuaCleanH101513.java (revision 40941) @@ -0,0 +1,170 @@ +package com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.Cascade; +import org.hibernate.annotations.CascadeType; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +@Entity +@DynamicInsert(false) +@DynamicUpdate(true) +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +public class XinhuaCleanH101513 { + + private Long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + /** + * 程序名称 - 灭菌程序的具体名称 + * 示例: "P04 常规器械"、"B03 织物灭菌" + */ + private String programName; + /** + * 机器号 + */ + private String machineNumber; + private Long deviceInterfaceID; + + /** + * 运转次数 - 该灭菌锅的总运行次数 + * 示例: 191 (表示第191次运行) + */ + private int operationCount; + + /** + * 总运行时间 - 从开始到结束的总耗时 + * 格式: "XX分XX秒",示例: "73分13秒" + */ + private String totalRunTime; + + + /** + * 灭菌运行时间 + * 单位: 秒,示例: 300 (表示5分钟) + */ + private int sterilizationRunTime; + + /** + * 灭菌压力 - 灭菌阶段的目标压力值(kPa) + * 单位: 千帕(kPa),示例: 212.0 + */ + private double sterilizationPressure; + + /** + * 灭菌日期 - 灭菌操作执行的日期 + * 格式: "YYYY-MM-DD",示例: "2025-07-15" + */ + private String sterilizationDate; + + /** + * 开始时间 - 灭菌程序开始的详细时间戳 + * 格式: Date对象,包含年月日时分秒 + * 示例: 2025-07-15 13:16:38 + */ + private Date startDate; + + /** + * 结束时间 - 灭菌程序结束的详细时间戳 + * 格式: Date对象,包含年月日时分秒 + * 示例: 2025-07-15 14:29:50 + */ + private Date endDate; + + public Date getStartDate() { + return startDate; + } + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + public Date getEndDate() { + return endDate; + } + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + /** + * 阶段详情信息 + */ + private List xinhuaCleanH101513DetailsList = new ArrayList(); + + Map stageNameMap = new HashMap(); + @OneToMany(fetch = FetchType.LAZY) + @Cascade(value = { CascadeType.ALL }) + @JoinColumn(name = "xinhuaCleanH101513Id") + @OrderBy(" id asc ") + public List getXinhuaCleanH101513DetailsList() { + return xinhuaCleanH101513DetailsList; + } + + public void setXinhuaCleanH101513DetailsList(List xinhuaCleanH101513DetailsList) { + this.xinhuaCleanH101513DetailsList = xinhuaCleanH101513DetailsList; + } + + // 结果信息 + private String runResult; + /** + * 对应的灭菌记录 + */ + private Long sterilizationRecordId; + + public Long getSterilizationRecordId() { + return sterilizationRecordId; + } + public void setSterilizationRecordId(Long sterilizationRecordId) { + this.sterilizationRecordId = sterilizationRecordId; + } + // getters and setters for main class + public String getProgramName() { return programName; } + public void setProgramName(String programName) { this.programName = programName; } + public int getOperationCount() { return operationCount; } + public void setOperationCount(int operationCount) { this.operationCount = operationCount; } + public String getTotalRunTime() { return totalRunTime; } + public void setTotalRunTime(String totalRunTime) { this.totalRunTime = totalRunTime; } + public double getSterilizationPressure() { return sterilizationPressure; } + public void setSterilizationPressure(double sterilizationPressure) { this.sterilizationPressure = sterilizationPressure; } + public String getSterilizationDate() { return sterilizationDate; } + public void setSterilizationDate(String sterilizationDate) { this.sterilizationDate = sterilizationDate; } + public String getRunResult() { return runResult; } + public void setRunResult(String runResult) { this.runResult = runResult; } + public int getSterilizationRunTime() { + return sterilizationRunTime; + } + public void setSterilizationRunTime(int sterilizationRunTime) { + this.sterilizationRunTime = sterilizationRunTime; + } + public String getMachineNumber() { + return machineNumber; + } + public void setMachineNumber(String machineNumber) { + this.machineNumber = machineNumber; + } + public Long getDeviceInterfaceID() { + return deviceInterfaceID; + } + public void setDeviceInterfaceID(Long deviceInterfaceID) { + this.deviceInterfaceID = deviceInterfaceID; + } + +} Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/washanddisinfectmanager/washData/XinHuaSuper6000Data.java =================================================================== diff -u --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/washanddisinfectmanager/washData/XinHuaSuper6000Data.java (revision 0) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/washanddisinfectmanager/washData/XinHuaSuper6000Data.java (revision 40941) @@ -0,0 +1,171 @@ +package com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.Cascade; +import org.hibernate.annotations.CascadeType; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +/** + * 新华清洗参数 + * 型号 super6000 + * FSEYEQ-26 + * + */ +@Entity +@DynamicInsert(false) +@DynamicUpdate(true) +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +public class XinHuaSuper6000Data { + private Long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + // 头部信息 + /** + * 程序名称 - 清洗程序的具体名称和类型 + * 示例: "器皿器具"、"手术器械"、"玻璃器皿" + * 用于标识本次清洗的物品种类和对应的清洗程序 + */ + private String programName; + /** + * 机器号 + */ + private String machineNumber; + private Long deviceInterfaceID; + /** + * 运行次数 - 该清洗机的总运行次数 + * 示例: 59 (表示第59次运行) + * 用于设备使用寿命统计和预防性维护 + */ + private int runCount; + /** + * 工作日期 + * 主要用来当成文件的年月日 + */ + private String workDate; + + // ==================== 运行结果信息 ==================== + + /** + * 总运行时间 - 从开始到结束的总耗时 + * 格式: "XX分XX秒",示例: "38分49秒" + * 包含清洗、消毒、干燥全过程的实际耗时 + */ + private String totalRunTime; + + /** + * A0值 - 消毒效果的关键评估指标 + * 示例: 4771 + * A0值 ≥ 600 表示消毒效果合格,值越大消毒效果越好 + * 计算公式: A0 = ∫10^((T-80)/z) dt,其中z=10 + */ + private int a0Value; + + /** + * 运行结果 - 清洗消毒程序的最终执行状态 + * 示例: "正常结束"、"异常结束"、"中断"、"故障" + * 用于判断本次运行是否成功完成 + */ + private String runResult; + + /** + * 开始时间 - 清洗程序开始的详细时间戳 + * 格式: Date对象,包含年月日时分秒 + * 示例: 2025-07-15 15:22:36 + * 用于精确的时间追溯和过程分析 + */ + private Date startDate; + + /** + * 结束时间 - 清洗程序结束的详细时间戳 + * 格式: Date对象,包含年月日时分秒 + * 示例: 2025-07-15 16:01:20 + * 用于计算实际运行时间和效率分析 + */ + private Date endDate; + + public Date getStartDate() { + return startDate; + } + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + public Date getEndDate() { + return endDate; + } + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + /** + * 清洗记录id + */ + private Long washAndDisinfectRecordId; + + public Long getWashAndDisinfectRecordId() { + return washAndDisinfectRecordId; + } + public void setWashAndDisinfectRecordId(Long washAndDisinfectRecordId) { + this.washAndDisinfectRecordId = washAndDisinfectRecordId; + } + private List xinHuaSuper6000DetailsList = new ArrayList(); + @OneToMany(fetch = FetchType.LAZY) + @Cascade(value = { CascadeType.ALL }) + @JoinColumn(name = "washDataRecordId") + @OrderBy(" time asc ") + public List getXinHuaSuper6000DetailsList() { + return xinHuaSuper6000DetailsList; + } + public void setXinHuaSuper6000DetailsList( + List xinHuaSuper6000DetailsList) { + this.xinHuaSuper6000DetailsList = xinHuaSuper6000DetailsList; + } + // getters and setters for main class + public String getProgramName() { return programName; } + public void setProgramName(String programName) { this.programName = programName; } + public int getRunCount() { return runCount; } + public void setRunCount(int runCount) { this.runCount = runCount; } + public String getTotalRunTime() { return totalRunTime; } + public void setTotalRunTime(String totalRunTime) { this.totalRunTime = totalRunTime; } + public int getA0Value() { return a0Value; } + public void setA0Value(int a0Value) { this.a0Value = a0Value; } + public String getRunResult() { return runResult; } + public void setRunResult(String runResult) { this.runResult = runResult; } + public String getWorkDate() { + return workDate; + } + public void setWorkDate(String workDate) { + this.workDate = workDate; + } + public String getMachineNumber() { + return machineNumber; + } + public void setMachineNumber(String machineNumber) { + this.machineNumber = machineNumber; + } + public Long getDeviceInterfaceID() { + return deviceInterfaceID; + } + public void setDeviceInterfaceID(Long deviceInterfaceID) { + this.deviceInterfaceID = deviceInterfaceID; + } + +} \ No newline at end of file Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/sterilizationmanager/sterilizerrecord/XinhuaCleanH101513Details.java =================================================================== diff -u --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/sterilizationmanager/sterilizerrecord/XinhuaCleanH101513Details.java (revision 0) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/sterilizationmanager/sterilizerrecord/XinhuaCleanH101513Details.java (revision 40941) @@ -0,0 +1,63 @@ +package com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +@Entity +@DynamicInsert(false) +@DynamicUpdate(true) +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +public class XinhuaCleanH101513Details { + private Long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + private String time; + private Date dateTime; + private String stage; + private double innerPressure; + private double innerTemperature; + private double interlayerPressure; + private double interlayerTemperature; + private Long xinhuaCleanH101513Id; + + public Long getXinhuaCleanH101513Id() { + return xinhuaCleanH101513Id; + } + public void setXinhuaCleanH101513Id(Long xinhuaCleanH101513Id) { + this.xinhuaCleanH101513Id = xinhuaCleanH101513Id; + } + + public Date getDateTime() { + return dateTime; + } + public void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } + public String getTime() { return time; } + public void setTime(String time) { this.time = time; } + public String getStage() { return stage; } + public void setStage(String stage) { this.stage = stage; } + public double getInnerPressure() { return innerPressure; } + public void setInnerPressure(double innerPressure) { this.innerPressure = innerPressure; } + public double getInnerTemperature() { return innerTemperature; } + public void setInnerTemperature(double innerTemperature) { this.innerTemperature = innerTemperature; } + public double getInterlayerPressure() { return interlayerPressure; } + public void setInterlayerPressure(double interlayerPressure) { this.interlayerPressure = interlayerPressure; } + public double getInterlayerTemperature() { return interlayerTemperature; } + public void setInterlayerTemperature(double interlayerTemperature) { this.interlayerTemperature = interlayerTemperature; } + +} Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/washanddisinfectmanager/washData/XinHuaSuper6000Details.java =================================================================== diff -u --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/washanddisinfectmanager/washData/XinHuaSuper6000Details.java (revision 0) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/washanddisinfectmanager/washData/XinHuaSuper6000Details.java (revision 40941) @@ -0,0 +1,66 @@ +package com.forgon.disinfectsystem.entity.washanddisinfectmanager.washData; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +@Entity +@DynamicInsert(false) +@DynamicUpdate(true) +@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) +public class XinHuaSuper6000Details { + private Long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + private String time; + private Date dateTime; + private String stage; + private double innerTemperature; + private double airTemperature; + private double lowTempWaterTank; + private double highTempWaterTank; + private int a0Value; + private Long washDataRecordId; + // getters and setters + public String getTime() { return time; } + public void setTime(String time) { this.time = time; } + + public Date getDateTime() { + return dateTime; + } + public void setDateTime(Date dateTime) { + this.dateTime = dateTime; + } + public String getStage() { return stage; } + public void setStage(String stage) { this.stage = stage; } + public double getInnerTemperature() { return innerTemperature; } + public void setInnerTemperature(double innerTemperature) { this.innerTemperature = innerTemperature; } + public double getAirTemperature() { return airTemperature; } + public void setAirTemperature(double airTemperature) { this.airTemperature = airTemperature; } + public double getLowTempWaterTank() { return lowTempWaterTank; } + public void setLowTempWaterTank(double lowTempWaterTank) { this.lowTempWaterTank = lowTempWaterTank; } + public double getHighTempWaterTank() { return highTempWaterTank; } + public void setHighTempWaterTank(double highTempWaterTank) { this.highTempWaterTank = highTempWaterTank; } + public int getA0Value() { return a0Value; } + public void setA0Value(int a0Value) { this.a0Value = a0Value; } + public Long getWashDataRecordId() { + return washDataRecordId; + } + public void setWashDataRecordId(Long washDataRecordId) { + this.washDataRecordId = washDataRecordId; + } + +} Index: ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/device/service/SterilizationDataParser.java =================================================================== diff -u --- ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/device/service/SterilizationDataParser.java (revision 0) +++ ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/device/service/SterilizationDataParser.java (revision 40941) @@ -0,0 +1,201 @@ +package com.forgon.disinfectsystem.maintain.device.service; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.XinhuaCleanH101513; +import com.forgon.disinfectsystem.entity.sterilizationmanager.sterilizerrecord.XinhuaCleanH101513Details; +import com.forgon.tools.date.DateTools; + +public class SterilizationDataParser { + public static XinhuaCleanH101513 parseText(String text) { + XinhuaCleanH101513 data = new XinhuaCleanH101513(); + + String[] lines = text.split("\n"); + + // 先预处理文本,合并可能被拆散的行 + List processedLines = preprocessLines(lines); + + // 解析所有信息 + parseAllInfo(processedLines, data); + + return data; + } + + private static List preprocessLines(String[] lines) { + List result = new ArrayList<>(); + StringBuilder currentLine = new StringBuilder(); + + for (String line : lines) { + String trimmedLine = line.trim(); + if (trimmedLine.isEmpty()) continue; + + // 如果当前行以时间开头(如13:16:38),则是新数据行 + if (trimmedLine.matches("^\\d{2}:\\d{2}:\\d{2}.*")) { + if (currentLine.length() > 0) { + result.add(currentLine.toString()); + currentLine = new StringBuilder(); + } + currentLine.append(trimmedLine); + } + // 如果当前行包含关键信息(如程序名称、灭菌日期等) + else if (trimmedLine.matches(".*[::].*") || + trimmedLine.contains("程序名称") || + trimmedLine.contains("灭菌批次") || + trimmedLine.contains("运转次数") || + trimmedLine.contains("灭菌日期") || + trimmedLine.contains("打印时间")) { + if (currentLine.length() > 0) { + result.add(currentLine.toString()); + currentLine = new StringBuilder(); + } + result.add(trimmedLine); + } + // 否则可能是被拆散的行,继续拼接 + else { + currentLine.append(" ").append(trimmedLine); + } + } + + if (currentLine.length() > 0) { + result.add(currentLine.toString()); + } + + return result; + } + public static void main(String[] args) { + String input = "灭菌维持阶段最高温度:135.6℃ 灭菌维持阶段最低温度:135.3℃ 灭菌运行时间:300秒"; + + // 匹配数字后跟"秒"的模式 + Pattern pattern = Pattern.compile("灭菌运行时间[::]\\s*([^\\s]+)秒"); + Matcher matcher = pattern.matcher(input); + String a = null; + if (matcher.find()) { + System.out.println(matcher.group(1)); + } + } + private static void parseAllInfo(List lines, XinhuaCleanH101513 data) { + // 匹配时间格式的数据行:13:16:38 准备 0.4 88.4 214.6 134.8 + Pattern dataPattern = Pattern.compile( + "(\\d{2}:\\d{2}:\\d{2})\\s+([^\\s]+(?:\\s[^\\s]+)*)\\s+([\\d.-]+)\\s+([\\d.-]+)\\s+([\\d.-]+)\\s+([\\d.-]+)"); + + Date endDate = null; + String ymd = null; + for (String line : lines) { + if(StringUtils.isBlank(data.getSterilizationDate())){ + Pattern pattern = Pattern.compile("([\\d]{4}-[\\d]{2}-[\\d]{2})"); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + data.setSterilizationDate(matcher.group(1)); + ymd = data.getSterilizationDate(); + continue; + } + } + // 解析过程数据行 + + Matcher matcher = dataPattern.matcher(line); + + if (matcher.find() && matcher.groupCount() >= 6) { + XinhuaCleanH101513Details processData = new XinhuaCleanH101513Details(); + + + String time = matcher.group(1); + processData.setTime(time); + Date thisendDate = null; + try { + thisendDate = DateTools.YMDHMSFORMAT.get().parse(ymd + " " + time); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if(data.getStartDate() == null){ + data.setStartDate(thisendDate); + } + if(endDate != null && endDate.after(thisendDate)){//跨天 + Calendar c = Calendar.getInstance(); + c.setTime(thisendDate); + c.add(Calendar.DAY_OF_MONTH, 1); + endDate = c.getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + ymd = sdf.format(endDate); + thisendDate = endDate; + }else{ + endDate = thisendDate; + } + processData.setTime(time); + processData.setDateTime(thisendDate); + processData.setStage(matcher.group(2).trim()); + processData.setInnerPressure(Double.parseDouble(matcher.group(3))); + processData.setInnerTemperature(Double.parseDouble(matcher.group(4))); + processData.setInterlayerPressure(Double.parseDouble(matcher.group(5))); + processData.setInterlayerTemperature(Double.parseDouble(matcher.group(6))); + processData.setXinhuaCleanH101513Id(data.getId()); + data.getXinhuaCleanH101513DetailsList().add(processData); + continue; + } + + + // 解析程序名称 + if (line.contains("程序名称")) { + extractValue(line, "程序名称[::]\\s*([^\\s]+\\s+[^\\s]+)", data::setProgramName); + } + + //灭菌批次混乱在灭菌时间中间 + /*if (line.contains("灭菌时间")) {//灭菌时间: 3ST250715-1-191 300秒 + // 匹配数字后跟"秒"的模式 + Pattern pattern = Pattern.compile("(\\d+)秒"); + Matcher matcher1 = pattern.matcher(line); + if (matcher1.find()) { + int sterilizationTime = Integer.parseInt(matcher1.group(1)); + data.setSterilizationTime(sterilizationTime); + line = line.replace(data.getSterilizationTime() + "", StringUtils.EMPTY); + } + line = line.replace("灭菌时间", StringUtils.EMPTY); + line = line.replace(":", StringUtils.EMPTY); + line = line.replace(":", StringUtils.EMPTY); + line = line.replace("秒", StringUtils.EMPTY); + data.setSterilizationBatch(line.trim()); + }*/ + if (line.contains("灭菌运行时间")) { + extractValue(line, "灭菌运行时间[::]\\s*([^\\s]+)秒", value -> + data.setSterilizationRunTime(Integer.parseInt(value))); + } + // 解析运转次数 + if (line.contains("运转次数")) { + extractValue(line, "运转次数[::]\\s*(\\d+)次", value -> + data.setOperationCount(Integer.parseInt(value))); + } + + // 解析总运行时间 + if (line.contains("总运行时间")) { + extractValue(line, "总运行时间[::]\\s*([^\\s]+)", data::setTotalRunTime); + } + + // 解析运行结果 + if (line.contains("运行结果")) { + extractValue(line, "运行结果[::]\\s*([^\\s]+)", data::setRunResult); + } + + } + data.setEndDate(endDate); + } + + // 通用的值提取方法 + private static void extractValue(String line, String patternStr, java.util.function.Consumer setter) { + Pattern pattern = Pattern.compile(patternStr); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + setter.accept(matcher.group(1)); + } + } + + +} \ No newline at end of file