FileUploadController.java 37.5 KB
Newer Older
liqin's avatar
liqin committed
1
package cn.chnmuseum.party.web.controller;
liqin's avatar
liqin committed
2

liqin's avatar
liqin committed
3
import cn.chnmuseum.party.common.dfs.FastDFSUtils;
liqin's avatar
liqin committed
4 5 6 7
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;
liqin's avatar
liqin committed
8 9 10 11 12 13 14 15
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;
liqin's avatar
liqin committed
16
import cn.hutool.core.util.ArrayUtil;
liqin's avatar
liqin committed
17
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
liqin's avatar
liqin committed
18 19
import com.github.tobato.fastdfs.domain.fdfs.FileInfo;
import com.github.tobato.fastdfs.domain.fdfs.MetaData;
liqin's avatar
liqin committed
20
import io.swagger.annotations.Api;
liqin's avatar
liqin committed
21 22 23 24 25
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;
liqin's avatar
liqin committed
26
import org.apache.commons.io.IOUtils;
liqin's avatar
liqin committed
27
import org.apache.commons.lang3.StringUtils;
wzp's avatar
wzp committed
28
import org.apache.shiro.authz.annotation.RequiresAuthentication;
liqin's avatar
liqin committed
29
import org.springframework.context.annotation.Scope;
liqin's avatar
liqin committed
30 31 32 33
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

liqin's avatar
liqin committed
34
import javax.annotation.Resource;
liqin's avatar
liqin committed
35 36
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
liqin's avatar
liqin committed
37
import java.io.IOException;
liqin's avatar
liqin committed
38
import java.time.LocalDateTime;
liqin's avatar
liqin committed
39
import java.util.*;
liqin's avatar
liqin committed
40 41 42 43 44 45 46 47 48 49 50 51

/**
 * <p>
 * 文件上传 前端控制器
 * </p>
 *
 * @author Danny Lee
 * @since 2021-03-16
 */
@Slf4j
@RestController
@RequestMapping("/file")
liqin's avatar
liqin committed
52
@Api(tags = {"文件上传接口"})
liqin's avatar
liqin committed
53
@Scope("prototype")
liqin's avatar
liqin committed
54
public class FileUploadController extends BaseController {
liqin's avatar
liqin committed
55 56

    private static final String[] IMAGE_TYPE = new String[]{"JPG", "JPEG", "PNG", "BMP", "WBMP"};
liqin's avatar
liqin committed
57
    private static final String[] AUDIO_TYPE = new String[]{"MP3", "AAC", "WMA", "FLAC", "RM", "OGG"};
liqin's avatar
liqin committed
58
    private static final String[] VIDEO_TYPE = new String[]{"MP4", "FLV", "MPEG", "MPG", "MOV"};
liqin's avatar
liqin committed
59
    private static final String[] DOC_TYPE = new String[]{"PDF", "DOC", "DOCX", "PPT", "PPTX"};
liqin's avatar
liqin committed
60 61 62 63
    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[]{'@', '#', '$', '%', '&'};
liqin's avatar
liqin committed
64
    private static final String[] DATUM_TYPE = ArrayUtil.addAll(DOC_TYPE, IMAGE_TYPE, VIDEO_TYPE);
liqin's avatar
liqin committed
65

liqin's avatar
liqin committed
66 67 68 69 70
    @Resource
    private AssetService assetService;

