package org.jeecg.modules.doc.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.io.IOUtils;
|
import org.apache.shiro.SecurityUtils;
|
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.util.DateUtils;
|
import org.jeecg.modules.doc.component.*;
|
import org.jeecg.modules.doc.constant.Constant;
|
import org.jeecg.modules.doc.dto.DownloadFileDTO;
|
import org.jeecg.modules.doc.dto.PreviewDTO;
|
import org.jeecg.modules.doc.dto.UploadFileDTO;
|
import org.jeecg.modules.doc.entity.*;
|
import org.jeecg.modules.doc.enums.UploadFileStatusEnum;
|
import org.jeecg.modules.doc.mapper.*;
|
import org.jeecg.modules.doc.service.IFiletransferService;
|
import org.jeecg.modules.doc.service.IUserStorageFlowService;
|
import org.jeecg.modules.doc.util.UFOPUtils;
|
import org.jeecg.modules.doc.vo.*;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpMethod;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.web.client.RestTemplate;
|
|
import javax.annotation.Resource;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.awt.image.BufferedImage;
|
import java.io.*;
|
import java.net.URI;
|
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
import java.text.SimpleDateFormat;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
import java.util.zip.Adler32;
|
import java.util.zip.CheckedOutputStream;
|
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipOutputStream;
|
|
@Slf4j
|
@Service
|
@Transactional(rollbackFor=Exception.class)
|
public class FiletransferService implements IFiletransferService {
|
|
@Resource
|
DocFileMapper docFileMapper;
|
|
@Resource
|
DocFilePathMapper docFilePathMapper;
|
@Resource
|
UploadTaskDetailMapper uploadTaskDetailMapper;
|
|
@Resource
|
UploadTaskMapper uploadTaskMapper;
|
|
@Resource
|
DocFileDealComp fileDealComp;
|
|
@Resource
|
ImageMapper imageMapper;
|
|
@Autowired
|
RestTemplate restTemplate;
|
|
@Autowired
|
IUserStorageFlowService userStorageFlowService;
|
|
@Override
|
public UploadFileVo uploadFileSpeed(UploadFileDTO uploadFileDTO) {
|
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
UploadFileVo uploadFileVo = new UploadFileVo();
|
Map<String, Object> param = new HashMap<>();
|
param.put("identifier", uploadFileDTO.getIdentifier());
|
// 查询是否已存在相同文件
|
List<DocFile> list = docFileMapper.selectList(new LambdaQueryWrapper<DocFile>().eq(DocFile::getIdentifier,uploadFileDTO.getIdentifier()));
|
|
String filePath = uploadFileDTO.getFilePath();
|
String relativePath = uploadFileDTO.getRelativePath();
|
QiwenFile qiwenFile = null;
|
if (relativePath.contains("/")) {
|
qiwenFile = new QiwenFile(filePath, relativePath, false);
|
} else {
|
qiwenFile = new QiwenFile(filePath, uploadFileDTO.getFilename(), false);
|
}
|
|
// 有相同文件
|
if (list != null && !list.isEmpty()) {
|
DocFile file = list.get(0);
|
|
DocFilePath userFile = new DocFilePath(qiwenFile, file.getFileId());
|
DocFilePath parent = fileDealComp.getParent(userFile.getFilePath());
|
if (parent != null) {
|
userFile.setParentId(parent.getPathId());
|
}
|
|
// 查询用户文件是否已存在
|
DocFilePath param1 = PathFileUtil.searchParam(userFile);
|
List<DocFilePath> FilePathList = docFilePathMapper.selectList(new QueryWrapper<>(param1));
|
if (FilePathList.size() <= 0) {
|
docFilePathMapper.insert(userFile);
|
//fileDealComp.uploadESByUserFileId(userFile.getUserFileId());
|
}
|
if (relativePath.contains("/")) {
|
fileDealComp.restoreParentFilePath(qiwenFile, userFile.getPathId());
|
}
|
|
// 已极速上传,文件不用再上传
|
uploadFileVo.setSkipUpload(true);
|
} else {
|
// 需要上传
|
uploadFileVo.setSkipUpload(false);
|
|
// 查询已上传块
|
List<Integer> uploaded = uploadTaskDetailMapper.selectUploadedChunkNumList(uploadFileDTO.getIdentifier());
|
if (uploaded != null && !uploaded.isEmpty()) {
|
uploadFileVo.setUploaded(uploaded);
|
} else {
|
|
// 添加上传任务
|
LambdaQueryWrapper<UploadTask> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
lambdaQueryWrapper.eq(UploadTask::getIdentifier, uploadFileDTO.getIdentifier());
|
List<UploadTask> rslist = uploadTaskMapper.selectList(lambdaQueryWrapper);
|
if (rslist == null || rslist.isEmpty()) {
|
UploadTask uploadTask = new UploadTask();
|
uploadTask.setIdentifier(uploadFileDTO.getIdentifier());
|
uploadTask.setUploadTime(DateUtils.getDataString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")));
|
uploadTask.setUploadStatus(UploadFileStatusEnum.UNCOMPLATE.getCode());
|
uploadTask.setFileName(qiwenFile.getNameNotExtend());
|
uploadTask.setFilePath(qiwenFile.getParent());
|
uploadTask.setExtendName(qiwenFile.getExtendName());
|
uploadTask.setUserId(loginUser.getUserIdentity());
|
uploadTaskMapper.insert(uploadTask);
|
}
|
}
|
|
}
|
return uploadFileVo;
|
}
|
|
@Override
|
public void uploadFile(HttpServletRequest request, UploadFileDTO uploadFileDto) {
|
|
UploadFile uploadFile = new UploadFile();
|
uploadFile.setChunkNumber(uploadFileDto.getChunkNumber());
|
uploadFile.setChunkSize(uploadFileDto.getChunkSize());
|
uploadFile.setTotalChunks(uploadFileDto.getTotalChunks());
|
uploadFile.setIdentifier(uploadFileDto.getIdentifier());
|
uploadFile.setTotalSize(uploadFileDto.getTotalSize());
|
uploadFile.setCurrentChunkSize(uploadFileDto.getCurrentChunkSize());
|
|
Uploader uploader = new LocalStorageUploader();
|
if (uploader == null) {
|
log.error("上传失败,请检查storageType是否配置正确");
|
throw new UploadException("上传失败");
|
}
|
List<UploadFileResult> uploadFileResultList;
|
try {
|
uploadFileResultList = uploader.upload(request, uploadFile);
|
} catch (Exception e) {
|
log.error("上传失败,请检查UFOP连接配置是否正确");
|
throw new UploadException("上传失败", e);
|
}
|
for (int i = 0; i < uploadFileResultList.size(); i++){
|
UploadFileResult uploadFileResult = uploadFileResultList.get(i);
|
String relativePath = uploadFileDto.getRelativePath();
|
QiwenFile qiwenFile = null;
|
if (relativePath.contains("/")) {
|
qiwenFile = new QiwenFile(uploadFileDto.getFilePath(), relativePath, false);
|
} else {
|
qiwenFile = new QiwenFile(uploadFileDto.getFilePath(), uploadFileDto.getFilename(), false);
|
}
|
|
if (UploadFileStatusEnum.SUCCESS.equals(uploadFileResult.getStatus())){
|
// log.info("开始保存===文件路径:{},文件名:{},文件唯一标识:{}", uploadFileResult.getFileUrl(), uploadFileResult.getFileName(), uploadFileResult.getIdentifier());
|
DocFile fileBean = new DocFile(uploadFileResult);
|
docFileMapper.insert(fileBean);
|
|
|
DocFilePath userFile = new DocFilePath(qiwenFile, fileBean.getFileId());
|
|
|
|
DocFilePath param = PathFileUtil.searchParam(userFile);
|
List<DocFilePath> userFileList = docFilePathMapper.selectList(new QueryWrapper<>(param));
|
if (userFileList.size() > 0) {
|
String fileName = fileDealComp.getRepeatFileName(userFile, userFile.getFilePath());
|
userFile.setFileName(fileName);
|
}
|
DocFilePath parent = fileDealComp.getParent(userFile.getFilePath());
|
if (parent!=null) {
|
userFile.setParentId(parent.getPathId());
|
}
|
try {
|
docFilePathMapper.insert(userFile);
|
} catch (Exception e) {
|
log.error("上传文件异常:" + e.getMessage());
|
|
}
|
|
if (relativePath.contains("/")) {
|
fileDealComp.restoreParentFilePath(qiwenFile, userFile.getPathId());
|
}
|
|
// fileDealComp.uploadESByUserFileId(userFile.getUserFileId());
|
|
|
LambdaQueryWrapper<UploadTaskDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
lambdaQueryWrapper.eq(UploadTaskDetail::getIdentifier, uploadFileDto.getIdentifier());
|
uploadTaskDetailMapper.delete(lambdaQueryWrapper);
|
|
LambdaUpdateWrapper<UploadTask> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
lambdaUpdateWrapper.set(UploadTask::getUploadStatus, UploadFileStatusEnum.SUCCESS.getCode())
|
.eq(UploadTask::getIdentifier, uploadFileDto.getIdentifier());
|
uploadTaskMapper.update(null, lambdaUpdateWrapper);
|
|
|
try {
|
if (UFOPUtils.isImageFile(uploadFileResult.getExtendName())) {
|
BufferedImage src = uploadFileResult.getBufferedImage();
|
Image image = new Image();
|
image.setImageWidth(src.getWidth());
|
image.setImageHeight(src.getHeight());
|
image.setFileId(fileBean.getFileId());
|
imageMapper.insert(image);
|
}
|
} catch (Exception e) {
|
log.error("生成图片缩略图失败!", e);
|
}
|
|
// fileDealComp.parseMusicFile(uploadFileResult.getExtendName(), uploadFileResult.getStorageType().getCode(), uploadFileResult.getFileUrl(), fileBean.getFileId());
|
|
} else if (UploadFileStatusEnum.UNCOMPLATE.equals(uploadFileResult.getStatus())) {
|
UploadTaskDetail uploadTaskDetail = new UploadTaskDetail();
|
uploadTaskDetail.setFilePath(qiwenFile.getParent());
|
uploadTaskDetail.setFileName(qiwenFile.getNameNotExtend());
|
uploadTaskDetail.setChunkNumber(uploadFileDto.getChunkNumber());
|
uploadTaskDetail.setChunkSize((int)uploadFileDto.getChunkSize());
|
uploadTaskDetail.setRelativePath(uploadFileDto.getRelativePath());
|
uploadTaskDetail.setTotalChunks(uploadFileDto.getTotalChunks());
|
uploadTaskDetail.setTotalSize((int)uploadFileDto.getTotalSize());
|
uploadTaskDetail.setIdentifier(uploadFileDto.getIdentifier());
|
uploadTaskDetailMapper.insert(uploadTaskDetail);
|
|
} else if (UploadFileStatusEnum.FAIL.equals(uploadFileResult.getStatus())) {
|
LambdaQueryWrapper<UploadTaskDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
lambdaQueryWrapper.eq(UploadTaskDetail::getIdentifier, uploadFileDto.getIdentifier());
|
uploadTaskDetailMapper.delete(lambdaQueryWrapper);
|
|
LambdaUpdateWrapper<UploadTask> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
lambdaUpdateWrapper.set(UploadTask::getUploadStatus, UploadFileStatusEnum.FAIL.getCode())
|
.eq(UploadTask::getIdentifier, uploadFileDto.getIdentifier());
|
uploadTaskMapper.update(null, lambdaUpdateWrapper);
|
}
|
}
|
|
}
|
|
|
private String formatChatset(String str) {
|
if (str == null) {
|
return "";
|
}
|
if (Charset.forName("ISO-8859-1").newEncoder().canEncode(str)) {
|
byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1);
|
return new String(bytes, Charset.forName("GBK"));
|
}
|
return str;
|
}
|
|
@Override
|
public void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO) {
|
DocFilePath userFile = docFilePathMapper.selectById(downloadFileDTO.getUserFileId());
|
|
if (userFile.getIsDir() == Constant.IS_NOT_DIR) {
|
|
|
DocFile fileBean = docFileMapper.selectById(userFile.getFileId());
|
Downloader downloader = new LocalStorageDownloader();
|
if (downloader == null) {
|
log.error("下载失败,文件存储类型不支持下载,storageType:{}", fileBean.getStorageType());
|
throw new DownloadException("下载失败");
|
}
|
DownloadFile downloadFile = new DownloadFile();
|
|
downloadFile.setFileUrl(fileBean.getFileUrl());
|
httpServletResponse.setContentLengthLong(fileBean.getFileSize());
|
userStorageFlowService.updateSurplusFlowByUserId(downloadFileDTO.getUserToken(), fileBean.getFileSize());
|
downloader.download(httpServletResponse, downloadFile);
|
} else {
|
|
QiwenFile qiwenFile = new QiwenFile(userFile.getFilePath(), userFile.getFileName(), true);
|
List<DocFilePath> userFileList = docFilePathMapper.selectUserFileByLikeRightFilePath(qiwenFile.getPath() );
|
List<String> userFileIds = userFileList.stream().map(DocFilePath::getPathId).collect(Collectors.toList());
|
|
downloadUserFileList(httpServletResponse, userFile.getFilePath()+QiwenFile.separator, userFile.getFileName(), userFileIds, downloadFileDTO.getUserToken());
|
}
|
}
|
|
@Override
|
public void downloadUserFileList(HttpServletResponse httpServletResponse, String filePath, String fileName, List<String> userFileIds, String token) {
|
String staticPath = UFOPUtils.getStaticPath();
|
String tempPath = staticPath + "temp" + File.separator;
|
File tempDirFile = new File(tempPath);
|
if (!tempDirFile.exists()) {
|
tempDirFile.mkdirs();
|
}
|
|
FileOutputStream f = null;
|
try {
|
f = new FileOutputStream(tempPath + fileName + ".zip");
|
} catch (FileNotFoundException e) {
|
e.printStackTrace();
|
}
|
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
|
ZipOutputStream zos = new ZipOutputStream(csum);
|
BufferedOutputStream out = new BufferedOutputStream(zos);
|
|
try {
|
for (String userFileId : userFileIds) {
|
DocFilePath userFile1 = docFilePathMapper.selectById(userFileId);
|
if (userFile1.getIsDir() == Constant.IS_NOT_DIR) {
|
DocFile fileBean = docFileMapper.selectById(userFile1.getFileId());
|
Downloader downloader = new LocalStorageDownloader();
|
if (downloader == null) {
|
log.error("下载失败,文件存储类型不支持下载,storageType:{}", fileBean.getStorageType());
|
throw new UploadException("下载失败");
|
}
|
DownloadFile downloadFile = new DownloadFile();
|
downloadFile.setFileUrl(fileBean.getFileUrl());
|
// String url = UFOPUtils.ENCRYPT_PATH + "/fileTransfer/encryptDownload";
|
// ResponseEntity<byte[]> responseEntity = restTemplate.exchange(url+"?userFileId=" + userFileId +"&userToken=" + token, HttpMethod.GET, null, byte[].class);
|
// byte[] data;
|
// if (responseEntity != null) {
|
// data=responseEntity.getBody();
|
// } else {
|
// data = new byte[0];
|
// }
|
// //byte[] data =responseEntity.getBody();
|
// InputStream inputStream = new ByteArrayInputStream(data);
|
InputStream inputStream = downloader.getInputStream(downloadFile);
|
BufferedInputStream bis = new BufferedInputStream(inputStream);
|
try {
|
QiwenFile qiwenFile = new QiwenFile(userFile1.getFilePath(), userFile1.getFileName() + "." + userFile1.getExtendName(), false);
|
zos.putNextEntry(new ZipEntry(qiwenFile.getPath().replaceFirst(filePath.replace("(","\\(").replace(")","\\)"), "")));
|
|
byte[] buffer = new byte[1024];
|
int i = bis.read(buffer);
|
while (i != -1) {
|
out.write(buffer, 0, i);
|
i = bis.read(buffer);
|
}
|
} catch (IOException e) {
|
log.error("" + e);
|
e.printStackTrace();
|
} finally {
|
IOUtils.closeQuietly(bis);
|
try {
|
out.flush();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
} else {
|
QiwenFile qiwenFile = new QiwenFile(userFile1.getFilePath(), userFile1.getFileName(), true);
|
// 空文件夹的处理
|
zos.putNextEntry(new ZipEntry(qiwenFile.getPath().replaceFirst(filePath.replace("(","\\(").replace(")","\\)"),"") + QiwenFile.separator));
|
// 没有文件,不需要文件的copy
|
zos.closeEntry();
|
}
|
}
|
|
} catch (Exception e) {
|
log.error("压缩过程中出现异常:"+ e);
|
} finally {
|
try {
|
out.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
String zipPath = "";
|
try {
|
Downloader downloader = new LocalStorageDownloader();
|
DownloadFile downloadFile = new DownloadFile();
|
downloadFile.setFileUrl("temp" + File.separator + fileName + ".zip");
|
File tempFile = new File(UFOPUtils.getStaticPath() + downloadFile.getFileUrl());
|
httpServletResponse.setContentLengthLong(tempFile.length());
|
downloader.download(httpServletResponse, downloadFile);
|
zipPath = UFOPUtils.getStaticPath() + "temp" + File.separator + fileName + ".zip";
|
} catch (Exception e) {
|
//org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
|
if (e.getMessage().contains("ClientAbortException")) {
|
//该异常忽略不做处理
|
} else {
|
log.error("下传zip文件出现异常:{}", e.getMessage());
|
}
|
|
} finally {
|
File file = new File(zipPath);
|
if (file.exists()) {
|
file.delete();
|
}
|
}
|
}
|
|
@Override
|
public void previewFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO) {
|
DocFilePath userFile = docFilePathMapper.selectById(previewDTO.getUserFileId());
|
DocFile fileBean = docFileMapper.selectById(userFile.getFileId());
|
Previewer previewer = new LocalStoragePreviewer(new ThumbImage(150,150));
|
if (previewer == null) {
|
log.error("预览失败,文件存储类型不支持预览,storageType:{}", fileBean.getStorageType());
|
throw new UploadException("预览失败");
|
}
|
try {
|
if ("true".equals(previewDTO.getIsMin())) {
|
previewer.imageThumbnailPreview(httpServletResponse, fileBean.getFileUrl());
|
} else {
|
previewer.imageOriginalPreview(httpServletResponse, fileBean.getFileUrl());
|
}
|
} catch (Exception e){
|
//org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
|
if (e.getMessage().contains("ClientAbortException")) {
|
//该异常忽略不做处理
|
} else {
|
log.error("预览文件出现异常:{}", e.getMessage());
|
}
|
|
}
|
|
}
|
//
|
// @Override
|
// public void previewPictureFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO) {
|
// byte[] bytesUrl = Base64.getDecoder().decode(previewDTO.getUrl());
|
// PictureFile pictureFile = new PictureFile();
|
// pictureFile.setFileUrl(new String(bytesUrl));
|
// pictureFile = pictureFileMapper.selectOne(new QueryWrapper<>(pictureFile));
|
// Previewer previewer = ufopFactory.getPreviewer(pictureFile.getStorageType());
|
// if (previewer == null) {
|
// log.error("预览失败,文件存储类型不支持预览,storageType:{}", pictureFile.getStorageType());
|
// throw new UploadException("预览失败");
|
// }
|
// PreviewFile previewFile = new PreviewFile();
|
// previewFile.setFileUrl(pictureFile.getFileUrl());
|
//// previewFile.setFileSize(pictureFile.getFileSize());
|
// try {
|
//
|
// String mime= MimeUtils.getMime(pictureFile.getExtendName());
|
// httpServletResponse.setHeader("Content-Type", mime);
|
//
|
// String fileName = pictureFile.getFileName() + "." + pictureFile.getExtendName();
|
// try {
|
// fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
|
// } catch (UnsupportedEncodingException e) {
|
// e.printStackTrace();
|
// }
|
//
|
// httpServletResponse.addHeader("Content-Disposition", "fileName=" + fileName);// 设置文件名
|
//
|
// previewer.imageOriginalPreview(httpServletResponse, previewFile);
|
// } catch (Exception e){
|
// //org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
|
// if (e.getMessage().contains("ClientAbortException")) {
|
// //该异常忽略不做处理
|
// } else {
|
// log.error("预览文件出现异常:{}", e.getMessage());
|
// }
|
//
|
// }
|
// }
|
|
@Override
|
public void deleteFile(DocFile fileBean) {
|
Deleter deleter = null;
|
|
deleter = new LocalStorageDeleter();
|
DeleteFile deleteFile = new DeleteFile();
|
deleteFile.setFileUrl(fileBean.getFileUrl());
|
deleter.delete(deleteFile);
|
}
|
|
|
//
|
// @Override
|
// public Long selectStorageSizeByUserId(Long userId){
|
// return userFileMapper.selectStorageSizeByUserId(userId);
|
// }
|
}
|