package com.jiayue.ipfcst.fileupload.service; import com.jiayue.ipfcst.common.core.util.DateTimeUtil; import com.jiayue.ipfcst.common.data.constant.enums.FileStatusEnum; import com.jiayue.ipfcst.common.data.constant.enums.FileTypeEnum; import com.jiayue.ipfcst.common.data.entity.UploadFileChannel; import com.jiayue.ipfcst.common.data.entity.UploadFileLog; import com.jiayue.ipfcst.common.data.entity.UploadObject; import com.jiayue.ipfcst.common.data.repository.UploadFileLogRepository; import com.jiayue.ipfcst.common.data.service.BaseService; import com.jiayue.ipfcst.fileupload.util.FileConstant; import com.jiayue.ipfcst.fileupload.util.FileUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; /** * 上报文件生成基础类 * * @author xsl * @version 3.0 */ @Service @Slf4j public abstract class BaseUploadFileService extends BaseService { @Autowired UploadFileLogRepository uploadFileLogRepository; @Autowired UploadObjectService uploadObjectService; @Autowired UploadFileChannelService uploadFileChannelService; /** * 获取文件上报数值类型参数 * * @param key * @param defaultValue * @return */ protected int getTranSysParameter(String key, String defaultValue, String stationCode) { int returnValue; try { String value = super.getSysParameter(key, defaultValue, stationCode); returnValue = Integer.parseInt(value); } catch (RuntimeException e) { String errorInfo = "参数表" + key + "获取失败"; log.error(errorInfo, e); returnValue = Integer.parseInt(defaultValue); } return returnValue; } /** * 查詢文件是否生成 * * @param fileName * @return 存在则返回false,不存在返回true */ protected boolean getFileName(String fileName, String fileType, String stationCode) { int cdqUpMin = getTranSysParameter("CDQ_UP_MIN", "0", stationCode); //今日凌晨 long jt = DateTimeUtil.getMillisecondsSubDay() - (15 * 60 * 1000 + (long) cdqUpMin * 1000 * 60); //明日凌晨 long mt = DateTimeUtil.getMillisecondsSubDay() + 1000 * 60 * 60 * 24; List list = this.uploadFileLogRepository.findByFileNameAndFileTypeEnumAndCreateTimeBetweenAndStationCode(fileName, FileTypeEnum.valueOf(fileType), new Date(jt), new Date(mt), stationCode); return null == list || list.size() <= 0; } /** * 创建临时文件 * * @param fileName 文件名 * @return 临时文件 */ protected File createTempFile(String fileName) { // 获取临时目录 String tempDir = FileUtil.getTempFilePath() + File.separator + UUID.randomUUID().toString().replace("-", ""); boolean b = new File(tempDir).mkdir(); if (!b) { throw new RuntimeException("创建文件" + fileName + "失败"); } File file = new File(tempDir + File.separator + fileName); try { b = file.createNewFile(); if (!b) throw new RuntimeException("创建文件" + fileName + "失败"); } catch (IOException e) { throw new RuntimeException(e); } return file; } /** * 生成上报文件 * * @param writer * @param file * @param fileType * @param uploadFileEndTime */ protected void copyUploadFile(StringWriter writer, File file, String fileType, Long uploadFileEndTime, Date createTime, String stationCode) { FileOutputStream os = null; try { os = new FileOutputStream(file); // 采用UTF-8字符集 os.write(writer.toString().getBytes(StandardCharsets.UTF_8)); os.flush(); // 将文件复制到上报路径中 copyFileToUploadDir(file, fileType, uploadFileEndTime, createTime, stationCode); } catch (IOException e) { throw new RuntimeException(e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { log.error("文件生成关闭流失败", e); } } try { FileUtils.forceDelete(file.getParentFile()); } catch (IOException e) { log.error("", e); } } } /** * 复制上报文件到上报路径 * * @param file 需要上报的文件 * @param fileType 文件类型 * @param uploadFileEndTime 上报文件截止时间 */ @Transactional(propagation = Propagation.REQUIRED) public void copyFileToUploadDir(File file, String fileType, Long uploadFileEndTime, Date createTime, String stationCode) { String destFileDir = null; try { // 获取上报对象 List uploadObjectList = uploadObjectService.get(); if (!uploadObjectList.isEmpty()) { // 遍历上报对象生成对应的文件 for (UploadObject uploadObject : uploadObjectList) { if (uploadObject.getStationCode().equals(stationCode)) { List uploadFileChannelList = uploadFileChannelService.getByObjectId(uploadObject.getId()); // 找出对象下是否有可用的通道 List filterUploadFileChannelList = uploadFileChannelList.stream().filter(s -> "E1".equals(s.getChannelStatusEnum().toString())).collect(Collectors.toList()); if (filterUploadFileChannelList.size() > 0) { String[] uploadFileType = uploadObject.getUploadFileType().split(","); for (String s : uploadFileType) { if (s.equals(fileType)) { // 上报文件目录 destFileDir = FileUtil.getFileUploadPath() + File.separator + "process" + File.separator + uploadObject.getObjectNo() + File.separator + fileType; File destDir = new File(destFileDir); if (!destDir.exists()) {// 如果目录不存在则创建uploadFileEndTime目录 boolean b = destDir.mkdirs(); if (!b) // 如果创建失败则抛出异常 throw new RuntimeException(destFileDir + " 目录创建失败"); } if (!new File(destDir + File.separator + file.getName()).exists()) { FileUtils.copyFileToDirectory(file, destDir); UploadFileLog uploadFileLog = new UploadFileLog(); uploadFileLog.setUploadObjectId(uploadObject.getId()); uploadFileLog.setUploadObjectName(uploadObject.getUploadObjectName()); uploadFileLog.setUploadObjectNo(uploadObject.getObjectNo()); uploadFileLog.setFileName(file.getName()); uploadFileLog.setFileTypeEnum(FileTypeEnum.valueOf(fileType)); uploadFileLog.setFileStatusEnum(FileStatusEnum.E1); uploadFileLog.setUploadProtocolEnum(uploadObject.getUploadProtocolEnum()); uploadFileLog.setUploadCounter(0); uploadFileLog.setUploadFileEndTime(uploadFileEndTime); uploadFileLog.setStationCode(stationCode); uploadFileLog = this.uploadFileLogRepository.save(uploadFileLog); if (createTime != null) { uploadFileLog.setCreateTime(createTime); Date date = new Date(); String format = DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss"); uploadFileLog.setBackupA(format); uploadFileLog = this.uploadFileLogRepository.save(uploadFileLog); } String readyFileKey = uploadObject.getObjectNo() + "@" + fileType + "@" + file.getName(); FileConstant.fileShouldMomentMap.put(readyFileKey, uploadFileLog.getId()); FileConstant.readyUploadFileMap.put(readyFileKey, uploadFileLog); log.debug("文件生成存入缓存:" + file.getName()); log.info("上报对象编号:" + uploadObject.getObjectNo() + ",生成文件" + file.getName() + "成功"); } else { log.info("本地文件已经生成,上报对象编号:" + uploadObject.getObjectNo() + "," + file.getName() + "不再生成了"); } break; } } } } } } } catch (Exception e) { // 文件复制失败进行告警 String errorInfo = "复制文件[" + file.getName() + "]到上报目录[" + destFileDir + "]失败"; log.error(errorInfo, e); } } }