FileServiceImpl.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package com.bizmatics.service.impl;
  2. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  3. import com.bizmatics.common.core.bean.UnifiedUser;
  4. import com.bizmatics.common.core.constants.CommonConst;
  5. import com.bizmatics.common.core.exception.BusinessException;
  6. import com.bizmatics.common.core.util.*;
  7. import com.bizmatics.common.mvc.base.AbstractCrudService;
  8. import com.bizmatics.common.spring.injectself.BeanSelfAware;
  9. import com.bizmatics.common.spring.util.GlobalUtils;
  10. import com.bizmatics.model.SysFile;
  11. import com.bizmatics.persistence.mapper.FileMapper;
  12. import com.bizmatics.service.FileSerivce;
  13. import com.bizmatics.service.dto.SysFileDTO;
  14. import com.bizmatics.service.dto.SysFileQueryRequest;
  15. import com.bizmatics.service.dto.SysFileUploadRequest;
  16. import com.bizmatics.service.enums.UploadType;
  17. import com.bizmatics.service.expcetion.FileErrorCode;
  18. import com.google.common.collect.Lists;
  19. import lombok.extern.slf4j.Slf4j;
  20. import org.apache.commons.collections.CollectionUtils;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23. import org.springframework.stereotype.Service;
  24. import org.springframework.transaction.annotation.Propagation;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import org.springframework.web.multipart.commons.CommonsMultipartFile;
  27. import javax.annotation.Nullable;
  28. import java.io.File;
  29. import java.io.IOException;
  30. import java.net.URL;
  31. import java.util.*;
  32. import static java.util.stream.Collectors.toList;
  33. /**
  34. * @author barry chen
  35. */
  36. @Service
  37. @Slf4j
  38. public class FileServiceImpl extends AbstractCrudService<FileMapper, SysFile> implements FileSerivce, BeanSelfAware {
  39. public static final String OSS_KEY_FILE_NAME_DATE_PATTERN = "yyyy-MM";
  40. public static final String SYS_FILE_TEMP_DIR = "file";
  41. public static final String DOT = ".";
  42. private final Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
  43. private FileSerivce self;
  44. @Override
  45. public void setSelf(Object bean) {
  46. this.self = (FileSerivce) bean;
  47. }
  48. @Override
  49. public String generateBatchNo() {
  50. return UUIDUtils.shortUUID();
  51. }
  52. @Override
  53. public List<SysFile> getFile(SysFileQueryRequest req) {
  54. if(StringUtils.isBlank(req.getBatchNo()) && CollectionUtils.isEmpty(req.getFileIds())){
  55. throw new BusinessException(FileErrorCode.FILE_GET_ERROR, "At least one of batchNo and fileIds is required.");
  56. }
  57. return this.list(Wrappers.lambdaQuery(SysFile.class)
  58. .eq(StringUtils.isNotBlank(req.getBatchNo()), SysFile::getBatchNo, req.getBatchNo())
  59. .eq(SysFile::getActiveFlag, CommonConst.TRUE_NUM)
  60. .in(CollectionUtils.isNotEmpty(req.getFileIds()), SysFile::getId, req.getFileIds()));
  61. }
  62. @Override
  63. @Nullable
  64. public List<SysFileDTO> addFile(SysFileUploadRequest sysFileUploadRequest) {
  65. if (StringUtils.isNotBlank(sysFileUploadRequest.getKey())) {
  66. throw new BusinessException(FileErrorCode.FILE_UPLOAD_FILE_ERROR, "V1 upload api doesn't support [key]");
  67. }
  68. if (Objects.isNull(sysFileUploadRequest.getUploadType())) {
  69. sysFileUploadRequest.setUploadType(UploadType.FILE);
  70. }
  71. switch (sysFileUploadRequest.getUploadType()) {
  72. case FILE:
  73. return sysFileUploadRequest.getMultipartFiles().stream().map(m -> self.uploadMultipartFile(m, sysFileUploadRequest)).collect(toList());
  74. case URL:
  75. return sysFileUploadRequest.getUrls().stream().map(m -> self.addExternalLink(m, sysFileUploadRequest)).collect(toList());
  76. case URLBYOSS:
  77. return sysFileUploadRequest.getUrls().stream().map(m -> self.uploadExternalFile(m, sysFileUploadRequest)).collect(toList());
  78. default:
  79. break;
  80. }
  81. return null;
  82. }
  83. @Override
  84. @Nullable
  85. public SysFileDTO addFileV2(SysFileUploadRequest sysFileUploadRequest) {
  86. if (CollectionUtils.isNotEmpty(sysFileUploadRequest.getMultipartFiles()) && sysFileUploadRequest.getMultipartFiles().size() > 1) {
  87. throw new BusinessException(FileErrorCode.FILE_UPLOAD_FILE_ERROR, "V2 upload api only support single file");
  88. }
  89. if (CollectionUtils.isNotEmpty(sysFileUploadRequest.getUrls()) && sysFileUploadRequest.getUrls().size() > 1) {
  90. throw new BusinessException(FileErrorCode.FILE_UPLOAD_FILE_ERROR, "V2 upload api only support single file");
  91. }
  92. if (Objects.isNull(sysFileUploadRequest.getUploadType())) {
  93. sysFileUploadRequest.setUploadType(UploadType.FILE);
  94. }
  95. //如果key以"/"开头, 则去掉
  96. String key = sysFileUploadRequest.getKey();
  97. if (StringUtils.isNotBlank(key) && StringUtils.startsWith(key, File.separator)) {
  98. sysFileUploadRequest.setKey(key.substring(1));
  99. }
  100. switch (sysFileUploadRequest.getUploadType()) {
  101. case FILE:
  102. return self.uploadMultipartFile(sysFileUploadRequest.getMultipartFiles().get(0), sysFileUploadRequest);
  103. case URL:
  104. String u = sysFileUploadRequest.getUrls().get(0);
  105. return self.addExternalLink(u, sysFileUploadRequest);
  106. case URLBYOSS:
  107. return self.uploadExternalFile(sysFileUploadRequest.getUrls().get(0), sysFileUploadRequest);
  108. default:
  109. break;
  110. }
  111. return null;
  112. }
  113. @Override
  114. @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
  115. public SysFileDTO uploadMultipartFile(CommonsMultipartFile multipartFile,
  116. SysFileUploadRequest sysFileUploadRequest) {
  117. SysFileDTO sysFileDTO = new SysFileDTO();
  118. File file = FileUtils.getFile(GlobalUtils.getTempBaseDir(), SYS_FILE_TEMP_DIR, multipartFile.getOriginalFilename());
  119. try {
  120. try {
  121. multipartFile.transferTo(file);
  122. } catch (IOException e) {
  123. throw new BusinessException(FileErrorCode.FILE_TRANSFER_TO_LOCAL_ERROR, e);
  124. }
  125. sysFileDTO = uploadToOss(file, sysFileDTO, sysFileUploadRequest);
  126. } catch (Exception e) {
  127. sysFileDTO.setSuccess(false);
  128. sysFileDTO.setMessage(e.getMessage());
  129. }
  130. return sysFileDTO;
  131. }
  132. @Override
  133. public SysFileDTO uploadExternalFile(String u, SysFileUploadRequest sysFileUploadRequest) {
  134. SysFileDTO sysFileDTO = new SysFileDTO();
  135. try {
  136. URL url = URLUtils.url(u);
  137. File file = FileUtils.downloadRemoteFile(url.toString(), FileUtils.getFile(GlobalUtils.getTempBaseDir(), SYS_FILE_TEMP_DIR).getAbsolutePath());
  138. if (file == null || !file.exists()) {
  139. throw new BusinessException(FileErrorCode.FILE_DOWNLOAD_ERROR);
  140. }
  141. uploadToOss(file, sysFileDTO, sysFileUploadRequest);
  142. } catch (Exception e) {
  143. sysFileDTO.setSuccess(false);
  144. sysFileDTO.setMessage(e.getMessage());
  145. }
  146. return sysFileDTO;
  147. }
  148. @Override
  149. public SysFileDTO addExternalLink(String u, SysFileUploadRequest sysFileUploadRequest) {
  150. SysFileDTO sysFileDTO = BeanMapperUtils.map(sysFileUploadRequest, SysFileDTO.class);
  151. sysFileDTO.setUrl(u);
  152. try {
  153. URL url = URLUtils.url(u);
  154. SysFile sysFile = new SysFile();
  155. sysFile.setId(UUIDUtils.shortUUID());
  156. sysFile.setBatchNo(sysFileUploadRequest.getBatchNo());
  157. sysFile.setBusinessType(sysFileUploadRequest.getBusinessType());
  158. sysFile.setUrl(url.toString());
  159. fillNecessaryOperatorProperty(sysFile, null, false);
  160. if (save(sysFile)) {
  161. sysFileDTO.setSuccess(true);
  162. sysFileDTO.setId(sysFile.getId());
  163. }
  164. } catch (Exception e) {
  165. sysFileDTO.setSuccess(false);
  166. sysFileDTO.setMessage(e.getMessage());
  167. }
  168. return sysFileDTO;
  169. }
  170. public SysFileDTO uploadToOss(File file, SysFileDTO sysFileDTO, SysFileUploadRequest sysFileUploadRequest) {
  171. try {
  172. prepareMetadata(file, sysFileDTO, sysFileUploadRequest);
  173. if (sysFileDTO.getSuccess()) {
  174. sysFileDTO.setId(UUIDUtils.shortUUID());
  175. SysFile sysfile = BeanMapperUtils.map(sysFileDTO, SysFile.class);
  176. fillNecessaryOperatorProperty(sysfile, null, false);
  177. save(sysfile);
  178. }
  179. } catch (Exception e) {
  180. logger.error("增加文件失败,error: {}", e.getMessage());
  181. sysFileDTO.setSuccess(false);
  182. sysFileDTO.setMessage(e.getMessage());
  183. }
  184. boolean delete = file.delete();
  185. return sysFileDTO;
  186. }
  187. @Override
  188. @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
  189. public Boolean active(String batchNo, List<String> fileIds) {
  190. if (CollectionUtils.isEmpty(fileIds)) {
  191. return false;
  192. }
  193. this.update(Wrappers.lambdaUpdate(SysFile.class)
  194. .set(SysFile::getActiveFlag, CommonConst.FALSE_NUM)
  195. .eq(SysFile::getBatchNo, batchNo));
  196. return this.update(Wrappers.lambdaUpdate(SysFile.class)
  197. .set(SysFile::getActiveFlag, CommonConst.TRUE_NUM)
  198. .eq(SysFile::getBatchNo, batchNo)
  199. .in(SysFile::getId, fileIds));
  200. }
  201. @Override
  202. public List<SysFile> getFileByExpireAt(Date expireAt) {
  203. return baseMapper.selectByExpireAt(expireAt);
  204. }
  205. @Transactional(rollbackFor = Exception.class)
  206. @Override
  207. public Integer deleteFiles(List<SysFile> sysFiles) {
  208. Date now = new Date();
  209. sysFiles = sysFiles.stream().peek(s -> {
  210. s.setDelFlag(CommonConst.TRUE_NUM.toString());
  211. s.setActiveFlag(CommonConst.FALSE_NUM);
  212. s.setExpireAt(now);
  213. }).collect(toList());
  214. return updateBatchById(sysFiles) ? sysFiles.size() : 0;
  215. }
  216. @Override
  217. public Integer clearFiles(List<SysFile> fileList) {
  218. return null;
  219. }
  220. @Override
  221. public Integer removeByBatchNo(String batchNo) {
  222. List<SysFile> sysFileList = list(Wrappers.lambdaQuery(SysFile.class).eq(SysFile::getBatchNo, batchNo));
  223. return this.deleteFiles(sysFileList);
  224. }
  225. private SysFileDTO prepareMetadata(File file, SysFileDTO sysFileDTO, SysFileUploadRequest sysFileUploadRequest) {
  226. String ossKey;
  227. if (StringUtils.isNotBlank(sysFileUploadRequest.getKey())) {
  228. ossKey = sysFileUploadRequest.getKey();
  229. } else {
  230. ossKey = generateKey(file, sysFileUploadRequest.getBusinessType());
  231. }
  232. sysFileDTO.setOssKey(ossKey);
  233. sysFileDTO.setOriName(file.getName());
  234. sysFileDTO.setBatchNo(sysFileUploadRequest.getBatchNo());
  235. sysFileDTO.setBusinessType(sysFileUploadRequest.getBusinessType());
  236. sysFileDTO.setActiveFlag(0);
  237. sysFileDTO.setFileSize((int) file.length());
  238. sysFileDTO.setFileType((StringUtils.isNotBlank(ossKey) && ossKey.lastIndexOf(".") > 0) ? ossKey.substring(ossKey.lastIndexOf(".") + 1) : "");
  239. sysFileDTO.setExpireAt(sysFileUploadRequest.getExpireAt());
  240. return sysFileDTO;
  241. }
  242. private String generateKey(File file, String businessType) {
  243. String newFileName;
  244. String dateTimeStr = DateUtils.format(new Date(), OSS_KEY_FILE_NAME_DATE_PATTERN);
  245. String fileName = file.getName();
  246. String random = UUIDUtils.shortUUID();
  247. if (fileName.indexOf(DOT) > 0) {
  248. String name = StringUtils.substring(fileName, 0, fileName.indexOf(DOT));
  249. String suffix = StringUtils.substring(fileName, fileName.indexOf(DOT) + 1, fileName.length());
  250. newFileName = String.format("%s-%s.%s", name, random, suffix);
  251. } else {
  252. newFileName = String.format("%s-%s", fileName, random);
  253. }
  254. return String.format("%s/%s/%s", businessType, dateTimeStr, newFileName);
  255. }
  256. }