package com.gk.hotwork.Service.ServiceImpl; 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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.gk.hotwork.Config.attachment.FilePathConfig; import com.gk.hotwork.Domain.AttachmentInfo; import com.gk.hotwork.Domain.Enum.ResultCodes; import com.gk.hotwork.Domain.Exception.BusinessException; import com.gk.hotwork.Domain.UserInfo; import com.gk.hotwork.Domain.Utils.StringUtils; import com.gk.hotwork.Mapper.AttachmentInfoMapper; import com.gk.hotwork.Service.AttachmentInfoService; import com.gk.hotwork.Service.AttachmentService; import com.gk.hotwork.common.FileProjectConstants; import org.apache.commons.collections4.CollectionUtils; 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.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.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; import static cn.hutool.core.io.FileTypeUtil.getType; /** * @email 1603559716@qq.com * @author: zf * @date: 2023/7/24 * @time: 13:54 */ @Service public class AttachmentServiceImpl implements AttachmentService { @Autowired private AttachmentInfoService attachmentInfoService; private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 错误信息格式 */ private static final String ERROR_FORMATTER = "{}:{}"; @Resource private FilePathConfig filePathConfig; @Override public AttachmentInfo findByKey(String key) { if (StringUtils.isBlank(key)){ throw new BusinessException("文件标识为空"); } return attachmentInfoService.findByKey(key); } @Override public AttachmentInfo findById(Long id) { if (id == null){ throw new BusinessException("文件主键为空"); } return attachmentInfoService.findById(id); } @Override public List findByIds(List ids) { if (CollectionUtils.isEmpty(ids)){ throw new BusinessException("文件主键为空"); } return attachmentInfoService.findByIds(ids); } @Override public List findByBusinessId(Long businessId) { if (businessId == null){ throw new BusinessException("业务主键为空"); } return attachmentInfoService.findByBusinessId(businessId); } @Override public void delete(Long id, UserInfo userInfo) { if (id == null){ throw new BusinessException("文件主键为空"); } attachmentInfoService.delete(id,userInfo); } @Override public Object saveFileToPath(MultipartFile file, String module, int type, UserInfo user) { //获取对应模块路径 String path; //获取对应模块根路径 String dcPath; path = filePathConfig.getModule().get(module); dcPath = filePathConfig.getDcPath(); String originalFilename = file.getOriginalFilename(); if (com.alibaba.druid.util.StringUtils.isEmpty(originalFilename)) { logger.error(ERROR_FORMATTER,module, ResultCodes.PATH_NOT_EXISIST.getDesc()); throw new BusinessException(ResultCodes.FILE_NOT_EXISIST); } if (com.alibaba.druid.util.StringUtils.isEmpty(path)) { logger.error(ERROR_FORMATTER, module, ResultCodes.PATH_NOT_EXISIST.getDesc()); throw new BusinessException(ResultCodes.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, ResultCodes.FILE_UPLOAD_FAIL.getDesc()); throw new BusinessException(ResultCodes.FILE_UPLOAD_FAIL); } file.transferTo(newFile); //创建文件信息 AttachmentInfo attachmentInfo = new AttachmentInfo(); attachmentInfo.setDelFlag(0); attachmentInfo.setFileKey(key); attachmentInfo.setFileSuffix(suffix); attachmentInfo.setFilePath(localPath); attachmentInfo.setFileUrl(url); attachmentInfo.setFileName(file.getOriginalFilename()); attachmentInfo.setFileSize(file.getSize()); attachmentInfo.setModule(module); attachmentInfo.setFileType(getType(suffix)); attachmentInfo.setCreateUid(user.getId()); attachmentInfo.setCreateUname(user.getRealname()); attachmentInfo.setUpdateUid(user.getId()); attachmentInfo.setUpdateUname(user.getRealname()); attachmentInfo.setUpdateTime(new Date()); attachmentInfo.setCreateTime(new Date()); AttachmentInfo attachment = attachmentInfoService.saveOne(attachmentInfo); switch (type) { case FileProjectConstants.ReturnType.URL: return url; case FileProjectConstants.ReturnType.KEY: return key; case FileProjectConstants.ReturnType.DETAIL: return attachment; default: return null; } } catch (IOException e) { if (newFile != null && newFile.exists()) { newFile.delete(); } logger.error(ERROR_FORMATTER, ResultCodes.FILE_UPLOAD_FAIL, e.getMessage()); throw new BusinessException(ResultCodes.FILE_UPLOAD_FAIL); } } @Override public Object saveBatchFileToPath(MultipartFile[] fileList, String module, UserInfo user) { //获取对应模块路径 String path; //获取对应模块根路径 String dcPath; path = filePathConfig.getModule().get(module); dcPath = filePathConfig.getDcPath(); List attachmentInfoList = new ArrayList<>(); for (MultipartFile file : fileList) { String originalFilename = file.getOriginalFilename(); if (com.alibaba.druid.util.StringUtils.isEmpty(originalFilename)) { logger.error(ERROR_FORMATTER,module, ResultCodes.PATH_NOT_EXISIST.getDesc()); throw new BusinessException(ResultCodes.FILE_NOT_EXISIST); } if (com.alibaba.druid.util.StringUtils.isEmpty(path)) { logger.error(ERROR_FORMATTER, module, ResultCodes.PATH_NOT_EXISIST.getDesc()); throw new BusinessException(ResultCodes.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, ResultCodes.FILE_UPLOAD_FAIL.getDesc()); throw new BusinessException(ResultCodes.FILE_UPLOAD_FAIL); } //上传文件 file.transferTo(newFile); //创建文件信息 AttachmentInfo attachmentInfo = new AttachmentInfo(); attachmentInfo.setDelFlag(0); attachmentInfo.setFileKey(key); attachmentInfo.setFileSuffix(suffix); attachmentInfo.setFilePath(localPath); attachmentInfo.setFileUrl(url); attachmentInfo.setFileName(file.getOriginalFilename()); attachmentInfo.setFileSize(file.getSize()); attachmentInfo.setModule(module); attachmentInfo.setFileType(getType(suffix)); attachmentInfo.setCreateUid(user.getId()); attachmentInfo.setCreateUname(user.getRealname()); attachmentInfo.setUpdateUid(user.getId()); attachmentInfo.setUpdateUname(user.getRealname()); attachmentInfo.setUpdateTime(new Date()); attachmentInfo.setCreateTime(new Date()); attachmentInfoList.add(attachmentInfo); } catch (IOException e) { if (newFile != null && newFile.exists()) { newFile.delete(); } logger.error(ERROR_FORMATTER, ResultCodes.FILE_UPLOAD_FAIL, e.getMessage()); throw new BusinessException(ResultCodes.FILE_UPLOAD_FAIL); } } List detailList = attachmentInfoService.saveBatchAttachment(attachmentInfoList); return detailList; } @Override public void downloadForStream(HttpServletResponse response, String key) { AttachmentInfo 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, ResultCodes.FILE_NOT_EXISIST.getDesc()); throw new BusinessException(ResultCodes.FILE_NOT_EXISIST); } OutputStream outputStream = response.getOutputStream(); FileInputStream inputStream = new FileInputStream(file); IoUtil.copy(inputStream, outputStream); outputStream.close(); } catch (IOException e) { logger.error(e.getMessage()); throw new BusinessException(ResultCodes.FILE_DOWNLOAD_EXPERTION); } } @Override public void downloadById(HttpServletResponse response, HttpServletRequest request, Long id) { Assert.isTrue(id == null, "文件key未知异常"); AttachmentInfo byId = findById(id); downloadByEntity(response, request, byId); } public void downloadByEntity(HttpServletResponse response, HttpServletRequest request, AttachmentInfo attachmentInfo) { if (ObjectUtil.isNotNull(attachmentInfo)) { String type = attachmentInfo.getFileType(); if (StrUtil.isBlank(type)) { type = "application/octet-stream"; } type = type + ";charset=utf-8"; String fileName = attachmentInfo.getFileName(); response.setContentType("multipart/form-data;charset=utf-8"); ServletUtil.setHeader(response, "Access-Control-Expose-Headers", "Content-Disposition"); //本地文件下载 File file = FileUtil.file(attachmentInfo.getFilePath()); if (!FileUtil.exist(file)) { throw new BusinessException(attachmentInfo.getFileKey() + "文件不存在"); } InputStream is = null; try { is = IoUtil.toStream(file); ServletUtil.write(response, is, type, fileName); } catch (Exception e) { throw new BusinessException(ResultCodes.FILE_DOWNLOAD_EXPERTION); } finally { IoUtil.close(is); } } else { throw new BusinessException(ResultCodes.FILE_NOT_EXISIST); } } }