package com.gkhy.labRiskManage.application.attachment.service.impl; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.ServletUtil; import com.alibaba.druid.util.StringUtils; import com.gkhy.labRiskManage.application.attachment.converter.AttachmentAppConverter; import com.gkhy.labRiskManage.application.attachment.service.AttachmentAppService; import com.gkhy.labRiskManage.application.attachment.service.dto.req.AttachmentAppReq; import com.gkhy.labRiskManage.application.attachment.service.dto.resp.AttachmentAppRespDTO; import com.gkhy.labRiskManage.commons.enums.ResultCode; import com.gkhy.labRiskManage.commons.exception.BusinessException; import com.gkhy.labRiskManage.config.file.FilePathConfig; import com.gkhy.labRiskManage.domain.account.model.dto.UserInfoDomainDTO; import com.gkhy.labRiskManage.domain.account.service.UserDomainService; import com.gkhy.labRiskManage.domain.attachment.dto.resp.AttachmentDomainDTO; import com.gkhy.labRiskManage.domain.attachment.enums.FileProjectConstants; import com.gkhy.labRiskManage.domain.attachment.service.AttachmentDomainService; import lombok.SneakyThrows; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.UUID; import static cn.hutool.core.io.FileTypeUtil.getType; /** * @email 1603559716@qq.com * @author: zf * @date: 2023/5/7 * @time: 13:37 */ @Service public class AttachmentAppServiceImpl implements AttachmentAppService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 错误信息格式 */ private static final String ERROR_FORMATTER = "{}:{}"; @Resource private FilePathConfig filePathConfig; @Autowired private UserDomainService userDomainService; @Autowired private AttachmentDomainService attachmentDomainService; @Autowired private AttachmentAppConverter converter; @Override @Transactional(rollbackFor = Exception.class) public Object saveFileToPath(MultipartFile file, String module, Integer type, Long currentUserId){ UserInfoDomainDTO userInfo = userDomainService.getUserInfoById(currentUserId); //获取对应模块路径 String path; //获取对应模块根路径 String dcPath; path = filePathConfig.getModule().get(module); dcPath = filePathConfig.getDcPath(); String originalFilename = file.getOriginalFilename(); if (StringUtils.isEmpty(originalFilename)) { logger.error(ERROR_FORMATTER,module,ResultCode.PATH_NOT_EXISIST.getDesc()); throw new BusinessException(this.getClass(), ResultCode.FILE_NOT_EXISIST); } if (StringUtils.isEmpty(path)) { logger.error(ERROR_FORMATTER, module, ResultCode.PATH_NOT_EXISIST.getDesc()); throw new BusinessException(this.getClass(), ResultCode.PATH_NOT_EXISIST); } assert originalFilename != null; LocalDateTime now = LocalDateTime.now(); File newFile = null; try { //文件标识 UUID 如4d6873609b144945935ae84442711fd6 String key = ""; String suffix = ""; if (originalFilename.contains(".mp3")) { key = originalFilename; suffix = ""; } else { key = UUID.randomUUID().toString().replace("-", ""); //文件后缀 包含. suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase(); } path = path.replace("/", File.separator); //文件模块路径 如 2021/base/build/0421 String modulePath = now.getYear() + path + now.format(DateTimeFormatter.ofPattern("MMdd")); //文件路径 如 2021/base/build/0421/4d6873609b144945935ae84442711fd6.后缀 String newFilePath = modulePath + File.separator + key + suffix; //文件绝对路径 如 /home/img/2021/base/build/0421/4d6873609b144945935ae84442711fd6.后缀 String localPath = dcPath + newFilePath; //文件访问路径 如 /upload/2021/base/build/0421/4d6873609b144945935ae84442711fd6.后缀 String url = filePathConfig.getUrlRootPath() + newFilePath.replace(File.separator, "/"); newFile = new File(localPath); if (!newFile.exists() && !newFile.mkdirs()) { logger.error(ERROR_FORMATTER, newFilePath, ResultCode.FILE_UPLOAD_FAIL.getDesc()); throw new BusinessException(this.getClass(),ResultCode.FILE_UPLOAD_FAIL); } file.transferTo(newFile); //创建文件信息 AttachmentAppReq attachmentAppReq = new AttachmentAppReq(); attachmentAppReq.setDelFlag(0); attachmentAppReq.setFileKey(key); attachmentAppReq.setFileSuffix(suffix); attachmentAppReq.setFilePath(localPath); attachmentAppReq.setFileUrl(url); attachmentAppReq.setFileName(file.getOriginalFilename()); attachmentAppReq.setFileSize(file.getSize()); attachmentAppReq.setModule(module); attachmentAppReq.setFileType(getType(suffix)); attachmentAppReq.setCreateUid(userInfo.getId()); attachmentAppReq.setCreateUname(userInfo.getName()); attachmentAppReq.setUpdateUid(userInfo.getId()); attachmentAppReq.setUpdateUname(userInfo.getName()); AttachmentDomainDTO attachmentDomainDTO = attachmentDomainService.save(attachmentAppReq); switch (type) { case FileProjectConstants.ReturnType.URL: return url; case FileProjectConstants.ReturnType.KEY: return key; case FileProjectConstants.ReturnType.DETAIL: return attachmentDomainDTO; default: return null; } } catch (IOException e) { if (newFile != null && newFile.exists()) { newFile.delete(); } logger.error(ERROR_FORMATTER, ResultCode.FILE_UPLOAD_FAIL, e.getMessage()); throw new BusinessException(this.getClass(),ResultCode.FILE_UPLOAD_FAIL); } } @Override public AttachmentAppRespDTO findByKey(String key) { if(StringUtils.isEmpty(key)){ throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL); } AttachmentDomainDTO byKey = attachmentDomainService.findByKey(key); return converter.getAppRespDTO(byKey); } @Override public AttachmentAppRespDTO findById(Long id) { if(id == null){ throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL); } AttachmentDomainDTO findById = attachmentDomainService.findById(id); return converter.getAppRespDTO(findById); } @Override public void delete(Long id) { if(id == null){ throw new BusinessException(this.getClass(),ResultCode.PARAM_ERROR_NULL); } attachmentDomainService.delete(id); } @Override public void downloadByKey(HttpServletResponse response, HttpServletRequest request, String key) { Assert.isTrue(StrUtil.isNotBlank(key) && !StrUtil.isNullOrUndefined(key), "文件key未知异常"); AttachmentAppRespDTO byKey = findByKey(key); downloadByEntity(response, request, byKey); } @SneakyThrows @Override public void downloadForStream(HttpServletResponse response, String key) { AttachmentAppRespDTO byKey = findByKey(key); File file; try { response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(byKey.getFileName(), StandardCharsets.UTF_8.name())); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); file = new File(byKey.getFilePath()); if (!file.exists()) { logger.error(ERROR_FORMATTER, key, ResultCode.FILE_NOT_EXISIST.getDesc()); throw new BusinessException(this.getClass(),ResultCode.FILE_NOT_EXISIST); } OutputStream outputStream = response.getOutputStream(); FileInputStream inputStream = new FileInputStream(file); IoUtil.copy(inputStream, outputStream); outputStream.close(); } catch (UnsupportedEncodingException e) { logger.error(e.getMessage()); throw new BusinessException(this.getClass(),ResultCode.FILE_DOWNLOAD_EXPERTION); } } //@Override public void downloadByEntity(HttpServletResponse response, HttpServletRequest request, AttachmentAppRespDTO appRespDTO) { if (ObjectUtil.isNotNull(appRespDTO)) { String type = appRespDTO.getFileType(); if (StrUtil.isBlank(type)) { type = "application/octet-stream"; } type = type + ";charset=utf-8"; String fileName = appRespDTO.getFileName(); response.setContentType("multipart/form-data;charset=utf-8"); ServletUtil.setHeader(response, "Access-Control-Expose-Headers", "Content-Disposition"); //本地文件下载 File file = FileUtil.file(appRespDTO.getFilePath()); if (!FileUtil.exist(file)) { throw new BusinessException(this.getClass(),ResultCode.FILE_NOT_EXISIST,appRespDTO.getFileKey() + "文件不存在"); } InputStream is = null; try { is = IoUtil.toStream(file); ServletUtil.write(response, is, type, fileName); } catch (Exception e) { throw new BusinessException(this.getClass(),ResultCode.FILE_DOWNLOAD_EXPERTION); } finally { IoUtil.close(is); } } else { throw new BusinessException(this.getClass(),ResultCode.BUSINESS_ERROR_DATA_NOT_EXISIST,"文件记录不存在"); } } }