package cn.chnmuseum.party.web.controller; import cn.chnmuseum.party.common.dfs.FastDFSUtils; import cn.chnmuseum.party.common.enums.FileCatEnum; import cn.chnmuseum.party.common.enums.FileTypeEnum; import cn.chnmuseum.party.common.enums.HANDLE_STATUS_ENUM; import cn.chnmuseum.party.common.enums.LanguageEnum; import cn.chnmuseum.party.common.util.LCSUtil; import cn.chnmuseum.party.common.util.TimeUtils; import cn.chnmuseum.party.common.video.VideoEncryptUtil; import cn.chnmuseum.party.common.vo.BatchUploadResVO; import cn.chnmuseum.party.common.vo.ImageUploadResult; import cn.chnmuseum.party.model.Asset; import cn.chnmuseum.party.service.AssetService; import cn.chnmuseum.party.web.controller.base.BaseController; import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.github.tobato.fastdfs.domain.fdfs.FileInfo; import com.github.tobato.fastdfs.domain.fdfs.MetaData; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.springframework.context.annotation.Scope; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.LocalDateTime; import java.util.*; /** * <p> * 文件上传 前端控制器 * </p> * * @author Danny Lee * @since 2021-03-16 */ @Slf4j @RestController @RequestMapping("/file") @Api(tags = {"文件上传接口"}) @Scope("prototype") public class FileUploadController extends BaseController { private static final String[] IMAGE_TYPE = new String[]{"JPG", "JPEG", "PNG", "BMP", "WBMP"}; private static final String[] AUDIO_TYPE = new String[]{"MP3", "AAC", "WMA", "FLAC", "RM", "OGG"}; private static final String[] VIDEO_TYPE = new String[]{"MP4", "FLV", "MPEG", "MPG", "MOV"}; private static final String[] DOC_TYPE = new String[]{"PDF", "DOC", "DOCX", "PPT", "PPTX"}; private static final char[] SPLITTER_CHAR_2 = new char[]{'@', '#'}; private static final char[] SPLITTER_CHAR_3 = new char[]{'@', '#', '$'}; private static final char[] SPLITTER_CHAR_4 = new char[]{'@', '#', '$', '%'}; private static final char[] SPLITTER_CHAR_5 = new char[]{'@', '#', '$', '%', '&'}; private static final String[] DATUM_TYPE = ArrayUtil.addAll(DOC_TYPE, IMAGE_TYPE, VIDEO_TYPE); @Resource private AssetService assetService; @ApiOperation(value = "根据文件ID刪除文件", notes = "根据文件ID刪除文件") @DeleteMapping(value = "/delete/{id}") @RequiresAuthentication //@RequiresPermissions("file:delete") public Map<String, Object> delete(@PathVariable(value = "id") String id) { final Asset asset = assetService.getById(id); if (asset != null) { final String fileUrl = asset.getFileUrl(); final String fileUrlCrypto = asset.getFileUrlCrypto(); try { FastDFSUtils.deleteFile(fileUrl); FastDFSUtils.deleteFile(fileUrlCrypto); } catch (Throwable e) { this.assetService.removeById(id); return getResult("文件已被删除"); } this.assetService.removeById(id); return getSuccessResult(); } return getResult("文件已被删除"); } @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "资料", paramType = "form", dataType = "__file", collectionFormat = "array", allowMultiple = true) }) @PostMapping(value = "/datum/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @ApiOperation(value = "展板资料上传", notes = "展板资料上传") public Map<String, Object> uploadDatum(@RequestPart(value = "file", required = false) MultipartFile[] files) throws IOException { if (files == null || files.length == 0) { return getFailResult("没有文件可供上传"); } int successCount = 0; int failureCount = 0; List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>(); Set<Asset> datumUrlList = new LinkedHashSet<>(); for (MultipartFile file : files) { // 当前维度表下线结果 BatchUploadResVO.HandleResult handleResult = new BatchUploadResVO.HandleResult(); // 原始文件名 String originalFilename = file.getOriginalFilename(); if (StringUtils.isBlank(originalFilename)) { handleResult.setFileName(""); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件名为空"); failureCount++; handleList.add(handleResult); continue; } if (file.getSize() == 0L) { handleResult.setFileName(""); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件" + originalFilename + "大小为0"); failureCount++; handleList.add(handleResult); continue; } String baseName = FilenameUtils.getBaseName(originalFilename); String extName = FilenameUtils.getExtension(originalFilename); String finalExtName = extName; boolean anyMatch = Arrays.stream(DATUM_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase())); if (anyMatch) { if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) { extName = "mp4"; originalFilename = FilenameUtils.getBaseName(originalFilename) + "." + extName; } final Asset asset = Asset.builder() .fileName(originalFilename) .fileExtName(extName) .fileCat(FileCatEnum.EXHIBITION_BOARD_DATUM.name()) .build(); String language = null; final Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("fileName", originalFilename)); if (originalFilename.contains("汉语")) { metaDataSet.add(new MetaData("language", LanguageEnum.ZH.name())); language = LanguageEnum.ZH.name(); } else if (originalFilename.contains("英语")) { metaDataSet.add(new MetaData("language", LanguageEnum.EN.name())); language = LanguageEnum.EN.name(); } else if (originalFilename.contains("蒙语")) { metaDataSet.add(new MetaData("language", LanguageEnum.MN.name())); language = LanguageEnum.MN.name(); } else if (originalFilename.contains("藏语")) { metaDataSet.add(new MetaData("language", LanguageEnum.BO.name())); language = LanguageEnum.BO.name(); } else if (originalFilename.contains("维吾尔语")) { metaDataSet.add(new MetaData("language", LanguageEnum.UYG.name())); language = LanguageEnum.UYG.name(); } String fileUrl = null; String fileUrlCrypto = null; if (Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) { metaDataSet.add(new MetaData("fileType", FileTypeEnum.VIDEO.name())); handleResult.setFileType(FileTypeEnum.VIDEO.name()); asset.setFileType(FileTypeEnum.VIDEO.name()); final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); IOUtils.copy(file.getInputStream(), byteArrayOutputStream); fileUrl = FastDFSUtils.uploadVideo(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), file.getSize(), originalFilename, metaDataSet); metaDataSet.add(new MetaData("fileName", baseName + ".chnmuseum")); fileUrlCrypto = FastDFSUtils.uploadVideo(VideoEncryptUtil.encrypt(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), VideoEncryptUtil.cipher), file.getSize(), baseName + ".chnmuseum", metaDataSet); final Set<MetaData> fileMetaData = FastDFSUtils.getFileMetaData(fileUrlCrypto); String md5 = fileMetaData.stream().filter(x -> "MD5".equals(x.getName())).map(MetaData::getValue).findFirst().get(); asset.setMd5(md5); asset.setIntro(Base64.getEncoder().encodeToString(fileUrl.getBytes())); asset.setFileUrlCrypto(md5 + ".chnmuseum"); } else if (Arrays.stream(AUDIO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) { metaDataSet.add(new MetaData("fileType", FileTypeEnum.AUDIO.name())); handleResult.setFileType(FileTypeEnum.AUDIO.name()); asset.setFileType(FileTypeEnum.AUDIO.name()); fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet); } else if (Arrays.stream(IMAGE_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) { metaDataSet.add(new MetaData("fileType", FileTypeEnum.IMAGE.name())); handleResult.setFileType(FileTypeEnum.IMAGE.name()); asset.setFileType(FileTypeEnum.IMAGE.name()); fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet); asset.setThumbnail(fileUrl); } else if (Arrays.stream(DOC_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) { metaDataSet.add(new MetaData("fileType", FileTypeEnum.DOCUMENT.name())); handleResult.setFileType(FileTypeEnum.DOCUMENT.name()); asset.setFileType(FileTypeEnum.DOCUMENT.name()); fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet); } final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl); final int crc32 = fileInfo.getCrc32(); final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1")); final LocalDateTime createTime = TimeUtils.getDateTimeOfTimestamp(fileInfo.getCreateTime() * 1000); asset.setFileSize(fileInfo.getFileSize()); asset.setFileUrl(fileUrl); asset.setFileUrlCrypto(fileUrlCrypto); asset.setFileCat(FileCatEnum.EXHIBITION_BOARD_DATUM.name()); asset.setLanguage(language); if (Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) { asset.setCrc32((long) crc32); } asset.setCreateTime(createTime); asset.setUpdateTime(createTime); if (one != null) { try { FastDFSUtils.deleteFile(fileUrl); FastDFSUtils.deleteFile(fileUrlCrypto); } catch (Throwable ignored) { } asset.setFileUrl(one.getFileUrl()); asset.setFileUrlCrypto(one.getFileUrlCrypto()); } this.assetService.save(asset); datumUrlList.add(asset); handleResult.setFileUrl(""); handleResult.setFileName(originalFilename); handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName()); handleResult.setDescription(""); successCount++; } else { handleResult.setFileUrl(""); handleResult.setDescription("文件" + originalFilename + "格式不支持"); failureCount++; } // 设置处理的业务表信息 handleList.add(handleResult); } BatchUploadResVO batchUploadResVO = new BatchUploadResVO(); batchUploadResVO.setFailureCount(failureCount); batchUploadResVO.setSuccessCount(successCount); batchUploadResVO.setTotal(files.length); batchUploadResVO.setHandleList(handleList); batchUploadResVO.setFileList(datumUrlList); if (failureCount > 0) { return getFailResult(batchUploadResVO); } return getResult(batchUploadResVO); } @PostMapping(value = "/image/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @RequiresAuthentication //@RequiresPermissions("file:image:upload") @ApiOperation(value = "单图片上传(封面/缩略图)", notes = "单图片上传(封面/缩略图)") public Map<String, Object> uploadImage(@RequestParam(value = "file") MultipartFile uploadFile) throws Exception { if (uploadFile == null) { return getFailResult("没有文件可供上传"); } String fileName = uploadFile.getOriginalFilename(); String extension = FilenameUtils.getExtension(fileName); if (StringUtils.isBlank(extension)) { return getFailResult("文件格式不支持"); } boolean anyMatch = Arrays.stream(IMAGE_TYPE).anyMatch(s -> Objects.equals(s, extension.toUpperCase())); if (!anyMatch) { return getFailResult("文件格式不支持"); } final Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("fileName", fileName)); metaDataSet.add(new MetaData("fileType", FileTypeEnum.IMAGE.name())); String url = FastDFSUtils.uploadFile(uploadFile.getInputStream(), uploadFile.getSize(), fileName, metaDataSet); ImageUploadResult imageUploadResult = new ImageUploadResult(); imageUploadResult.setFileName(fileName); imageUploadResult.setFileExtName(extension); imageUploadResult.setFileSize(uploadFile.getSize()); imageUploadResult.setUrl(url); return getResult(imageUploadResult); } @PostMapping(value = "/upload/allType", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @RequiresAuthentication //@RequiresPermissions("file:upload:allType") @ApiOperation(value = "单文件上传(不限格式)", notes = "单文件上传(不限格式)") public Map<String, Object> uploadAllType(@RequestParam(value = "file") MultipartFile uploadFile) throws Exception { if (uploadFile == null) { return getFailResult("没有文件可供上传"); } String fileName = uploadFile.getOriginalFilename(); String extension = FilenameUtils.getExtension(fileName); if (StringUtils.isBlank(extension)) { return getFailResult("文件格式不支持"); } final Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("fileName", fileName)); String url = FastDFSUtils.uploadFile(uploadFile.getInputStream(), uploadFile.getSize(), fileName, metaDataSet); ImageUploadResult imageUploadResult = new ImageUploadResult(); imageUploadResult.setFileName(fileName); imageUploadResult.setFileExtName(extension); imageUploadResult.setFileSize(uploadFile.getSize()); imageUploadResult.setUrl(url); return getResult(imageUploadResult); } @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "音频文件", paramType = "form", dataType = "__file", collectionFormat = "array", allowMultiple = true) }) @PostMapping(value = "/audio/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @RequiresAuthentication //@RequiresPermissions("audio:upload") @ApiOperation(value = "展板多音频上传", notes = "展板多音频上传") public Map<String, Object> uploadAudio(@RequestPart(value = "file", required = false) MultipartFile[] files) throws IOException { if (files == null || files.length == 0) { return getFailResult("没有文件可供上传"); } final boolean existChineseAudio = Arrays.stream(files).anyMatch(s -> Objects.requireNonNull(s.getOriginalFilename()).contains("汉语")); if (!existChineseAudio) { return getFailResult("必须包含汉语音频"); } int successCount = 0; int failureCount = 0; List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>(); Set<Asset> fileList = new LinkedHashSet<>(); for (MultipartFile file : files) { // 当前维度表下线结果 BatchUploadResVO.HandleResult handleResult = new BatchUploadResVO.HandleResult(); // 原始文件名 String originalFilename = file.getOriginalFilename(); if (StringUtils.isBlank(originalFilename)) { handleResult.setFileName(""); handleResult.setFileType(FileTypeEnum.AUDIO.getName()); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件名为空"); failureCount++; handleList.add(handleResult); continue; } if (file.getSize() == 0L) { handleResult.setFileName(""); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件" + originalFilename + "大小为0"); failureCount++; handleList.add(handleResult); continue; } String extName = FilenameUtils.getExtension(originalFilename); boolean anyMatch = Arrays.stream(AUDIO_TYPE).anyMatch(s -> Objects.equals(s, extName.toUpperCase())); if (anyMatch) { String language = null; final Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("fileName", originalFilename)); metaDataSet.add(new MetaData("fileType", FileTypeEnum.AUDIO.name())); if (originalFilename.contains("汉语")) { metaDataSet.add(new MetaData("language", LanguageEnum.ZH.name())); language = LanguageEnum.ZH.name(); } else if (originalFilename.contains("英语")) { metaDataSet.add(new MetaData("language", LanguageEnum.EN.name())); language = LanguageEnum.EN.name(); } else if (originalFilename.contains("蒙语")) { metaDataSet.add(new MetaData("language", LanguageEnum.MN.name())); language = LanguageEnum.MN.name(); } else if (originalFilename.contains("藏语")) { metaDataSet.add(new MetaData("language", LanguageEnum.BO.name())); language = LanguageEnum.BO.name(); } else if (originalFilename.contains("维吾尔语")) { metaDataSet.add(new MetaData("language", LanguageEnum.UYG.name())); language = LanguageEnum.UYG.name(); } String fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet); final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl); final int crc32 = fileInfo.getCrc32(); final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1")); final LocalDateTime createTime = TimeUtils.getDateTimeOfTimestamp(fileInfo.getCreateTime() * 1000); final long fileSize = fileInfo.getFileSize(); final Asset asset = Asset.builder() .fileName(originalFilename) .fileExtName(extName) .fileType(FileTypeEnum.AUDIO.name()) .fileUrl(fileUrl) .fileSize(fileSize) .fileCat(FileCatEnum.EXHIBITION_BOARD_AUDIO.name()) .language(language) .crc32((long) crc32) .createTime(createTime) .updateTime(createTime) .build(); if (one != null) { FastDFSUtils.deleteFile(fileUrl); asset.setFileUrl(one.getFileUrl()); } this.assetService.save(asset); fileList.add(asset); handleResult.setFileUrl(fileUrl); handleResult.setFileName(originalFilename); handleResult.setFileType(FileTypeEnum.AUDIO.getName()); handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName()); handleResult.setDescription(""); successCount++; } else { handleResult.setFileUrl(""); handleResult.setFileType(FileTypeEnum.AUDIO.getName()); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件" + originalFilename + "格式不支持"); failureCount++; } // 设置处理的业务表信息 handleList.add(handleResult); } BatchUploadResVO batchUploadResVO = new BatchUploadResVO(); batchUploadResVO.setFailureCount(failureCount); batchUploadResVO.setSuccessCount(successCount); batchUploadResVO.setTotal(files.length); batchUploadResVO.setHandleList(handleList); batchUploadResVO.setFileList(fileList); return getResult(batchUploadResVO); } @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "视频文件", paramType = "form", dataType = "__file", collectionFormat = "array", allowMultiple = true, required = true) }) @PostMapping(value = "/video/content/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @RequiresAuthentication //@RequiresPermissions("file:video:content:upload") @ApiOperation(value = "展板视频上传", notes = "展板视频上传") public Map<String, Object> uploadContentVideo(@RequestPart("file") MultipartFile[] files) throws Exception { if (files == null || files.length == 0) { return getFailResult("没有文件可供上传"); } if (files.length == 1) { String extName = FilenameUtils.getExtension(files[0].getOriginalFilename()); boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, extName.toUpperCase())); if (!anyMatch) { return getFailResult("目前仅支持" + String.join("、", VIDEO_TYPE) + "格式"); } } String videoContentName = null; String text; LCSUtil strie = null; final String[] fileBaseNameArray = Arrays.stream(files).map(x -> FilenameUtils.getBaseName(x.getOriginalFilename())).toArray(String[]::new); switch (fileBaseNameArray.length) { case 1: videoContentName = fileBaseNameArray[0]; break; case 2: text = fileBaseNameArray[0] + SPLITTER_CHAR_2[0] + fileBaseNameArray[1] + SPLITTER_CHAR_2[1]; strie = new LCSUtil(text, SPLITTER_CHAR_2); break; case 3: text = fileBaseNameArray[0] + SPLITTER_CHAR_3[0] + fileBaseNameArray[1] + SPLITTER_CHAR_3[1] + fileBaseNameArray[2] + SPLITTER_CHAR_3[2]; strie = new LCSUtil(text, SPLITTER_CHAR_3); break; case 4: text = fileBaseNameArray[0] + SPLITTER_CHAR_4[0] + fileBaseNameArray[1] + SPLITTER_CHAR_4[1] + fileBaseNameArray[2] + SPLITTER_CHAR_4[2] + fileBaseNameArray[3] + SPLITTER_CHAR_4[3]; strie = new LCSUtil(text, SPLITTER_CHAR_4); break; case 5: text = fileBaseNameArray[0] + SPLITTER_CHAR_5[0] + fileBaseNameArray[1] + SPLITTER_CHAR_5[1] + fileBaseNameArray[2] + SPLITTER_CHAR_5[2] + fileBaseNameArray[3] + SPLITTER_CHAR_5[3] + fileBaseNameArray[4] + SPLITTER_CHAR_5[4]; strie = new LCSUtil(text, SPLITTER_CHAR_5); break; default: break; } if (strie != null) { strie.buildSuffixTree(); videoContentName = strie.findLCS(); if (StringUtils.isBlank(videoContentName)) { return getFailResult("请修改你的文件名并保持前缀一致后再上传"); } else { videoContentName = StringUtils.removeEnd(videoContentName.trim(), "{"); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "["); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "【"); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "("); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "("); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "-"); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "_"); videoContentName = StringUtils.removeEnd(videoContentName.trim(), "之"); } } int successCount = 0; int failureCount = 0; List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>(); Set<Asset> fileList = new LinkedHashSet<>(); for (MultipartFile file : files) { // 当前维度表下线结果 BatchUploadResVO.HandleResult handleResult = new BatchUploadResVO.HandleResult(); // 原始文件名 String originalFilename = file.getOriginalFilename(); if (StringUtils.isBlank(originalFilename)) { handleResult.setFileName(""); handleResult.setFileType(FileTypeEnum.VIDEO.getName()); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件名为空"); failureCount++; handleList.add(handleResult); continue; } if (file.getSize() == 0L) { handleResult.setFileName(""); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件" + originalFilename + "大小为0"); failureCount++; handleList.add(handleResult); continue; } final String baseName = FilenameUtils.getBaseName(originalFilename); String extName = FilenameUtils.getExtension(originalFilename); String finalExtName = extName; boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase())); if (anyMatch) { if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) { extName = "mp4"; originalFilename = baseName + "." + extName; } String language = null; final Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("fileName", originalFilename)); metaDataSet.add(new MetaData("fileType", FileTypeEnum.VIDEO.name())); if (originalFilename.contains("汉语")) { metaDataSet.add(new MetaData("language", LanguageEnum.ZH.name())); language = LanguageEnum.ZH.name(); } else if (originalFilename.contains("蒙语")) { metaDataSet.add(new MetaData("language", LanguageEnum.MN.name())); language = LanguageEnum.MN.name(); } else if (originalFilename.contains("藏语")) { metaDataSet.add(new MetaData("language", LanguageEnum.BO.name())); language = LanguageEnum.BO.name(); } else if (originalFilename.contains("维吾尔语")) { metaDataSet.add(new MetaData("language", LanguageEnum.UYG.name())); language = LanguageEnum.UYG.name(); } final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); IOUtils.copy(file.getInputStream(), byteArrayOutputStream); final String fileUrl = FastDFSUtils.uploadVideo(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), file.getSize(), originalFilename, metaDataSet); metaDataSet.add(new MetaData("fileName", baseName + ".chnmuseum")); final String fileUrlCrypto = FastDFSUtils.uploadVideo(VideoEncryptUtil.encrypt(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), VideoEncryptUtil.cipher), file.getSize(), baseName + ".chnmuseum", metaDataSet); final Set<MetaData> fileMetaData = FastDFSUtils.getFileMetaData(fileUrlCrypto); String md5 = fileMetaData.stream().filter(x -> "MD5".equals(x.getName())).map(MetaData::getValue).findFirst().get(); final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl); final int crc32 = fileInfo.getCrc32(); final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1")); final LocalDateTime createTime = TimeUtils.getDateTimeOfTimestamp(fileInfo.getCreateTime() * 1000); final long fileSize = fileInfo.getFileSize(); final Asset asset = Asset.builder() .fileName(originalFilename) .fileNameCrypto(md5 + ".chnmuseum") .fileExtName(extName) .fileType(FileTypeEnum.VIDEO.name()) .fileSize(fileSize) .fileUrl(fileUrl) .intro(Base64.getEncoder().encodeToString(fileUrl.getBytes())) .fileUrlCrypto(fileUrlCrypto) .fileCat(FileCatEnum.VIDEO_CONTENT.name()) .language(language) .md5(md5) .crc32((long) crc32) .videoContentName(videoContentName) .createTime(createTime) .updateTime(createTime) .build(); if (one != null) { FastDFSUtils.deleteFile(fileUrl); FastDFSUtils.deleteFile(fileUrlCrypto); asset.setFileUrl(one.getFileUrl()); asset.setFileUrlCrypto(one.getFileUrlCrypto()); } this.assetService.save(asset); fileList.add(asset); handleResult.setFileUrl(""); handleResult.setFileName(originalFilename); handleResult.setFileType(FileTypeEnum.VIDEO.getName()); handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName()); handleResult.setDescription(""); successCount++; } else { handleResult.setFileUrl(""); handleResult.setHandleResult("上传失败"); handleResult.setDescription("文件" + originalFilename + "格式不支持"); failureCount++; } // 设置处理的业务表信息 handleList.add(handleResult); } BatchUploadResVO batchUploadResVO = new BatchUploadResVO(); batchUploadResVO.setFailureCount(failureCount); batchUploadResVO.setSuccessCount(successCount); batchUploadResVO.setTotal(files.length); batchUploadResVO.setHandleList(handleList); batchUploadResVO.setFileList(fileList); return getResult(batchUploadResVO); } @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "视频文件", paramType = "form", dataType = "__file", collectionFormat = "array", allowMultiple = true, required = true) }) @PostMapping(value = "/video/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @RequiresAuthentication //@RequiresPermissions("file:video:upload") @ApiOperation(value = "多视频上传", notes = "多视频上传") public Map<String, Object> uploadVideo(@RequestPart("file") MultipartFile[] files) throws IOException { if (files == null || files.length == 0) { return getFailResult("没有文件可供上传"); } if (files.length == 1) { String extName = FilenameUtils.getExtension(files[0].getOriginalFilename()); boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, extName.toUpperCase())); if (!anyMatch) { return getFailResult("目前仅支持" + String.join("、", VIDEO_TYPE) + "格式"); } } int successCount = 0; int failureCount = 0; List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>(); Set<Asset> fileList = new LinkedHashSet<>(); for (MultipartFile file : files) { // 当前维度表下线结果 BatchUploadResVO.HandleResult handleResult = new BatchUploadResVO.HandleResult(); // 原始文件名 String originalFilename = file.getOriginalFilename(); if (StringUtils.isBlank(originalFilename)) { handleResult.setFileName(""); handleResult.setFileType(FileTypeEnum.VIDEO.getName()); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件名为空"); failureCount++; handleList.add(handleResult); continue; } if (file.getSize() == 0L) { handleResult.setFileName(""); handleResult.setFileUrl(""); handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName()); handleResult.setDescription("文件" + originalFilename + "大小为0"); failureCount++; handleList.add(handleResult); continue; } String extName = FilenameUtils.getExtension(originalFilename); String finalExtName = extName; boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase())); if (anyMatch) { if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) { extName = "mp4"; originalFilename = FilenameUtils.getBaseName(originalFilename) + "." + extName; } final Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("fileName", originalFilename)); metaDataSet.add(new MetaData("fileType", FileTypeEnum.VIDEO.name())); final String fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet); final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl); final Asset asset = Asset.builder() .fileName(originalFilename) .fileExtName(extName) .fileType(FileTypeEnum.VIDEO.name()) .fileSize(fileInfo.getFileSize()) .fileUrl(fileUrl) .fileCat(FileCatEnum.VIEWING_INTERACTION.name()) .crc32((long) fileInfo.getCrc32()) .build(); this.assetService.save(asset); fileList.add(asset); handleResult.setFileUrl(fileUrl); handleResult.setFileName(originalFilename); handleResult.setFileType(FileTypeEnum.VIDEO.getName()); handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName()); handleResult.setDescription(""); successCount++; } else { handleResult.setFileUrl(""); handleResult.setHandleResult("上传失败"); handleResult.setDescription("文件" + originalFilename + "格式不支持"); failureCount++; } // 设置处理的业务表信息 handleList.add(handleResult); } BatchUploadResVO batchUploadResVO = new BatchUploadResVO(); batchUploadResVO.setFailureCount(failureCount); batchUploadResVO.setSuccessCount(successCount); batchUploadResVO.setTotal(files.length); batchUploadResVO.setHandleList(handleList); batchUploadResVO.setFileList(fileList); return getResult(batchUploadResVO); } }