From a68a97914910ca500c9fbd2d92a225fa82a1fe09 Mon Sep 17 00:00:00 2001 From: jiangqiang Date: Thu, 7 Jul 2022 09:40:23 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E5=92=8C=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E9=95=BF=E5=BA=A6=E4=B8=80=E8=87=B4=EF=BC=8C=E5=9B=A0?= =?UTF-8?q?=E4=B8=BA=E5=A6=82=E6=9E=9C=E4=B8=8D=E5=AD=98=E5=9C=A8=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=90=8D=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C?= =?UTF-8?q?=E4=BC=9A=E4=BD=BF=E7=94=A8=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E5=AD=97=E6=AE=B5=E5=90=8D=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E6=95=B0=E6=8D=AE=E5=BA=93=E6=8A=A5=E9=94=99=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E5=86=85=E5=AE=B9=E5=A4=AA=E9=95=BF=E3=80=82=202.=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9type=E5=AD=97=E6=AE=B5=E4=B8=BAext=5Fname?= =?UTF-8?q?=EF=BC=8C=E5=9B=A0=E4=B8=BA=E6=AD=A4=E5=AD=97=E6=AE=B5=E6=9C=AC?= =?UTF-8?q?=E6=9D=A5=E5=B0=B1=E5=AD=98=E7=9A=84=E6=96=87=E4=BB=B6=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E5=90=8D=EF=BC=8C=E5=B9=B6=E4=B8=94=E6=96=B0=E5=A2=9E?= =?UTF-8?q?mime=5Ftype=E5=AD=97=E6=AE=B5=EF=BC=8C=E7=94=A8=E6=9D=A5?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E6=96=87=E4=BB=B6=E7=9A=84=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E3=80=82=E6=96=B9=E4=BE=BF=E5=90=8E=E6=9C=9F=E6=8B=93=E5=B1=95?= =?UTF-8?q?=E7=BD=91=E7=9B=98=E9=A1=B9=E7=9B=AE=E3=80=82=203.=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=EF=BC=9A=E4=B9=8B=E5=89=8D=E6=98=AFmd5?= =?UTF-8?q?=EF=BC=8C=E7=8E=B0=E5=9C=A8=E6=98=AFsha256=EF=BC=8C=E9=99=8D?= =?UTF-8?q?=E4=BD=8E=E6=96=87=E4=BB=B6=E7=A2=B0=E6=92=9E=E6=A6=82=E7=8E=87?= =?UTF-8?q?=E3=80=82=E6=96=B9=E4=BE=BF=E6=8B=93=E5=B1=95=E7=BD=91=E7=9B=98?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=EF=BC=8C=E5=AE=9E=E7=8E=B0=E7=A7=92=E4=BC=A0?= =?UTF-8?q?=E7=AD=89=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 5 +++-- sql/oracle/ruoyi-vue-pro.sql | 6 ++++-- sql/postgresql/ruoyi-vue-pro.sql | 8 +++++--- sql/sqlserver/ruoyi-vue-pro.sql | 16 ++++++++++++---- .../yudao/module/infra/api/file/FileApi.java | 13 +++++++------ .../yudao/module/infra/api/file/FileApiImpl.java | 4 ++-- .../controller/admin/file/FileController.java | 2 +- .../module/infra/dal/dataobject/file/FileDO.java | 12 ++++++++---- .../module/infra/service/file/FileService.java | 3 ++- .../infra/service/file/FileServiceImpl.java | 14 +++++++++----- .../infra/service/file/FileServiceTest.java | 8 ++++---- 11 files changed, 57 insertions(+), 34 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index a014a1b8c..e6baf5dc6 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -689,10 +689,11 @@ DROP TABLE IF EXISTS `infra_file`; CREATE TABLE `infra_file` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '文件编号', `config_id` bigint NULL DEFAULT NULL COMMENT '配置编号', - `name` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件名', + `name` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件名', `path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件路径', `url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件 URL', - `type` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件类型', + `ext_name` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件扩展名', + `mime_type` varchar(63) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文件MIME类型', `size` int NOT NULL COMMENT '文件大小', `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', diff --git a/sql/oracle/ruoyi-vue-pro.sql b/sql/oracle/ruoyi-vue-pro.sql index 1f4908645..614cac0f8 100644 --- a/sql/oracle/ruoyi-vue-pro.sql +++ b/sql/oracle/ruoyi-vue-pro.sql @@ -878,7 +878,8 @@ CREATE TABLE "INFRA_FILE" ( "CONFIG_ID" NUMBER(20,0), "PATH" NVARCHAR2(512), "URL" NCLOB, - "TYPE" NVARCHAR2(63), + "EXT_NAME" NVARCHAR2(63), + "MIME_TYPE" NVARCHAR2(63), "SIZE" NUMBER(11,0) NOT NULL, "CREATOR" NVARCHAR2(64), "CREATE_TIME" DATE NOT NULL, @@ -908,7 +909,8 @@ COMMENT ON COLUMN "INFRA_FILE"."ID" IS '文件编号'; COMMENT ON COLUMN "INFRA_FILE"."CONFIG_ID" IS '配置编号'; COMMENT ON COLUMN "INFRA_FILE"."PATH" IS '文件路径'; COMMENT ON COLUMN "INFRA_FILE"."URL" IS '文件 URL'; -COMMENT ON COLUMN "INFRA_FILE"."TYPE" IS '文件类型'; +COMMENT ON COLUMN "INFRA_FILE"."EXT_NAME" IS '文件扩展名'; +COMMENT ON COLUMN "INFRA_FILE"."MIME_TYPE" IS '文件MIME类型'; COMMENT ON COLUMN "INFRA_FILE"."SIZE" IS '文件大小'; COMMENT ON COLUMN "INFRA_FILE"."CREATOR" IS '创建者'; COMMENT ON COLUMN "INFRA_FILE"."CREATE_TIME" IS '创建时间'; diff --git a/sql/postgresql/ruoyi-vue-pro.sql b/sql/postgresql/ruoyi-vue-pro.sql index 9e80ce70d..663a169f0 100644 --- a/sql/postgresql/ruoyi-vue-pro.sql +++ b/sql/postgresql/ruoyi-vue-pro.sql @@ -1717,21 +1717,23 @@ CREATE TABLE "infra_file" ( "config_id" int8, "path" varchar(512) COLLATE "pg_catalog"."default" NOT NULL, "url" varchar(1024) COLLATE "pg_catalog"."default" NOT NULL, - "type" varchar(63) COLLATE "pg_catalog"."default", + "ext_name" varchar(63) COLLATE "pg_catalog"."default", + "mime_type" varchar(63) COLLATE "pg_catalog"."default", "size" int4 NOT NULL, "creator" varchar(64) COLLATE "pg_catalog"."default", "create_time" timestamp(6) NOT NULL, "updater" varchar(64) COLLATE "pg_catalog"."default", "update_time" timestamp(6) NOT NULL, "deleted" int2 NOT NULL DEFAULT 0, - "name" varchar(255) COLLATE "pg_catalog"."default" + "name" varchar(512) COLLATE "pg_catalog"."default" ) ; COMMENT ON COLUMN "infra_file"."id" IS '文件编号'; COMMENT ON COLUMN "infra_file"."config_id" IS '配置编号'; COMMENT ON COLUMN "infra_file"."path" IS '文件路径'; COMMENT ON COLUMN "infra_file"."url" IS '文件 URL'; -COMMENT ON COLUMN "infra_file"."type" IS '文件类型'; +COMMENT ON COLUMN "infra_file"."ext_name" IS '文件扩展名'; +COMMENT ON COLUMN "infra_file"."mime_type" IS '文件MIME类型'; COMMENT ON COLUMN "infra_file"."size" IS '文件大小'; COMMENT ON COLUMN "infra_file"."creator" IS '创建者'; COMMENT ON COLUMN "infra_file"."create_time" IS '创建时间'; diff --git a/sql/sqlserver/ruoyi-vue-pro.sql b/sql/sqlserver/ruoyi-vue-pro.sql index d6bd1847c..40b01dac6 100644 --- a/sql/sqlserver/ruoyi-vue-pro.sql +++ b/sql/sqlserver/ruoyi-vue-pro.sql @@ -2634,14 +2634,15 @@ CREATE TABLE [dbo].[infra_file] ( [config_id] bigint NULL, [path] nvarchar(512) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [url] nvarchar(1024) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, - [type] nvarchar(63) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, + [ext_name] nvarchar(63) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, + [mime_type] nvarchar(63) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [size] int NOT NULL, [creator] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [create_time] datetime2(7) NOT NULL, [updater] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [update_time] datetime2(7) NOT NULL, [deleted] bit DEFAULT 0 NOT NULL, - [name] nvarchar(256) COLLATE SQL_Latin1_General_CP1_CI_AS NULL + [name] nvarchar(512) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ) GO @@ -2677,10 +2678,17 @@ EXEC sp_addextendedproperty GO EXEC sp_addextendedproperty -'MS_Description', N'文件类型', +'MS_Description', N'文件扩展名', 'SCHEMA', N'dbo', 'TABLE', N'infra_file', -'COLUMN', N'type' +'COLUMN', N'ext_name' +GO + +EXEC sp_addextendedproperty +'MS_Description', N'文件MIME类型', +'SCHEMA', N'dbo', +'TABLE', N'infra_file', +'COLUMN', N'mime_type' GO EXEC sp_addextendedproperty diff --git a/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java b/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java index c41c6e039..85e629d25 100644 --- a/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java +++ b/yudao-module-infra/yudao-module-infra-api/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApi.java @@ -14,7 +14,7 @@ public interface FileApi { * @return 文件路径 */ default String createFile(byte[] content) { - return createFile(null, null, content); + return createFile(null, null, "application/octet-stream", content); } /** @@ -25,17 +25,18 @@ public interface FileApi { * @return 文件路径 */ default String createFile(String path, byte[] content) { - return createFile(null, path, content); + return createFile(null, path, "application/octet-stream", content); } /** * 保存文件,并返回文件的访问路径 * - * @param name 文件名称 - * @param path 文件路径 - * @param content 文件内容 + * @param name 文件名称 + * @param path 文件路径 + * @param mimeType 文件类型 + * @param content 文件内容 * @return 文件路径 */ - String createFile(String name, String path, byte[] content); + String createFile(String name, String path, String mimeType, byte[] content); } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java index 05fb946fe..851221374 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/api/file/FileApiImpl.java @@ -19,8 +19,8 @@ public class FileApiImpl implements FileApi { private FileService fileService; @Override - public String createFile(String name, String path, byte[] content) { - return fileService.createFile(name, path, content); + public String createFile(String name, String path, String mimeType, byte[] content) { + return fileService.createFile(name, path, mimeType, content); } } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index fcdca025f..0ddd5dc43 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java @@ -46,7 +46,7 @@ public class FileController { @OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要 public CommonResult uploadFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "path", required = false) String path) throws Exception { - return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()))); + return success(fileService.createFile(file.getOriginalFilename(), path, file.getContentType(), IoUtil.readBytes(file.getInputStream()))); } @DeleteMapping("/delete") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java index 7e81280da..36ef56113 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileDO.java @@ -38,7 +38,7 @@ public class FileDO extends BaseDO { */ private String name; /** - * 路径,即文件名 + * 路径,即文件名,唯一不可重复 */ private String path; /** @@ -46,11 +46,15 @@ public class FileDO extends BaseDO { */ private String url; /** - * 文件类型 - * + * 文件扩展名 + *

* 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取 */ - private String type; + private String extName; + /** + * 文件的MIME类型,默认为"application/octet-stream" + */ + private String mimeType; /** * 文件大小 */ diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java index 24baf4218..07a7ebd59 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java @@ -24,10 +24,11 @@ public interface FileService { * * @param name 文件名称 * @param path 文件路径 + * @param mimeType 文件MIME类型 * @param content 文件内容 * @return 文件路径 */ - String createFile(String name, String path, byte[] content); + String createFile(String name, String path, String mimeType,byte[] content); /** * 删除文件 diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java index b90e92752..cf6dc700b 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.infra.service.file; import cn.hutool.core.io.FileTypeUtil; +import cn.hutool.core.io.file.FileNameUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; @@ -39,11 +40,13 @@ public class FileServiceImpl implements FileService { @Override @SneakyThrows - public String createFile(String name, String path, byte[] content) { - // 计算默认的 path 名 - String type = FileTypeUtil.getType(new ByteArrayInputStream(content), name); + public String createFile(String name, String path, String mimeType, byte[] content) { + //获取文件的真实扩展名 + String extName = FileTypeUtil.getType(new ByteArrayInputStream(content), name); + FileNameUtil.extName(name); if (StrUtil.isEmpty(path)) { - path = DigestUtil.md5Hex(content) + '.' + type; + //使用sha256计算文件都唯一路径,降低碰撞概率 + path = DigestUtil.sha256Hex(content) + '.' + extName; } // 如果 name 为空,则使用 path 填充 if (StrUtil.isEmpty(name)) { @@ -61,7 +64,8 @@ public class FileServiceImpl implements FileService { file.setName(name); file.setPath(path); file.setUrl(url); - file.setType(type); + file.setExtName(extName); + file.setMimeType(mimeType); file.setSize(content.length); fileMapper.insert(file); return url; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java index e61039385..21db8ac8a 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceTest.java @@ -40,7 +40,7 @@ public class FileServiceTest extends BaseDbUnitTest { // mock 数据 FileDO dbFile = randomPojo(FileDO.class, o -> { // 等会查询到 o.setPath("yunai"); - o.setType("jpg"); + o.setExtName("jpg"); o.setCreateTime(buildTime(2021, 1, 15)); }); fileMapper.insert(dbFile); @@ -48,7 +48,7 @@ public class FileServiceTest extends BaseDbUnitTest { fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> o.setPath("tudou"))); // 测试 type 不匹配 fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> { - o.setType("png"); + o.setExtName("png"); })); // 测试 createTime 不匹配 fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> { @@ -82,7 +82,7 @@ public class FileServiceTest extends BaseDbUnitTest { when(client.getId()).thenReturn(10L); String name = "单测文件名"; // 调用 - String result = fileService.createFile(name, path, content); + String result = fileService.createFile(name, path, "application/octet-stream", content); // 断言 assertEquals(result, url); // 校验数据 @@ -90,7 +90,7 @@ public class FileServiceTest extends BaseDbUnitTest { assertEquals(10L, file.getConfigId()); assertEquals(path, file.getPath()); assertEquals(url, file.getUrl()); - assertEquals("jpg", file.getType()); + assertEquals("jpg", file.getExtName()); assertEquals(content.length, file.getSize()); }