|
|
@@ -1,23 +1,44 @@
|
|
|
package vip.xiaonuo.disk.util;
|
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.qiwenshare.common.util.DateUtil;
|
|
|
+import com.qiwenshare.ufop.constant.UploadFileStatusEnum;
|
|
|
+import com.qiwenshare.ufop.util.UFOPUtils;
|
|
|
import io.minio.*;
|
|
|
+import io.minio.errors.*;
|
|
|
import io.minio.messages.DeleteError;
|
|
|
import io.minio.messages.DeleteObject;
|
|
|
import io.minio.messages.Item;
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
-import vip.xiaonuo.disk.domain.FileLink;
|
|
|
-import vip.xiaonuo.disk.domain.UploadFile;
|
|
|
+import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
|
|
+import vip.xiaonuo.disk.commpen.ProducerCommpen;
|
|
|
+import vip.xiaonuo.disk.component.ResourceFileDealComp;
|
|
|
+import vip.xiaonuo.disk.domain.*;
|
|
|
+import vip.xiaonuo.disk.dto.file.TranscodingResourceReqDTO;
|
|
|
+import vip.xiaonuo.disk.io.QiwenFile;
|
|
|
+import vip.xiaonuo.disk.mapper.ImageMapper;
|
|
|
+import vip.xiaonuo.disk.mapper.ResourceFileMapper;
|
|
|
+import vip.xiaonuo.disk.mapper.ResourceUserFileMapper;
|
|
|
+import vip.xiaonuo.disk.mapper.UploadTaskMapper;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
+import java.security.InvalidKeyException;
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.LinkedList;
|
|
|
import java.util.List;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
import java.util.stream.Collectors;
|
|
|
import java.util.stream.IntStream;
|
|
|
|
|
|
@@ -40,6 +61,24 @@ public class MinioUtil {
|
|
|
@Resource
|
|
|
private MinioClient minioClient;
|
|
|
|
|
|
+ @Resource
|
|
|
+ ResourceFileMapper resourceFileMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ ResourceUserFileMapper resourceUserFileMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ ResourceFileDealComp resourceFileDealComp;
|
|
|
+ @Resource
|
|
|
+ private ProducerCommpen producer;
|
|
|
+ @Resource
|
|
|
+ private KafKaProducerUtil kafKaProducerUtil;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ UploadTaskMapper uploadTaskMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ ImageMapper imageMapper;
|
|
|
|
|
|
Logger logger = LoggerFactory.getLogger(MinioUtil.class);
|
|
|
|
|
|
@@ -65,11 +104,19 @@ public class MinioUtil {
|
|
|
* @return
|
|
|
*/
|
|
|
public List<String> checkFilesExits(List<UploadFile> md5List) {
|
|
|
+
|
|
|
ArrayList<String> noExitList = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
md5List.forEach(item -> {
|
|
|
try {
|
|
|
- logger.info("校验是否存在的文件名是: files/" + item.getMd5() + item.getFileSuffix());
|
|
|
- minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object("files/" + item.getMd5() + item.getFileSuffix()).build());
|
|
|
+
|
|
|
+ String fileSuffix=item.getFileSuffix().substring(1, item.getFileSuffix().length());
|
|
|
+
|
|
|
+ String fileUrl = UFOPUtils.getUploadFileUrl(item.getMd5(), fileSuffix);
|
|
|
+
|
|
|
+ logger.info("校验是否存在的文件名是: "+fileUrl);
|
|
|
+ minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(fileUrl).build());
|
|
|
} catch (Exception e) {
|
|
|
logger.info("该文件需要上传,md5值是:" + item.getMd5());
|
|
|
// 未存在的文件添加到队列中,前端仍需上传
|
|
|
@@ -88,7 +135,7 @@ public class MinioUtil {
|
|
|
* @param fileSize 分块文件大小
|
|
|
* @return 上传结果
|
|
|
*/
|
|
|
- public Boolean upload(String md5, Integer chunkIndex, InputStream inputStream, long fileSize) {
|
|
|
+ public Boolean upload(String md5, Integer chunkIndex, InputStream inputStream , long fileSize) {
|
|
|
logger.info("开始上传, 文件" + md5);
|
|
|
logger.info("开始上传, 文件" + chunkIndex);
|
|
|
|
|
|
@@ -202,7 +249,10 @@ public class MinioUtil {
|
|
|
* @param fileSuffix
|
|
|
* @return
|
|
|
*/
|
|
|
- public Boolean merge(String md5, Integer chunkTotal, String fileSuffix) {
|
|
|
+ public Boolean merge(String md5, Integer chunkTotal, String fileSuffix,long fileSize,String fileName) {
|
|
|
+ fileSuffix=fileSuffix.substring(1, fileSuffix.length());
|
|
|
+
|
|
|
+ String fileUrl = UFOPUtils.getUploadFileUrl(md5, fileSuffix);
|
|
|
logger.info("开始合并");
|
|
|
// 获取所有分块
|
|
|
List<Item> itemList = getChunkList(md5);
|
|
|
@@ -227,7 +277,7 @@ public class MinioUtil {
|
|
|
minioClient.composeObject(
|
|
|
ComposeObjectArgs.builder()
|
|
|
.bucket(bucket)
|
|
|
- .object("files/" + md5 + fileSuffix)
|
|
|
+ .object(fileUrl)
|
|
|
.sources(sourceObjectList)
|
|
|
.build());
|
|
|
|
|
|
@@ -237,10 +287,10 @@ public class MinioUtil {
|
|
|
return false;
|
|
|
}
|
|
|
logger.info("合并成功了...");
|
|
|
-// http://192.168.123.101:9000/sph/files/71149ab18f8279400e4ba5269ae295f5.jpg
|
|
|
- String url = endpoint + "/" + bucket + "/" + "files/" + md5 + fileSuffix;
|
|
|
+
|
|
|
+ String url = fileUrl;
|
|
|
logger.info("插入的的url是:" + url);
|
|
|
- Boolean insertResult = this.insertUrl(url);
|
|
|
+ Boolean insertResult = this.insertUrl(url, fileSize,md5,fileName);
|
|
|
Boolean deleteResult = this.deleteChunks(md5);
|
|
|
logger.info(insertResult.toString());
|
|
|
logger.info(deleteResult.toString());
|
|
|
@@ -249,10 +299,18 @@ public class MinioUtil {
|
|
|
return true;
|
|
|
} else {
|
|
|
logger.error("插入失败...");
|
|
|
+ UploadTask uploadTask = new UploadTask();
|
|
|
+ uploadTask.setIdentifier(md5);
|
|
|
+ uploadTask.setUploadTime(DateUtil.getCurrentTime());
|
|
|
+ uploadTask.setUploadStatus(UploadFileStatusEnum.FAIL.getCode());
|
|
|
+ uploadTask.setFileName(fileName);
|
|
|
+ uploadTask.setFilePath("/");
|
|
|
+ uploadTask.setExtendName(fileSuffix);
|
|
|
+ uploadTask.setUserId(StpLoginUserUtil.getLoginUser().getId());
|
|
|
+ uploadTaskMapper.insert(uploadTask);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -262,12 +320,91 @@ public class MinioUtil {
|
|
|
* @param url
|
|
|
* @return
|
|
|
*/
|
|
|
- public Boolean insertUrl(String url) {
|
|
|
- FileLink fileLink = new FileLink();
|
|
|
- fileLink.setUrl(url);
|
|
|
- // mongoTemplate.insert(fileLink);
|
|
|
- // List<FileLink> fileLinks = mongoTemplate.find(Query.query(Criteria.where("url").is(url)), FileLink.class);
|
|
|
- return false;
|
|
|
+ public Boolean insertUrl(String url,long fileSize,String md5,String fileName) {
|
|
|
+ ResourceFile file = new ResourceFile(url,fileSize,3,md5, StpLoginUserUtil.getLoginUser().getId());
|
|
|
+ resourceFileMapper.insert(file);
|
|
|
+
|
|
|
+ QiwenFile qiwenFile = new QiwenFile("/", fileName, false);
|
|
|
+
|
|
|
+ ResourceUserFile resourceUserFile = new ResourceUserFile(qiwenFile, StpLoginUserUtil.getLoginUser().getId(), file.getFileId());
|
|
|
+ resourceUserFile.setIsCollet("0");
|
|
|
+ try {
|
|
|
+ resourceUserFile.setIsCollet("0");
|
|
|
+ resourceUserFileMapper.insert(resourceUserFile);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ ResourceUserFile userFile1 = resourceUserFileMapper.selectOne(new QueryWrapper<ResourceUserFile>().lambda()
|
|
|
+ .eq(ResourceUserFile::getUserId, resourceUserFile.getUserId())
|
|
|
+ .eq(ResourceUserFile::getFilePath, resourceUserFile.getFilePath())
|
|
|
+ .eq(ResourceUserFile::getFileName, resourceUserFile.getFileName())
|
|
|
+ .eq(ResourceUserFile::getExtendName, resourceUserFile.getExtendName())
|
|
|
+ .eq(ResourceUserFile::getDeleteFlag, resourceUserFile.getDeleteFlag())
|
|
|
+ .eq(ResourceUserFile::getIsDir, resourceUserFile.getIsDir()));
|
|
|
+ ResourceFile file1 = resourceFileMapper.selectById(userFile1.getFileId());
|
|
|
+ if (!StringUtils.equals(md5, file1.getIdentifier())) {
|
|
|
+ logger.warn("文件冲突重命名处理: {}", JSON.toJSONString(userFile1));
|
|
|
+ String fileName1 = resourceFileDealComp.getRepeatFileName(resourceUserFile, resourceUserFile.getFilePath());
|
|
|
+ resourceUserFile.setFileName(fileName1);
|
|
|
+ resourceUserFileMapper.insert(resourceUserFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ExecutorService threadPool = CheckThreadPool.getExecutor();
|
|
|
+ try {
|
|
|
+ threadPool.execute(() -> {
|
|
|
+ TranscodingResourceReqDTO transcodingResourceReqDTO = new TranscodingResourceReqDTO();
|
|
|
+ transcodingResourceReqDTO.setUserFileId(resourceUserFile.getUserFileId());
|
|
|
+ transcodingResourceReqDTO.setUserId(StpLoginUserUtil.getLoginUser().getId());
|
|
|
+ kafKaProducerUtil.sendTranscodingResource(producer.getProducer(), JSON.toJSONString(transcodingResourceReqDTO));
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ //上传成功同时用新线程异步转换格式用来创建预览用的文件
|
|
|
+ if (fileName.contains("/")) {
|
|
|
+ QiwenFile finalQiwenFile = qiwenFile;
|
|
|
+ threadPool.execute(()->{
|
|
|
+ resourceFileDealComp.restoreParentFilePath(finalQiwenFile, StpLoginUserUtil.getLoginUser().getId());
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ UploadTask uploadTask = new UploadTask();
|
|
|
+ uploadTask.setIdentifier(md5);
|
|
|
+ uploadTask.setUploadTime(DateUtil.getCurrentTime());
|
|
|
+ uploadTask.setUploadStatus(UploadFileStatusEnum.SUCCESS.getCode());
|
|
|
+ uploadTask.setFileName(qiwenFile.getNameNotExtend());
|
|
|
+ uploadTask.setFilePath(qiwenFile.getParent());
|
|
|
+ uploadTask.setExtendName(qiwenFile.getExtendName());
|
|
|
+ uploadTask.setUserId(StpLoginUserUtil.getLoginUser().getId());
|
|
|
+ uploadTaskMapper.insert(uploadTask);
|
|
|
+
|
|
|
+
|
|
|
+ if (UFOPUtils.isImageFile(qiwenFile.getExtendName())) {
|
|
|
+ InputStream inputStream = null;
|
|
|
+ try {
|
|
|
+ MinioClient minioClient =
|
|
|
+ MinioClient.builder().endpoint(endpoint)
|
|
|
+ .credentials(accessKey, secretKey).build();
|
|
|
+
|
|
|
+ inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(url).build());
|
|
|
+
|
|
|
+ BufferedImage src = ImageIO.read(inputStream);
|
|
|
+ Image image = new Image();
|
|
|
+ image.setImageWidth(src.getWidth());
|
|
|
+ image.setImageHeight(src.getHeight());
|
|
|
+ image.setFileId(file.getFileId());
|
|
|
+ imageMapper.insert(image);
|
|
|
+ } catch (IOException | InternalException | XmlParserException | InvalidResponseException |
|
|
|
+ InvalidKeyException | NoSuchAlgorithmException | ErrorResponseException |
|
|
|
+ InsufficientDataException | ServerException e) {
|
|
|
+ logger.error("生成图片缩略图失败!", e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ IOUtils.closeQuietly(inputStream);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resourceFileDealComp.parseMusicFile(qiwenFile.getExtendName(), 3, url, file.getFileId());
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
|