From 1e318b4faf3daf42a581d3f63999abc983ea159f Mon Sep 17 00:00:00 2001 From: fengshuonan Date: Wed, 30 Dec 2020 21:29:32 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90file=E3=80=91=E6=9B=B4=E6=96=B0file?= =?UTF-8?q?=EF=BC=8C=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kernel/file/constants/FileConstants.java | 14 +++- .../kernel/file/enums/FileStatusEnum.java | 32 +++++++++ .../exception/enums/FileExceptionEnum.java | 49 ++++++++++---- .../file/pojo/request/SysFileInfoRequest.java | 48 ++++++++++---- .../response/SysFileInfoListResponse.java | 63 ++++++++++++++++++ .../pojo/response/SysFileInfoResponse.java | 66 +++++++++++++------ .../kernel/file/util/PdfFileTypeUtil.java | 45 +++++++++++++ .../controller/SysFileInfoController.java | 4 +- .../kernel/file/local/LocalFileOperator.java | 2 +- .../kernel/file/minio/MinIoFileOperator.java | 2 +- 10 files changed, 272 insertions(+), 53 deletions(-) create mode 100644 kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/enums/FileStatusEnum.java create mode 100644 kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoListResponse.java create mode 100644 kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/util/PdfFileTypeUtil.java diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/constants/FileConstants.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/constants/FileConstants.java index 3eeeb09b1..67cc3fee8 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/constants/FileConstants.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/constants/FileConstants.java @@ -39,9 +39,19 @@ public interface FileConstants { Long DEFAULT_FILE_TIMEOUT_SECONDS = 7200L; /** - * Guns中文件预览的接口 + * 默认文件上传方式 */ - String FILE_PREVIEW_URL = "/sysFileInfo/preview"; + String DEFAULT_ATTACHMENT_UPLOAD_METHOD = "local_file_config"; + + /** + * 文件预览的接口(需要带token,一般用在机密文件) + */ + String FILE_PRIVATE_PREVIEW_URL = "/sysFileInfo/private/preview"; + + /** + * Guns中公共文件预览的接口(不用带token,一般用在首页背景,首页banner等地方) + */ + String FILE_PUBLIC_PREVIEW_URL = "/sysFileInfo/public/preview"; /** * 系统默认头像的文件object名称 diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/enums/FileStatusEnum.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/enums/FileStatusEnum.java new file mode 100644 index 000000000..e3e4c41ff --- /dev/null +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/enums/FileStatusEnum.java @@ -0,0 +1,32 @@ +package cn.stylefeng.roses.kernel.file.enums; + +import lombok.Getter; + +/** + * 文件状态 + * + * @author majianguo + * @date 2020/12/16 12:00 + */ +@Getter +public enum FileStatusEnum { + + /** + * 新文件 + *

+ * 如果code相同,每次版本号替换都会把当前文件设置成最新文件 + */ + NEW("1"), + + /** + * 旧文件 + */ + OLD("0"); + + private final String code; + + FileStatusEnum(String code) { + this.code = code; + } + +} \ No newline at end of file diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/exception/enums/FileExceptionEnum.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/exception/enums/FileExceptionEnum.java index 1e00b1aec..99e59edcb 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/exception/enums/FileExceptionEnum.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/exception/enums/FileExceptionEnum.java @@ -14,60 +14,85 @@ import lombok.Getter; @Getter public enum FileExceptionEnum implements AbstractExceptionEnum { + /** + * 附件IDS为空 + */ + FILE_IDS_EMPTY(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "01", "附件IDS为空!"), + + /** + * 下载的文件中包含私有文件 + */ + SECRET_FLAG_INFO_ERROR(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "02", "下载的文件中包含私有文件,具体文件为:{}"), + /** * 阿里云文件操作异常 */ - ALIYUN_FILE_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "01", "阿里云文件操作异常,具体信息为:{}"), + ALIYUN_FILE_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "03", "阿里云文件操作异常,具体信息为:{}"), /** * 腾讯云文件操作异常 */ - TENCENT_FILE_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "02", "腾讯云文件操作异常,具体信息为:{}"), + TENCENT_FILE_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "04", "腾讯云文件操作异常,具体信息为:{}"), /** * 文件不存在 */ - FILE_NOT_FOUND(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "03", "本地文件不存在,具体信息为:{}"), + FILE_NOT_FOUND(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "05", "本地文件不存在,具体信息为:{}"), /** * MinIO文件操作异常 */ - MINIO_FILE_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "04", "MinIO文件操作异常,具体信息为:{}"), + MINIO_FILE_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "06", "MinIO文件操作异常,具体信息为:{}"), /** * 上传文件操作异常 */ - ERROR_FILE(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "05", "上传文件操作异常,具体信息为:{}"), + ERROR_FILE(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "07", "上传文件操作异常,具体信息为:{}"), /** - * 该文件信息不存在 + * 该条文件信息记录不存在 */ - NOT_EXISTED(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "06", "该文件信息不存在,文件id为:{}"), + NOT_EXISTED(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "08", "该条文件信息记录不存在,文件id为:{}"), /** * 获取文件流错误 */ - FILE_STREAM_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "07", "获取文件流错误"), + FILE_STREAM_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "09", "获取文件流错误"), /** * 下载文件错误 */ - DOWNLOAD_FILE_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "08", "下载文件错误,具体信息为:{}"), + DOWNLOAD_FILE_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "10", "下载文件错误,具体信息为:{}"), /** * 预览文件异常 */ - PREVIEW_ERROR_NOT_SUPPORT(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "09", "预览文件异常,您预览的文件类型不支持或文件出现错误"), + PREVIEW_ERROR_NOT_SUPPORT(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "11", "预览文件异常,您预览的文件类型不支持或文件出现错误"), /** * 预览文件参数存在空值 */ - PREVIEW_EMPTY_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "10", "预览文件参数存在空值,请求参数为:{}"), + PREVIEW_EMPTY_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "12", "预览文件参数存在空值,请求参数为:{}"), /** * 渲染文件流字节出错 */ - WRITE_BYTES_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "10", "渲染文件流字节出错,具体信息为:{}"); + WRITE_BYTES_ERROR(RuleConstants.BUSINESS_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "13", "渲染文件流字节出错,具体信息为:{}"), + + /** + * 文件id不能为空 + */ + FILE_ID_NOT_NULL(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "14", "文件ID不能为空!"), + + /** + * 文件Code不能为空 + */ + FILE_CODE_NOT_NULL(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "15", "文件CODE不能为空!"), + + /** + * 文件不允许被访问 + */ + FILE_DENIED_ACCESS(RuleConstants.USER_OPERATION_ERROR_TYPE_CODE + FileConstants.FILE_EXCEPTION_STEP_CODE + "16", "文件不允许被访问!"); /** * 错误编码 diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/request/SysFileInfoRequest.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/request/SysFileInfoRequest.java index a0c1d0a8e..dda5651f9 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/request/SysFileInfoRequest.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/request/SysFileInfoRequest.java @@ -4,31 +4,56 @@ import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; import lombok.Data; import lombok.EqualsAndHashCode; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; /** - *

* 文件信息表 - *

+ * 注意: + * 1、如果文件上传不关心版本号只关心文件本身,则业务关联fileCode,文件升级code不变 + * 2、如果业务场景类似合同这类,文件升级不影响已签发的文件,则业务关联fileId,每次版本升级都会生成新的fileId * - * @author stylefeng - * @date 2020/6/7 22:15 + * @author majianguo + * @date 2020/12/27 12:35 */ @EqualsAndHashCode(callSuper = true) @Data public class SysFileInfoRequest extends BaseRequest { /** - * 主键id + * 文件ID */ - @NotNull(message = "fileId不能为空", groups = {delete.class, detail.class}) + @NotNull(message = "fileId不能为空", groups = {versionBack.class, detail.class}) private Long fileId; /** - * 文件编码,解决一个文件多个版本问题,多次上传文件编码不变 + * 文件编码 + *

+ * 解决一个文件多个版本问题,多次上传文件编码不变 + *

+ * 版本号升级的依据,code相同id不同视为同一个文件的不同版本 */ + @NotNull(message = "fileCode不能为空,请检查fileCode参数", groups = {edit.class, delete.class,}) private Long fileCode; + /** + * 是否为机密文件,Y-是机密,N-不是机密 + *

+ * 机密文件为需要鉴权的文件,非机密文件则不需要任何权限(不登录也可以访问) + */ + @NotBlank(message = "是否是机密文件不能为空,请检查secretFlag参数", groups = {add.class, edit.class}) + private String secretFlag; + + /** + * 文件名称(上传时候的文件全名,例如:开发文档.txt) + */ + private String fileOriginName; + + /** + * 其他文件形式传参 + */ + private String token; + /** * 文件存储位置:1-阿里云,2-腾讯云,3-minio,4-本地 */ @@ -39,11 +64,6 @@ public class SysFileInfoRequest extends BaseRequest { */ private String fileBucket; - /** - * 文件名称(上传时候的文件全名) - */ - private String fileOriginName; - /** * 文件后缀 */ @@ -65,9 +85,9 @@ public class SysFileInfoRequest extends BaseRequest { private String filePath; /** - * 校验组,预览图片 + * 版本回退 */ - public @interface preview { + public @interface versionBack { } } diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoListResponse.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoListResponse.java new file mode 100644 index 000000000..6c934573c --- /dev/null +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoListResponse.java @@ -0,0 +1,63 @@ +package cn.stylefeng.roses.kernel.file.pojo.response; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 附件列表返回类 + * + * @author fengshuonan + * @date 2020/12/30 21:24 + */ +@Data +public class SysFileInfoListResponse implements Serializable { + + private static final long serialVersionUID = -1L; + + /** + * 主键id + */ + private Long fileId; + + /** + * 文件应用Code名称 + */ + private String fileAppCodeName; + + /** + * 文件名称(上传时候的文件名) + */ + private String fileOriginName; + + /** + * 文件后缀 + */ + private String fileSuffix; + + /** + * 文件大小信息,计算后的 + */ + private String fileSizeInfo; + + /** + * 文件版本 + */ + private Integer fileVersion; + + /** + * 创建人 + */ + private Long createAccountId; + + /** + * 创建人部门id + */ + private Long createDeptId; + + /** + * 创建人姓名 + */ + private String createUserName; + +} diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoResponse.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoResponse.java index 8ab128e8a..adcafd292 100644 --- a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoResponse.java +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/pojo/response/SysFileInfoResponse.java @@ -17,10 +17,54 @@ public class SysFileInfoResponse { private Long fileId; /** - * 文件编码,解决一个文件多个版本问题,多次上传文件编码不变 + * 文件编码 + *

+ * 解决一个文件多个版本问题,多次上传文件编码不变 + *

+ * 版本号升级的依据,code相同id不同视为同一个文件的不同版本 */ private Long fileCode; + /** + * 文件版本 + */ + private Integer fileVersion; + + /** + * 文件状态(0-历史版,1-最新版) + */ + private String fileStatus; + + /** + * 文件后缀,例如.txt + */ + private String fileSuffix; + + /** + * 文件大小kb + */ + private Long fileSizeKb; + + /** + * 文件大小信息,计算后的 + */ + private String fileSizeInfo; + + /** + * 是否为机密文件 + */ + private String secretFlag; + + /** + * 文件的字节 + */ + private byte[] fileBytes; + + /** + * 存储到bucket中的名称,主键id+.后缀 + */ + private String fileObjectName; + /** * 文件存储位置:1-阿里云,2-腾讯云,3-minio,4-本地 */ @@ -36,29 +80,9 @@ public class SysFileInfoResponse { */ private String fileOriginName; - /** - * 文件后缀,例如.txt - */ - private String fileSuffix; - - /** - * 文件大小kb - */ - private Long fileSizeKb; - - /** - * 存储到bucket中的名称,主键id+.后缀 - */ - private String fileObjectName; - /** * 存储路径 */ private String filePath; - /** - * 文件的字节 - */ - private byte[] fileBytes; - } diff --git a/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/util/PdfFileTypeUtil.java b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/util/PdfFileTypeUtil.java new file mode 100644 index 000000000..e8b7e8f9d --- /dev/null +++ b/kernel-d-file/file-api/src/main/java/cn/stylefeng/roses/kernel/file/util/PdfFileTypeUtil.java @@ -0,0 +1,45 @@ +package cn.stylefeng.roses.kernel.file.util; + +import cn.hutool.core.util.StrUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * pdf文件类型识别工具 + * + * @author majianguo + * @date 2020/12/27 13:06 + */ +public class PdfFileTypeUtil { + + private static final List PDF_TYPES; + + static { + PDF_TYPES = new ArrayList<>(); + PDF_TYPES.add("pdf"); + } + + /** + * 根据文件名称获取文件是否为PDF类型 + * + * @param fileName 文件名称 + * @return boolean true-是图片类型,false-不是图片类型 + * @author fengshuonan + * @date 2020/11/29 14:04 + */ + public static boolean getFilePdfTypeFlag(String fileName) { + if (StrUtil.isEmpty(fileName)) { + return false; + } + + for (String picType : PDF_TYPES) { + if (fileName.toLowerCase().endsWith(picType)) { + return true; + } + } + + return false; + } + +} diff --git a/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/controller/SysFileInfoController.java b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/controller/SysFileInfoController.java index c3182b0f1..bcd88b812 100644 --- a/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/controller/SysFileInfoController.java +++ b/kernel-d-file/file-business/src/main/java/cn/stylefeng/roses/kernel/file/modular/controller/SysFileInfoController.java @@ -26,7 +26,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import static cn.stylefeng.roses.kernel.file.constants.FileConstants.DEFAULT_AVATAR_FILE_OBJ_NAME; -import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_PREVIEW_URL; +import static cn.stylefeng.roses.kernel.file.constants.FileConstants.FILE_PRIVATE_PREVIEW_URL; /** * 文件信息管理 @@ -84,7 +84,7 @@ public class SysFileInfoController { * @author fengshuonan * @date 2020/11/29 11:29 */ - @GetResource(name = "文件预览", path = FILE_PREVIEW_URL) + @GetResource(name = "文件预览", path = FILE_PRIVATE_PREVIEW_URL) public void preview(SysFileInfoRequest sysFileInfoRequest) { HttpServletResponse response = HttpServletUtil.getResponse(); diff --git a/kernel-d-file/file-sdk-local/src/main/java/cn/stylefeng/roses/kernel/file/local/LocalFileOperator.java b/kernel-d-file/file-sdk-local/src/main/java/cn/stylefeng/roses/kernel/file/local/LocalFileOperator.java index 0cc4a3bec..ddc3b2336 100644 --- a/kernel-d-file/file-sdk-local/src/main/java/cn/stylefeng/roses/kernel/file/local/LocalFileOperator.java +++ b/kernel-d-file/file-sdk-local/src/main/java/cn/stylefeng/roses/kernel/file/local/LocalFileOperator.java @@ -152,7 +152,7 @@ public class LocalFileOperator implements FileOperatorApi { String token = LoginContext.me().getToken(); // 拼接url = “host” + “预览图片的url” + “?token=xxx” - return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token; + return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token; } @Override diff --git a/kernel-d-file/file-sdk-minio/src/main/java/cn/stylefeng/roses/kernel/file/minio/MinIoFileOperator.java b/kernel-d-file/file-sdk-minio/src/main/java/cn/stylefeng/roses/kernel/file/minio/MinIoFileOperator.java index 2b259f055..6a49b6c0e 100644 --- a/kernel-d-file/file-sdk-minio/src/main/java/cn/stylefeng/roses/kernel/file/minio/MinIoFileOperator.java +++ b/kernel-d-file/file-sdk-minio/src/main/java/cn/stylefeng/roses/kernel/file/minio/MinIoFileOperator.java @@ -196,7 +196,7 @@ public class MinIoFileOperator implements FileOperatorApi { String token = LoginContext.me().getToken(); // 拼接url = “host” + “预览图片的url” + “?token=xxx” - return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token; + return FileConfigExpander.getServerDeployHost() + FileConstants.FILE_PRIVATE_PREVIEW_URL + "?fileBucket=" + bucketName + "&fileObjectName=" + key + "&token=" + token; }