|
|
@@ -0,0 +1,286 @@
|
|
|
+From 30c5e5f1f7b70d18d7006266640f6e24b1a000b9 Mon Sep 17 00:00:00 2001
|
|
|
+From: xiongzhu <692949348@qq.com>
|
|
|
+Date: Wed, 29 Dec 2021 18:15:08 +0800
|
|
|
+Subject: [PATCH] 3d
|
|
|
+
|
|
|
+---
|
|
|
+ .../com/izouma/nineth/domain/Collection.java | 4 ++
|
|
|
+ .../izouma/nineth/service/AssetService.java | 2 +-
|
|
|
+ .../com/izouma/nineth/utils/FileUtils.java | 66 +++++++++++++++++++
|
|
|
+ .../nineth/web/FileUploadController.java | 33 ++++++++--
|
|
|
+ src/main/vue/src/components/FileUpload.vue | 7 +-
|
|
|
+ src/main/vue/src/views/BlindBoxEdit.vue | 4 +-
|
|
|
+ src/main/vue/src/views/CollectionEdit.vue | 13 +++-
|
|
|
+ 7 files changed, 119 insertions(+), 10 deletions(-)
|
|
|
+
|
|
|
+diff --git a/src/main/java/com/izouma/nineth/domain/Collection.java b/src/main/java/com/izouma/nineth/domain/Collection.java
|
|
|
+index f3ee2ed..75c7949 100644
|
|
|
+--- a/src/main/java/com/izouma/nineth/domain/Collection.java
|
|
|
++++ b/src/main/java/com/izouma/nineth/domain/Collection.java
|
|
|
+@@ -37,6 +37,10 @@ public class Collection extends BaseEntity {
|
|
|
+ @Convert(converter = FileObjectListConverter.class)
|
|
|
+ private List<FileObject> pic;
|
|
|
+
|
|
|
++ @Column(columnDefinition = "TEXT")
|
|
|
++ @Convert(converter = FileObjectListConverter.class)
|
|
|
++ private FileObject model3d;
|
|
|
++
|
|
|
+ @ApiModelProperty("铸造者")
|
|
|
+ @Searchable
|
|
|
+ private String minter;
|
|
|
+diff --git a/src/main/java/com/izouma/nineth/service/AssetService.java b/src/main/java/com/izouma/nineth/service/AssetService.java
|
|
|
+index 134a056..01e1b01 100644
|
|
|
+--- a/src/main/java/com/izouma/nineth/service/AssetService.java
|
|
|
++++ b/src/main/java/com/izouma/nineth/service/AssetService.java
|
|
|
+@@ -289,7 +289,7 @@ public class AssetService {
|
|
|
+ .toUserId(toUser.getId())
|
|
|
+ .toAvatar(toUser.getAvatar())
|
|
|
+ .operation(reason)
|
|
|
+- .price("转赠".equals(reason) ? price : null)
|
|
|
++ .price("转赠".equals(reason) ? null : price)
|
|
|
+ .build());
|
|
|
+
|
|
|
+ asset.setPublicShow(false);
|
|
|
+diff --git a/src/main/java/com/izouma/nineth/utils/FileUtils.java b/src/main/java/com/izouma/nineth/utils/FileUtils.java
|
|
|
+index 3545e2c..d4454d9 100644
|
|
|
+--- a/src/main/java/com/izouma/nineth/utils/FileUtils.java
|
|
|
++++ b/src/main/java/com/izouma/nineth/utils/FileUtils.java
|
|
|
+@@ -3,13 +3,18 @@ package com.izouma.nineth.utils;
|
|
|
+ import org.apache.commons.lang3.StringUtils;
|
|
|
+
|
|
|
+ import java.io.*;
|
|
|
++import java.nio.charset.Charset;
|
|
|
++import java.nio.charset.StandardCharsets;
|
|
|
+ import java.nio.file.Files;
|
|
|
+ import java.nio.file.Path;
|
|
|
+ import java.nio.file.attribute.PosixFileAttributeView;
|
|
|
+ import java.nio.file.attribute.PosixFileAttributes;
|
|
|
+ import java.nio.file.attribute.PosixFilePermission;
|
|
|
+ import java.nio.file.attribute.PosixFilePermissions;
|
|
|
++import java.util.Optional;
|
|
|
+ import java.util.Set;
|
|
|
++import java.util.zip.ZipEntry;
|
|
|
++import java.util.zip.ZipInputStream;
|
|
|
+
|
|
|
+ public class FileUtils {
|
|
|
+
|
|
|
+@@ -200,5 +205,66 @@ public class FileUtils {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
++ public static void unzip(InputStream in, File destDir) throws IOException {
|
|
|
++ try {
|
|
|
++ unzip(in, destDir, StandardCharsets.UTF_8);
|
|
|
++ } catch (Exception e) {
|
|
|
++ unzip(in, destDir, Charset.forName("GB2312"));
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ public static void unzip(InputStream in, File destDir, Charset charset) throws IOException {
|
|
|
++ byte[] buffer = new byte[1024];
|
|
|
++ ZipInputStream zis = new ZipInputStream(in);
|
|
|
++ ZipEntry zipEntry = zis.getNextEntry();
|
|
|
++ while (zipEntry != null) {
|
|
|
++ File newFile = newFile(destDir, zipEntry);
|
|
|
++ if (zipEntry.isDirectory()) {
|
|
|
++ if (!newFile.isDirectory() && !newFile.mkdirs()) {
|
|
|
++ throw new IOException("Failed to create directory " + newFile);
|
|
|
++ }
|
|
|
++ } else {
|
|
|
++ // fix for Windows-created archives
|
|
|
++ File parent = newFile.getParentFile();
|
|
|
++ if (!parent.isDirectory() && !parent.mkdirs()) {
|
|
|
++ throw new IOException("Failed to create directory " + parent);
|
|
|
++ }
|
|
|
+
|
|
|
++ // write file content
|
|
|
++ FileOutputStream fos = new FileOutputStream(newFile);
|
|
|
++ int len;
|
|
|
++ while ((len = zis.read(buffer)) > 0) {
|
|
|
++ fos.write(buffer, 0, len);
|
|
|
++ }
|
|
|
++ fos.close();
|
|
|
++ }
|
|
|
++ zipEntry = zis.getNextEntry();
|
|
|
++ }
|
|
|
++ zis.closeEntry();
|
|
|
++ zis.close();
|
|
|
++ }
|
|
|
++
|
|
|
++ public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
|
|
|
++ File destFile = new File(destinationDir, zipEntry.getName());
|
|
|
++
|
|
|
++ String destDirPath = destinationDir.getCanonicalPath();
|
|
|
++ String destFilePath = destFile.getCanonicalPath();
|
|
|
++
|
|
|
++ if (!destFilePath.startsWith(destDirPath + File.separator)) {
|
|
|
++ throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
|
|
|
++ }
|
|
|
++
|
|
|
++ return destFile;
|
|
|
++ }
|
|
|
++
|
|
|
++ public static File findInDir(File dir, String ext) {
|
|
|
++ if (!(dir.exists() && dir.isDirectory())) return null;
|
|
|
++ for (File file : Optional.ofNullable(dir.listFiles()).orElse(new File[0])) {
|
|
|
++ String name = file.getName().toLowerCase();
|
|
|
++ if (name.endsWith(ext.toLowerCase()) && !file.isHidden()) {
|
|
|
++ return file;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ return null;
|
|
|
++ }
|
|
|
+ }
|
|
|
+diff --git a/src/main/java/com/izouma/nineth/web/FileUploadController.java b/src/main/java/com/izouma/nineth/web/FileUploadController.java
|
|
|
+index 47580f3..114788e 100644
|
|
|
+--- a/src/main/java/com/izouma/nineth/web/FileUploadController.java
|
|
|
++++ b/src/main/java/com/izouma/nineth/web/FileUploadController.java
|
|
|
+@@ -10,10 +10,10 @@ import org.apache.commons.io.FilenameUtils;
|
|
|
+ import org.apache.commons.lang3.ArrayUtils;
|
|
|
+ import org.apache.commons.lang3.RandomStringUtils;
|
|
|
+ import org.apache.commons.lang3.StringUtils;
|
|
|
++import org.apache.poi.util.TempFile;
|
|
|
+ import org.bytedeco.javacv.FFmpegFrameGrabber;
|
|
|
+ import org.bytedeco.javacv.Frame;
|
|
|
+ import org.bytedeco.javacv.Java2DFrameConverter;
|
|
|
+-import org.pngquant.PngQuant;
|
|
|
+ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+ import org.springframework.web.bind.annotation.PostMapping;
|
|
|
+ import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+@@ -26,10 +26,7 @@ import java.awt.image.BufferedImage;
|
|
|
+ import java.io.*;
|
|
|
+ import java.net.URLConnection;
|
|
|
+ import java.text.SimpleDateFormat;
|
|
|
+-import java.util.Base64;
|
|
|
+-import java.util.Date;
|
|
|
+-import java.util.Objects;
|
|
|
+-import java.util.Optional;
|
|
|
++import java.util.*;
|
|
|
+ import java.util.regex.Pattern;
|
|
|
+
|
|
|
+
|
|
|
+@@ -182,4 +179,30 @@ public class FileUploadController {
|
|
|
+
|
|
|
+ return new FileObject(file.getOriginalFilename(), url, thumbUrl, file.getContentType());
|
|
|
+ }
|
|
|
++
|
|
|
++ @PostMapping("/3dModel")
|
|
|
++ public FileObject upload3dModel(@RequestParam("file") MultipartFile file) throws IOException {
|
|
|
++ if (!"zip".equalsIgnoreCase(FilenameUtils.getExtension(file.getOriginalFilename()))) {
|
|
|
++ throw new BusinessException("只能上传zip");
|
|
|
++ }
|
|
|
++ File destDir = TempFile.createTempDirectory(RandomStringUtils.randomAlphabetic(20));
|
|
|
++ com.izouma.nineth.utils.FileUtils.unzip(file.getInputStream(), destDir);
|
|
|
++ File fbxFile = com.izouma.nineth.utils.FileUtils.findInDir(destDir, ".fbx");
|
|
|
++ if (fbxFile == null) {
|
|
|
++ throw new BusinessException("找不到fbx文件");
|
|
|
++ }
|
|
|
++ File fbxDir = fbxFile.getParentFile();
|
|
|
++ String basePath = "fbx/"
|
|
|
++ + new SimpleDateFormat("yyyy-MM_dd-HH").format(new Date()) + "/"
|
|
|
++ + RandomStringUtils.randomAlphabetic(16);
|
|
|
++ List<String> urls = new ArrayList<>();
|
|
|
++ for (File listFile : fbxDir.listFiles()) {
|
|
|
++ if (!listFile.isHidden() && !listFile.isDirectory()) {
|
|
|
++ urls.add(storageService.uploadFromInputStream(new FileInputStream(listFile), basePath + "/" + listFile.getName()));
|
|
|
++ }
|
|
|
++ }
|
|
|
++ String fbxUrl = urls.stream().filter(s -> s.toLowerCase().endsWith(".fbx")).findAny()
|
|
|
++ .orElseThrow(new BusinessException("找不到fbx文件"));
|
|
|
++ return new FileObject(fbxFile.getName(), fbxUrl, null, "fbx");
|
|
|
++ }
|
|
|
+ }
|
|
|
+diff --git a/src/main/vue/src/components/FileUpload.vue b/src/main/vue/src/components/FileUpload.vue
|
|
|
+index beed236..e5257e1 100644
|
|
|
+--- a/src/main/vue/src/components/FileUpload.vue
|
|
|
++++ b/src/main/vue/src/components/FileUpload.vue
|
|
|
+@@ -1,13 +1,14 @@
|
|
|
+ <template>
|
|
|
+ <el-upload
|
|
|
+ class="file-upload"
|
|
|
+- :action="uploadUrl"
|
|
|
++ :action="customUrl || uploadUrl"
|
|
|
+ :on-success="onSuccess"
|
|
|
+ :headers="headers"
|
|
|
+ :file-list="fileList"
|
|
|
+ :limit="filesLimit"
|
|
|
+ :on-exceed="onExceed"
|
|
|
+ :on-preview="onPreview"
|
|
|
++ :accept="accept || '*/*'"
|
|
|
+ ref="upload"
|
|
|
+ >
|
|
|
+ <el-button type="primary" size="mini" slot="trigger"> 点击上传 </el-button>
|
|
|
+@@ -62,7 +63,9 @@ export default {
|
|
|
+ format: {
|
|
|
+ type: String,
|
|
|
+ default: 'string'
|
|
|
+- }
|
|
|
++ },
|
|
|
++ customUrl: {},
|
|
|
++ accept: {}
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+diff --git a/src/main/vue/src/views/BlindBoxEdit.vue b/src/main/vue/src/views/BlindBoxEdit.vue
|
|
|
+index 773a3aa..2459522 100644
|
|
|
+--- a/src/main/vue/src/views/BlindBoxEdit.vue
|
|
|
++++ b/src/main/vue/src/views/BlindBoxEdit.vue
|
|
|
+@@ -189,6 +189,7 @@
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <script>
|
|
|
++import resolveUrl from 'resolve-url';
|
|
|
+ export default {
|
|
|
+ name: 'BlindBoxEdit',
|
|
|
+ created() {
|
|
|
+@@ -428,7 +429,8 @@ export default {
|
|
|
+ id: [{ required: true, message: '请选择作品' }],
|
|
|
+ total: [{ required: true, message: '请输入数量' }]
|
|
|
+ },
|
|
|
+- cateogories: ['勋章', '收藏品', '数字艺术', '门票', '游戏', '音乐', '使用', '其他']
|
|
|
++ cateogories: ['勋章', '收藏品', '数字艺术', '门票', '游戏', '音乐', '使用', '其他'],
|
|
|
++ customUrl: resolveUrl(this.$baseUrl, 'upload/3dModel')
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+diff --git a/src/main/vue/src/views/CollectionEdit.vue b/src/main/vue/src/views/CollectionEdit.vue
|
|
|
+index d794f0d..5574fc7 100644
|
|
|
+--- a/src/main/vue/src/views/CollectionEdit.vue
|
|
|
++++ b/src/main/vue/src/views/CollectionEdit.vue
|
|
|
+@@ -29,6 +29,15 @@
|
|
|
+ ></object-upload>
|
|
|
+ <div class="tip">支持JPG、PNG、GIF、MP4,推荐长宽比1:1</div>
|
|
|
+ </el-form-item>
|
|
|
++ <el-form-item prop="model3d" label="3D模型">
|
|
|
++ <file-upload
|
|
|
++ :limit="1"
|
|
|
++ v-model="formData.model3d"
|
|
|
++ :customUrl="customUrl"
|
|
|
++ accept="application/zip"
|
|
|
++ ></file-upload>
|
|
|
++ <div class="tip">请将FBX文件与贴图打包成zip压缩包上传</div>
|
|
|
++ </el-form-item>
|
|
|
+ <el-form-item prop="minterId" label="铸造者">
|
|
|
+ <minter-select
|
|
|
+ v-model="formData.minterId"
|
|
|
+@@ -221,6 +230,7 @@
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <script>
|
|
|
++import resolveUrl from 'resolve-url';
|
|
|
+ export default {
|
|
|
+ name: 'CollectionEdit',
|
|
|
+ created() {
|
|
|
+@@ -418,7 +428,8 @@ export default {
|
|
|
+ privelegeRules: {
|
|
|
+ detail: [{ required: true, message: '请填写内容' }],
|
|
|
+ remark: [{ required: true, message: '请填写说明' }]
|
|
|
+- }
|
|
|
++ },
|
|
|
++ customUrl: resolveUrl(this.$baseUrl, 'upload/3dModel')
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+--
|
|
|
+2.30.1 (Apple Git-130)
|
|
|
+
|