diff --git a/README.md b/README.md index b1f67eadd69d181bf7eb676b94bc474c1c38efe0..8b788e46eadef428e607aa3a070d1e0e0e30edc8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Bootx-Platform (v1.3.5-园博园) +# Bootx-Platform (v1.3.6-园博园)
-
+
@@ -28,7 +28,7 @@
## 📚资料和文档
-- 系统演示地址:[管理平台(vue3)](http://v3.platform.bootx.cn/)、[可视化大屏](http://visualization.platform.bootx.cn/)
+- 系统演示地址:[管理平台(vue3)](https://admin.platform.demo.bootx.cn/)、[可视化大屏](https://visualization.platform.demo.bootx.cn/)
- 前端项目地址:[前端项目(vue3)](https://gitee.com/bootx/bootx-platform-vue3)、[可视化大屏](https://gitee.com/bootx/bootx-platform-visualization)、[前端项目(vue2只维护不再更新)](https://gitee.com/bootx/bootx-platform-ui)
- 移动端项目地址:[移动端项目(taro+vue3+ts)](https://gitee.com/xucun/bootx-platform-mobile)
- 日志收集:[PlumeLog](http://139.198.29.219:8891/)
@@ -131,8 +131,7 @@ bootx-platform
QQ扫码加入QQ交流群
-
-
+
+ * //方式一,通过字符串设置通用的 ACL 详情:{@link Constant.ACL }
+ * setFileAcl(ACL.PUBLIC_READ);
+ * //方式二,针对指定存储平台设置更复杂的权限控制,以华为云 OBS 为例
+ * AccessControlList acl = new AccessControlList();
+ * Owner owner = new Owner();
+ * owner.setId("ownerid");
+ * acl.setOwner(owner);
+ * // 保留Owner的完全控制权限(注:如果不设置该权限,该对象Owner自身将没有访问权限)
+ * acl.grantPermission(new CanonicalGrantee("ownerid"), Permission.PERMISSION_FULL_CONTROL);
+ * // 为指定用户设置完全控制权限
+ * acl.grantPermission(new CanonicalGrantee("userid"), Permission.PERMISSION_FULL_CONTROL);
+ * // 为所有用户设置读权限
+ * acl.grantPermission(GroupGrantee.ALL_USERS, Permission.PERMISSION_READ);
+ * setFileAcl(acl);
+ *
+ */
+ private Object fileAcl;
+
+ /**
+ * 缩略图的访问控制列表,一般情况下只有对象存储支持该功能
+ * 详情见{@link FileInfo#setFileAcl}
+ */
+ private Object thFileAcl;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+
+ /**
+ * 文件大小
+ */
+ public String getFileSize() {
+ return FileUtil.readableFileSize(size);
+ }
+
+}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UpdateFileInfo.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UpdateFileInfo.java
deleted file mode 100644
index 10f8a7cabb4660205c24cb9a6170711b02233dd3..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UpdateFileInfo.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package cn.bootx.platform.starter.file.entity;
-
-import cn.bootx.platform.starter.file.convert.FileConvert;
-import cn.bootx.platform.common.core.function.EntityBaseFunction;
-import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
-import cn.bootx.platform.starter.file.dto.UpdateFileDto;
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.experimental.Accessors;
-
-import java.time.LocalDateTime;
-
-/**
- * 上传文件信息
- *
- * @author xxm
- * @since 2022/1/12
- */
-@EqualsAndHashCode(callSuper = true)
-@Data
-@Accessors(chain = true)
-@TableName("starter_file_upload_info")
-public class UpdateFileInfo extends MpIdEntity implements EntityBaseFunction {
-
- /** 存储位置 */
- private String filePath;
-
- /** 文件名称 */
- private String fileName;
-
- /** 文件类型 */
- private String fileType;
-
- /** 文件后缀 */
- private String fileSuffix;
-
- /** 文件大小 */
- private Long fileSize;
-
- /** 外部存储id */
- private String externalStorageId;
-
- /** 创建者ID */
- @TableField(fill = FieldFill.INSERT)
- private Long creator;
-
- /** 创建时间 */
- @TableField(fill = FieldFill.INSERT)
- private LocalDateTime createTime;
-
- @Override
- public UpdateFileDto toDto() {
- return FileConvert.CONVERT.convert(this);
- }
-
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UploadFileContext.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UploadFileContext.java
deleted file mode 100644
index 442a4d54cc848b668007180836ea45dbf5314cf0..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UploadFileContext.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cn.bootx.platform.starter.file.entity;
-
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * 上传文件上下文
- *
- * @author xxm
- * @since 2022/1/20
- */
-@Data
-@Accessors(chain = true)
-public class UploadFileContext {
-
- /** 文件id */
- private Long fileId;
-
- /** 文件名称 */
- private String fileName;
-
- /** 文件后缀名 */
- private String fileSuffix;
-
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UploadFileInfo.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UploadFileInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..44db35a2cf24033ac8b733257aea5a95ae100c2d
--- /dev/null
+++ b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/entity/UploadFileInfo.java
@@ -0,0 +1,190 @@
+package cn.bootx.platform.starter.file.entity;
+
+import cn.bootx.platform.common.core.function.EntityBaseFunction;
+import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
+import cn.bootx.platform.common.mybatisplus.handler.JacksonRawTypeHandler;
+import cn.bootx.platform.starter.file.convert.FileConvert;
+import cn.bootx.platform.starter.file.dto.UploadFileDto;
+import cn.hutool.core.lang.Dict;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.dromara.x.file.storage.core.FileInfo;
+import org.dromara.x.file.storage.core.constant.Constant;
+
+import java.time.LocalDateTime;
+import java.util.Map;
+
+/**
+ * 上传文件信息
+ *
+ * @author xxm
+ * @since 2022/1/12
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Accessors(chain = true)
+@TableName(value = "starter_file_upload_info", autoResultMap = true)
+public class UploadFileInfo extends MpIdEntity implements EntityBaseFunction {
+
+ /**
+ * 文件访问地址
+ */
+ private String url;
+
+ /**
+ * 文件大小,单位字节
+ */
+ private Long size;
+
+ /**
+ * 文件名称
+ */
+ private String filename;
+
+ /**
+ * 原始文件名
+ */
+ private String originalFilename;
+
+ /**
+ * 基础存储路径
+ */
+ private String basePath;
+
+ /**
+ * 存储路径
+ */
+ private String path;
+
+ /**
+ * 文件扩展名
+ */
+ private String ext;
+
+ /**
+ * MIME 类型
+ */
+ private String contentType;
+
+ /**
+ * 存储平台
+ */
+ private String platform;
+
+ /**
+ * 缩略图访问路径
+ */
+ private String thUrl;
+
+ /**
+ * 缩略图名称
+ */
+ private String thFilename;
+
+ /**
+ * 缩略图大小,单位字节
+ */
+ private Long thSize;
+
+ /**
+ * 缩略图 MIME 类型
+ */
+ private String thContentType;
+
+ /**
+ * 文件所属对象id
+ */
+ private String objectId;
+
+ /**
+ * 文件所属对象类型,例如用户头像,评价图片
+ */
+ private String objectType;
+
+ /**
+ * 文件元数据
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Map metadata;
+
+ /**
+ * 文件用户元数据
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Map userMetadata;
+
+ /**
+ * 缩略图元数据
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Map thMetadata;
+
+ /**
+ * 缩略图用户元数据
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Map thUserMetadata;
+
+ /**
+ * 附加属性字典
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Dict attr;
+
+ /**
+ * 文件的访问控制列表,一般情况下只有对象存储支持该功能,支持 String 或对应存储平台的 ACL 对象
+ *
+ * //方式一,通过字符串设置通用的 ACL 详情:{@link Constant.ACL }
+ * setFileAcl(ACL.PUBLIC_READ);
+ * //方式二,针对指定存储平台设置更复杂的权限控制,以华为云 OBS 为例
+ * AccessControlList acl = new AccessControlList();
+ * Owner owner = new Owner();
+ * owner.setId("ownerid");
+ * acl.setOwner(owner);
+ * // 保留Owner的完全控制权限(注:如果不设置该权限,该对象Owner自身将没有访问权限)
+ * acl.grantPermission(new CanonicalGrantee("ownerid"), Permission.PERMISSION_FULL_CONTROL);
+ * // 为指定用户设置完全控制权限
+ * acl.grantPermission(new CanonicalGrantee("userid"), Permission.PERMISSION_FULL_CONTROL);
+ * // 为所有用户设置读权限
+ * acl.grantPermission(GroupGrantee.ALL_USERS, Permission.PERMISSION_READ);
+ * setFileAcl(acl);
+ *
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Object fileAcl;
+
+ /**
+ * 缩略图的访问控制列表,一般情况下只有对象存储支持该功能
+ * 详情见{@link FileInfo#setFileAcl}
+ */
+ @TableField(typeHandler = JacksonRawTypeHandler.class)
+ private Object thFileAcl;
+
+ /** 创建时间 */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ @Override
+ public UploadFileDto toDto() {
+ return FileConvert.CONVERT.convert(this);
+ }
+
+ /**
+ * 初始化创建
+ */
+ public static UploadFileInfo init(FileInfo fileInfo){
+ return FileConvert.CONVERT.convert(fileInfo);
+ }
+
+ /**
+ * 转换为 x.file.storage 的文件信息对象
+ */
+ public FileInfo toFileInfo(){
+ return FileConvert.CONVERT.toFileInfo(this);
+ }
+
+}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/handler/FileDetailRecordHandler.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/handler/FileDetailRecordHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce5048eb7f2acf8679c9ee327177c69a901fbb7d
--- /dev/null
+++ b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/handler/FileDetailRecordHandler.java
@@ -0,0 +1,58 @@
+package cn.bootx.platform.starter.file.handler;
+
+import cn.bootx.platform.common.core.exception.BizException;
+import cn.bootx.platform.starter.file.dao.UploadFileManager;
+import cn.bootx.platform.starter.file.entity.UploadFileInfo;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.x.file.storage.core.FileInfo;
+import org.dromara.x.file.storage.core.recorder.FileRecorder;
+import org.springframework.stereotype.Service;
+
+/**
+ * x.file.storage 文件上传信息储存
+ * @author xxm
+ * @since 2023/11/13
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class FileDetailRecordHandler implements FileRecorder {
+ private final UploadFileManager uploadFileManager;
+
+ /**
+ * 保存文件记录
+ */
+ @Override
+ public boolean save(FileInfo fileInfo) {
+ UploadFileInfo save = uploadFileManager.save(UploadFileInfo.init(fileInfo));
+ fileInfo.setId(String.valueOf(save.getId()));
+ return true;
+ }
+
+ /**
+ * 根据 ID(Long) 获取文件记录, 注意不是根据URL
+ */
+ @Override
+ public FileInfo getByUrl(String url) {
+ try {
+ Long id = Long.valueOf(url);
+ return uploadFileManager.findById(id).map(UploadFileInfo::toFileInfo).orElse(null);
+ } catch (NumberFormatException e) {
+ throw new BizException("URL是文件的ID,注意不要传错参数");
+ }
+ }
+
+ /**
+ * 根据 ID(Long) 删除文件记录, 注意不是根据URL
+ */
+ @Override
+ public boolean delete(String url) {
+ try {
+ Long id = Long.valueOf(url);
+ return uploadFileManager.deleteById(id);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java
index 7d1a712692508240b0922485e76be5aed535495b..5a9daa1749ee79c0b514f5949a1eb370c4c982e1 100644
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java
+++ b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/FileUploadService.java
@@ -1,26 +1,25 @@
package cn.bootx.platform.starter.file.service;
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.configuration.FileUploadProperties;
-import cn.bootx.platform.common.core.exception.BizException;
-import cn.bootx.platform.common.core.function.ParamService;
+import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
-import cn.bootx.platform.starter.file.dao.UpdateFileManager;
-import cn.bootx.platform.starter.file.dto.UpLoadOptions;
-import cn.bootx.platform.starter.file.dto.UpdateFileDto;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import cn.bootx.platform.starter.file.service.impl.OssUploadService;
-import cn.bootx.platform.starter.file.service.impl.TencentOssUploadService;
-import cn.hutool.core.io.FileTypeUtil;
+import cn.bootx.platform.starter.file.UploadFileParam;
+import cn.bootx.platform.starter.file.configuration.FileUploadProperties;
+import cn.bootx.platform.starter.file.convert.FileConvert;
+import cn.bootx.platform.starter.file.dao.UploadFileManager;
+import cn.bootx.platform.starter.file.dto.UploadFileDto;
+import cn.bootx.platform.starter.file.entity.UploadFileInfo;
import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
+import org.dromara.x.file.storage.core.FileInfo;
+import org.dromara.x.file.storage.core.FileStorageService;
+import org.dromara.x.file.storage.core.UploadPretreatment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -29,11 +28,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
+import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.util.List;
+import java.io.ByteArrayInputStream;
+import java.net.URLEncoder;
/**
* 文件上传管理类
@@ -45,50 +43,24 @@ import java.util.List;
@Service
@RequiredArgsConstructor
public class FileUploadService {
-
- private final List uploadServices;
-
- private final UpdateFileManager updateFileManager;
-
+ private final UploadFileManager uploadFileManager;
+ private final FileStorageService fileStorageService;
private final FileUploadProperties fileUploadProperties;
- private final ParamService paramService;
-
/**
- * 文件上传
- * @param file 文件
- * @param fileName 文件名称
+ * 分页
*/
- @Transactional(rollbackFor = Exception.class)
- public UpdateFileDto upload(MultipartFile file, String fileName) throws IOException {
- val uploadType = fileUploadProperties.getUploadType();
- UploadService uploadService = uploadServices.stream()
- .filter(s -> s.enable(uploadType))
- .findFirst()
- .orElseThrow(() -> new BizException("未找到该类的上传处理器"));
- if (file.isEmpty()) {
- throw new BizException("文件不可为空");
- }
- // 上传文件信息
- if (StrUtil.isBlank(fileName)) {
- fileName = file.getOriginalFilename();
- }
- String fileType = FileTypeUtil.getType(file.getInputStream(), fileName);
- String fileSuffix = fileType;
-
- // 获取不到类型名,后缀名使用上传文件名称的后缀
- if (StrUtil.isBlank(fileSuffix)) {
- fileSuffix = StrUtil.subAfter(fileName, ".", true);
- }
- UploadFileContext context = new UploadFileContext().setFileId(IdUtil.getSnowflakeNextId())
- .setFileName(fileName)
- .setFileSuffix(fileSuffix);
+ public PageResult page(PageParam pageParam, UploadFileParam param) {
+ return MpUtil.convert2DtoPageResult(uploadFileManager.page(pageParam,param));
+ }
- UpdateFileInfo uploadInfo = uploadService.upload(file, context);
- uploadInfo.setFileSuffix(fileSuffix).setFileType(fileType).setFileName(fileName);
- uploadInfo.setId(context.getFileId());
- updateFileManager.save(uploadInfo);
- return uploadInfo.toDto();
+ /**
+ * 获取单条详情
+ */
+ public UploadFileDto findById(Long id){
+ return uploadFileManager.findById(id)
+ .map(UploadFileInfo::toDto)
+ .orElseThrow(DataNotExistException::new);
}
/**
@@ -96,74 +68,66 @@ public class FileUploadService {
*/
@Transactional(rollbackFor = Exception.class)
public void delete(Long id){
- val uploadType = fileUploadProperties.getUploadType();
- UploadService uploadService = uploadServices.stream()
- .filter(s -> s.enable(uploadType))
- .findFirst()
- .orElseThrow(() -> new BizException("未找到该类的上传处理器"));
- UpdateFileInfo updateFileInfo = updateFileManager.findById(id).orElseThrow(() -> new BizException("文件不存在"));
- uploadService.delete(updateFileInfo);
- updateFileManager.deleteById(updateFileInfo.getId());
+ UploadFileInfo uploadFileInfo = uploadFileManager.findById(id)
+ .orElseThrow(DataNotExistException::new);
+ fileStorageService.delete(FileConvert.CONVERT.toFileInfo(uploadFileInfo));
+ }
+
+ /**
+ * 文件上传
+ * @param file 文件
+ * @param fileName 文件名称
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public UploadFileDto upload(MultipartFile file, String fileName) {
+ UploadPretreatment uploadPretreatment = fileStorageService.of(file);
+ if (StrUtil.isNotBlank(fileName)){
+ uploadPretreatment.setOriginalFilename(fileName);
+ }
+ FileInfo upload =uploadPretreatment.upload();
+ return FileConvert.CONVERT.toDto(upload);
}
/**
* 浏览
*/
+ @SneakyThrows
public void preview(Long id, HttpServletResponse response) {
- val uploadType = fileUploadProperties.getUploadType();
- UploadService uploadService = uploadServices.stream()
- .filter(s -> s.enable(uploadType))
- .findFirst()
- .orElseThrow(() -> new BizException("未找到该类的上传处理器"));
- UpdateFileInfo updateFileInfo = updateFileManager.findById(id).orElseThrow(() -> new BizException("文件不存在"));
- uploadService.preview(updateFileInfo, response);
+ FileInfo info = fileStorageService.getFileInfoByUrl(String.valueOf(id));
+ byte[] bytes = fileStorageService.download(info).bytes();
+ val is = new ByteArrayInputStream(bytes);
+ // 获取响应输出流
+ ServletOutputStream os = response.getOutputStream();
+ IoUtil.copy(is, os);
+ response.addHeader(HttpHeaders.CONTENT_DISPOSITION, info.getContentType());
+ IoUtil.close(is);
+ IoUtil.close(os);
}
/**
* 文件下载
*/
+ @SneakyThrows
public ResponseEntity download(Long id) {
- val uploadType = fileUploadProperties.getUploadType();
- UploadService uploadService = uploadServices.stream()
- .filter(s -> s.enable(uploadType))
- .findFirst()
- .orElseThrow(() -> new BizException("未找到该类文件的处理器"));
- UpdateFileInfo updateFileInfo = updateFileManager.findById(id).orElseThrow(() -> new BizException("文件不存在"));
- InputStream inputStream = uploadService.download(updateFileInfo);
+ FileInfo fileInfo = fileStorageService.getFileInfoByUrl(String.valueOf(id));
+ byte[] bytes = fileStorageService.download(fileInfo).bytes();
// 设置header信息
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
- headers.setContentDispositionFormData("attachment",
- new String(updateFileInfo.getFileName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
- return new ResponseEntity<>(IoUtil.readBytes(inputStream), headers, HttpStatus.OK);
- }
-
- /**
- * 获取文件字节数组
- */
- public byte[] getFileBytes(Long id) {
- val uploadType = fileUploadProperties.getUploadType();
- UploadService uploadService = uploadServices.stream()
- .filter(s -> s.enable(uploadType))
- .findFirst()
- .orElseThrow(() -> new BizException("未找到该类文件的处理器"));
- UpdateFileInfo updateFileInfo = updateFileManager.findById(id).orElseThrow(() -> new BizException("文件不存在"));
- InputStream inputStream = uploadService.download(updateFileInfo);
- return IoUtil.readBytes(inputStream);
- }
-
- /**
- * 分页
- */
- public PageResult page(PageParam pageParam) {
- return MpUtil.convert2DtoPageResult(updateFileManager.page(pageParam));
+ String fileName = fileInfo.getOriginalFilename();
+ headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, CharsetUtil.UTF_8));
+ return new ResponseEntity<>(bytes,headers,HttpStatus.OK);
}
/**
* 获取文件预览地址
*/
public String getFilePreviewUrl(Long id) {
- return this.getServerUrl() + "/file/preview/" + id;
+ if (fileUploadProperties.isServiceProxy()){
+ return this.getServerUrl() + "/file/preview/" + id;
+ } else {
+ return "";
+ }
}
/**
@@ -177,33 +141,17 @@ public class FileUploadService {
* 获取文件地址
*/
public String getFileDownloadUrl(Long id) {
- return this.getServerUrl() + "/file/download/" + id;
+ if (fileUploadProperties.isServiceProxy()){
+ return this.getServerUrl() + "/file/download/" + id;
+ } else {
+ return "";
+ }
}
/**
* 服务地址
*/
private String getServerUrl() {
- String serverUrl = paramService.getValue("FileServerUrl");
- if (StrUtil.isBlank(serverUrl)) {
- serverUrl = fileUploadProperties.getServerUrl();
- }
- return serverUrl;
- }
-
- public UpLoadOptions getTempCredentials() {
-
- TencentOssUploadService ossUploadService=(TencentOssUploadService)uploadServices.stream().filter(s -> s.enable(FileUploadTypeEnum.TENCENT_OSS))
- .findFirst().orElseThrow(() -> new BizException("未找到该类文件的处理器"));
-
- return ossUploadService.getTemplateCredential();
-
- }
-
- public UpdateFileDto saveUploadResult(UpdateFileInfo uploadInfo) {
-
- uploadInfo.setId(IdUtil.getSnowflakeNextId());
- updateFileManager.save(uploadInfo);
- return uploadInfo.toDto();
+ return fileUploadProperties.getServerUrl();
}
}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/UploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/UploadService.java
deleted file mode 100644
index e3e818dfddca865b121b8567b473eecc0334a147..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/UploadService.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package cn.bootx.platform.starter.file.service;
-
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.InputStream;
-
-/**
- * 文件上传接口
- *
- * @author xxm
- * @since 2022/1/14
- */
-public interface UploadService {
-
- /**
- * 判断启用
- */
- boolean enable(FileUploadTypeEnum type);
-
- /**
- * 上传文件
- */
- UpdateFileInfo upload(MultipartFile file, UploadFileContext context);
-
- /**
- * 预览文件
- */
- void preview(UpdateFileInfo updateFileInfo, HttpServletResponse response);
-
- /**
- * 下载文件
- */
- InputStream download(UpdateFileInfo updateFileInfo);
-
- /**
- * 删除文件
- */
- void delete(UpdateFileInfo updateFileInfo);
-
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/JdbcUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/JdbcUploadService.java
deleted file mode 100644
index 8e57479abf63f57d36cebfebe2b1e56785ce6340..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/JdbcUploadService.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package cn.bootx.platform.starter.file.service.impl;
-
-import cn.bootx.platform.common.core.exception.DataNotExistException;
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.configuration.FileUploadProperties;
-import cn.bootx.platform.starter.file.dao.JdbcFileDataManager;
-import cn.bootx.platform.starter.file.entity.JdbcFileData;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import cn.bootx.platform.starter.file.service.UploadService;
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.io.IoUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpHeaders;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-
-/**
- * 数据库存储上传文件
- * @author xxm
- * @since 2023/8/5
- */
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class JdbcUploadService implements UploadService {
- private final JdbcFileDataManager jdbcFileDataManager;
-
- private final FileUploadProperties fileUploadProperties;
-
- /**
- * 判断启用
- */
- @Override
- public boolean enable(FileUploadTypeEnum type) {
- return type==FileUploadTypeEnum.JDBC;
- }
-
- /**
- * 上传文件
- *
- * @param file
- * @param context
- */
- @SneakyThrows
- @Override
- public UpdateFileInfo upload(MultipartFile file, UploadFileContext context) {
- FileUploadProperties.JDBC jdbc = fileUploadProperties.getJdbc();
- JdbcFileData jdbcFileData;
- byte[] bytes = file.getBytes();
- if (jdbc.isBase64()){
- jdbcFileData =new JdbcFileData().setBase64(Base64.encode(bytes));
- } else {
- jdbcFileData =new JdbcFileData().setData(bytes);
- }
- jdbcFileDataManager.save(jdbcFileData);
- return new UpdateFileInfo().setExternalStorageId(String.valueOf(jdbcFileData.getId())).setFileSize(file.getSize());
- }
-
- /**
- * 预览文件
- */
- @SneakyThrows
- @Override
- public void preview(UpdateFileInfo updateFileInfo, HttpServletResponse response) {
- FileUploadProperties.JDBC jdbc = fileUploadProperties.getJdbc();
- Long id = Long.valueOf(updateFileInfo.getExternalStorageId());
- JdbcFileData jdbcFileData = jdbcFileDataManager.findById(id)
- .orElseThrow(DataNotExistException::new);
- InputStream inputStream;
- if (jdbc.isBase64()){
- inputStream = new ByteArrayInputStream(Base64.decode(jdbcFileData.getBase64()));
- } else {
- inputStream = new ByteArrayInputStream(jdbcFileData.getData());
- }
-
- // 获取响应输出流
- ServletOutputStream os = response.getOutputStream();
- IoUtil.copy(inputStream, os);
- response.addHeader(HttpHeaders.CONTENT_DISPOSITION, updateFileInfo.getFileType());
- IoUtil.close(inputStream);
- IoUtil.close(os);
-
- }
-
- /**
- * 下载文件
- */
- @Override
- public InputStream download(UpdateFileInfo updateFileInfo) {
- FileUploadProperties.JDBC jdbc = fileUploadProperties.getJdbc();
- Long id = Long.valueOf(updateFileInfo.getExternalStorageId());
- JdbcFileData jdbcFileData = jdbcFileDataManager.findById(id)
- .orElseThrow(DataNotExistException::new);
- if (jdbc.isBase64()){
- return new ByteArrayInputStream(Base64.decode(jdbcFileData.getBase64()));
- } else {
- return new ByteArrayInputStream(jdbcFileData.getData());
- }
- }
-
- /**
- * 删除文件
- */
- @Override
- public void delete(UpdateFileInfo updateFileInfo) {
- Long id = Long.valueOf(updateFileInfo.getExternalStorageId());
- jdbcFileDataManager.deleteById(id);
- }
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/LocalUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/LocalUploadService.java
deleted file mode 100644
index 4cdbf72b20baae134d3a9b16a5f34469ac1dd8fa..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/LocalUploadService.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package cn.bootx.platform.starter.file.service.impl;
-
-import cn.bootx.platform.starter.file.configuration.FileUploadProperties;
-import cn.bootx.platform.common.core.exception.BizException;
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import cn.bootx.platform.starter.file.service.UploadService;
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.IdUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpHeaders;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.util.Optional;
-
-/**
- * 上传文件本地存储
- *
- * @author xxm
- * @since 2022/1/12
- */
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class LocalUploadService implements UploadService {
-
- private final FileUploadProperties fileUploadProperties;
-
- @Override
- public boolean enable(FileUploadTypeEnum type) {
- return type == FileUploadTypeEnum.LOCAL;
- }
-
- /**
- * 文件上传
- */
- @SneakyThrows
- @Override
- public UpdateFileInfo upload(MultipartFile file, UploadFileContext context) {
- String fileSuffix = Optional.ofNullable(context.getFileSuffix()).map(s -> "." + s).orElse("");
- String filePath = DateUtil.today() + "/" + IdUtil.getSnowflakeNextIdStr() + fileSuffix;
- String storePath = fileUploadProperties.getLocal().getLocalPath() + filePath;
- FileUtil.writeFromStream(file.getInputStream(), storePath);
- return new UpdateFileInfo().setFilePath(filePath).setFileSize(file.getSize());
- }
-
- /**
- * 浏览
- */
- @SneakyThrows
- @Override
- public void preview(UpdateFileInfo updateFileInfo, HttpServletResponse response) {
- String storePath = fileUploadProperties.getLocal().getLocalPath() + updateFileInfo.getFilePath();
- File file = new File(storePath);
- if (!file.exists()) {
- throw new BizException("文件不存在");
- }
- FileInputStream is = new FileInputStream(file);
- // 获取响应输出流
- ServletOutputStream os = response.getOutputStream();
- IoUtil.copy(is, os);
- response.addHeader(HttpHeaders.CONTENT_DISPOSITION, updateFileInfo.getFileType());
- IoUtil.close(is);
- IoUtil.close(os);
- }
-
- /**
- * 下载
- */
- @SneakyThrows
- @Override
- public InputStream download(UpdateFileInfo updateFileInfo) {
- String storePath = fileUploadProperties.getLocal().getLocalPath() + updateFileInfo.getFilePath();
- File file = new File(storePath);
- if (!file.exists()) {
- throw new BizException("文件不存在");
- }
- return Files.newInputStream(file.toPath());
- }
-
- /**
- * 删除文件
- */
- @Override
- public void delete(UpdateFileInfo updateFileInfo) {
- String storePath = fileUploadProperties.getLocal().getLocalPath() + updateFileInfo.getFilePath();
- FileUtil.del(storePath);
- }
-
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/MinioUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/MinioUploadService.java
deleted file mode 100644
index 09d1b19551376ce6fdcc4b776c0fcf3e058842e1..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/MinioUploadService.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package cn.bootx.platform.starter.file.service.impl;
-
-import cn.bootx.platform.starter.file.configuration.FileUploadProperties;
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import cn.bootx.platform.starter.file.service.UploadService;
-import cn.hutool.core.io.IoUtil;
-import io.minio.*;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
-import org.springframework.http.HttpHeaders;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.InputStream;
-import java.util.Objects;
-
-/**
- * minio方式存储文件
- *
- * @author xxm
- * @since 2022/1/12
- */
-@Slf4j
-@Service
-@ConditionalOnMissingClass("io.minio.MinioClient")
-@RequiredArgsConstructor
-public class MinioUploadService implements UploadService {
-
- private final FileUploadProperties fileUploadProperties;
-
- private MinioClient client;
-
- /**
- * 判断启用
- */
- @Override
- public boolean enable(FileUploadTypeEnum type) {
- boolean initFlag = type == FileUploadTypeEnum.MINIO;
- if (initFlag) {
- this.doInit();
- }
- return initFlag;
- }
-
- /**
- * 上传文件
- */
- @SneakyThrows
- @Override
- public UpdateFileInfo upload(MultipartFile file, UploadFileContext context) {
- FileUploadProperties.Minio minio = fileUploadProperties.getMinio();
- PutObjectArgs putObjectArgs = PutObjectArgs.builder()
- .bucket(minio.getBucket()) // bucket必须传递
- .contentType(file.getContentType())
- .object(context.getFileId() + "." + context.getFileSuffix())
- .stream(file.getInputStream(), file.getSize(), -1) // 文件内容
- .build();
- // 执行上传
- client.putObject(putObjectArgs);
- return new UpdateFileInfo().setExternalStorageId(putObjectArgs.object()).setFileSize(file.getSize());
- }
-
- /**
- * 预览文件
- */
- @SneakyThrows
- @Override
- public void preview(UpdateFileInfo updateFileInfo, HttpServletResponse response) {
- FileUploadProperties.Minio minio = fileUploadProperties.getMinio();
- String storageId = updateFileInfo.getExternalStorageId();
- GetObjectResponse inputStream = client
- .getObject(GetObjectArgs.builder().bucket(minio.getBucket()).object(storageId).build());
- // 获取响应输出流
- ServletOutputStream os = response.getOutputStream();
- IoUtil.copy(inputStream, os);
- response.addHeader(HttpHeaders.CONTENT_DISPOSITION, updateFileInfo.getFileType());
- IoUtil.close(inputStream);
- IoUtil.close(os);
- }
-
- /**
- * 下载文件
- */
- @SneakyThrows
- @Override
- public InputStream download(UpdateFileInfo updateFileInfo) {
- FileUploadProperties.Minio minio = fileUploadProperties.getMinio();
- String storageId = updateFileInfo.getExternalStorageId();
- return client.getObject(GetObjectArgs.builder()
- .bucket(minio.getBucket()) // bucket 必须传递
- .object(storageId) // 相对路径作为 key
- .build());
- }
-
- /**
- * 删除文件
- */
- @SneakyThrows
- @Override
- public void delete(UpdateFileInfo updateFileInfo) {
- FileUploadProperties.Minio minio = fileUploadProperties.getMinio();
- client.removeObject(RemoveObjectArgs.builder()
- .bucket(minio.getBucket()) // bucket必须传递
- .object(updateFileInfo.getExternalStorageId()) // 相对路径作为 key
- .build());
- }
-
- /**
- * 初始化
- */
- protected void doInit() {
- if (Objects.nonNull(client)) {
- return;
- }
- FileUploadProperties.Minio minio = fileUploadProperties.getMinio();
- // 初始化客户端
- client = MinioClient.builder()
- .endpoint(minio.getEndpoint()) // Endpoint URL
- .region(minio.getRegion()) // Region
- .credentials(minio.getAccessKey(), minio.getAccessSecret()) // 认证密钥
- .build();
- }
-
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/MongoUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/MongoUploadService.java
deleted file mode 100644
index f2ccbc86a3ba74403771e661fc7e70179df2aa6a..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/MongoUploadService.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package cn.bootx.platform.starter.file.service.impl;
-
-import cn.bootx.platform.common.core.exception.DataNotExistException;
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import cn.bootx.platform.starter.file.service.UploadService;
-import cn.hutool.core.io.IoUtil;
-import com.mongodb.client.gridfs.model.GridFSFile;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import org.bson.types.ObjectId;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.data.mongodb.gridfs.GridFsResource;
-import org.springframework.data.mongodb.gridfs.GridFsTemplate;
-import org.springframework.http.HttpHeaders;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.InputStream;
-import java.util.Optional;
-
-/**
- * mongo方式存储文件
- *
- * @author xxm
- * @since 2022/1/12
- */
-@Slf4j
-@Service
-@ConditionalOnClass(name="org.springframework.data.mongodb.gridfs.GridFsTemplate")
-@RequiredArgsConstructor
-public class MongoUploadService implements UploadService {
-
- private final GridFsTemplate gridFsTemplate;
-
- @Override
- public boolean enable(FileUploadTypeEnum type) {
- return type == FileUploadTypeEnum.MONGO;
- }
-
- /**
- * 上传
- */
- @SneakyThrows
- @Override
- public UpdateFileInfo upload(MultipartFile file, UploadFileContext context) {
- ObjectId store = gridFsTemplate.store(file.getInputStream(), context.getFileName(), file.getContentType());
- return new UpdateFileInfo().setExternalStorageId(store.toString()).setFileSize(file.getSize());
- }
-
- @SneakyThrows
- @Override
- public void preview(UpdateFileInfo updateFileInfo, HttpServletResponse response) {
- Criteria criteria = Criteria.where("_id").is(updateFileInfo.getExternalStorageId());
- Query query = new Query(criteria);
-
- GridFSFile gridFSFile = Optional.ofNullable(gridFsTemplate.findOne(query))
- .orElseThrow(DataNotExistException::new);
- GridFsResource resource = gridFsTemplate.getResource(gridFSFile);
- InputStream inputStream = resource.getInputStream();
-
- // 获取响应输出流
- ServletOutputStream os = response.getOutputStream();
- IoUtil.copy(inputStream, os);
- response.addHeader(HttpHeaders.CONTENT_DISPOSITION, updateFileInfo.getFileType());
- IoUtil.close(inputStream);
- IoUtil.close(os);
- }
-
- @SneakyThrows
- @Override
- public InputStream download(UpdateFileInfo updateFileInfo) {
- Criteria criteria = Criteria.where("_id").is(new ObjectId(updateFileInfo.getExternalStorageId()));
- Query query = new Query(criteria);
-
- GridFSFile gridFSFile = Optional.ofNullable(gridFsTemplate.findOne(query))
- .orElseThrow(DataNotExistException::new);
- GridFsResource resource = gridFsTemplate.getResource(gridFSFile);
- return resource.getInputStream();
- }
-
- /**
- * 删除文件
- */
- @Override
- public void delete(UpdateFileInfo updateFileInfo) {
- Criteria criteria = Criteria.where("_id").is(new ObjectId(updateFileInfo.getExternalStorageId()));
- Query query = new Query(criteria);
- gridFsTemplate.delete(query);
- }
-
-}
diff --git a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/TencentOssUploadService.java b/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/TencentOssUploadService.java
deleted file mode 100644
index efd397fc24b18047fa2fb9f891b6611794bb585d..0000000000000000000000000000000000000000
--- a/bootx-common-starters/common-starter-file/src/main/java/cn/bootx/platform/starter/file/service/impl/TencentOssUploadService.java
+++ /dev/null
@@ -1,248 +0,0 @@
-package cn.bootx.platform.starter.file.service.impl;
-
-import cn.bootx.platform.common.core.exception.BizException;
-import cn.bootx.platform.common.jackson.util.JacksonUtil;
-import cn.bootx.platform.starter.file.code.FileUploadTypeEnum;
-import cn.bootx.platform.starter.file.configuration.FileUploadProperties;
-import cn.bootx.platform.starter.file.dto.UpLoadOptions;
-import cn.bootx.platform.starter.file.entity.UpdateFileInfo;
-import cn.bootx.platform.starter.file.entity.UploadFileContext;
-import cn.bootx.platform.starter.file.service.UploadService;
-import cn.hutool.core.codec.Base64Encoder;
-import cn.hutool.core.date.LocalDateTimeUtil;
-import cn.hutool.crypto.SecureUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.qcloud.cos.COSClient;
-import com.qcloud.cos.ClientConfig;
-import com.qcloud.cos.auth.BasicCOSCredentials;
-import com.qcloud.cos.auth.COSCredentials;
-import com.qcloud.cos.exception.CosClientException;
-import com.qcloud.cos.http.HttpMethodName;
-import com.qcloud.cos.http.HttpProtocol;
-import com.qcloud.cos.model.GeneratePresignedUrlRequest;
-import com.qcloud.cos.model.ObjectMetadata;
-import com.qcloud.cos.model.PutObjectRequest;
-import com.qcloud.cos.model.UploadResult;
-import com.qcloud.cos.region.Region;
-import com.qcloud.cos.transfer.TransferManager;
-import com.qcloud.cos.transfer.TransferManagerConfiguration;
-import com.qcloud.cos.transfer.Upload;
-import com.tencent.cloud.CosStsClient;
-import com.tencent.cloud.Response;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.util.Date;
-import java.util.Objects;
-import java.util.TreeMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import static java.time.temporal.ChronoUnit.MINUTES;
-
-/**
- * 阿里云OSS上传文件
- *
- * @author xxm
- * @since 2022/1/12
- */
-@Slf4j
-@Service
-@RequiredArgsConstructor
-public class TencentOssUploadService implements UploadService {
- private final FileUploadProperties fileUploadProperties;
-
- private final ObjectMapper objectMapper;
-
- COSClient client;
- TransferManager transferManager;
-
- @Override
- public boolean enable(FileUploadTypeEnum type) {
- boolean initFlag = type == FileUploadTypeEnum.TENCENT_OSS;
- if (initFlag) {
- this.doInit();
- }
- return initFlag;
- }
-
- @Override
- public UpdateFileInfo upload(MultipartFile file, UploadFileContext context) {
- FileUploadProperties.TencentOss oss = fileUploadProperties.getTencentOss();
- ObjectMetadata objectMetadata = new ObjectMetadata();
- objectMetadata.setContentLength(file.getSize());
- PutObjectRequest putObjectRequest;
- UploadResult uploadResult;
- try {
- putObjectRequest = new PutObjectRequest(oss.getBucket(), context.getFileId().toString(), file.getInputStream(), objectMetadata);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- try {
- // 高级接口会返回一个异步结果Upload
- // 可同步地调用 waitForUploadResult 方法等待上传完成,成功返回 UploadResult, 失败抛出异常
- Upload upload = transferManager.upload(putObjectRequest);
- uploadResult = upload.waitForUploadResult();
- } catch (CosClientException | InterruptedException e) {
- e.printStackTrace();
- log.error("上传失败,原因:", e);
- throw new BizException("上传失败");
- }
-
- return new UpdateFileInfo().setExternalStorageId(uploadResult.getKey()).setFileSize(file.getSize());
- }
-
- @Override
- public void preview(UpdateFileInfo updateFileInfo, HttpServletResponse response) {
- FileUploadProperties.TencentOss oss = fileUploadProperties.getTencentOss();
- String key = updateFileInfo.getExternalStorageId();
- GeneratePresignedUrlRequest req =
- new GeneratePresignedUrlRequest(oss.getBucket(), key, HttpMethodName.GET);
- Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
- req.setExpiration(expirationDate);
- URL url = client.generatePresignedUrl(req);
- try {
- response.sendRedirect(url.toString());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public InputStream download(UpdateFileInfo updateFileInfo) {
- FileUploadProperties.TencentOss oss = fileUploadProperties.getTencentOss();
- String key = updateFileInfo.getExternalStorageId();
- GeneratePresignedUrlRequest req =
- new GeneratePresignedUrlRequest(oss.getBucket(), key, HttpMethodName.GET);
- Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
- req.setExpiration(expirationDate);
- URL url = client.generatePresignedUrl(req);
- try {
- return url.openStream();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void delete(UpdateFileInfo updateFileInfo) {
- FileUploadProperties.TencentOss oss = fileUploadProperties.getTencentOss();
- client.deleteObject(oss.getBucket(), updateFileInfo.getFileName());
- }
-
- public UpLoadOptions getTemplateCredential() {
- UpLoadOptions options;
- FileUploadProperties.TencentOss oss = fileUploadProperties.getTencentOss();
- TreeMap config = new TreeMap();
- config.put("secretId", oss.getSecretId());
- config.put("secretKey", oss.getSecretKey());
- config.put("durationSeconds", 1800);
- config.put("bucket", oss.getBucket());
- config.put("region", oss.getRegion());
- config.put("allowPrefixes", new String[]{
- "bootx/*"
- });
-
- String[] allowActions = new String[]{
- // 简单上传
- "name/cos:PutObject",
- // 表单上传、小程序上传
- "name/cos:PostObject",
- // 分块上传
- "name/cos:InitiateMultipartUpload",
- "name/cos:ListMultipartUploads",
- "name/cos:ListParts",
- "name/cos:UploadPart",
- "name/cos:CompleteMultipartUpload"
- };
-
- config.put("allowActions", allowActions);
- try {
- Response response = CosStsClient.getCredential(config);
- options = new UpLoadOptions();
- options.setSessionToken(response.credentials.sessionToken);
- options.setTmpSecretKey(response.credentials.tmpSecretKey);
- options.setTmpSecretId(response.credentials.tmpSecretId);
- options.setExpiredTime(1800L);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- LocalDateTime startTime = LocalDateTime.now();
- LocalDateTime endTime = startTime.plus(5, MINUTES);
- String keyTime = LocalDateTimeUtil.toEpochMilli(startTime) / 1000 + ";" + LocalDateTimeUtil.toEpochMilli(endTime) / 1000;
- TreeMap formData = new TreeMap<>();
- ObjectNode root = objectMapper.createObjectNode();
- root.put("expiration", endTime.plus(30, MINUTES).withNano(0).atZone(ZoneId.of("Z"))
- .toString());
- ArrayNode conditions = objectMapper.createArrayNode();
- root.putIfAbsent("conditions", conditions);
- ObjectNode child = objectMapper.createObjectNode();
- child.put("acl", "default");
- child = objectMapper.createObjectNode();
- child.put("bucket", oss.getBucket());
- ArrayNode tempArr = objectMapper.createArrayNode();
- tempArr.add("starts-with");
- tempArr.add("$key");
- tempArr.add("bootx/");
- conditions.addPOJO(tempArr);
- conditions.addPOJO(child);
- child = objectMapper.createObjectNode();
- child.put("q-sign-algorithm", "sha1");
- conditions.addPOJO(child);
- child = objectMapper.createObjectNode();
- child.put("q-ak", options.getTmpSecretId());
-
- conditions.addPOJO(child);
- child = objectMapper.createObjectNode();
- child.put("q-sign-time", keyTime);
- conditions.addPOJO(child);
- formData.put("x-cos-security-token", options.getSessionToken());
- String policyText = JacksonUtil.toJson(root);
- formData.put("policy", Base64Encoder.encode(policyText));
- formData.put("acl", "default");
- formData.put("q-sign-algorithm", "sha1");
- formData.put("q-ak", options.getTmpSecretId());
- formData.put("q-key-time", keyTime);
- String signKey = SecureUtil.hmacSha1(options.getTmpSecretKey()).digestHex(keyTime);
- String stringToSign = SecureUtil.sha1().digestHex(policyText);
- String signature = SecureUtil.hmacSha1(signKey).digestHex(stringToSign);
- formData.put("q-signature", signature);
- log.info("signKey:{},stringToSign:{},signature:{}", signKey, stringToSign, signature);
- options.setFormData(formData);
- options.setUploadUrl("https://" + oss.getBucket() + ".cos.ap-beijing.myqcloud.com");
-
-
- return options;
- }
-
- protected void doInit() {
- if (Objects.nonNull(client)) {
- return;
- }
- // 初始化客户端
- FileUploadProperties.TencentOss oss = fileUploadProperties.getTencentOss();
-
- Region region = new Region(oss.getRegion()); //COS_REGION 参数:配置成存储桶 bucket 的实际地域,例如 ap-beijing,更多 COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224
- ClientConfig clientConfig = new ClientConfig(region);
- clientConfig.setHttpProtocol(HttpProtocol.https);
- COSCredentials cred = new BasicCOSCredentials(oss.getSecretId(), oss.getSecretKey());
- client = new COSClient(cred, clientConfig);
- ExecutorService threadPool = Executors.newFixedThreadPool(32);
- transferManager = new TransferManager(client, threadPool);
- TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
- transferManagerConfiguration.setMultipartUploadThreshold(5 * 1024 * 1024);
- transferManagerConfiguration.setMinimumUploadPartSize(1024 * 1024);
- transferManager.setConfiguration(transferManagerConfiguration);
-
- }
-}
diff --git a/bootx-common-starters/common-starter-monitor/pom.xml b/bootx-common-starters/common-starter-monitor/pom.xml
index fda54f962eedf64b88e983992a4980c35025e209..3dfa080098af640978e4fa3baf9bb1aebe2ffbba 100644
--- a/bootx-common-starters/common-starter-monitor/pom.xml
+++ b/bootx-common-starters/common-starter-monitor/pom.xml
@@ -5,7 +5,7 @@
bootx-common-starters
cn.bootx.platform
- 1.3.5
+ 1.3.6
4.0.0
jar
diff --git a/bootx-common-starters/common-starter-quartz/pom.xml b/bootx-common-starters/common-starter-quartz/pom.xml
index 931c925b5b9c983e6401720a915fa5c07dcb5a46..76600697b650fb9fde76218ba2d2fc3aed9ef49b 100644
--- a/bootx-common-starters/common-starter-quartz/pom.xml
+++ b/bootx-common-starters/common-starter-quartz/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-common-starters
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/platform/starter/quartz/task/TestTask.java b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/platform/starter/quartz/task/TestTask.java
index 34d275558a5d195469869b5c9912ade01eb41773..0208fbcaa2f7275d9d64ad88c7b4ccb22e51b3b2 100644
--- a/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/platform/starter/quartz/task/TestTask.java
+++ b/bootx-common-starters/common-starter-quartz/src/main/java/cn/bootx/platform/starter/quartz/task/TestTask.java
@@ -12,7 +12,6 @@ import org.springframework.stereotype.Component;
/**
* 测试定时任务
- *
* @author xxm
* @since 2021/11/8
*/
diff --git a/bootx-common-starters/common-starter-wechat/pom.xml b/bootx-common-starters/common-starter-wechat/pom.xml
index 169a71b135e25ce2cef57d56c7533bd87b0a04d4..0baae280c95c8a8dc0a708d6fea1fa2a25ada1fb 100644
--- a/bootx-common-starters/common-starter-wechat/pom.xml
+++ b/bootx-common-starters/common-starter-wechat/pom.xml
@@ -5,7 +5,7 @@
bootx-common-starters
cn.bootx.platform
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatAppletProperties.java b/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatAppletProperties.java
index 2dc48b7b86f774ff6b01049d0ad53104adf8377c..1a95ed7d4a2d22ec155f43c242e23d7c4daeba69 100644
--- a/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatAppletProperties.java
+++ b/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatAppletProperties.java
@@ -16,11 +16,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
public class WeChatAppletProperties {
/** AppKey */
- private String appId;
+ private String appId = "?";
/** AppSecret */
- private String appSecret;
-
-
+ private String appSecret = "?";
}
diff --git a/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatProperties.java b/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatProperties.java
index 7d1c4353607b494e481342f654cc0fb01bd94d9a..b6246580f0c1152ebd13ffd58f97e1386668d94c 100644
--- a/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatProperties.java
+++ b/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/configuration/WeChatProperties.java
@@ -16,15 +16,15 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
public class WeChatProperties {
/** AppKey */
- private String appId;
+ private String appId = "?";
/** AppSecret */
- private String appSecret;
+ private String appSecret = "?";
/** token */
- private String token;
+ private String token = "?";
/** 消息加解密密钥 */
- private String encodingAesKey;
+ private String encodingAesKey = "?";
}
diff --git a/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/controller/WeChatQrLoginController.java b/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/controller/WeChatQrLoginController.java
index de3fda8b67a052bb26e0ffc35264550d046aa90f..825f56305c0e0edf06c062a205653a24ed6a4f6d 100644
--- a/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/controller/WeChatQrLoginController.java
+++ b/bootx-common-starters/common-starter-wechat/src/main/java/cn/bootx/platform/starter/wechat/controller/WeChatQrLoginController.java
@@ -32,14 +32,12 @@ public class WeChatQrLoginController {
@PostMapping("/applyQrCode")
public ResResult applyQrCode() {
return Res.ok(weChatQrLoginService.applyQrCode());
-// return Res.ok(new WeChatLoginQrCode().setQrCodeKey("123").setQrCodeUrl("xxkl"));
}
@Operation(summary = "获取扫码状态")
@GetMapping("/getStatus")
public ResResult getStatus(String qrCodeKey) {
return Res.ok(weChatQrLoginService.getStatus(qrCodeKey));
-// return Res.ok("wait");
}
}
diff --git a/bootx-common-starters/common-starter-wecom/pom.xml b/bootx-common-starters/common-starter-wecom/pom.xml
index e91e9c032230a57600a6256ef267122ab54793b5..0c52fbfc58fd805e5308763d303fcbbc373d7797 100644
--- a/bootx-common-starters/common-starter-wecom/pom.xml
+++ b/bootx-common-starters/common-starter-wecom/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-common-starters
- 1.3.5
+ 1.3.6
4.0.0
jar
diff --git a/bootx-common-starters/pom.xml b/bootx-common-starters/pom.xml
index 065167fdf3e89fc21ab0a23023054ad7bdba4282..d31add1382cc11aac842d721dbb85674d44da2d3 100644
--- a/bootx-common-starters/pom.xml
+++ b/bootx-common-starters/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-platform-parent
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-cache/pom.xml b/bootx-commons/common-cache/pom.xml
index 793b603d9daef8ade0a8789e44f1ee7e5eb98404..64ff405b42a73ed23ae36a2d04a7bd504abc9713 100644
--- a/bootx-commons/common-cache/pom.xml
+++ b/bootx-commons/common-cache/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-commons
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-data-translate/pom.xml b/bootx-commons/common-data-translate/pom.xml
index 9ccc84e59a7dd699505dfca5cf5752ad44877090..ae89a44cab7f3cb6bd2ce497de32b530023b8c0f 100644
--- a/bootx-commons/common-data-translate/pom.xml
+++ b/bootx-commons/common-data-translate/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-commons
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-eventer/pom.xml b/bootx-commons/common-eventer/pom.xml
index affde9f606ff4b06d97442bdd09386aa1f8fba5a..8da165b329625200b423db387cee53325a5cf562 100644
--- a/bootx-commons/common-eventer/pom.xml
+++ b/bootx-commons/common-eventer/pom.xml
@@ -6,7 +6,7 @@
cn.bootx.platform
bootx-commons
- 1.3.5
+ 1.3.6
common-eventer
diff --git a/bootx-commons/common-exception-handler/pom.xml b/bootx-commons/common-exception-handler/pom.xml
index 97d95ddf2816b90dc23390c121ffb6bfc0670b3c..0d94bdd12436e2ae4c55cedb5835c270e015765e 100644
--- a/bootx-commons/common-exception-handler/pom.xml
+++ b/bootx-commons/common-exception-handler/pom.xml
@@ -5,7 +5,7 @@
bootx-commons
cn.bootx.platform
- 1.3.5
+ 1.3.6
4.0.0
common-exception-handler
diff --git a/bootx-commons/common-header-holder/pom.xml b/bootx-commons/common-header-holder/pom.xml
index e46dfd9decf1966502a7bb7f9af8b27d7016d98e..b42a427e571d3c1f882bb4f831938ff680c17b01 100644
--- a/bootx-commons/common-header-holder/pom.xml
+++ b/bootx-commons/common-header-holder/pom.xml
@@ -5,7 +5,7 @@
bootx-commons
cn.bootx.platform
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-idempotency/pom.xml b/bootx-commons/common-idempotency/pom.xml
index 411c31a228b9aa5ecf951fcdc59cd2f5662c13c4..fe73eb491fabde193f147889d1158db652cf825d 100644
--- a/bootx-commons/common-idempotency/pom.xml
+++ b/bootx-commons/common-idempotency/pom.xml
@@ -5,7 +5,7 @@
bootx-commons
cn.bootx.platform
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-jackson/pom.xml b/bootx-commons/common-jackson/pom.xml
index c739d5861bd18b7ad7cd7c8cfcda511a7e71849d..87d111b5f2561d9106d8fba325e57a6726a29ab0 100644
--- a/bootx-commons/common-jackson/pom.xml
+++ b/bootx-commons/common-jackson/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-commons
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/deserializer/BootxLocalDateTimeDeserializer.java b/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/deserializer/BootxLocalDateTimeDeserializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f92d37e5d21ae86451570374a06857602d7b2241
--- /dev/null
+++ b/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/deserializer/BootxLocalDateTimeDeserializer.java
@@ -0,0 +1,32 @@
+package cn.bootx.platform.common.jackson.deserializer;
+
+import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
+import cn.hutool.core.date.DatePattern;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeParseException;
+
+/**
+ * java8日期时间反序列化, 支持反序列化秒和毫秒级别的时间
+ * @author xxm
+ * @since 2024/1/16
+ */
+public class BootxLocalDateTimeDeserializer extends LocalDateTimeDeserializer {
+
+ /**
+ * 解析日期时间
+ */
+ @Override
+ protected LocalDateTime _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws IOException {
+ // 首先解析毫秒级时间, 如果解析失败, 则解析秒级时间
+ try {
+ return LocalDateTimeUtil.parse(string0, DatePattern.NORM_DATETIME_MS_PATTERN);
+ } catch (DateTimeParseException e) {
+ return LocalDateTimeUtil.parse(string0, DatePattern.NORM_DATETIME_PATTERN);
+ }
+ }
+}
diff --git a/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/deserializer/BootxLocalTimeDeserializer.java b/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/deserializer/BootxLocalTimeDeserializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f177e9493450fb97eda66aa7b4c7a8fd3254635
--- /dev/null
+++ b/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/deserializer/BootxLocalTimeDeserializer.java
@@ -0,0 +1,31 @@
+package cn.bootx.platform.common.jackson.deserializer;
+
+import cn.hutool.core.date.DatePattern;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+
+import java.io.IOException;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+
+/**
+ * java时间反序列化, 支持反序列化秒和毫秒级别的时间
+ * @author xxm
+ * @since 2024/1/16
+ */
+public class BootxLocalTimeDeserializer extends LocalTimeDeserializer {
+
+ /**
+ * 反序列化
+ */
+ @Override
+ protected LocalTime _fromString(JsonParser p, DeserializationContext ctxt, String string0) throws IOException {
+ try {
+ return LocalTime.parse(string0, DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));
+ } catch (DateTimeParseException e) {
+ return LocalTime.parse(string0, DatePattern.NORM_TIME_FORMATTER);
+ }
+ }
+}
diff --git a/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/jdk/Java8TimeModule.java b/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/jdk/Java8TimeModule.java
index dfc1d39c81d9529d370a026c8302535e9700bc34..e929781377b0d39e2f1a7fc0b5935453eac80bf6 100644
--- a/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/jdk/Java8TimeModule.java
+++ b/bootx-commons/common-jackson/src/main/java/cn/bootx/platform/common/jackson/jdk/Java8TimeModule.java
@@ -1,10 +1,10 @@
package cn.bootx.platform.common.jackson.jdk;
+import cn.bootx.platform.common.jackson.deserializer.BootxLocalDateTimeDeserializer;
+import cn.bootx.platform.common.jackson.deserializer.BootxLocalTimeDeserializer;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
-import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
-import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
@@ -15,26 +15,27 @@ import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
- * java8 时间序列化
- *
+ * java8 时间序列化 受MySQL限制, 无法存储毫秒值. 只能处理到秒级别
+ * 写入时间支持毫秒格式的时间
+ * 读取时间时可以处理到秒或毫秒
* @author xxm
* @since 2020/4/14 13:33
*/
public class Java8TimeModule extends SimpleModule {
public Java8TimeModule() {
+ // 序列化
this.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
this.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
this.addSerializer(LocalTime.class,
new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
- this.addDeserializer(LocalDateTime.class,
- new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
+ // 反序列化
+ this.addDeserializer(LocalDateTime.class, new BootxLocalDateTimeDeserializer());
this.addDeserializer(LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
- this.addDeserializer(LocalTime.class,
- new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
+ this.addDeserializer(LocalTime.class,new BootxLocalTimeDeserializer());
}
}
diff --git a/bootx-commons/common-log/pom.xml b/bootx-commons/common-log/pom.xml
index d1a8d81268cf93f8ab20d1ee49a6c1f693c21901..98e46e190551d386f75b73833ff9aa812043adb3 100644
--- a/bootx-commons/common-log/pom.xml
+++ b/bootx-commons/common-log/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-commons
- 1.3.5
+ 1.3.6
4.0.0
@@ -27,7 +27,7 @@
com.plumelog
- plumelog-lite-spring-boot-starter
+ plumelog-lite
${plumelog.version}
provided
diff --git a/bootx-commons/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java b/bootx-commons/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java
index cdf583578889cc589d853e7a45e80dc3408bc19b..12aa194ef106d58456b50e8a7dd334a454875fad 100644
--- a/bootx-commons/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java
+++ b/bootx-commons/common-log/src/main/java/cn/bootx/platform/common/log/handler/LogTraceHeaderHolderFilter.java
@@ -34,8 +34,10 @@ public class LogTraceHeaderHolderFilter extends OncePerRequestFilter {
try {
String traceId = RandomUtil.randomString(12);
// 添加普通日志和 plumelog 日志的 TraceId
- TraceId.logTraceID.set(traceId);
MDC.put(CommonCode.TRACE_ID, traceId);
+ try {
+ TraceId.logTraceID.set(traceId);
+ } catch (NoClassDefFoundError ignored) {}
chain.doFilter(request, response);
}
finally {
diff --git a/bootx-commons/common-mongo/pom.xml b/bootx-commons/common-mongo/pom.xml
index 05c04eb027dc1581b1c61e78943da2a88dd29cd5..3c50226e5b3f647c6b7146e015d89e6487e9d766 100644
--- a/bootx-commons/common-mongo/pom.xml
+++ b/bootx-commons/common-mongo/pom.xml
@@ -5,7 +5,7 @@
cn.bootx.platform
bootx-commons
- 1.3.5
+ 1.3.6
4.0.0
common-mongo
diff --git a/bootx-commons/common-mybatis-plus/pom.xml b/bootx-commons/common-mybatis-plus/pom.xml
index 4cebbe13c772f51a475092cc475e2ca2dd81bcc0..6f7ee90f374a108ac6fa2e470ed527f4c93adf7a 100644
--- a/bootx-commons/common-mybatis-plus/pom.xml
+++ b/bootx-commons/common-mybatis-plus/pom.xml
@@ -5,7 +5,7 @@
bootx-commons
cn.bootx.platform
- 1.3.5
+ 1.3.6
4.0.0
diff --git a/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/base/MpIdEntity.java b/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/base/MpIdEntity.java
index 018559504ab3b7dc1487f7637cf21209f3d224eb..f722c95a6e83f6ab7346deea4147ac3e09acd6da 100644
--- a/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/base/MpIdEntity.java
+++ b/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/base/MpIdEntity.java
@@ -2,6 +2,7 @@ package cn.bootx.platform.common.mybatisplus.base;
import cn.bootx.table.modify.annotation.DbColumn;
import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.OrderBy;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Getter;
import lombok.Setter;
@@ -24,6 +25,7 @@ public abstract class MpIdEntity implements Serializable {
@DbColumn(comment = "主键", isKey = true, order = Integer.MIN_VALUE + 100)
@TableId(type = IdType.ASSIGN_ID)
+ @OrderBy
private Long id;
}
diff --git a/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonRawTypeHandler.java b/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonRawTypeHandler.java
index 68a0fe5a17b75a03dadf1022eb78d1df94bc4a83..3073d0299d50608db2856507af5c955184e0f23f 100644
--- a/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonRawTypeHandler.java
+++ b/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonRawTypeHandler.java
@@ -10,8 +10,9 @@ import org.apache.ibatis.type.MappedTypes;
/**
* Jackson 实现 JSON 字段类型处理器, 会记录对象属性类型, 通常用于储存不确定对象的属性上
- * 例如: 泛型对象、存储的数据是字段类型的子类等
- *
+ * 例如: object对象, 泛型对象、存储的数据是字段声明类型的子类等
+ * 如果在使用知道明确类型的包装类是,如List、Set, 请使用 JacksonTypeReferenceHandler
+ * @see JacksonTypeReferenceHandler
* @author xxm
* @since 2022/7/11
*/
diff --git a/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonTypeReferenceHandler.java b/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonTypeReferenceHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..580e10ba51c6e4fa107eef60032d63e510201995
--- /dev/null
+++ b/bootx-commons/common-mybatis-plus/src/main/java/cn/bootx/platform/common/mybatisplus/handler/JacksonTypeReferenceHandler.java
@@ -0,0 +1,45 @@
+package cn.bootx.platform.common.mybatisplus.handler;
+
+import cn.bootx.platform.common.jackson.util.JacksonUtil;
+import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
+import com.fasterxml.jackson.core.type.TypeReference;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+/**
+ * JSON字段类型转换抽象处理器, 需要进行继承实现, 可以在不在JSON字符串中记录数据类型,就可以对一些特殊类型进行反序列化
+ * 例如: 集合类型List, 泛型对象ResResult 等
+ * 通过 getTypeReference 接口, 将要进行反序列的对象传入
+ *
+ * @author xxm
+ * @since 2024/1/3
+ */
+@Slf4j
+@MappedTypes({ Object.class })
+@MappedJdbcTypes(value = { JdbcType.VARCHAR, JdbcType.LONGVARCHAR })
+public abstract class JacksonTypeReferenceHandler extends AbstractJsonTypeHandler