    @ApiOperation(value = "根据文件ID刪除文件", notes = "根据文件ID刪除文件")
    @DeleteMapping(value = "/delete/{id}")
wzp's avatar
wzp committed
71
    @RequiresAuthentication  //@RequiresPermissions("file:delete")
liqin's avatar
liqin committed
72
    public Map<String, Object> delete(@PathVariable(value = "id") String id) {
liqin's avatar
liqin committed
73 74 75
        final Asset asset = assetService.getById(id);
        if (asset != null) {
            final String fileUrl = asset.getFileUrl();
liqin's avatar
liqin committed
76
            final String fileUrlCrypto = asset.getFileUrlCrypto();
liqin's avatar
liqin committed
77 78
            try {
                FastDFSUtils.deleteFile(fileUrl);
liqin's avatar
liqin committed
79
                FastDFSUtils.deleteFile(fileUrlCrypto);
liqin's avatar
liqin committed
80
            } catch (Throwable e) {
liqin's avatar
liqin committed
81
                this.assetService.removeById(id);
liqin's avatar
liqin committed
82
                return getResult("文件已被删除");
liqin's avatar
liqin committed
83
            }
liqin's avatar
liqin committed
84
            this.assetService.removeById(id);
liqin's avatar
liqin committed
85
            return getSuccessResult();
liqin's avatar
liqin committed
86
        }
liqin's avatar
liqin committed
87
        return getResult("文件已被删除");
liqin's avatar
liqin committed
88
    }
liqin's avatar
liqin committed
89

liqin's avatar
liqin committed
90
    @ApiImplicitParams({
liqin's avatar
liqin committed
91
            @ApiImplicitParam(name = "file", value = "资料", paramType = "form", dataType = "__file", collectionFormat = "array", allowMultiple = true)
liqin's avatar
liqin committed
92
    })
liqin's avatar
liqin committed
93
    @PostMapping(value = "/datum/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
liqin's avatar
liqin committed
94
    @ApiOperation(value = "展板资料上传", notes = "展板资料上传")
liqin's avatar
liqin committed
95
    public Map<String, Object> uploadDatum(@RequestPart(value = "file", required = false) MultipartFile[] files) throws IOException {
liqin's avatar
liqin committed
96 97
        if (files == null || files.length == 0) {
            return getFailResult("没有文件可供上传");
liqin's avatar
liqin committed
98 99 100 101 102
        }
        int successCount = 0;
        int failureCount = 0;
        List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>();

liqin's avatar
liqin committed
103
        Set<Asset> datumUrlList = new LinkedHashSet<>();
liqin's avatar
liqin committed
104 105 106 107 108 109 110 111 112 113 114
        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++;
liqin's avatar
liqin committed
115
                handleList.add(handleResult);
liqin's avatar
liqin committed
116 117
                continue;
            }
liqin's avatar
liqin committed
118 119 120 121
            if (file.getSize() == 0L) {
                handleResult.setFileName("");
                handleResult.setFileUrl("");
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName());
liqin's avatar
liqin committed
122
                handleResult.setDescription("文件" + originalFilename + "大小为0");
liqin's avatar
liqin committed
123
                failureCount++;
liqin's avatar
liqin committed
124
                handleList.add(handleResult);
liqin's avatar
liqin committed
125 126
                continue;
            }
liqin's avatar
liqin committed
127

liqin's avatar
liqin committed
128
            String baseName = FilenameUtils.getBaseName(originalFilename);
liqin's avatar
liqin committed
129
            String extName = FilenameUtils.getExtension(originalFilename);
liqin's avatar
liqin committed
130 131
            String finalExtName = extName;
            boolean anyMatch = Arrays.stream(DATUM_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()));
liqin's avatar
liqin committed
132
            if (anyMatch) {
liqin's avatar
liqin committed
133
                if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) {
liqin's avatar
liqin committed
134 135 136
                    extName = "mp4";
                    originalFilename = FilenameUtils.getBaseName(originalFilename) + "." + extName;
                }
liqin's avatar
liqin committed
137 138 139 140 141 142
                final Asset asset = Asset.builder()
                        .fileName(originalFilename)
                        .fileExtName(extName)
                        .fileCat(FileCatEnum.EXHIBITION_BOARD_DATUM.name())
                        .build();

liqin's avatar
liqin committed
143
                String language = null;
liqin's avatar
liqin committed
144 145
                final Set<MetaData> metaDataSet = new HashSet<>();
                metaDataSet.add(new MetaData("fileName", originalFilename));
liqin's avatar
liqin committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
                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;
liqin's avatar
liqin committed
165
                if (Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) {
liqin's avatar
liqin committed
166 167 168
                    metaDataSet.add(new MetaData("fileType", FileTypeEnum.VIDEO.name()));
                    handleResult.setFileType(FileTypeEnum.VIDEO.name());
                    asset.setFileType(FileTypeEnum.VIDEO.name());
liqin's avatar
liqin committed
169 170 171 172 173 174 175

                    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);
liqin's avatar
liqin committed
176 177
                    String md5 = fileMetaData.stream().filter(x -> "MD5".equals(x.getName())).map(MetaData::getValue).findFirst().get();
                    asset.setMd5(md5);
