From a68a97914910ca500c9fbd2d92a225fa82a1fe09 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Thu, 7 Jul 2022 09:40:23 +0800 Subject: [PATCH 01/13] =?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<String> 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; /** - * 文件类型 - * + * 文件扩展名 + * <p> * 通过 {@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()); } From 36d7775171d3fdc381414b84a450db93cafa92ef Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Thu, 7 Jul 2022 09:40:23 +0800 Subject: [PATCH 02/13] =?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/dal/mysql/file/FileMapper.java | 2 +- .../module/infra/service/file/FileService.java | 3 ++- .../infra/service/file/FileServiceImpl.java | 14 +++++++++----- .../infra/service/file/FileServiceTest.java | 8 ++++---- 12 files changed, 58 insertions(+), 35 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<String> 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; /** - * 文件类型 - * + * 文件扩展名 + * <p> * 通过 {@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/dal/mysql/file/FileMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java index 845addc14..8cf50cddc 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java @@ -18,7 +18,7 @@ public interface FileMapper extends BaseMapperX<FileDO> { default PageResult<FileDO> selectPage(FilePageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>() .likeIfPresent(FileDO::getPath, reqVO.getPath()) - .likeIfPresent(FileDO::getType, reqVO.getType()) + .likeIfPresent(FileDO::getExtName, reqVO.getType()) .betweenIfPresent(FileDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) .orderByDesc(FileDO::getId)); } 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()); } From b741ed480b0d0df9711d47c1bbe2dd692cfec126 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Thu, 7 Jul 2022 10:51:33 +0800 Subject: [PATCH 03/13] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E4=B8=8A=E6=AC=A1?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=AF=BC=E8=87=B4=E7=9A=84=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8F=96=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/file/vo/file/FilePageReqVO.java | 4 ++-- .../controller/admin/file/vo/file/FileRespVO.java | 7 +++++-- .../module/infra/dal/mysql/file/FileMapper.java | 2 +- yudao-ui-admin/src/views/infra/file/index.vue | 13 +++++++------ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java index 346314e83..043cf11bb 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java @@ -21,8 +21,8 @@ public class FilePageReqVO extends PageParam { @ApiModelProperty(value = "文件路径", example = "yudao", notes = "模糊匹配") private String path; - @ApiModelProperty(value = "文件类型", example = "jpg", notes = "模糊匹配") - private String type; + @ApiModelProperty(value = "文件扩展名", example = "jpg", notes = "模糊匹配") + private String extName; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @ApiModelProperty(value = "开始创建时间") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java index 10737693d..7a53bf2e1 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java @@ -22,8 +22,11 @@ public class FileRespVO { @ApiModelProperty(value = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg") private String url; - @ApiModelProperty(value = "文件类型", example = "jpg") - private String type; + @ApiModelProperty(value = "文件扩展名", example = "jpg") + private String extName; + + @ApiModelProperty(value = "文件MIME类型", example = "application/octet-stream") + private String mimeType; @ApiModelProperty(value = "文件大小", example = "2048", required = true) private Integer size; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java index 8cf50cddc..28c37067c 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java @@ -18,7 +18,7 @@ public interface FileMapper extends BaseMapperX<FileDO> { default PageResult<FileDO> selectPage(FilePageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>() .likeIfPresent(FileDO::getPath, reqVO.getPath()) - .likeIfPresent(FileDO::getExtName, reqVO.getType()) + .likeIfPresent(FileDO::getExtName, reqVO.getExtName()) .betweenIfPresent(FileDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) .orderByDesc(FileDO::getId)); } diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 462a879de..76e189c83 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -26,14 +26,15 @@ <!-- 列表 --> <el-table v-loading="loading" :data="list"> - <el-table-column label="文件名" align="center" prop="name" /> - <el-table-column label="文件路径" align="center" prop="path" /> - <el-table-column label="文件 URL" align="center" prop="url" /> + <el-table-column label="文件名" :show-overflow-tooltip="true" align="center" min-width="250" prop="name" /> + <el-table-column :show-overflow-tooltip="true" label="文件路径" align="center" min-width="300" prop="path" /> + <el-table-column :show-overflow-tooltip="true" label="文件 URL" align="center" min-width="400" prop="url" /> <el-table-column label="文件大小" align="center" prop="size" width="120" :formatter="sizeFormat" /> - <el-table-column label="文件类型" align="center" prop="type" width="80" /> + <el-table-column label="文件类型" align="center" prop="mimeType" width="210" /> + <el-table-column label="文件扩展名" align="center" prop="extName" width="80" /> <!-- <el-table-column label="文件内容" align="center" prop="content">--> <!-- <template slot-scope="scope">--> -<!-- <img v-if="scope.row.type === 'jpg' || scope.row.type === 'png' || scope.row.type === 'gif'"--> +<!-- <img v-if="scope.row.extName === 'jpg' || scope.row.extName === 'png' || scope.row.extName === 'gif'"--> <!-- width="200px" :src="getFileUrl + scope.row.id">--> <!-- <i v-else>非图片,无法预览</i>--> <!-- </template>--> @@ -101,7 +102,7 @@ export default { pageNo: 1, pageSize: 10, path: null, - type: null, + extName: null, }, // 用户导入参数 upload: { From 0ed332171989a4fc4a9744def85f58a6d0150f5e Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Fri, 8 Jul 2022 08:44:09 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=A1=A8=E8=A1=A8=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 3 +-- sql/oracle/ruoyi-vue-pro.sql | 6 ++---- sql/postgresql/ruoyi-vue-pro.sql | 6 ++---- sql/sqlserver/ruoyi-vue-pro.sql | 12 ++---------- 4 files changed, 7 insertions(+), 20 deletions(-) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index e6baf5dc6..12e77d40f 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -692,8 +692,7 @@ CREATE TABLE `infra_file` ( `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', - `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类型', + `type` varchar(64) 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 614cac0f8..07e0a85e3 100644 --- a/sql/oracle/ruoyi-vue-pro.sql +++ b/sql/oracle/ruoyi-vue-pro.sql @@ -878,8 +878,7 @@ CREATE TABLE "INFRA_FILE" ( "CONFIG_ID" NUMBER(20,0), "PATH" NVARCHAR2(512), "URL" NCLOB, - "EXT_NAME" NVARCHAR2(63), - "MIME_TYPE" NVARCHAR2(63), + "TYPE" NVARCHAR2(64), "SIZE" NUMBER(11,0) NOT NULL, "CREATOR" NVARCHAR2(64), "CREATE_TIME" DATE NOT NULL, @@ -909,8 +908,7 @@ 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"."EXT_NAME" IS '文件扩展名'; -COMMENT ON COLUMN "INFRA_FILE"."MIME_TYPE" IS '文件MIME类型'; +COMMENT ON COLUMN "INFRA_FILE"."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 663a169f0..a6575bccb 100644 --- a/sql/postgresql/ruoyi-vue-pro.sql +++ b/sql/postgresql/ruoyi-vue-pro.sql @@ -1717,8 +1717,7 @@ 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, - "ext_name" varchar(63) COLLATE "pg_catalog"."default", - "mime_type" varchar(63) COLLATE "pg_catalog"."default", + "type" varchar(64) COLLATE "pg_catalog"."default", "size" int4 NOT NULL, "creator" varchar(64) COLLATE "pg_catalog"."default", "create_time" timestamp(6) NOT NULL, @@ -1732,8 +1731,7 @@ 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"."ext_name" IS '文件扩展名'; -COMMENT ON COLUMN "infra_file"."mime_type" IS '文件MIME类型'; +COMMENT ON COLUMN "infra_file"."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 40b01dac6..6e058e02e 100644 --- a/sql/sqlserver/ruoyi-vue-pro.sql +++ b/sql/sqlserver/ruoyi-vue-pro.sql @@ -2634,8 +2634,7 @@ 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, - [ext_name] nvarchar(63) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, - [mime_type] nvarchar(63) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, + [type] nvarchar(64) 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, @@ -2677,18 +2676,11 @@ EXEC sp_addextendedproperty 'COLUMN', N'url' GO -EXEC sp_addextendedproperty -'MS_Description', N'文件扩展名', -'SCHEMA', N'dbo', -'TABLE', N'infra_file', -'COLUMN', N'ext_name' -GO - EXEC sp_addextendedproperty 'MS_Description', N'文件MIME类型', 'SCHEMA', N'dbo', 'TABLE', N'infra_file', -'COLUMN', N'mime_type' +'COLUMN', N'type' GO EXEC sp_addextendedproperty From da0ba105033c3d51865793274f7c06644dde32a8 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Fri, 8 Jul 2022 09:14:39 +0800 Subject: [PATCH 05/13] =?UTF-8?q?=E4=BF=AE=E6=94=B9mimetype=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E4=B8=BAtype=EF=BC=8C=E4=BF=AE=E6=94=B9=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=96=87=E4=BB=B6=E5=90=8E=E7=BC=80=E5=90=8D=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E7=9B=AE=E5=89=8D=E5=9B=BE=E7=89=87=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=A2=84=E8=A7=88=E8=BF=98=E6=9C=89=E4=BA=9B=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/file/vo/file/FilePageReqVO.java | 4 ++-- .../controller/admin/file/vo/file/FileRespVO.java | 5 +---- .../module/infra/dal/dataobject/file/FileDO.java | 9 ++------- .../yudao/module/infra/dal/mysql/file/FileMapper.java | 2 +- .../module/infra/service/file/FileServiceImpl.java | 11 +++++------ .../module/infra/service/file/FileServiceTest.java | 6 ------ yudao-ui-admin/src/views/infra/file/index.vue | 8 +++----- 7 files changed, 14 insertions(+), 31 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java index 043cf11bb..e803fcf25 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FilePageReqVO.java @@ -21,8 +21,8 @@ public class FilePageReqVO extends PageParam { @ApiModelProperty(value = "文件路径", example = "yudao", notes = "模糊匹配") private String path; - @ApiModelProperty(value = "文件扩展名", example = "jpg", notes = "模糊匹配") - private String extName; + @ApiModelProperty(value = "文件类型", example = "application/octet-stream", notes = "模糊匹配") + private String type; @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @ApiModelProperty(value = "开始创建时间") diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java index 7a53bf2e1..fa6ec8444 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java @@ -22,11 +22,8 @@ public class FileRespVO { @ApiModelProperty(value = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg") private String url; - @ApiModelProperty(value = "文件扩展名", example = "jpg") - private String extName; - @ApiModelProperty(value = "文件MIME类型", example = "application/octet-stream") - private String mimeType; + private String type; @ApiModelProperty(value = "文件大小", example = "2048", required = true) private Integer size; 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 36ef56113..ae898c8cd 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 @@ -45,16 +45,11 @@ public class FileDO extends BaseDO { * 访问地址 */ private String url; - /** - * 文件扩展名 - * <p> - * 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取 - */ - private String extName; + /** * 文件的MIME类型,默认为"application/octet-stream" */ - private String mimeType; + private String type; /** * 文件大小 */ diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java index 28c37067c..845addc14 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileMapper.java @@ -18,7 +18,7 @@ public interface FileMapper extends BaseMapperX<FileDO> { default PageResult<FileDO> selectPage(FilePageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX<FileDO>() .likeIfPresent(FileDO::getPath, reqVO.getPath()) - .likeIfPresent(FileDO::getExtName, reqVO.getExtName()) + .likeIfPresent(FileDO::getType, reqVO.getType()) .betweenIfPresent(FileDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) .orderByDesc(FileDO::getId)); } 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 cf6dc700b..0df38d22c 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 @@ -41,12 +41,12 @@ public class FileServiceImpl implements FileService { @Override @SneakyThrows public String createFile(String name, String path, String mimeType, byte[] content) { - //获取文件的真实扩展名 - String extName = FileTypeUtil.getType(new ByteArrayInputStream(content), name); - FileNameUtil.extName(name); + //获取文件的扩展名 + String extName = FileNameUtil.extName(name); if (StrUtil.isEmpty(path)) { //使用sha256计算文件都唯一路径,降低碰撞概率 - path = DigestUtil.sha256Hex(content) + '.' + extName; + String sha256Hex = DigestUtil.sha256Hex(content); + path = StrUtil.isBlank(extName) ? sha256Hex : (sha256Hex + '.' + extName); } // 如果 name 为空,则使用 path 填充 if (StrUtil.isEmpty(name)) { @@ -64,8 +64,7 @@ public class FileServiceImpl implements FileService { file.setName(name); file.setPath(path); file.setUrl(url); - file.setExtName(extName); - file.setMimeType(mimeType); + file.setType(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 21db8ac8a..a4e9966a5 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,16 +40,11 @@ public class FileServiceTest extends BaseDbUnitTest { // mock 数据 FileDO dbFile = randomPojo(FileDO.class, o -> { // 等会查询到 o.setPath("yunai"); - o.setExtName("jpg"); o.setCreateTime(buildTime(2021, 1, 15)); }); fileMapper.insert(dbFile); // 测试 path 不匹配 fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> o.setPath("tudou"))); - // 测试 type 不匹配 - fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> { - o.setExtName("png"); - })); // 测试 createTime 不匹配 fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> { o.setCreateTime(buildTime(2020, 1, 15)); @@ -90,7 +85,6 @@ public class FileServiceTest extends BaseDbUnitTest { assertEquals(10L, file.getConfigId()); assertEquals(path, file.getPath()); assertEquals(url, file.getUrl()); - assertEquals("jpg", file.getExtName()); assertEquals(content.length, file.getSize()); } diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 76e189c83..5bcf721a3 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -30,11 +30,10 @@ <el-table-column :show-overflow-tooltip="true" label="文件路径" align="center" min-width="300" prop="path" /> <el-table-column :show-overflow-tooltip="true" label="文件 URL" align="center" min-width="400" prop="url" /> <el-table-column label="文件大小" align="center" prop="size" width="120" :formatter="sizeFormat" /> - <el-table-column label="文件类型" align="center" prop="mimeType" width="210" /> - <el-table-column label="文件扩展名" align="center" prop="extName" width="80" /> + <el-table-column label="文件类型" align="center" prop="type" width="210" /> <!-- <el-table-column label="文件内容" align="center" prop="content">--> <!-- <template slot-scope="scope">--> -<!-- <img v-if="scope.row.extName === 'jpg' || scope.row.extName === 'png' || scope.row.extName === 'gif'"--> +<!-- <img v-if="scope.row.type&&scope.row.type.indexOf('image/') === 0"--> <!-- width="200px" :src="getFileUrl + scope.row.id">--> <!-- <i v-else>非图片,无法预览</i>--> <!-- </template>--> @@ -101,8 +100,7 @@ export default { queryParams: { pageNo: 1, pageSize: 10, - path: null, - extName: null, + path: null }, // 用户导入参数 upload: { From eb3228d4c781ff21418acf93e8ed4036a72520db Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Fri, 8 Jul 2022 11:02:21 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E4=BC=9A=E6=98=BE=E7=A4=BA=E5=9B=BE=E7=89=87=E7=BC=A9=E7=95=A5?= =?UTF-8?q?=E5=9B=BE=EF=BC=8C=E7=82=B9=E5=87=BB=E7=BC=A9=E7=95=A5=E5=9B=BE?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E9=A2=84=E8=A7=88=E5=A4=A7=E5=9B=BE=E3=80=82?= =?UTF-8?q?=E9=9D=9E=E5=9B=BE=E7=89=87=E6=96=87=E4=BB=B6=E5=9C=A8=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=A1=B5=E9=9D=A2=E4=BC=9A=E6=98=BE=E7=A4=BA=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E6=8C=89=E9=92=AE=E3=80=82=E7=82=B9=E5=87=BB=E5=8D=B3?= =?UTF-8?q?=E5=8F=AF=E4=B8=8B=E8=BD=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/file/vo/file/FileRespVO.java | 3 +++ yudao-ui-admin/src/views/infra/file/index.vue | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java index fa6ec8444..31b790a21 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/vo/file/FileRespVO.java @@ -13,6 +13,9 @@ public class FileRespVO { @ApiModelProperty(value = "文件编号", required = true, example = "1024") private Long id; + @ApiModelProperty(value = "配置编号", required = true, example = "11") + private Long configId; + @ApiModelProperty(value = "文件路径", required = true, example = "yudao.jpg") private String path; diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 5bcf721a3..6f368d5c0 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -31,13 +31,17 @@ <el-table-column :show-overflow-tooltip="true" label="文件 URL" align="center" min-width="400" prop="url" /> <el-table-column label="文件大小" align="center" prop="size" width="120" :formatter="sizeFormat" /> <el-table-column label="文件类型" align="center" prop="type" width="210" /> -<!-- <el-table-column label="文件内容" align="center" prop="content">--> -<!-- <template slot-scope="scope">--> -<!-- <img v-if="scope.row.type&&scope.row.type.indexOf('image/') === 0"--> -<!-- width="200px" :src="getFileUrl + scope.row.id">--> -<!-- <i v-else>非图片,无法预览</i>--> -<!-- </template>--> -<!-- </el-table-column>--> + <el-table-column label="文件内容" align="center" prop="content" min-width="150px"> + <template slot-scope="scope"> + <image-preview v-if="scope.row.type&&scope.row.type.indexOf('image/') === 0" :src="scope.row.url" + :width="'100px'"></image-preview> + <i v-else>无法预览,点击 + <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" + :href="getFileUrl+scope.row.configId+'/get/' + scope.row.path">下载 + </el-link> + </i> + </template> + </el-table-column> <el-table-column label="上传时间" align="center" prop="createTime" width="180"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.createTime) }}</span> @@ -79,12 +83,16 @@ <script> import { deleteFile, getFilePage } from "@/api/infra/file"; import {getAccessToken} from "@/utils/auth"; +import ImagePreview from "@/components/ImagePreview"; export default { name: "File", + components: { + ImagePreview + }, data() { return { - getFileUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/get/', + getFileUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/', // 遮罩层 loading: true, // 显示搜索条件 From 84ef0b449a418ce51472f84f8b04f393fec10bd3 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Fri, 8 Jul 2022 11:59:21 +0800 Subject: [PATCH 07/13] =?UTF-8?q?SocialUserBindDO=E7=B1=BB=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E4=B8=BB=E9=94=AE=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=90=A6?= =?UTF-8?q?=E5=88=99=E6=8E=A7=E5=88=B6=E5=8F=B0=E4=BC=9A=E6=9C=89mybatis?= =?UTF-8?q?=20plus=E7=9A=84=E6=97=A5=E5=BF=97=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/dal/dataobject/social/SocialUserBindDO.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserBindDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserBindDO.java index c5dd5f4ac..0f4e41f96 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserBindDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialUserBindDO.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.social; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; @@ -21,6 +22,11 @@ import lombok.*; @AllArgsConstructor public class SocialUserBindDO extends BaseDO { + /** + * 编号 + */ + @TableId + private Long id; /** * 关联的用户编号 * From c64295f432999bc3cb76f06931fc50ef7ccc0dfc Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Sat, 9 Jul 2022 10:41:06 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E5=90=88=E5=B9=B6fetch=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/infra/api/file/FileApi.java | 13 ++++++------- .../yudao/module/infra/api/file/FileApiImpl.java | 4 ++-- .../infra/controller/admin/file/FileController.java | 2 +- .../module/infra/dal/dataobject/file/FileDO.java | 5 ++--- .../module/infra/service/file/FileService.java | 3 +-- .../module/infra/service/file/FileServiceTest.java | 8 +++++++- yudao-ui-admin/src/views/infra/file/index.vue | 3 ++- 7 files changed, 21 insertions(+), 17 deletions(-) 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 85e629d25..c41c6e039 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, "application/octet-stream", content); + return createFile(null, null, content); } /** @@ -25,18 +25,17 @@ public interface FileApi { * @return 文件路径 */ default String createFile(String path, byte[] content) { - return createFile(null, path, "application/octet-stream", content); + return createFile(null, path, content); } /** * 保存文件,并返回文件的访问路径 * - * @param name 文件名称 - * @param path 文件路径 - * @param mimeType 文件类型 - * @param content 文件内容 + * @param name 文件名称 + * @param path 文件路径 + * @param content 文件内容 * @return 文件路径 */ - String createFile(String name, String path, String mimeType, byte[] content); + String createFile(String name, String path, 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 851221374..05fb946fe 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, String mimeType, byte[] content) { - return fileService.createFile(name, path, mimeType, content); + public String createFile(String name, String path, byte[] content) { + return fileService.createFile(name, path, 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 7c3b7d574..5ea52b7e5 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 @@ -47,7 +47,7 @@ public class FileController { @OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要 public CommonResult<String> uploadFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "path", required = false) String path) throws Exception { - return success(fileService.createFile(file.getOriginalFilename(), path, file.getContentType(), IoUtil.readBytes(file.getInputStream()))); + return success(fileService.createFile(file.getOriginalFilename(), path, 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 ae898c8cd..7c242d4eb 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,16 +38,15 @@ public class FileDO extends BaseDO { */ private String name; /** - * 路径,即文件名,唯一不可重复 + * 路径,即文件名 */ private String path; /** * 访问地址 */ private String url; - /** - * 文件的MIME类型,默认为"application/octet-stream" + * 文件的MIME类型,例如"application/octet-stream" */ private String type; /** 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 07a7ebd59..24baf4218 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,11 +24,10 @@ public interface FileService { * * @param name 文件名称 * @param path 文件路径 - * @param mimeType 文件MIME类型 * @param content 文件内容 * @return 文件路径 */ - String createFile(String name, String path, String mimeType,byte[] content); + String createFile(String name, String path, byte[] content); /** * 删除文件 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 a4e9966a5..b5acbb8a4 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,11 +40,16 @@ public class FileServiceTest extends BaseDbUnitTest { // mock 数据 FileDO dbFile = randomPojo(FileDO.class, o -> { // 等会查询到 o.setPath("yunai"); + o.setType("image/jpg"); o.setCreateTime(buildTime(2021, 1, 15)); }); fileMapper.insert(dbFile); // 测试 path 不匹配 fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> o.setPath("tudou"))); + // 测试 type 不匹配 + fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> { + o.setType("image/png"); + })); // 测试 createTime 不匹配 fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> { o.setCreateTime(buildTime(2020, 1, 15)); @@ -77,7 +82,7 @@ public class FileServiceTest extends BaseDbUnitTest { when(client.getId()).thenReturn(10L); String name = "单测文件名"; // 调用 - String result = fileService.createFile(name, path, "application/octet-stream", content); + String result = fileService.createFile(name, path, content); // 断言 assertEquals(result, url); // 校验数据 @@ -85,6 +90,7 @@ public class FileServiceTest extends BaseDbUnitTest { assertEquals(10L, file.getConfigId()); assertEquals(path, file.getPath()); assertEquals(url, file.getUrl()); + assertEquals("image/jpg", file.getType()); assertEquals(content.length, file.getSize()); } diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 6f368d5c0..838fe492a 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -108,7 +108,8 @@ export default { queryParams: { pageNo: 1, pageSize: 10, - path: null + path: null, + type: null, }, // 用户导入参数 upload: { From a5d16c11e8a63db84ff9597f9807e9c3d914ccf8 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Sat, 9 Jul 2022 11:27:45 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8E=B7=E5=8F=96mimet?= =?UTF-8?q?ype=E6=96=B9=E5=BC=8F=EF=BC=8C=E4=BC=98=E5=8C=96=E7=94=9F?= =?UTF-8?q?=E6=88=90path=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../file/core/utils/FileTypeUtils.java | 31 +++++++++++++++---- .../infra/service/file/FileServiceImpl.java | 15 +++++++-- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java index d21b4879a..b623d364a 100644 --- a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java @@ -4,8 +4,6 @@ import com.alibaba.ttl.TransmittableThreadLocal; import lombok.SneakyThrows; import org.apache.tika.Tika; -import java.io.ByteArrayInputStream; - /** * 文件类型 Utils * @@ -16,14 +14,35 @@ public class FileTypeUtils { private static final ThreadLocal<Tika> TIKA = TransmittableThreadLocal.withInitial(Tika::new); /** - * 获得文件的 mineType + * 获得文件的 mineType,对于doc,jar等文件会有误差 * - * @param data 文件内容 - * @return mineType + * @param data 包含文件开头几千个字节的字节数组 + * @return mineType 无法识别时会返回“application/octet-stream” */ @SneakyThrows public static String getMineType(byte[] data) { - return TIKA.get().detect(new ByteArrayInputStream(data)); + return TIKA.get().detect(data); + } + + /** + * 已知文件名,获取文件类型,在某些情况下比通过字节数组准确,例如使用jar文件时,通过名字更为准确 + * + * @param name 文件名 + * @return mineType 无法识别时会返回“application/octet-stream” + */ + public static String getMineType(String name) { + return TIKA.get().detect(name); + } + + /** + * 在拥有文件和数据的情况下,最好使用此方法,最为准确 + * + * @param data 包含文件开头几千个字节的字节数组 + * @param name 文件名 + * @return mineType 无法识别时会返回“application/octet-stream” + */ + public static String getMineType(byte[] data, String name) { + return TIKA.get().detect(data, name); } } 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 98af005f7..f4aac3014 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,5 +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; @@ -13,6 +15,7 @@ import lombok.SneakyThrows; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.io.ByteArrayInputStream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; @@ -40,10 +43,16 @@ public class FileServiceImpl implements FileService { @SneakyThrows public String createFile(String name, String path, byte[] content) { // 计算默认的 path 名 - String type = FileTypeUtils.getMineType(content); + String type = FileTypeUtils.getMineType(content, name); if (StrUtil.isEmpty(path)) { - path = DigestUtil.md5Hex(content) - + '.' + StrUtil.subAfter(type, '/', true); // 文件的后缀 + String sha256Hex = DigestUtil.sha256Hex(content); + /* 如果存在name,则优先使用name的后缀 */ + if (StrUtil.isNotBlank(name)) { + String extName = FileNameUtil.extName(name); + path = StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName; + } else { + path = sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content), name); + } } // 如果 name 为空,则使用 path 填充 if (StrUtil.isEmpty(name)) { From 30f2c1a496461f6c2ac9e1d1ec6b2fde305e798d Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Sat, 9 Jul 2022 14:25:45 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2=E5=9C=A8=E5=B0=8F=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E4=B8=8A=E7=9A=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-ui-admin/src/views/infra/file/index.vue | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 838fe492a..5f5c53b46 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -26,11 +26,11 @@ <!-- 列表 --> <el-table v-loading="loading" :data="list"> - <el-table-column label="文件名" :show-overflow-tooltip="true" align="center" min-width="250" prop="name" /> - <el-table-column :show-overflow-tooltip="true" label="文件路径" align="center" min-width="300" prop="path" /> - <el-table-column :show-overflow-tooltip="true" label="文件 URL" align="center" min-width="400" prop="url" /> - <el-table-column label="文件大小" align="center" prop="size" width="120" :formatter="sizeFormat" /> - <el-table-column label="文件类型" align="center" prop="type" width="210" /> + <el-table-column label="文件名" :show-overflow-tooltip="true" align="center" min-width="200px" prop="name"/> + <el-table-column label="文件路径" :show-overflow-tooltip="true" align="center" min-width="250px" prop="path"/> + <el-table-column label="文件 URL" :show-overflow-tooltip="true" align="center" min-width="300px" prop="url"/> + <el-table-column label="文件大小" align="center" prop="size" min-width="120px" :formatter="sizeFormat"/> + <el-table-column label="文件类型" :show-overflow-tooltip="true" align="center" prop="type" width="180px"/> <el-table-column label="文件内容" align="center" prop="content" min-width="150px"> <template slot-scope="scope"> <image-preview v-if="scope.row.type&&scope.row.type.indexOf('image/') === 0" :src="scope.row.url" @@ -42,15 +42,16 @@ </i> </template> </el-table-column> - <el-table-column label="上传时间" align="center" prop="createTime" width="180"> + <el-table-column label="上传时间" align="center" prop="createTime" min-width="170px"> <template slot-scope="scope"> <span>{{ parseTime(scope.row.createTime) }}</span> </template> </el-table-column> - <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100"> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="100px"> <template slot-scope="scope"> <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" - v-hasPermi="['infra:file:delete']">删除</el-button> + v-hasPermi="['infra:file:delete']">删除 + </el-button> </template> </el-table-column> </el-table> @@ -81,7 +82,7 @@ </template> <script> -import { deleteFile, getFilePage } from "@/api/infra/file"; +import {deleteFile, getFilePage} from "@/api/infra/file"; import {getAccessToken} from "@/utils/auth"; import ImagePreview from "@/components/ImagePreview"; From dd726f79852de6b01e7cd5120594b3f58b984687 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Sat, 9 Jul 2022 17:11:39 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E4=B8=AD=E8=8B=B1=E6=96=87=E4=B9=8B?= =?UTF-8?q?=E9=97=B4=E5=8A=A0=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/sqlserver/ruoyi-vue-pro.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sqlserver/ruoyi-vue-pro.sql b/sql/sqlserver/ruoyi-vue-pro.sql index 6e058e02e..1c0d93776 100644 --- a/sql/sqlserver/ruoyi-vue-pro.sql +++ b/sql/sqlserver/ruoyi-vue-pro.sql @@ -2677,7 +2677,7 @@ EXEC sp_addextendedproperty GO EXEC sp_addextendedproperty -'MS_Description', N'文件MIME类型', +'MS_Description', N'文件 MIME 类型', 'SCHEMA', N'dbo', 'TABLE', N'infra_file', 'COLUMN', N'type' From 2621f2195d1bacfbc56d143ff827bd1d717e6a8d Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Sat, 9 Jul 2022 17:46:29 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/io/FileUtils.java | 21 +++++++++++++++++-- .../file/core/utils/FileTypeUtils.java | 4 ++-- .../infra/service/file/FileServiceImpl.java | 15 +++---------- yudao-ui-admin/src/views/infra/file/index.vue | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java index 89fab2da2..f6cb2c82d 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java @@ -1,9 +1,14 @@ package cn.iocoder.yudao.framework.common.util.io; +import cn.hutool.core.io.FileTypeUtil; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.file.FileNameUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.DigestUtil; import lombok.SneakyThrows; +import java.io.ByteArrayInputStream; import java.io.File; /** @@ -58,8 +63,20 @@ public class FileUtils { return file; } - - public static void main(String[] args) { + /** + * @param content 文件内容 + * @param originalName 原始文件名 + * @return path,唯一不可重复 + */ + public static String generatePath(byte[] content, String originalName) { + String sha256Hex = DigestUtil.sha256Hex(content); + // 如果存在name,则优先使用name的后缀 + if (StrUtil.isNotBlank(originalName)) { + String extName = FileNameUtil.extName(originalName); + return StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName; + } else { + return sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content)); + } } } diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java index b623d364a..8b99227b1 100644 --- a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/utils/FileTypeUtils.java @@ -16,7 +16,7 @@ public class FileTypeUtils { /** * 获得文件的 mineType,对于doc,jar等文件会有误差 * - * @param data 包含文件开头几千个字节的字节数组 + * @param data 文件内容 * @return mineType 无法识别时会返回“application/octet-stream” */ @SneakyThrows @@ -37,7 +37,7 @@ public class FileTypeUtils { /** * 在拥有文件和数据的情况下,最好使用此方法,最为准确 * - * @param data 包含文件开头几千个字节的字节数组 + * @param data 文件内容 * @param name 文件名 * @return mineType 无法识别时会返回“application/octet-stream” */ 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 f4aac3014..c69eddfa4 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,11 +1,10 @@ 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.io.FileUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; -import cn.hutool.crypto.digest.DigestUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.io.FileUtils; import cn.iocoder.yudao.framework.file.core.client.FileClient; import cn.iocoder.yudao.framework.file.core.utils.FileTypeUtils; import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO; @@ -15,7 +14,6 @@ import lombok.SneakyThrows; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.io.ByteArrayInputStream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; @@ -45,14 +43,7 @@ public class FileServiceImpl implements FileService { // 计算默认的 path 名 String type = FileTypeUtils.getMineType(content, name); if (StrUtil.isEmpty(path)) { - String sha256Hex = DigestUtil.sha256Hex(content); - /* 如果存在name,则优先使用name的后缀 */ - if (StrUtil.isNotBlank(name)) { - String extName = FileNameUtil.extName(name); - path = StrUtil.isBlank(extName) ? sha256Hex : sha256Hex + "." + extName; - } else { - path = sha256Hex + '.' + FileTypeUtil.getType(new ByteArrayInputStream(content), name); - } + path = FileUtils.generatePath(content, name); } // 如果 name 为空,则使用 path 填充 if (StrUtil.isEmpty(name)) { diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 5f5c53b46..02de6410c 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -37,7 +37,7 @@ :width="'100px'"></image-preview> <i v-else>无法预览,点击 <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" - :href="getFileUrl+scope.row.configId+'/get/' + scope.row.path">下载 + :href="getFileUrl + scope.row.configId + '/get/' + scope.row.path">下载 </el-link> </i> </template> From 1f5c3e7484f349ecbc0bdfa35a84cdb59c4a1dc5 Mon Sep 17 00:00:00 2001 From: jiangqiang <jq1257403419@vip.qq.com> Date: Sat, 9 Jul 2022 17:55:22 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9Etarget=3D"=5Fblank"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-ui-admin/src/views/infra/file/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yudao-ui-admin/src/views/infra/file/index.vue b/yudao-ui-admin/src/views/infra/file/index.vue index 02de6410c..53716782e 100644 --- a/yudao-ui-admin/src/views/infra/file/index.vue +++ b/yudao-ui-admin/src/views/infra/file/index.vue @@ -36,7 +36,7 @@ <image-preview v-if="scope.row.type&&scope.row.type.indexOf('image/') === 0" :src="scope.row.url" :width="'100px'"></image-preview> <i v-else>无法预览,点击 - <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" + <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" target="_blank" :href="getFileUrl + scope.row.configId + '/get/' + scope.row.path">下载 </el-link> </i>