Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/supplyroomconfig/SupplyRoomConfig.java =================================================================== diff -u -r36001 -r36111 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/supplyroomconfig/SupplyRoomConfig.java (.../SupplyRoomConfig.java) (revision 36001) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/supplyroomconfig/SupplyRoomConfig.java (.../SupplyRoomConfig.java) (revision 36111) @@ -544,6 +544,16 @@ */ private String instrumentRepairRemindOrgUnitNames; + /** + * 器械包拍摄图片/视频保留时长(天)(DGKHYY-29) + */ + private Integer tousseCamImgVidRetentionTime; + + /** + * 外来器械包拍摄图片/视频保留时长(DGKHYY-29) + */ + private Integer ftCamImgVidRetentionTime; + @Id @GeneratedValue(strategy = GenerationType.AUTO) public Long getId() { @@ -1491,4 +1501,20 @@ this.instrumentRepairRemindOrgUnitNames = instrumentRepairRemindOrgUnitNames; } + public Integer getTousseCamImgVidRetentionTime() { + return tousseCamImgVidRetentionTime; + } + + public void setTousseCamImgVidRetentionTime(Integer tousseCamImgVidRetentionTime) { + this.tousseCamImgVidRetentionTime = tousseCamImgVidRetentionTime; + } + + public Integer getFtCamImgVidRetentionTime() { + return ftCamImgVidRetentionTime; + } + + public void setFtCamImgVidRetentionTime(Integer ftCamImgVidRetentionTime) { + this.ftCamImgVidRetentionTime = ftCamImgVidRetentionTime; + } + } Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/imagefilemanager/service/ImageFileManager.java =================================================================== diff -u -r35539 -r36111 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/imagefilemanager/service/ImageFileManager.java (.../ImageFileManager.java) (revision 35539) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/imagefilemanager/service/ImageFileManager.java (.../ImageFileManager.java) (revision 36111) @@ -186,4 +186,9 @@ * @return */ public JSONObject getImageAndVideoInfoByTousseItemId(Long invoicePlanId, Long tousseId); + + /** + * 定时删除图片 + */ + public void timingDeleteImageFile(); } Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/videomanager/service/VideoFileManagerImpl.java =================================================================== diff -u -r34904 -r36111 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/videomanager/service/VideoFileManagerImpl.java (.../VideoFileManagerImpl.java) (revision 34904) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/videomanager/service/VideoFileManagerImpl.java (.../VideoFileManagerImpl.java) (revision 36111) @@ -7,7 +7,10 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; +import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -27,8 +30,11 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; import org.hibernate.Query; import org.hibernate.Session; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; import ws.schild.jave.AudioAttributes; import ws.schild.jave.Encoder; @@ -38,20 +44,28 @@ import ws.schild.jave.ScreenExtractor; import ws.schild.jave.VideoAttributes; +import com.forgon.databaseadapter.service.DateQueryAdapter; import com.forgon.directory.acegi.tools.AcegiHelper; +import com.forgon.directory.vo.LoginUserData; import com.forgon.disinfectsystem.basedatamanager.supplyroomconfig.service.SupplyRoomConfigManager; import com.forgon.disinfectsystem.datamodifyrecord.service.DataModifyRecordManager; +import com.forgon.disinfectsystem.entity.basedatamanager.imagefilemanager.ImageFile; import com.forgon.disinfectsystem.entity.basedatamanager.supplyroomconfig.SupplyRoomConfig; +import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseDefinition; +import com.forgon.disinfectsystem.entity.basedatamanager.toussedefinition.TousseInstance; import com.forgon.disinfectsystem.entity.basedatamanager.videomanager.VideoFile; import com.forgon.disinfectsystem.entity.datamodifyrecord.DataModifyRecord; import com.forgon.disinfectsystem.entity.recyclingrecord.RecyclingItem; import com.forgon.disinfectsystem.exception.DataCheckException; +import com.forgon.log.model.Log; import com.forgon.tools.StrutsResponseUtils; import com.forgon.tools.date.DateTools; import com.forgon.tools.db.DatabaseUtil; +import com.forgon.tools.db.InitDbConnection; import com.forgon.tools.hibernate.ObjectDao; import com.forgon.tools.json.JSONUtil; import com.forgon.tools.string.StringTools; +import com.forgon.tools.util.ConfigUtils; import com.forgon.tools.util.SqlUtils; public class VideoFileManagerImpl implements VideoFileManager { @@ -61,6 +75,23 @@ private DataModifyRecordManager dataModifyRecordManager; + private DateQueryAdapter dateQueryAdapter; + + private JdbcTemplate jdbcTemplate; + + private InitDbConnection dbConnection; + + private final Logger logger = Logger.getLogger(this.getClass()); + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + public void setDbConnection(InitDbConnection dbConnection) { + this.dbConnection = dbConnection; + } + public void setDateQueryAdapter(DateQueryAdapter dateQueryAdapter) { + this.dateQueryAdapter = dateQueryAdapter; + } public void setDataModifyRecordManager( DataModifyRecordManager dataModifyRecordManager) { this.dataModifyRecordManager = dataModifyRecordManager; @@ -397,19 +428,9 @@ String videoDir = supplyRoomConfig.getSaveImagePath(); String realPath = ""; for (VideoFile videoFile : videoFileList) { - String videoType = videoFile.getVideoType(); - if (VideoFile.VIDEO_TYPE_TOUSSE.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_TOUSSE; - }else if (VideoFile.VIDEO_TYPE_TOUSSE_WASH_TEACHING.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_TOUSSE_WASH_TEACHING; - } else if (VideoFile.VIDEO_TYPE_CAMERA_APPLICATION.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_CAMERA_APPLICATION; - } else if (VideoFile.VIDEO_TYPE_CAMERA_PACKING.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_CAMERA_PACKING; - } else if(VideoFile.VIDEO_TYPE_CAMERA_RECYCLING.equals(videoType)){ - realPath = videoDir + VideoFile.VIDEO_PATH_CAMERA_RECYCLING; - } + realPath = videoFile.loadVideoFileRealPath(); if (StringUtils.isNotBlank(realPath)) { + realPath = videoDir + realPath; deleteLocalFile(videoFile.getUuid_videoName(), realPath); } } @@ -427,21 +448,12 @@ if (videoFile != null) { SupplyRoomConfig supplyRoomConfig = supplyRoomConfigManager.getSystemParamsObj(); String videoDir = supplyRoomConfig.getSaveImagePath(); - String realPath = ""; + String realPath = videoFile.loadVideoFileRealPath(); String videoType = videoFile.getVideoType(); - if (VideoFile.VIDEO_TYPE_TOUSSE.equals(videoFile.getVideoType())) { - realPath = videoDir + VideoFile.VIDEO_PATH_TOUSSE; - } else if (VideoFile.VIDEO_TYPE_TOUSSE_WASH_TEACHING.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_TOUSSE_WASH_TEACHING; - } else if (VideoFile.VIDEO_TYPE_CAMERA_APPLICATION.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_CAMERA_APPLICATION; - } else if (VideoFile.VIDEO_TYPE_CAMERA_PACKING.equals(videoType)) { - realPath = videoDir + VideoFile.VIDEO_PATH_CAMERA_PACKING; - } else if(VideoFile.VIDEO_TYPE_CAMERA_RECYCLING.equals(videoType)){ - realPath = videoDir + VideoFile.VIDEO_TYPE_CAMERA_RECYCLING; - }else { + if(StringUtils.isBlank(realPath)){ throw new RuntimeException("参数异常!"); } + realPath = videoDir + realPath; deleteVideo(videoFile.getObjectId(), videoFile.getUuid_videoName(), realPath); // 重新设置顺序号 List videoList = null; @@ -687,6 +699,8 @@ return videoDir + VideoFile.VIDEO_PATH_CAMERA_PACKING; } else if(VideoFile.VIDEO_TYPE_CAMERA_RECYCLING.equals(videoType)){ return videoDir + VideoFile.VIDEO_PATH_CAMERA_RECYCLING; + } else if(VideoFile.VIDEO_TYPE_TOUSSE_PACKING_NOTE.equals(videoType)){ + return videoDir + VideoFile.VIDEO_PATH_TOUSSE_PACKING_NOTE; } else { throw new DataCheckException("视频类型参数异常"); } @@ -737,4 +751,269 @@ } return resultArr; } + + @SuppressWarnings("unchecked") + @Override + public void timingDeleteVideoFile() { + logger.debug("定时清理拍摄功能所产生的视频"); + boolean showCameraPhoto = ConfigUtils.getSystemSetConfigByNameBool("showCameraPhoto"); + if(!showCameraPhoto){ + logger.debug("showCameraPhoto = false"); + return; + } + SupplyRoomConfig supplyRoomConfig = (SupplyRoomConfig) objectDao.getByProperty( + SupplyRoomConfig.class.getSimpleName(), "supplyRoomType", + SupplyRoomConfig.SUPPLYROOM_TYPE_SYSTEM_CONFIG); + if(supplyRoomConfig == null){ + logger.debug("科室供应室设置为空!"); + return; + } + List deleteVideoList = new ArrayList(); + Integer ftCamImgVidRetentionTime = supplyRoomConfig.getFtCamImgVidRetentionTime(); + if(ftCamImgVidRetentionTime != null + && ftCamImgVidRetentionTime.intValue() > 0 + && ftCamImgVidRetentionTime.intValue() <= 100000){ + //删除外来器械拍摄的视频 + Date lastUploadDate = DateTools.addDate(new Date(), -ftCamImgVidRetentionTime); + //查询申请采集视频 + String applicationVideoSql = String.format("select po.id from %s po " + + "join %s td on po.objectId = td.id " + + "where po.videoType = '%s' " + + "and td.tousseType = '%s' " + + "and po.uploadDateTime <= %s ", + VideoFile.class.getSimpleName(), + TousseDefinition.class.getSimpleName(), + VideoFile.VIDEO_TYPE_CAMERA_APPLICATION, + TousseDefinition.PACKAGE_TYPE_FOREIGN, + dateQueryAdapter.dateAdapter(lastUploadDate)); + List applicationVideoIdList = searchIdBySql(applicationVideoSql); + if(CollectionUtils.isNotEmpty(applicationVideoIdList)){ + logger.debug("外来器械" + VideoFile.VIDEO_TYPE_CAMERA_APPLICATION + "数量:" + applicationVideoIdList.size()); + List applicationVideoList = objectDao.findByIds(VideoFile.class.getSimpleName(), applicationVideoIdList); + deleteVideoList.addAll(applicationVideoList); + } + //查询装配采集视频 + String packingVideoSql = String.format("select po.id from %s po " + + "join %s ti on po.objectId = ti.id " + + "join %s td on ti.tousseDefinition_id = td.id " + + "where po.videoType = '%s' " + + "and td.tousseType in ('%s','%s') " + + "and po.uploadDateTime <= %s ", + VideoFile.class.getSimpleName(), + TousseInstance.class.getSimpleName(), + TousseDefinition.class.getSimpleName(), + VideoFile.VIDEO_TYPE_CAMERA_PACKING, + TousseDefinition.PACKAGE_TYPE_FOREIGN, + TousseDefinition.PACKAGE_TYPE_SPLIT, + dateQueryAdapter.dateAdapter(lastUploadDate)); + List packingVideoIdList = searchIdBySql(packingVideoSql); + if(CollectionUtils.isNotEmpty(packingVideoIdList)){ + logger.debug("外来器械" + VideoFile.VIDEO_TYPE_CAMERA_PACKING + "数量:" + applicationVideoIdList.size()); + List packingVideoList = objectDao.findByIds(VideoFile.class.getSimpleName(), packingVideoIdList); + deleteVideoList.addAll(packingVideoList); + } + } + Integer tousseCamImgVidRetentionTime = supplyRoomConfig.getTousseCamImgVidRetentionTime(); + if(tousseCamImgVidRetentionTime != null + && tousseCamImgVidRetentionTime.intValue() > 0 + && tousseCamImgVidRetentionTime.intValue() <= 100000){ + Date lastUploadDate = DateTools.addDate(new Date(), -tousseCamImgVidRetentionTime); + //查询装配采集视频 + String packingVideoSql = String.format("select po.id from %s po " + + "join %s ti on po.objectId = ti.id " + + "join %s td on ti.tousseDefinition_id = td.id " + + "where po.videoType = '%s' " + + "and td.tousseType not in ('%s','%s') " + + "and po.uploadDateTime <= %s ", + VideoFile.class.getSimpleName(), + TousseInstance.class.getSimpleName(), + TousseDefinition.class.getSimpleName(), + VideoFile.VIDEO_TYPE_CAMERA_PACKING, + TousseDefinition.PACKAGE_TYPE_FOREIGN, + TousseDefinition.PACKAGE_TYPE_SPLIT, + dateQueryAdapter.dateAdapter(lastUploadDate)); + List packingVideoIdList = searchIdBySql(packingVideoSql); + if(CollectionUtils.isNotEmpty(packingVideoIdList)){ + logger.debug("器械包" + VideoFile.VIDEO_TYPE_CAMERA_PACKING + "数量:" + packingVideoIdList.size()); + List packingVideoList = objectDao.findByIds(VideoFile.class.getSimpleName(), packingVideoIdList); + deleteVideoList.addAll(packingVideoList); + } + } + logger.debug("需要清理的视频数量:" + deleteVideoList.size()); + //删除视频文件 + timingBatchDeleteVideoFile(deleteVideoList); + //重新设置视频顺序 + timingBatchResetVideoSerialNum(deleteVideoList); + //添加日志 + timingBatchInsertDeleteVideoLog(deleteVideoList); + logger.debug("清理的视频数量:" + deleteVideoList.size()); + } + + private List searchIdBySql(String sql1) { + List idList = new ArrayList(); + if(StringUtils.isBlank(sql1)){ + return idList; + } + ResultSet rs = null; + try { + rs = objectDao.executeSql(sql1); + while(rs.next()){ + Long id = rs.getLong("id"); + idList.add(id); + } + } catch (Exception e) { + } finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + return idList; + } + + /** + * 批量删除视频 + * @param deleteVideoList + */ + private void timingBatchDeleteVideoFile(List deleteVideoList) { + logger.debug("删除视频记录及视频文件"); + if(CollectionUtils.isEmpty(deleteVideoList)){ + return; + } + SupplyRoomConfig supplyRoomConfig = (SupplyRoomConfig) objectDao.getByProperty( + SupplyRoomConfig.class.getSimpleName(), "supplyRoomType", + SupplyRoomConfig.SUPPLYROOM_TYPE_SYSTEM_CONFIG); + String videoDir = supplyRoomConfig.getSaveImagePath(); + String realPath = ""; + for (VideoFile videoFile : deleteVideoList) { + realPath = videoFile.loadVideoFileRealPath(); + if (StringUtils.isNotBlank(realPath)) { + realPath = videoDir + realPath; + deleteLocalFile(videoFile.getUuid_videoName(), realPath); + } + } + objectDao.deleteAll(deleteVideoList); + } + + /** + * 批量重置视频顺序 + * @param deleteVideoList + */ + @SuppressWarnings("unchecked") + private void timingBatchResetVideoSerialNum(List deleteVideoList) { + logger.debug("重置视频顺序"); + if(CollectionUtils.isEmpty(deleteVideoList)){ + return; + } + List deleteVideoIdList = new ArrayList(); + Map> videoTypeObjectIdMap = new HashMap>(); + for (VideoFile videoFile : deleteVideoList) { + deleteVideoIdList.add(videoFile.getId()); + String videoType = videoFile.getVideoType(); + String objectId = videoFile.getObjectId(); + List objectIdList = videoTypeObjectIdMap.get(videoType); + if(objectIdList == null){ + objectIdList = new ArrayList(); + } + objectIdList.add(objectId); + videoTypeObjectIdMap.put(videoType, objectIdList); + } + for (String videoType : videoTypeObjectIdMap.keySet()) { + List objectIdList = videoTypeObjectIdMap.get(videoType); + String sql = String.format("select po from %s po where po.videoType = '%s' and %s ", + VideoFile.class.getSimpleName(), + videoType, + SqlUtils.getStringFieldInLargeCollectionsPredicate("po.objectId", objectIdList)); + List videoFileList = objectDao.findByHql(sql); + if(CollectionUtils.isEmpty(videoFileList)){ + continue; + } + String objectId = null; + Long index = null; + for (VideoFile videoFile : videoFileList) { + String tempObjectId = videoFile.getObjectId(); + if(StringUtils.isBlank(tempObjectId)){ + continue; + } + if(deleteVideoIdList.contains(videoFile.getId())){ + continue; + } + if(index == null || !StringUtils.equals(objectId, tempObjectId)){ + index = 1l; + } + videoFile.setSerialNum(index++); + objectId = tempObjectId; + objectDao.saveOrUpdate(videoFile); + } + } + } + + /** + * 插入视频删除日志 + * @param deleteVideoList + */ + private void timingBatchInsertDeleteVideoLog(List deleteVideoList) { + logger.debug("保存视频输出日志"); + if(CollectionUtils.isEmpty(deleteVideoList)){ + return; + } + List logList = new ArrayList(); + Date logDateTime = new Date(); + LoginUserData loginUser = AcegiHelper.getLoginUser(); + for (VideoFile videoFile : deleteVideoList) { + JSONObject description = new JSONObject(); + description.put("操作", "删除" + videoFile.getVideoType()); + description.put("id", videoFile.getId()); + description.put("objectId", videoFile.getObjectId()); + description.put("videoName", videoFile.getVideoName()); + description.put("UUIDVideoName", videoFile.getUuid_videoName()); + + Log log = new Log(); + String userId = loginUser.getUserName(); + String userIP = loginUser.getUserIP(); + + String userFullName = loginUser.getUserFullName(); + + log.setLogDateTime(logDateTime); + log.setUsername(userFullName); + log.setUserId(userId); + log.setUserIP(userIP); + log.setModel(Log.MODEL_BASEDATA); + log.setOperationType("定时删除视频"); + log.setOperationDescription(description.toString()); + log.setClientType(loginUser.getClientType()); + log.setClientVersion(loginUser.getClientVersion()); + log.setSessionID(loginUser.getSessionID()); + + logList.add(log); + } + String idColumnName = ""; + String idColumnValue = ""; + if(DatabaseUtil.isOracle(dbConnection.getDatabase())){ + idColumnName = "id,"; + idColumnValue = "hibernate_sequence.nextval,"; + } + String sql = String.format("insert into %s (%s logDateTime,userName, userId, userIp, model, operationType, operationDescription, clientType, clientVersion, sessionID)" + + "values (%s ?,?,?,?,?,?,?,?,?,?)", Log.class.getSimpleName(), idColumnName, idColumnValue); + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + Log log = logList.get(i); + ps.setTimestamp(1, new Timestamp(log.getLogDateTime().getTime())); + ps.setString(2, log.getUsername()); + ps.setString(3, log.getUserId()); + ps.setString(4, log.getUserIP()); + ps.setString(5, log.getModel()); + ps.setString(6, log.getOperationType()); + ps.setString(7, log.getOperationDescription()); + ps.setString(8, log.getClientType()); + ps.setString(9, log.getClientVersion()); + ps.setString(10, log.getSessionID()); + } + + @Override + public int getBatchSize() { + return logList.size(); + } + }); + } + } Index: forgon-tools/src/main/java/com/forgon/Constants.java =================================================================== diff -u -r35859 -r36111 --- forgon-tools/src/main/java/com/forgon/Constants.java (.../Constants.java) (revision 35859) +++ forgon-tools/src/main/java/com/forgon/Constants.java (.../Constants.java) (revision 36111) @@ -28,7 +28,7 @@ "4.9.45","4.9.46","4.9.47","4.9.48","4.9.49","4.9.50","4.9.51","4.9.52","4.9.53","4.9.54","4.9.55","4.9.56","4.9.57","4.9.58","4.9.59","4.9.60","4.9.61","4.9.62", "4.9.63","4.9.64","4.9.65","4.9.66","4.9.67","4.9.68","4.9.69","4.9.70","4.9.71","4.9.72","4.9.73","4.9.74","4.9.75","4.9.76","4.9.77","4.9.78","4.9.79","4.9.80","4.9.81","4.9.82","4.9.83","4.9.84","4.9.85", "4.9.86","4.9.87","4.9.88","4.9.89","4.9.90","4.9.91","4.9.92","4.9.93","4.9.94","4.9.95","4.9.96","4.9.97","4.9.98","4.9.99","5.0.0","5.0.1","5.0.2","5.0.3","5.0.4","5.0.5","5.0.6","5.0.7", - "5.0.8","5.0.9","5.0.10","5.0.11"}; + "5.0.8","5.0.9","5.0.10","5.0.11","5.0.12"}; // 版本列表(4.0版本升级4.1版需要分两步:先从4.0升到4.1.0、然后从4.1.0升级4.1最新版本) /*public final static String[] SOFTWARE_VERSION_ARRAY = new String[] { Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/supplyroomconfig/action/SupplyRoomConfigAction.java =================================================================== diff -u -r36001 -r36111 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/supplyroomconfig/action/SupplyRoomConfigAction.java (.../SupplyRoomConfigAction.java) (revision 36001) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/basedatamanager/supplyroomconfig/action/SupplyRoomConfigAction.java (.../SupplyRoomConfigAction.java) (revision 36111) @@ -1163,6 +1163,30 @@ saveOrUpdateInstrumentRepairRemindOrgUnit(supplyRoomConfig, instrumentRepairRemindOrgUnitIds); } + //系统参数设置: + //器械包拍摄图片/视频保留时长(天) + //外来器械包拍摄图片/视频保留时长(天)DGKHYY-29 + boolean showCameraPhoto = ConfigUtils.getSystemSetConfigByNameBool("showCameraPhoto", false); + if(showCameraPhoto){ + //器械包拍摄图片/视频保留时长(天) + String tousseCamImgVidRetentionTime = rq.getParameter("tousseCamImgVidRetentionTime"); + if(DatabaseUtil.isPoIdValid(tousseCamImgVidRetentionTime)){ + supplyRoomConfig.setTousseCamImgVidRetentionTime(Integer.valueOf(tousseCamImgVidRetentionTime)); + if(supplyRoomConfig.getTousseCamImgVidRetentionTime() < 0 || supplyRoomConfig.getTousseCamImgVidRetentionTime() > 100000){ + StrutsResponseUtils.output(false, "字段“器械包拍摄图片/视频保留时长”,大于0且小于等于100000"); + return; + } + } + //外来器械包拍摄图片/视频保留时长(天) + String ftCamImgVidRetentionTime = rq.getParameter("ftCamImgVidRetentionTime"); + if(DatabaseUtil.isPoIdValid(ftCamImgVidRetentionTime)){ + supplyRoomConfig.setFtCamImgVidRetentionTime(Integer.valueOf(ftCamImgVidRetentionTime)); + if(supplyRoomConfig.getFtCamImgVidRetentionTime() < 0 || supplyRoomConfig.getFtCamImgVidRetentionTime() > 100000){ + StrutsResponseUtils.output(false, "字段“外来器械包拍摄图片/视频保留时长”,大于0且小于等于100000"); + return; + } + } + } supplyRoomConfigManager.save(supplyRoomConfig); Index: ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/videomanager/VideoFile.java =================================================================== diff -u -r34210 -r36111 --- ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/videomanager/VideoFile.java (.../VideoFile.java) (revision 34210) +++ ssts-basedata/src/main/java/com/forgon/disinfectsystem/entity/basedatamanager/videomanager/VideoFile.java (.../VideoFile.java) (revision 36111) @@ -1,7 +1,12 @@ package com.forgon.disinfectsystem.entity.basedatamanager.videomanager; +import java.util.Date; + import javax.persistence.Entity; + +import org.apache.commons.lang.StringUtils; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; + import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -95,6 +100,12 @@ * 回收包条码或标识牌条码拍 */ private String barcode; + + /** + * 上传时间 + */ + private Date uploadDateTime = new Date(); + @Id @GeneratedValue(strategy = GenerationType.AUTO) public Long getId() { @@ -186,5 +197,37 @@ public void setPreviewPicName(String previewPicName) { this.previewPicName = previewPicName; } + + public Date getUploadDateTime() { + return uploadDateTime; + } + public void setUploadDateTime(Date uploadDateTime) { + this.uploadDateTime = uploadDateTime; + } + + /** + * 根据视频类型,返回视频目录 + * @param videoFile + * @return + */ + public String loadVideoFileRealPath(){ + String realPath = ""; + if (VideoFile.VIDEO_TYPE_TOUSSE.equals(videoType)) { + realPath = VideoFile.VIDEO_PATH_TOUSSE; + }else if (VideoFile.VIDEO_TYPE_TOUSSE_WASH_TEACHING.equals(videoType)) { + realPath = VideoFile.VIDEO_PATH_TOUSSE_WASH_TEACHING; + } else if (VideoFile.VIDEO_TYPE_CAMERA_APPLICATION.equals(videoType)) { + realPath = VideoFile.VIDEO_PATH_CAMERA_APPLICATION; + } else if (VideoFile.VIDEO_TYPE_CAMERA_PACKING.equals(videoType)) { + realPath = VideoFile.VIDEO_PATH_CAMERA_PACKING; + } else if(VideoFile.VIDEO_TYPE_CAMERA_RECYCLING.equals(videoType)){ + realPath = VideoFile.VIDEO_PATH_CAMERA_RECYCLING; + } else if(VideoFile.VIDEO_TYPE_TOUSSE_PACKING_NOTE.equals(videoType)){ + realPath = VideoFile.VIDEO_PATH_TOUSSE_PACKING_NOTE; + } + + return realPath; + } + } Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/imagefilemanager/service/ImageFileManagerImpl.java =================================================================== diff -u -r35539 -r36111 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/imagefilemanager/service/ImageFileManagerImpl.java (.../ImageFileManagerImpl.java) (revision 35539) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/imagefilemanager/service/ImageFileManagerImpl.java (.../ImageFileManagerImpl.java) (revision 36111) @@ -15,12 +15,17 @@ import java.io.OutputStream; import java.math.BigDecimal; import java.net.URLEncoder; +import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; @@ -37,11 +42,15 @@ import org.apache.log4j.Logger; import org.hibernate.Query; import org.hibernate.Session; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; import ws.schild.jave.MultimediaInfo; import ws.schild.jave.MultimediaObject; +import com.forgon.databaseadapter.service.DateQueryAdapter; import com.forgon.directory.acegi.tools.AcegiHelper; +import com.forgon.directory.vo.LoginUserData; import com.forgon.disinfectsystem.basedatamanager.supplyroomconfig.service.SupplyRoomConfigManager; import com.forgon.disinfectsystem.common.geom.SizeAndPosition; import com.forgon.disinfectsystem.datamodifyrecord.service.DataModifyRecordManager; @@ -65,9 +74,12 @@ import com.forgon.log.service.LogManager; import com.forgon.tools.MathTools; import com.forgon.tools.StrutsResponseUtils; +import com.forgon.tools.date.DateTools; import com.forgon.tools.db.DatabaseUtil; +import com.forgon.tools.db.InitDbConnection; import com.forgon.tools.hibernate.ObjectDao; import com.forgon.tools.json.JSONUtil; +import com.forgon.tools.util.ConfigUtils; import com.forgon.tools.util.FileUtils; import com.forgon.tools.util.SqlUtils; import com.sun.image.codec.jpeg.ImageFormatException; @@ -90,7 +102,25 @@ private LogManager appLogManager; private DataModifyRecordManager dataModifyRecordManager; + + private DateQueryAdapter dateQueryAdapter; + + private JdbcTemplate jdbcTemplate; + + private InitDbConnection dbConnection; + public void setDbConnection(InitDbConnection dbConnection) { + this.dbConnection = dbConnection; + } + + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public void setDateQueryAdapter(DateQueryAdapter dateQueryAdapter) { + this.dateQueryAdapter = dateQueryAdapter; + } + public void setDataModifyRecordManager(DataModifyRecordManager dataModifyRecordManager) { this.dataModifyRecordManager = dataModifyRecordManager; } @@ -1525,4 +1555,276 @@ JSONUtil.addProperty(json, "videoArray", videoArray); return json; } + + @SuppressWarnings("unchecked") + @Override + public void timingDeleteImageFile() { + logger.debug("定时清理拍摄功能所产生的图片"); + boolean showCameraPhoto = ConfigUtils.getSystemSetConfigByNameBool("showCameraPhoto"); + if(!showCameraPhoto){ + logger.debug("showCameraPhoto=false"); + return; + } + SupplyRoomConfig supplyRoomConfig = (SupplyRoomConfig) objectDao.getByProperty( + SupplyRoomConfig.class.getSimpleName(), "supplyRoomType", + SupplyRoomConfig.SUPPLYROOM_TYPE_SYSTEM_CONFIG); + if(supplyRoomConfig == null){ + logger.debug("科室供应室设置为空!"); + return; + } + //申请采集图片、装配采集图片、包实例装配采集图片 + List deleteImageFileList = new ArrayList(); + Integer ftCamImgVidRetentionTime = supplyRoomConfig.getFtCamImgVidRetentionTime(); + if(ftCamImgVidRetentionTime != null + && ftCamImgVidRetentionTime.intValue() > 0 + && ftCamImgVidRetentionTime.intValue() <= 100000){ + //删除外来器械拍摄的图片 + Date lastUploadDate = DateTools.addDate(new Date(), -ftCamImgVidRetentionTime); + //查询申请采集图片 + String applicationCamImageSql = String.format("select po.id from %s po " + + "join %s td on po.objectId = td.id " + + "where po.imageType = '%s' " + + "and td.tousseType = '%s' " + + "and po.uploadDateTime <= %s ", + ImageFile.class.getSimpleName(), + TousseDefinition.class.getSimpleName(), + ImageFile.IMAGE_TYPE_CAMERA_APPLICATION, + TousseDefinition.PACKAGE_TYPE_FOREIGN, + dateQueryAdapter.dateAdapter(lastUploadDate)); + List applicationCamImageFileIdList = searchImageFileIdBySql(applicationCamImageSql); + if(CollectionUtils.isNotEmpty(applicationCamImageFileIdList)){ + List applicationCamImageList = objectDao.findByIds(ImageFile.class.getSimpleName(), applicationCamImageFileIdList); + logger.debug("外来器械" + ImageFile.IMAGE_TYPE_CAMERA_APPLICATION + "数量:" + applicationCamImageList.size()); + deleteImageFileList.addAll(applicationCamImageList); + } + //查询装配采集图片、包实例装配采集图片 + String packingCamImageSql = String.format("select po.id from %s po " + + "join %s ti on po.objectId = ti.id " + + "join %s td on ti.tousseDefinition_id = td.id " + + "where po.imageType in ('%s','%s') " + + "and td.tousseType in ('%s','%s') " + + "and po.uploadDateTime <= %s ", + ImageFile.class.getSimpleName(), + TousseInstance.class.getSimpleName(), + TousseDefinition.class.getSimpleName(), + ImageFile.IMAGE_TYPE_CAMERA_PACKING, + ImageFile.IMAGE_TYPE_TOUSSEINSTANCE_CAMERA_PACKING, + TousseDefinition.PACKAGE_TYPE_FOREIGN, + TousseDefinition.PACKAGE_TYPE_SPLIT, + dateQueryAdapter.dateAdapter(lastUploadDate)); + List packingCamImageIdList = searchImageFileIdBySql(packingCamImageSql); + if(CollectionUtils.isNotEmpty(packingCamImageIdList)){ + List packingCamImageList = objectDao.findByIds(ImageFile.class.getSimpleName(), packingCamImageIdList); + logger.debug("外来器械" + ImageFile.IMAGE_TYPE_CAMERA_PACKING + "数量:" + packingCamImageList.size()); + deleteImageFileList.addAll(packingCamImageList); + } + } + Integer tousseCamImgVidRetentionTime = supplyRoomConfig.getTousseCamImgVidRetentionTime(); + if(tousseCamImgVidRetentionTime != null + && tousseCamImgVidRetentionTime.intValue() > 0 + && tousseCamImgVidRetentionTime.intValue() <= 100000){ + Date lastUploadDate = DateTools.addDate(new Date(), -tousseCamImgVidRetentionTime); + //查询装配采集图片 + String sql = String.format("select po.id from %s po " + + "join %s ti on po.objectId = ti.id " + + "join %s td on ti.tousseDefinition_id = td.id " + + "where po.imageType = '%s' " + + "and td.tousseType not in ('%s','%s') " + + "and po.uploadDateTime <= %s ", + ImageFile.class.getSimpleName(), + TousseInstance.class.getSimpleName(), + TousseDefinition.class.getSimpleName(), + ImageFile.IMAGE_TYPE_CAMERA_PACKING, + TousseDefinition.PACKAGE_TYPE_FOREIGN, + TousseDefinition.PACKAGE_TYPE_SPLIT, + dateQueryAdapter.dateAdapter(lastUploadDate)); + List packingCamImageIdList = searchImageFileIdBySql(sql); + if(CollectionUtils.isNotEmpty(packingCamImageIdList)){ + List packingCamImageList = objectDao.findByIds(ImageFile.class.getSimpleName(), packingCamImageIdList); + logger.debug("器械包" + ImageFile.IMAGE_TYPE_CAMERA_PACKING + "数量:" + packingCamImageList.size()); + deleteImageFileList.addAll(packingCamImageList); + } + } + logger.debug("需要清理的图片数量:" + deleteImageFileList.size()); + //删除图片 + timingBatchDeleteImageFileObj(deleteImageFileList); + //重新设置图片的序号 + timingBatchResetImageSerialNum(deleteImageFileList); + //添加日志 + timingBatchInsertDeleteImageFileLog(deleteImageFileList); + logger.debug("清理的图片数量:" + deleteImageFileList.size()); + } + + private List searchImageFileIdBySql(String sql1) { + List imageFileIdList = new ArrayList(); + if(StringUtils.isBlank(sql1)){ + return imageFileIdList; + } + ResultSet rs = null; + try { + rs = objectDao.executeSql(sql1); + while(rs.next()){ + Long id = rs.getLong("id"); + imageFileIdList.add(id); + } + } catch (Exception e) { + } finally { + DatabaseUtil.closeResultSetAndStatement(rs); + } + return imageFileIdList; + } + + /** + * 删除图片记录及图片文件 + * @param deleteImageFileList + */ + private void timingBatchDeleteImageFileObj(List deleteImageFileList) { + logger.debug("删除图片记录及图片文件"); + if(CollectionUtils.isEmpty(deleteImageFileList)){ + return; + } + //1、删除数据库记录 + objectDao.deleteAll(deleteImageFileList); + //2、删除文件 + SupplyRoomConfig systemParamsObj = (SupplyRoomConfig) objectDao.getByProperty( + SupplyRoomConfig.class.getSimpleName(), "supplyRoomType", + SupplyRoomConfig.SUPPLYROOM_TYPE_SYSTEM_CONFIG); + String saveImagePath = systemParamsObj.getSaveImagePath();//默认的保存路径 + for (ImageFile imageFile : deleteImageFileList) { + deletePicturesOfImageFile(saveImagePath, imageFile); + } + } + + /** + * 更新图片序号 + * @param deleteImageFileList + */ + @SuppressWarnings("unchecked") + private void timingBatchResetImageSerialNum(List deleteImageFileList) { + logger.debug("更新图片序号"); + if(CollectionUtils.isEmpty(deleteImageFileList)){ + return; + } + List deleteImageFileIdList = new ArrayList(); + Map>> imageTypeObjectIdImageIdMap = new HashMap>>(); + for (ImageFile imageFile : deleteImageFileList) { + String imageType = imageFile.getImageType(); + String objectId = imageFile.getObjectId(); + Map> objectIdImageIdMap = imageTypeObjectIdImageIdMap.get(imageType); + if(objectIdImageIdMap == null){ + objectIdImageIdMap = new HashMap>(); + } + List imageIdList = objectIdImageIdMap.get(objectId); + if(imageIdList == null){ + imageIdList = new ArrayList(); + } + imageIdList.add(imageFile.getId()); + objectIdImageIdMap.put(objectId, imageIdList); + imageTypeObjectIdImageIdMap.put(imageType, objectIdImageIdMap); + deleteImageFileIdList.add(imageFile.getId()); + } + for (String imageType : imageTypeObjectIdImageIdMap.keySet()) { + Map> objectIdImageIdMap = imageTypeObjectIdImageIdMap.get(imageType); + Set objectIdSet = objectIdImageIdMap.keySet(); + String hql = String.format("select po from %s po where po.imageType='%s' and %s order by po.objectId, po.serialNum", + ImageFile.class.getSimpleName(), + imageType, + SqlUtils.getStringFieldInLargeCollectionsPredicate("po.objectId", objectIdSet)); + List imageFileList = objectDao.findByHql(hql); + if(CollectionUtils.isEmpty(imageFileList)){ + continue; + } + String objectId = null; + Long index = null; + for (ImageFile imageFile : imageFileList) { + String tempObjectId = imageFile.getObjectId(); + if(StringUtils.isBlank(tempObjectId)){ + continue; + } + if(deleteImageFileIdList.contains(imageFile.getId())){ + continue; + } + if(index == null || !StringUtils.equals(objectId, tempObjectId)){ + index = 1l; + } + imageFile.setSerialNum(index++); + objectId = tempObjectId; + objectDao.saveOrUpdate(imageFile); + } + } + } + + /** + * 插入图片删除日志 + * @param deleteImageFileList + */ + private void timingBatchInsertDeleteImageFileLog(List deleteImageFileList) { + logger.debug("保存图片删除日志"); + if(CollectionUtils.isEmpty(deleteImageFileList)){ + return; + } + + List logList = new ArrayList(); + Date logDateTime = new Date(); + LoginUserData loginUser = AcegiHelper.getLoginUser(); + for (ImageFile imageFileObj : deleteImageFileList) { + JSONObject description = new JSONObject(); + description.put("操作", "删除" + imageFileObj.getImageType()); + description.put("id", imageFileObj.getId()); + description.put("objectId", imageFileObj.getObjectId()); + description.put("imageName", imageFileObj.getImageName()); + description.put("imagePath", imageFileObj.getImagePath()); + description.put("UUIDImageName", imageFileObj.getUUIDImageName()); + + Log log = new Log(); + String userId = loginUser.getUserName(); + String userIP = loginUser.getUserIP(); + + String userFullName = loginUser.getUserFullName(); + + log.setLogDateTime(logDateTime); + log.setUsername(userFullName); + log.setUserId(userId); + log.setUserIP(userIP); + log.setModel(Log.MODEL_BASEDATA); + log.setOperationType("定时删除图片"); + log.setOperationDescription(description.toString()); + log.setClientType(loginUser.getClientType()); + log.setClientVersion(loginUser.getClientVersion()); + log.setSessionID(loginUser.getSessionID()); + + logList.add(log); + } + String idColumnName = ""; + String idColumnValue = ""; + if(DatabaseUtil.isOracle(dbConnection.getDatabase())){ + idColumnName = "id,"; + idColumnValue = "hibernate_sequence.nextval,"; + } + String sql = String.format("insert into %s (%s logDateTime,userName, userId, userIp, model, operationType, operationDescription, clientType, clientVersion, sessionID)" + + "values (%s ?,?,?,?,?,?,?,?,?,?)", Log.class.getSimpleName(), idColumnName, idColumnValue); + jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + + @Override + public void setValues(PreparedStatement ps, int i) throws SQLException { + Log log = logList.get(i); + ps.setTimestamp(1, new Timestamp(log.getLogDateTime().getTime())); + ps.setString(2, log.getUsername()); + ps.setString(3, log.getUserId()); + ps.setString(4, log.getUserIP()); + ps.setString(5, log.getModel()); + ps.setString(6, log.getOperationType()); + ps.setString(7, log.getOperationDescription()); + ps.setString(8, log.getClientType()); + ps.setString(9, log.getClientVersion()); + ps.setString(10, log.getSessionID()); + } + + @Override + public int getBatchSize() { + return logList.size(); + } + }); + } + } Index: ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/basic/service/MaintainManagerImpl.java =================================================================== diff -u -r35835 -r36111 --- ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/basic/service/MaintainManagerImpl.java (.../MaintainManagerImpl.java) (revision 35835) +++ ssts-maintain/src/main/java/com/forgon/disinfectsystem/maintain/basic/service/MaintainManagerImpl.java (.../MaintainManagerImpl.java) (revision 36111) @@ -1597,6 +1597,9 @@ case "5.0.10_5.0.11": UpdateData_5_0_10_5_0_11(updateDataContext); break; + case "5.0.11_5.0.12": + UpdateData_5_0_11_5_0_12(updateDataContext); + break; } return false; } @@ -1972,6 +1975,45 @@ dataUpdater.logInfo(msg); } + + @SuppressWarnings("deprecation") + private void UpdateData_5_0_11_5_0_12(UpdateDataContext updateDataContext) { + + DataUpdater dataUpdater = updateDataContext.getDataUpdater(); + String msg = null; + msg = String.format("已执行方法(%s.%s)!", + MaintainManagerImpl.class.getName(), + "UpdateData_5_0_11_5_0_12()"); + SupplyRoomConfig supplyRoomConfig = supplyRoomConfigManager.getSystemParamsObj(); + String videoDir = supplyRoomConfig.getSaveImagePath(); + if(supplyRoomConfig == null || StringUtils.isBlank(videoDir)){ + dataUpdater.logInfo(msg); + return; + } + + // 视频的没有上传时间,直接取视频文件的时间 + String videoHql = String.format("select po from %s po where po.uploadDateTime is null", + VideoFile.class.getSimpleName()); + List videoList = objectDao.findByHql(videoHql); + if(CollectionUtils.isNotEmpty(videoList)){ + Date uploadDateTime = new Date(); + for (VideoFile videoFile : videoList) { + String savePath = videoDir + videoFile.loadVideoFileRealPath(); + String filePath = savePath + "/" + videoFile.getUuid_videoName(); + File file = new File(filePath); + if(file.exists()){ + //最后修改时间 + Long uploadDateTimeLong = file.lastModified(); + if(uploadDateTimeLong != null){ + uploadDateTime = new Date(uploadDateTimeLong); + } + } + videoFile.setUploadDateTime(uploadDateTime); + } + objectDao.batchSaveOrUpdate(videoList); + } + dataUpdater.logInfo(msg); + } /** * 升级程序从5.0.3升级到5.0.4,解决设备接口的用户名与密码存储由明文改成Base64密文的形式 Index: ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/videomanager/service/VideoFileManager.java =================================================================== diff -u -r34904 -r36111 --- ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/videomanager/service/VideoFileManager.java (.../VideoFileManager.java) (revision 34904) +++ ssts-tousse/src/main/java/com/forgon/disinfectsystem/tousse/videomanager/service/VideoFileManager.java (.../VideoFileManager.java) (revision 36111) @@ -146,4 +146,10 @@ * @return */ public byte[] getVideoFilePreviewPic(String videoId); + + /** + * 定时删除视频文件 + */ + public void timingDeleteVideoFile(); + } Index: ssts-web/src/main/webapp/disinfectsystem/config/dgskhyy/spring/timer.xml =================================================================== diff -u --- ssts-web/src/main/webapp/disinfectsystem/config/dgskhyy/spring/timer.xml (revision 0) +++ ssts-web/src/main/webapp/disinfectsystem/config/dgskhyy/spring/timer.xml (revision 36111) @@ -0,0 +1,61 @@ + + + + + + + + + + + + timingDeleteImageFile + + + + + + + + + + + 0 0 2 * * ? + + + + + + + + + + timingDeleteVideoFile + + + + + + + + + + + 0 0 2 * * ? + + + + + + + + + + + + + + + \ No newline at end of file