liqin's avatar
liqin committed
178
                    asset.setIntro(Base64.getEncoder().encodeToString(fileUrl.getBytes()));
liqin's avatar
liqin committed
179
                    asset.setFileUrlCrypto(md5 + ".chnmuseum");
liqin's avatar
liqin committed
180
                } else if (Arrays.stream(AUDIO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) {
liqin's avatar
liqin committed
181 182 183 184
                    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);
liqin's avatar
liqin committed
185
                } else if (Arrays.stream(IMAGE_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) {
liqin's avatar
liqin committed
186 187 188 189 190
                    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);
liqin's avatar
liqin committed
191
                } else if (Arrays.stream(DOC_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) {
liqin's avatar
liqin committed
192 193 194 195
                    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);
liqin's avatar
liqin committed
196
                }
liqin's avatar
liqin committed
197
                final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl);
liqin's avatar
liqin committed
198
                final int crc32 = fileInfo.getCrc32();
liqin's avatar
liqin committed
199
                final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1"));
liqin's avatar
liqin committed
200

liqin's avatar
liqin committed
201
                final LocalDateTime createTime = TimeUtils.getDateTimeOfTimestamp(fileInfo.getCreateTime() * 1000);
liqin's avatar
liqin committed
202 203
                asset.setFileSize(fileInfo.getFileSize());
                asset.setFileUrl(fileUrl);
liqin's avatar
liqin committed
204
                asset.setFileUrlCrypto(fileUrlCrypto);
liqin's avatar
liqin committed
205
                asset.setFileCat(FileCatEnum.EXHIBITION_BOARD_DATUM.name());
liqin's avatar
liqin committed
206
                asset.setLanguage(language);
liqin's avatar
liqin committed
207 208 209
                if (Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()))) {
                    asset.setCrc32((long) crc32);
                }
liqin's avatar
liqin committed
210 211
                asset.setCreateTime(createTime);
                asset.setUpdateTime(createTime);
liqin's avatar
liqin committed
212
                if (one != null) {
liqin's avatar
liqin committed
213 214 215 216 217
                    try {
                        FastDFSUtils.deleteFile(fileUrl);
                        FastDFSUtils.deleteFile(fileUrlCrypto);
                    } catch (Throwable ignored) {
                    }
liqin's avatar
liqin committed
218
                    asset.setFileUrl(one.getFileUrl());
liqin's avatar
liqin committed
219
                    asset.setFileUrlCrypto(one.getFileUrlCrypto());
liqin's avatar
liqin committed
220
                }
liqin's avatar
liqin committed
221 222 223
                this.assetService.save(asset);
                datumUrlList.add(asset);

liqin's avatar
liqin committed
224
                handleResult.setFileUrl("");
liqin's avatar
liqin committed
225 226 227
                handleResult.setFileName(originalFilename);
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName());
                handleResult.setDescription("");
liqin's avatar
liqin committed
228 229 230
                successCount++;
            } else {
                handleResult.setFileUrl("");
liqin's avatar
liqin committed
231
                handleResult.setDescription("文件" + originalFilename + "格式不支持");
liqin's avatar
liqin committed
232 233 234 235 236 237 238 239 240 241
                failureCount++;
            }
            // 设置处理的业务表信息
            handleList.add(handleResult);
        }
        BatchUploadResVO batchUploadResVO = new BatchUploadResVO();
        batchUploadResVO.setFailureCount(failureCount);
        batchUploadResVO.setSuccessCount(successCount);
        batchUploadResVO.setTotal(files.length);
        batchUploadResVO.setHandleList(handleList);
liqin's avatar
liqin committed
242
        batchUploadResVO.setFileList(datumUrlList);
liqin's avatar
liqin committed
243 244 245 246

        if (failureCount > 0) {
            return getFailResult(batchUploadResVO);
        }
liqin's avatar
liqin committed
247
        return getResult(batchUploadResVO);
