|
@@ -0,0 +1,280 @@
|
|
|
+package com.bizmatics.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.bizmatics.common.core.bean.UnifiedUser;
|
|
|
+import com.bizmatics.common.core.constants.CommonConst;
|
|
|
+import com.bizmatics.common.core.exception.BusinessException;
|
|
|
+import com.bizmatics.common.core.util.*;
|
|
|
+import com.bizmatics.common.mvc.base.AbstractCrudService;
|
|
|
+import com.bizmatics.common.spring.injectself.BeanSelfAware;
|
|
|
+import com.bizmatics.common.spring.util.GlobalUtils;
|
|
|
+import com.bizmatics.model.SysFile;
|
|
|
+import com.bizmatics.persistence.mapper.FileMapper;
|
|
|
+import com.bizmatics.service.FileSerivce;
|
|
|
+import com.bizmatics.service.dto.SysFileDTO;
|
|
|
+import com.bizmatics.service.dto.SysFileQueryRequest;
|
|
|
+import com.bizmatics.service.dto.SysFileUploadRequest;
|
|
|
+import com.bizmatics.service.enums.UploadType;
|
|
|
+import com.bizmatics.service.expcetion.FileErrorCode;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Propagation;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
|
|
|
+
|
|
|
+import javax.annotation.Nullable;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.net.URL;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+import static java.util.stream.Collectors.toList;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author barry chen
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class FileServiceImpl extends AbstractCrudService<FileMapper, SysFile> implements FileSerivce, BeanSelfAware {
|
|
|
+ public static final String OSS_KEY_FILE_NAME_DATE_PATTERN = "yyyy-MM";
|
|
|
+ public static final String SYS_FILE_TEMP_DIR = "file";
|
|
|
+ public static final String DOT = ".";
|
|
|
+ private final Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
|
|
|
+
|
|
|
+ private FileSerivce self;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setSelf(Object bean) {
|
|
|
+ this.self = (FileSerivce) bean;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String generateBatchNo() {
|
|
|
+ return UUIDUtils.shortUUID();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<SysFile> getFile(SysFileQueryRequest req) {
|
|
|
+ if(StringUtils.isBlank(req.getBatchNo()) && CollectionUtils.isEmpty(req.getFileIds())){
|
|
|
+ throw new BusinessException(FileErrorCode.FILE_GET_ERROR, "At least one of batchNo and fileIds is required.");
|
|
|
+ }
|
|
|
+ return this.list(Wrappers.lambdaQuery(SysFile.class)
|
|
|
+ .eq(StringUtils.isNotBlank(req.getBatchNo()), SysFile::getBatchNo, req.getBatchNo())
|
|
|
+ .eq(SysFile::getActiveFlag, CommonConst.TRUE_NUM)
|
|
|
+ .in(CollectionUtils.isNotEmpty(req.getFileIds()), SysFile::getId, req.getFileIds()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Nullable
|
|
|
+ public List<SysFileDTO> addFile(SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ if (StringUtils.isNotBlank(sysFileUploadRequest.getKey())) {
|
|
|
+ throw new BusinessException(FileErrorCode.FILE_UPLOAD_FILE_ERROR, "V1 upload api doesn't support [key]");
|
|
|
+ }
|
|
|
+ if (Objects.isNull(sysFileUploadRequest.getUploadType())) {
|
|
|
+ sysFileUploadRequest.setUploadType(UploadType.FILE);
|
|
|
+ }
|
|
|
+ switch (sysFileUploadRequest.getUploadType()) {
|
|
|
+ case FILE:
|
|
|
+ return sysFileUploadRequest.getMultipartFiles().stream().map(m -> self.uploadMultipartFile(m, sysFileUploadRequest)).collect(toList());
|
|
|
+ case URL:
|
|
|
+ return sysFileUploadRequest.getUrls().stream().map(m -> self.addExternalLink(m, sysFileUploadRequest)).collect(toList());
|
|
|
+ case URLBYOSS:
|
|
|
+ return sysFileUploadRequest.getUrls().stream().map(m -> self.uploadExternalFile(m, sysFileUploadRequest)).collect(toList());
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Nullable
|
|
|
+ public SysFileDTO addFileV2(SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ if (CollectionUtils.isNotEmpty(sysFileUploadRequest.getMultipartFiles()) && sysFileUploadRequest.getMultipartFiles().size() > 1) {
|
|
|
+ throw new BusinessException(FileErrorCode.FILE_UPLOAD_FILE_ERROR, "V2 upload api only support single file");
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(sysFileUploadRequest.getUrls()) && sysFileUploadRequest.getUrls().size() > 1) {
|
|
|
+ throw new BusinessException(FileErrorCode.FILE_UPLOAD_FILE_ERROR, "V2 upload api only support single file");
|
|
|
+ }
|
|
|
+ if (Objects.isNull(sysFileUploadRequest.getUploadType())) {
|
|
|
+ sysFileUploadRequest.setUploadType(UploadType.FILE);
|
|
|
+ }
|
|
|
+ //如果key以"/"开头, 则去掉
|
|
|
+ String key = sysFileUploadRequest.getKey();
|
|
|
+ if (StringUtils.isNotBlank(key) && StringUtils.startsWith(key, File.separator)) {
|
|
|
+ sysFileUploadRequest.setKey(key.substring(1));
|
|
|
+ }
|
|
|
+ switch (sysFileUploadRequest.getUploadType()) {
|
|
|
+ case FILE:
|
|
|
+ return self.uploadMultipartFile(sysFileUploadRequest.getMultipartFiles().get(0), sysFileUploadRequest);
|
|
|
+ case URL:
|
|
|
+ String u = sysFileUploadRequest.getUrls().get(0);
|
|
|
+ return self.addExternalLink(u, sysFileUploadRequest);
|
|
|
+ case URLBYOSS:
|
|
|
+ return self.uploadExternalFile(sysFileUploadRequest.getUrls().get(0), sysFileUploadRequest);
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
|
|
+ public SysFileDTO uploadMultipartFile(CommonsMultipartFile multipartFile,
|
|
|
+ SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ SysFileDTO sysFileDTO = new SysFileDTO();
|
|
|
+ File file = FileUtils.getFile(GlobalUtils.getTempBaseDir(), SYS_FILE_TEMP_DIR, multipartFile.getOriginalFilename());
|
|
|
+ try {
|
|
|
+ try {
|
|
|
+ multipartFile.transferTo(file);
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new BusinessException(FileErrorCode.FILE_TRANSFER_TO_LOCAL_ERROR, e);
|
|
|
+ }
|
|
|
+ sysFileDTO = uploadToOss(file, sysFileDTO, sysFileUploadRequest);
|
|
|
+ } catch (Exception e) {
|
|
|
+ sysFileDTO.setSuccess(false);
|
|
|
+ sysFileDTO.setMessage(e.getMessage());
|
|
|
+ }
|
|
|
+ return sysFileDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SysFileDTO uploadExternalFile(String u, SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ SysFileDTO sysFileDTO = new SysFileDTO();
|
|
|
+ try {
|
|
|
+ URL url = URLUtils.url(u);
|
|
|
+ File file = FileUtils.downloadRemoteFile(url.toString(), FileUtils.getFile(GlobalUtils.getTempBaseDir(), SYS_FILE_TEMP_DIR).getAbsolutePath());
|
|
|
+ if (file == null || !file.exists()) {
|
|
|
+ throw new BusinessException(FileErrorCode.FILE_DOWNLOAD_ERROR);
|
|
|
+ }
|
|
|
+ uploadToOss(file, sysFileDTO, sysFileUploadRequest);
|
|
|
+ } catch (Exception e) {
|
|
|
+ sysFileDTO.setSuccess(false);
|
|
|
+ sysFileDTO.setMessage(e.getMessage());
|
|
|
+ }
|
|
|
+ return sysFileDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public SysFileDTO addExternalLink(String u, SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ SysFileDTO sysFileDTO = BeanMapperUtils.map(sysFileUploadRequest, SysFileDTO.class);
|
|
|
+ sysFileDTO.setUrl(u);
|
|
|
+ try {
|
|
|
+ URL url = URLUtils.url(u);
|
|
|
+ SysFile sysFile = new SysFile();
|
|
|
+ sysFile.setId(UUIDUtils.shortUUID());
|
|
|
+ sysFile.setBatchNo(sysFileUploadRequest.getBatchNo());
|
|
|
+ sysFile.setBusinessType(sysFileUploadRequest.getBusinessType());
|
|
|
+ sysFile.setUrl(url.toString());
|
|
|
+ fillNecessaryOperatorProperty(sysFile, null, false);
|
|
|
+ if (save(sysFile)) {
|
|
|
+ sysFileDTO.setSuccess(true);
|
|
|
+ sysFileDTO.setId(sysFile.getId());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ sysFileDTO.setSuccess(false);
|
|
|
+ sysFileDTO.setMessage(e.getMessage());
|
|
|
+ }
|
|
|
+ return sysFileDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ public SysFileDTO uploadToOss(File file, SysFileDTO sysFileDTO, SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ try {
|
|
|
+ prepareMetadata(file, sysFileDTO, sysFileUploadRequest);
|
|
|
+ if (sysFileDTO.getSuccess()) {
|
|
|
+ sysFileDTO.setId(UUIDUtils.shortUUID());
|
|
|
+ SysFile sysfile = BeanMapperUtils.map(sysFileDTO, SysFile.class);
|
|
|
+ fillNecessaryOperatorProperty(sysfile, null, false);
|
|
|
+ save(sysfile);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("增加文件失败,error: {}", e.getMessage());
|
|
|
+ sysFileDTO.setSuccess(false);
|
|
|
+ sysFileDTO.setMessage(e.getMessage());
|
|
|
+ }
|
|
|
+ boolean delete = file.delete();
|
|
|
+ return sysFileDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
|
|
+ public Boolean active(String batchNo, List<String> fileIds) {
|
|
|
+ if (CollectionUtils.isEmpty(fileIds)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ this.update(Wrappers.lambdaUpdate(SysFile.class)
|
|
|
+ .set(SysFile::getActiveFlag, CommonConst.FALSE_NUM)
|
|
|
+ .eq(SysFile::getBatchNo, batchNo));
|
|
|
+ return this.update(Wrappers.lambdaUpdate(SysFile.class)
|
|
|
+ .set(SysFile::getActiveFlag, CommonConst.TRUE_NUM)
|
|
|
+ .eq(SysFile::getBatchNo, batchNo)
|
|
|
+ .in(SysFile::getId, fileIds));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<SysFile> getFileByExpireAt(Date expireAt) {
|
|
|
+ return baseMapper.selectByExpireAt(expireAt);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ @Override
|
|
|
+ public Integer deleteFiles(List<SysFile> sysFiles) {
|
|
|
+ Date now = new Date();
|
|
|
+ sysFiles = sysFiles.stream().peek(s -> {
|
|
|
+ s.setDelFlag(CommonConst.TRUE_NUM.toString());
|
|
|
+ s.setActiveFlag(CommonConst.FALSE_NUM);
|
|
|
+ s.setExpireAt(now);
|
|
|
+ }).collect(toList());
|
|
|
+ return updateBatchById(sysFiles) ? sysFiles.size() : 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Integer clearFiles(List<SysFile> fileList) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Integer removeByBatchNo(String batchNo) {
|
|
|
+ List<SysFile> sysFileList = list(Wrappers.lambdaQuery(SysFile.class).eq(SysFile::getBatchNo, batchNo));
|
|
|
+ return this.deleteFiles(sysFileList);
|
|
|
+ }
|
|
|
+
|
|
|
+ private SysFileDTO prepareMetadata(File file, SysFileDTO sysFileDTO, SysFileUploadRequest sysFileUploadRequest) {
|
|
|
+ String ossKey;
|
|
|
+ if (StringUtils.isNotBlank(sysFileUploadRequest.getKey())) {
|
|
|
+ ossKey = sysFileUploadRequest.getKey();
|
|
|
+ } else {
|
|
|
+ ossKey = generateKey(file, sysFileUploadRequest.getBusinessType());
|
|
|
+ }
|
|
|
+ sysFileDTO.setOssKey(ossKey);
|
|
|
+ sysFileDTO.setOriName(file.getName());
|
|
|
+ sysFileDTO.setBatchNo(sysFileUploadRequest.getBatchNo());
|
|
|
+ sysFileDTO.setBusinessType(sysFileUploadRequest.getBusinessType());
|
|
|
+ sysFileDTO.setActiveFlag(0);
|
|
|
+ sysFileDTO.setFileSize((int) file.length());
|
|
|
+ sysFileDTO.setFileType((StringUtils.isNotBlank(ossKey) && ossKey.lastIndexOf(".") > 0) ? ossKey.substring(ossKey.lastIndexOf(".") + 1) : "");
|
|
|
+ sysFileDTO.setExpireAt(sysFileUploadRequest.getExpireAt());
|
|
|
+ return sysFileDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String generateKey(File file, String businessType) {
|
|
|
+ String newFileName;
|
|
|
+ String dateTimeStr = DateUtils.format(new Date(), OSS_KEY_FILE_NAME_DATE_PATTERN);
|
|
|
+ String fileName = file.getName();
|
|
|
+ String random = UUIDUtils.shortUUID();
|
|
|
+ if (fileName.indexOf(DOT) > 0) {
|
|
|
+ String name = StringUtils.substring(fileName, 0, fileName.indexOf(DOT));
|
|
|
+ String suffix = StringUtils.substring(fileName, fileName.indexOf(DOT) + 1, fileName.length());
|
|
|
+ newFileName = String.format("%s-%s.%s", name, random, suffix);
|
|
|
+ } else {
|
|
|
+ newFileName = String.format("%s-%s", fileName, random);
|
|
|
+ }
|
|
|
+ return String.format("%s/%s/%s", businessType, dateTimeStr, newFileName);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|