package com.ruoyi.file.service.impl;
|
|
|
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.extra.servlet.ServletUtil;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
import com.ruoyi.common.constant.HttpStatus;
|
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.file.constants.FileProjectConstants;
|
import com.ruoyi.file.entity.AttachmentInfo;
|
import com.ruoyi.file.properties.FilePathProperties;
|
import com.ruoyi.file.service.AttachmentInfoService;
|
import com.ruoyi.file.service.AttachmentService;
|
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.lang3.StringUtils;
|
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 FilePathProperties filePathProperties;
|
@Override
|
public AttachmentInfo findByKey(String key) {
|
if (StringUtils.isBlank(key)){
|
throw new ServiceException("文件标识为空", HttpStatus.ERROR);
|
}
|
return attachmentInfoService.findByKey(key);
|
}
|
@Override
|
public AttachmentInfo findById(Long id) {
|
if (id == null){
|
throw new ServiceException("文件主键为空");
|
}
|
return attachmentInfoService.findById(id);
|
}
|
@Override
|
public List<AttachmentInfo> findByIds(List<Long> ids) {
|
if (CollectionUtils.isEmpty(ids)){
|
throw new ServiceException("文件主键为空");
|
}
|
return attachmentInfoService.findByIds(ids);
|
}
|
@Override
|
public List<AttachmentInfo> findByBusinessId(Long businessId) {
|
if (businessId == null){
|
throw new ServiceException("业务主键为空");
|
}
|
return attachmentInfoService.findByBusinessId(businessId);
|
}
|
|
@Override
|
public void delete(Long id) {
|
if (id == null){
|
throw new ServiceException("文件主键为空");
|
}
|
attachmentInfoService.delete(id);
|
}
|
|
@Override
|
public Object saveFileToPath(MultipartFile file, String module, int type) {
|
//获取对应模块路径
|
String path;
|
//获取对应模块根路径
|
String dcPath;
|
path = filePathProperties.getModule().get(module);
|
dcPath = filePathProperties.getDcPath();
|
|
String originalFilename = file.getOriginalFilename();
|
if (StringUtils.isEmpty(originalFilename)) {
|
logger.error(ERROR_FORMATTER,module, "文件不存在");
|
throw new ServiceException("文件不存在");
|
}
|
if (StringUtils.isEmpty(path)) {
|
logger.error(ERROR_FORMATTER, module, "文件路径不存在");
|
throw new ServiceException("文件路径不存在");
|
}
|
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 = filePathProperties.getUrlRootPath() + newFilePath.replace(File.separator, "/");
|
newFile = new File(localPath);
|
if (!newFile.exists() && !newFile.mkdirs()) {
|
logger.error(ERROR_FORMATTER, newFilePath, "文件上传失败");
|
throw new ServiceException("文件上传失败");
|
}
|
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.setCreateBy(SecurityUtils.getUsername());
|
attachmentInfo.setUpdateBy(SecurityUtils.getUsername());
|
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, "文件上传失败");
|
throw new ServiceException("文件上传失败");
|
}
|
}
|
|
@Override
|
public Object saveBatchFileToPath(MultipartFile[] fileList, String module) {
|
//获取对应模块路径
|
String path;
|
//获取对应模块根路径
|
String dcPath;
|
path = filePathProperties.getModule().get(module);
|
dcPath = filePathProperties.getDcPath();
|
List<AttachmentInfo> attachmentInfoList = new ArrayList<>();
|
for (MultipartFile file : fileList) {
|
String originalFilename = file.getOriginalFilename();
|
if (StringUtils.isEmpty(originalFilename)) {
|
logger.error(ERROR_FORMATTER,module, "文件不存在");
|
throw new ServiceException("文件不存在");
|
}
|
if (StringUtils.isEmpty(path)) {
|
logger.error(ERROR_FORMATTER, module, "文件路径不存在");
|
throw new ServiceException("文件路径不存在");
|
}
|
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 = filePathProperties.getUrlRootPath() + newFilePath.replace(File.separator, "/");
|
newFile = new File(localPath);
|
if (!newFile.exists() && !newFile.mkdirs()) {
|
logger.error(ERROR_FORMATTER, newFilePath, "文件上传失败");
|
throw new ServiceException("文件上传失败");
|
}
|
//上传文件
|
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.setCreateBy(SecurityUtils.getUsername());
|
attachmentInfo.setUpdateBy(SecurityUtils.getUsername());*/
|
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, "文件上传失败", e.getMessage());
|
throw new ServiceException("文件上传失败");
|
}
|
}
|
List<AttachmentInfo> 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, "文件不存在");
|
throw new ServiceException("文件不存在");
|
}
|
OutputStream outputStream = response.getOutputStream();
|
FileInputStream inputStream = new FileInputStream(file);
|
IoUtil.copy(inputStream, outputStream);
|
outputStream.close();
|
} catch (IOException e) {
|
logger.error(e.getMessage());
|
throw new ServiceException("文件下载异常");
|
}
|
}
|
@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 (ObjectUtils.isNotNull(attachmentInfo)) {
|
String type = attachmentInfo.getFileType();
|
if (StringUtils.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 ServiceException(attachmentInfo.getFileKey() + "文件不存在");
|
}
|
InputStream is = null;
|
try {
|
is = IoUtil.toStream(file);
|
ServletUtil.write(response, is, type, fileName);
|
} catch (Exception e) {
|
throw new ServiceException("文件下载异常");
|
} finally {
|
IoUtil.close(is);
|
}
|
} else {
|
throw new ServiceException("文件不存在");
|
}
|
}
|
}
|