liqin's avatar
liqin committed
248 249 250
    }

    @PostMapping(value = "/image/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
wzp's avatar
wzp committed
251
    @RequiresAuthentication  //@RequiresPermissions("file:image:upload")
liqin's avatar
liqin committed
252
    @ApiOperation(value = "单图片上传(封面/缩略图)", notes = "单图片上传(封面/缩略图)")
liqin's avatar
liqin committed
253
    public Map<String, Object> uploadImage(@RequestParam(value = "file") MultipartFile uploadFile) throws Exception {
liqin's avatar
liqin committed
254 255
        if (uploadFile == null) {
            return getFailResult("没有文件可供上传");
liqin's avatar
liqin committed
256 257 258 259
        }
        String fileName = uploadFile.getOriginalFilename();
        String extension = FilenameUtils.getExtension(fileName);
        if (StringUtils.isBlank(extension)) {
liqin's avatar
liqin committed
260
            return getFailResult("文件格式不支持");
liqin's avatar
liqin committed
261 262 263
        }
        boolean anyMatch = Arrays.stream(IMAGE_TYPE).anyMatch(s -> Objects.equals(s, extension.toUpperCase()));
        if (!anyMatch) {
liqin's avatar
liqin committed
264
            return getFailResult("文件格式不支持");
liqin's avatar
liqin committed
265 266
        }

liqin's avatar
liqin committed
267 268 269 270
        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);
liqin's avatar
liqin committed
271 272 273 274 275
        ImageUploadResult imageUploadResult = new ImageUploadResult();
        imageUploadResult.setFileName(fileName);
        imageUploadResult.setFileExtName(extension);
        imageUploadResult.setFileSize(uploadFile.getSize());
        imageUploadResult.setUrl(url);
liqin's avatar
liqin committed
276
        return getResult(imageUploadResult);
liqin's avatar
liqin committed
277 278
    }

279
    @PostMapping(value = "/upload/allType", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
wzp's avatar
wzp committed
280
    @RequiresAuthentication  //@RequiresPermissions("file:upload:allType")
281
    @ApiOperation(value = "单文件上传(不限格式)", notes = "单文件上传(不限格式)")
liqin's avatar
liqin committed
282
    public Map<String, Object> uploadAllType(@RequestParam(value = "file") MultipartFile uploadFile) throws Exception {
liqin's avatar
liqin committed
283 284
        if (uploadFile == null) {
            return getFailResult("没有文件可供上传");
285 286 287 288
        }
        String fileName = uploadFile.getOriginalFilename();
        String extension = FilenameUtils.getExtension(fileName);
        if (StringUtils.isBlank(extension)) {
liqin's avatar
liqin committed
289
            return getFailResult("文件格式不支持");
290
        }
liqin's avatar
liqin committed
291 292 293
        final Set<MetaData> metaDataSet = new HashSet<>();
        metaDataSet.add(new MetaData("fileName", fileName));
        String url = FastDFSUtils.uploadFile(uploadFile.getInputStream(), uploadFile.getSize(), fileName, metaDataSet);
294 295 296 297 298
        ImageUploadResult imageUploadResult = new ImageUploadResult();
        imageUploadResult.setFileName(fileName);
        imageUploadResult.setFileExtName(extension);
        imageUploadResult.setFileSize(uploadFile.getSize());
        imageUploadResult.setUrl(url);
liqin's avatar
liqin committed
299
        return getResult(imageUploadResult);
300 301
    }

liqin's avatar
liqin committed
302 303 304 305
    @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)
wzp's avatar
wzp committed
306
    @RequiresAuthentication  //@RequiresPermissions("audio:upload")
liqin's avatar
liqin committed
307
    @ApiOperation(value = "展板多音频上传", notes = "展板多音频上传")
liqin's avatar
liqin committed
308
    public Map<String, Object> uploadAudio(@RequestPart(value = "file", required = false) MultipartFile[] files) throws IOException {
wzp's avatar
wzp committed
309
        if (files == null || files.length == 0) {
liqin's avatar
liqin committed
310
            return getFailResult("没有文件可供上传");
liqin's avatar
liqin committed
311 312 313
        }
        final boolean existChineseAudio = Arrays.stream(files).anyMatch(s -> Objects.requireNonNull(s.getOriginalFilename()).contains("汉语"));
        if (!existChineseAudio) {
liqin's avatar
liqin committed
314
            return getFailResult("必须包含汉语音频");
liqin's avatar
liqin committed
315 316 317 318 319 320
        }

        int successCount = 0;
        int failureCount = 0;
        List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>();

liqin's avatar
liqin committed
321
        Set<Asset> fileList = new LinkedHashSet<>();
liqin's avatar
liqin committed
322 323 324 325 326 327 328 329 330 331 332 333
        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++;
liqin's avatar
liqin committed
334
                handleList.add(handleResult);
liqin's avatar
liqin committed
335 336
                continue;
            }
liqin's avatar
liqin committed
337 338 339 340
            if (file.getSize() == 0L) {
                handleResult.setFileName("");
                handleResult.setFileUrl("");
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName());
liqin's avatar
liqin committed
341
                handleResult.setDescription("文件" + originalFilename + "大小为0");
liqin's avatar
liqin committed
342
                failureCount++;
liqin's avatar
liqin committed
343
                handleList.add(handleResult);
liqin's avatar
liqin committed
344 345
                continue;
            }
liqin's avatar
liqin committed
346

liqin's avatar
liqin committed
347 348
            String extName = FilenameUtils.getExtension(originalFilename);
            boolean anyMatch = Arrays.stream(AUDIO_TYPE).anyMatch(s -> Objects.equals(s, extName.toUpperCase()));
liqin's avatar
liqin committed
349
            if (anyMatch) {
liqin's avatar
liqin committed
350 351 352 353 354
                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("汉语")) {
liqin's avatar
liqin committed
355 356
                    metaDataSet.add(new MetaData("language", LanguageEnum.ZH.name()));
                    language = LanguageEnum.ZH.name();
liqin's avatar
liqin committed
357
                } else if (originalFilename.contains("英语")) {
liqin's avatar
liqin committed
358 359
                    metaDataSet.add(new MetaData("language", LanguageEnum.EN.name()));
                    language = LanguageEnum.EN.name();
liqin's avatar
liqin committed
360
                } else if (originalFilename.contains("蒙语")) {
liqin's avatar
liqin committed
361 362
                    metaDataSet.add(new MetaData("language", LanguageEnum.MN.name()));
                    language = LanguageEnum.MN.name();
liqin's avatar
liqin committed
363
                } else if (originalFilename.contains("藏语")) {
liqin's avatar
liqin committed
364 365
                    metaDataSet.add(new MetaData("language", LanguageEnum.BO.name()));
                    language = LanguageEnum.BO.name();
liqin's avatar
liqin committed
366
                } else if (originalFilename.contains("维吾尔语")) {
liqin's avatar
liqin committed
367 368
                    metaDataSet.add(new MetaData("language", LanguageEnum.UYG.name()));
                    language = LanguageEnum.UYG.name();
liqin's avatar
liqin committed
369 370 371
                }
                String fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet);
                final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl);
liqin's avatar
liqin committed
372
                final int crc32 = fileInfo.getCrc32();
liqin's avatar
liqin committed
373
                final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1"));
liqin's avatar
liqin committed
374
                final LocalDateTime createTime = TimeUtils.getDateTimeOfTimestamp(fileInfo.getCreateTime() * 1000);
liqin's avatar
liqin committed
375 376 377 378 379 380 381 382 383
                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)
liqin's avatar
liqin committed
384
                        .crc32((long) crc32)
liqin's avatar
liqin committed
385 386 387
                        .createTime(createTime)
                        .updateTime(createTime)
                        .build();
liqin's avatar
liqin committed
388 389 390 391
                if (one != null) {
                    FastDFSUtils.deleteFile(fileUrl);
                    asset.setFileUrl(one.getFileUrl());
                }
liqin's avatar
liqin committed
392
                this.assetService.save(asset);
liqin's avatar
liqin committed
393
                fileList.add(asset);
liqin's avatar
liqin committed
394 395 396 397 398 399

                handleResult.setFileUrl(fileUrl);
                handleResult.setFileName(originalFilename);
                handleResult.setFileType(FileTypeEnum.AUDIO.getName());
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName());
                handleResult.setDescription("");
liqin's avatar
liqin committed
400 401 402
                successCount++;
            } else {
                handleResult.setFileUrl("");
liqin's avatar
liqin committed
403 404 405
                handleResult.setFileType(FileTypeEnum.AUDIO.getName());
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName());
                handleResult.setDescription("文件" + originalFilename + "格式不支持");
liqin's avatar
liqin committed
406 407 408 409 410 411 412 413 414 415 416
                failureCount++;
            }
            // 设置处理的业务表信息
            handleList.add(handleResult);
        }

        BatchUploadResVO batchUploadResVO = new BatchUploadResVO();
        batchUploadResVO.setFailureCount(failureCount);
        batchUploadResVO.setSuccessCount(successCount);
        batchUploadResVO.setTotal(files.length);
        batchUploadResVO.setHandleList(handleList);
liqin's avatar
liqin committed
417
        batchUploadResVO.setFileList(fileList);
liqin's avatar
liqin committed
418
        return getResult(batchUploadResVO);
liqin's avatar
liqin committed
419 420
    }

liqin's avatar
liqin committed
421
    @ApiImplicitParams({
liqin's avatar
liqin committed
422
            @ApiImplicitParam(name = "file", value = "视频文件", paramType = "form", dataType = "__file", collectionFormat = "array", allowMultiple = true, required = true)
liqin's avatar
liqin committed
423
    })
liqin's avatar
liqin committed
424
    @PostMapping(value = "/video/content/upload", headers = "content-type=multipart/form-data", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
wzp's avatar
wzp committed
425
    @RequiresAuthentication  //@RequiresPermissions("file:video:content:upload")
liqin's avatar
liqin committed
426
    @ApiOperation(value = "展板视频上传", notes = "展板视频上传")
liqin's avatar
liqin committed
427
    public Map<String, Object> uploadContentVideo(@RequestPart("file") MultipartFile[] files) throws Exception {
liqin's avatar
liqin committed
428
        if (files == null || files.length == 0) {
liqin's avatar
liqin committed
429
            return getFailResult("没有文件可供上传");
liqin's avatar
liqin committed
430
        }
liqin's avatar
liqin committed
431 432 433 434 435 436 437
        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) + "格式");
            }
        }
liqin's avatar
liqin committed
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
        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(), "之");
            }
        }
liqin's avatar
liqin committed
481 482 483 484 485

        int successCount = 0;
        int failureCount = 0;
        List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>();

liqin's avatar
liqin committed
486
        Set<Asset> fileList = new LinkedHashSet<>();
liqin's avatar
liqin committed
487 488 489 490 491 492 493 494 495 496 497 498
        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++;
liqin's avatar
liqin committed
499
                handleList.add(handleResult);
liqin's avatar
liqin committed
500 501
                continue;
            }
liqin's avatar
liqin committed
502 503 504 505
            if (file.getSize() == 0L) {
                handleResult.setFileName("");
                handleResult.setFileUrl("");
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName());
liqin's avatar
liqin committed
506
                handleResult.setDescription("文件" + originalFilename + "大小为0");
liqin's avatar
liqin committed
507
                failureCount++;
liqin's avatar
liqin committed
508
                handleList.add(handleResult);
liqin's avatar
liqin committed
509 510
                continue;
            }
liqin's avatar
liqin committed
511 512

            final String baseName = FilenameUtils.getBaseName(originalFilename);
liqin's avatar
liqin committed
513
            String extName = FilenameUtils.getExtension(originalFilename);
liqin's avatar
liqin committed
514 515
            String finalExtName = extName;
            boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()));
liqin's avatar
liqin committed
516
            if (anyMatch) {
liqin's avatar
liqin committed
517
                if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) {
liqin's avatar
liqin committed
518
                    extName = "mp4";
liqin's avatar
liqin committed
519
                    originalFilename = baseName + "." + extName;
liqin's avatar
liqin committed
520
                }
liqin's avatar
liqin committed
521 522 523 524 525
                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("汉语")) {
liqin's avatar
liqin committed
526 527
                    metaDataSet.add(new MetaData("language", LanguageEnum.ZH.name()));
                    language = LanguageEnum.ZH.name();
liqin's avatar
liqin committed
528
                } else if (originalFilename.contains("蒙语")) {
liqin's avatar
liqin committed
529 530
                    metaDataSet.add(new MetaData("language", LanguageEnum.MN.name()));
                    language = LanguageEnum.MN.name();
liqin's avatar
liqin committed
531
                } else if (originalFilename.contains("藏语")) {
liqin's avatar
liqin committed
532 533
                    metaDataSet.add(new MetaData("language", LanguageEnum.BO.name()));
                    language = LanguageEnum.BO.name();
liqin's avatar
liqin committed
534
                } else if (originalFilename.contains("维吾尔语")) {
liqin's avatar
liqin committed
535 536
                    metaDataSet.add(new MetaData("language", LanguageEnum.UYG.name()));
                    language = LanguageEnum.UYG.name();
liqin's avatar
liqin committed
537
                }
liqin's avatar
liqin committed
538 539 540 541 542 543
                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);
liqin's avatar
liqin committed
544
                String md5 = fileMetaData.stream().filter(x -> "MD5".equals(x.getName())).map(MetaData::getValue).findFirst().get();
liqin's avatar
liqin committed
545

liqin's avatar
liqin committed
546 547
                final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl);
                final int crc32 = fileInfo.getCrc32();
liqin's avatar
liqin committed
548
                final Asset one = this.assetService.getOne(Wrappers.<Asset>lambdaQuery().eq(Asset::getCrc32, (long) crc32).last(" limit 1"));
liqin's avatar
liqin committed
549
                final LocalDateTime createTime = TimeUtils.getDateTimeOfTimestamp(fileInfo.getCreateTime() * 1000);
liqin's avatar
liqin committed
550 551 552
                final long fileSize = fileInfo.getFileSize();
                final Asset asset = Asset.builder()
                        .fileName(originalFilename)
liqin's avatar
liqin committed
553
                        .fileNameCrypto(md5 + ".chnmuseum")
liqin's avatar
liqin committed
554
                        .fileExtName(extName)
liqin's avatar
liqin committed
555
                        .fileType(FileTypeEnum.VIDEO.name())
liqin's avatar
liqin committed
556 557
                        .fileSize(fileSize)
                        .fileUrl(fileUrl)
liqin's avatar
liqin committed
558
                        .intro(Base64.getEncoder().encodeToString(fileUrl.getBytes()))
liqin's avatar
liqin committed
559
                        .fileUrlCrypto(fileUrlCrypto)
liqin's avatar
liqin committed
560 561 562
                        .fileCat(FileCatEnum.VIDEO_CONTENT.name())
                        .language(language)
                        .md5(md5)
liqin's avatar
liqin committed
563
                        .crc32((long) crc32)
liqin's avatar
liqin committed
564
                        .videoContentName(videoContentName)
liqin's avatar
liqin committed
565 566 567
                        .createTime(createTime)
                        .updateTime(createTime)
                        .build();
liqin's avatar
liqin committed
568 569
                if (one != null) {
                    FastDFSUtils.deleteFile(fileUrl);
liqin's avatar
liqin committed
570
                    FastDFSUtils.deleteFile(fileUrlCrypto);
liqin's avatar
liqin committed
571
                    asset.setFileUrl(one.getFileUrl());
liqin's avatar
liqin committed
572
                    asset.setFileUrlCrypto(one.getFileUrlCrypto());
liqin's avatar
liqin committed
573
                }
liqin's avatar
liqin committed
574 575 576
                this.assetService.save(asset);
                fileList.add(asset);

liqin's avatar
liqin committed
577
                handleResult.setFileUrl("");
liqin's avatar
liqin committed
578 579 580
                handleResult.setFileName(originalFilename);
                handleResult.setFileType(FileTypeEnum.VIDEO.getName());
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName());
liqin's avatar
liqin committed
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
                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)
wzp's avatar
wzp committed
606
    @RequiresAuthentication  //@RequiresPermissions("file:video:upload")
liqin's avatar
liqin committed
607 608 609
    @ApiOperation(value = "多视频上传", notes = "多视频上传")
    public Map<String, Object> uploadVideo(@RequestPart("file") MultipartFile[] files) throws IOException {
        if (files == null || files.length == 0) {
liqin's avatar
liqin committed
610
            return getFailResult("没有文件可供上传");
liqin's avatar
liqin committed
611
        }
liqin's avatar
liqin committed
612 613 614 615 616 617 618
        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) + "格式");
            }
        }
liqin's avatar
liqin committed
619 620 621 622 623

        int successCount = 0;
        int failureCount = 0;
        List<BatchUploadResVO.HandleResult> handleList = new ArrayList<>();

liqin's avatar
liqin committed
624
        Set<Asset> fileList = new LinkedHashSet<>();
liqin's avatar
liqin committed
625 626 627 628 629 630 631 632 633 634 635 636
        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++;
liqin's avatar
liqin committed
637
                handleList.add(handleResult);
liqin's avatar
liqin committed
638 639
                continue;
            }
liqin's avatar
liqin committed
640 641 642 643
            if (file.getSize() == 0L) {
                handleResult.setFileName("");
                handleResult.setFileUrl("");
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.FAILURE.getName());
liqin's avatar
liqin committed
644
                handleResult.setDescription("文件" + originalFilename + "大小为0");
liqin's avatar
liqin committed
645
                failureCount++;
liqin's avatar
liqin committed
646
                handleList.add(handleResult);
liqin's avatar
liqin committed
647 648
                continue;
            }
liqin's avatar
liqin committed
649 650

            String extName = FilenameUtils.getExtension(originalFilename);
liqin's avatar
liqin committed
651 652
            String finalExtName = extName;
            boolean anyMatch = Arrays.stream(VIDEO_TYPE).anyMatch(s -> Objects.equals(s, finalExtName.toUpperCase()));
liqin's avatar
liqin committed
653
            if (anyMatch) {
liqin's avatar
liqin committed
654
                if ("MPEG".equals(extName.toUpperCase()) || "MOV".equals(extName.toUpperCase())) {
liqin's avatar
liqin committed
655 656 657
                    extName = "mp4";
                    originalFilename = FilenameUtils.getBaseName(originalFilename) + "." + extName;
                }
liqin's avatar
liqin committed
658 659 660
                final Set<MetaData> metaDataSet = new HashSet<>();
                metaDataSet.add(new MetaData("fileName", originalFilename));
                metaDataSet.add(new MetaData("fileType", FileTypeEnum.VIDEO.name()));
liqin's avatar
liqin committed
661
                final String fileUrl = FastDFSUtils.uploadFile(file.getInputStream(), file.getSize(), originalFilename, metaDataSet);
liqin's avatar
liqin committed
662 663 664 665 666
                final FileInfo fileInfo = FastDFSUtils.getFileInfo(fileUrl);
                final Asset asset = Asset.builder()
                        .fileName(originalFilename)
                        .fileExtName(extName)
                        .fileType(FileTypeEnum.VIDEO.name())
liqin's avatar
liqin committed
667
                        .fileSize(fileInfo.getFileSize())
liqin's avatar
liqin committed
668 669
                        .fileUrl(fileUrl)
                        .fileCat(FileCatEnum.VIEWING_INTERACTION.name())
liqin's avatar
liqin committed
670
                        .crc32((long) fileInfo.getCrc32())
liqin's avatar
liqin committed
671 672 673 674 675 676 677
                        .build();
                this.assetService.save(asset);
                fileList.add(asset);

                handleResult.setFileUrl(fileUrl);
                handleResult.setFileName(originalFilename);
                handleResult.setFileType(FileTypeEnum.VIDEO.getName());
liqin's avatar
liqin committed
678 679
                handleResult.setHandleResult(HANDLE_STATUS_ENUM.SUCCESS.getName());
                handleResult.setDescription("");
liqin's avatar
liqin committed
680 681 682
                successCount++;
            } else {
                handleResult.setFileUrl("");
liqin's avatar
liqin committed
683 684
                handleResult.setHandleResult("上传失败");
                handleResult.setDescription("文件" + originalFilename + "格式不支持");
liqin's avatar
liqin committed
685 686 687 688 689 690 691 692 693 694 695
                failureCount++;
            }
            // 设置处理的业务表信息
            handleList.add(handleResult);
        }

        BatchUploadResVO batchUploadResVO = new BatchUploadResVO();
        batchUploadResVO.setFailureCount(failureCount);
        batchUploadResVO.setSuccessCount(successCount);
        batchUploadResVO.setTotal(files.length);
        batchUploadResVO.setHandleList(handleList);
liqin's avatar
liqin committed
696
        batchUploadResVO.setFileList(fileList);
liqin's avatar
liqin committed
697
        return getResult(batchUploadResVO);
liqin's avatar
liqin committed
698 699 700
    }

}