Просмотр исходного кода

fix(用户菜单):
用户菜单默认获取默认门户下菜单
feat(订阅发布、文件存储):
消息总线改为主题订阅发布模式
新增阿里云、本地、DB文件存储方式

18339543638 2 лет назад
Родитель
Сommit
fb6ef08a23
68 измененных файлов с 1240 добавлено и 813 удалено
  1. 4 4
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/CurrentUserController.java
  2. 13 4
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/service/CurrentUserService.java
  3. 77 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/controller/FileDownloadController.java
  4. 62 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/controller/StorageFileController.java
  5. 80 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/controller/SysStorageRecordController.java
  6. 23 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/FileUploadDTO.java
  7. 6 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/SysStorageConfigDTO.java
  8. 51 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/SysStorageRecordDTO.java
  9. 22 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/SysStorageRecordQueryDTO.java
  10. 6 1
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/mapper/SysStorageConfigMapper.java
  11. 28 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/mapper/SysStorageRecordMapper.java
  12. 12 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/po/SysStorageConfigPO.java
  13. 34 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/po/SysStorageFilePO.java
  14. 56 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/po/SysStorageRecordPO.java
  15. 16 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/repository/SysStorageFileRepository.java
  16. 16 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/repository/SysStorageRecordRepository.java
  17. 43 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/IStorageFileService.java
  18. 15 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/ISysStorageConfigService.java
  19. 71 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/ISysStorageRecordService.java
  20. 46 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/DbClientImpl.java
  21. 122 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/StorageFileServiceImpl.java
  22. 26 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/SysStorageConfigServiceImpl.java
  23. 106 0
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/SysStorageRecordServiceImpl.java
  24. 0 3
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantPackageController.java
  25. 9 13
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPortalController.java
  26. 2 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPortalQueryDTO.java
  27. 3 3
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/ISysPortalMenuService.java
  28. 24 11
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPortalMenuServiceImpl.java
  29. 2 2
      tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPortalServiceImpl.java
  30. 0 7
      tr-plugins/tr-spring-boot-starter-plugin-doc/src/main/java/cn/tr/plugin/doc/ModifyOkStatusCodeResponseMessageReader.java
  31. 10 10
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/pom.xml
  32. 17 0
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/EvenBusApplication.java
  33. 26 40
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/TrEventBusAutoConfiguration.java
  34. 0 6
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/annotation/Subscribe.java
  35. 0 141
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/bean/Subscription.java
  36. 17 20
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/EventBus.java
  37. 3 25
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/SubscribeListenerAnnotationBeanPostProcessor.java
  38. 0 141
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/AbstractEvenBusDataRichSourceFunction.java
  39. 0 27
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/EventBusDataSourceEmitter.java
  40. 0 26
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/LocalEventBusDataRichSourceFunction.java
  41. 0 19
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/ShareEventBusDataRichSourceFunction.java
  42. 0 102
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/redission/RedissionEventBus.java
  43. 0 45
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/redission/RedissionEventBusDataSourceEmitter.java
  44. 0 15
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/constant/EventBusConstant.java
  45. 44 0
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/AbstractBusProducer.java
  46. 23 0
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/consumer/EvenBusConsumer.java
  47. 23 0
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/message/EvenBusMessageEvent.java
  48. 4 1
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/message/TopicPayload.java
  49. 27 0
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/producer/EvenBusProducer.java
  50. 2 3
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/proxy/ProxyMessageListener.java
  51. 1 8
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/utils/EventBusStrategy.java
  52. 11 1
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/utils/TopicUtils.java
  53. 5 26
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/resources/application-unit-test.yml
  54. 0 73
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/test/java/cn/tr/plugin/eventbus/RedissonTest.java
  55. 8 6
      tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/test/java/cn/tr/plugin/eventbus/SpringBootSubPubTest.java
  56. 6 0
      tr-plugins/tr-spring-boot-starter-plugin-file/pom.xml
  57. 1 1
      tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/AbstractFileClient.java
  58. 4 2
      tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/FileClientConfig.java
  59. 5 5
      tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/ali/AliFileClientConfig.java
  60. 5 4
      tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/db/DbFileClient.java
  61. 4 2
      tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/local/LocalFileClient.java
  62. 1 0
      tr-plugins/tr-spring-boot-starter-plugin-file/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  63. 7 5
      tr-plugins/tr-spring-boot-starter-plugin-file/src/test/java/cn/tr/plugin/file/config/FileClientTest.java
  64. 1 0
      tr-plugins/tr-spring-boot-starter-plugin-numbering-strategy/pom.xml
  65. 6 0
      tr-plugins/tr-spring-boot-starter-plugin-test/pom.xml
  66. 1 1
      tr-plugins/tr-spring-boot-starter-plugin-test/src/main/java/cn/tr/plugin/test/ut/BaseRabbitMqUnitTest.java
  67. 0 2
      tr-plugins/tr-spring-boot-starter-plugin-test/src/main/java/cn/tr/plugin/test/ut/BaseRedisUnitTest.java
  68. 3 0
      tr-test/src/main/resources/application.yml

+ 4 - 4
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/controller/CurrentUserController.java

@@ -7,7 +7,6 @@ import cn.tr.core.utils.TreeUtil;
 import cn.tr.module.sys.oauth2.psw.operator.AbstractOAuth2PswUserOperator;
 import cn.tr.module.sys.oauth2.psw.operator.OAuth2PswUserOperatorManager;
 import cn.tr.module.sys.oauth2.service.CurrentUserService;
-import cn.tr.module.sys.user.dto.SysPortalDTO;
 import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
 import cn.tr.module.sys.user.vo.RouteItemVO;
 import cn.tr.plugin.security.context.LoginUserContextHolder;
@@ -16,6 +15,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import java.util.Collection;
@@ -53,11 +53,11 @@ public class CurrentUserController {
         return CommonResult.success(currentUserService.currentUserPermission());
     }
 
-    @GetMapping("/listMenus")
+    @GetMapping("/listMenus-{portalId}")
     @ApiOperation("获得登录用户的菜单列表")
-    public CommonResult<List<RouteItemVO>> getMenus() {
+    public CommonResult<List<RouteItemVO>> getMenus(@PathVariable(value = "portalId",required = false) String portalId) {
         SaTokenUtils.getStpUtil().checkLogin();
-        return CommonResult.success(TreeUtil.buildTree(currentUserService.currentUserMenus()));
+        return CommonResult.success(TreeUtil.buildTree(currentUserService.currentUserMenus(portalId)));
     }
 
     @GetMapping("/listPortal")

+ 13 - 4
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/oauth2/service/CurrentUserService.java

@@ -7,7 +7,6 @@ import cn.tr.core.exception.ServiceException;
 import cn.tr.core.exception.TRExcCode;
 import cn.tr.module.sys.tenant.service.ISysTenantService;
 import cn.tr.module.sys.user.dto.SysMenuDTO;
-import cn.tr.module.sys.user.dto.SysPortalDTO;
 import cn.tr.module.sys.user.dto.SysUserPortalListDTO;
 import cn.tr.module.sys.user.enums.MenuEnum;
 import cn.tr.module.sys.user.service.ISysMenuService;
@@ -52,12 +51,22 @@ public class CurrentUserService {
      * 获取当前用户菜单
      * @return
      */
-    public List<RouteItemVO> currentUserMenus(){
+    public List<RouteItemVO> currentUserMenus(String portalId){
         String currentUserId = String.valueOf(SaTokenUtils.getStpUtil().getLoginId());
         Set<SysMenuDTO> tenantMenus = tenantService.currentTenantMenus();
         Set<SysMenuDTO> roleMenus = menuService.findUserMenus(currentUserId);
-        //门面菜单
-        Set<SysMenuDTO> portalMenus =new HashSet<>(portalMenuService.findAllMenusByPortalId("1"));
+        //当未传门户id时,使用默认门户
+        if(StrUtil.isEmpty(portalId)){
+            List<SysUserPortalListDTO> portalList = currentUserPortals();
+            if (CollectionUtil.isNotEmpty(portalList)) {
+                portalId=portalList.stream()
+                        .filter(portal->Boolean.TRUE.equals(portal.getIsDefault()))
+                        .map(SysUserPortalListDTO::getId)
+                        .findFirst()
+                        .orElse(CollectionUtil.getFirst(portalList).getId());
+            }
+        }
+        Set<SysMenuDTO> portalMenus =StrUtil.isEmpty(portalId)?Collections.emptySet():new HashSet<>(portalMenuService.findAllMenusByPortalId(portalId));
         // 交集(门面菜单,租户菜单,角色菜单)
         Collection<SysMenuDTO> allMenus = CollectionUtil.intersection(tenantMenus, roleMenus,portalMenus);
         if(CollectionUtil.isEmpty(allMenus)){

+ 77 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/controller/FileDownloadController.java

@@ -0,0 +1,77 @@
+package cn.tr.module.sys.storage.controller;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.tr.core.utils.JsonUtils;
+import cn.tr.module.sys.storage.dto.SysStorageConfigDTO;
+import cn.tr.module.sys.storage.service.ISysStorageConfigService;
+import cn.tr.plugin.file.config.FileClient;
+import cn.tr.plugin.file.config.FileClientConfig;
+import cn.tr.plugin.file.config.FileClientFactory;
+import cn.tr.plugin.file.config.FileContent;
+import cn.tr.plugin.file.config.local.LocalFileClientConfig;
+import cn.tr.plugin.file.enums.FileStorageEnum;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * @ClassName : FileDownloadController
+ * @Description : 文件下载
+ * @Author : LF
+ * @Date: 2023年05月11日
+ */
+@Api(tags = "本地、DB文件下载")
+@RestController
+@RequestMapping("/download/file")
+@AllArgsConstructor
+public class FileDownloadController {
+    private final ISysStorageConfigService storageConfigService;
+    private final FileClientFactory fileClientFactory;
+    @GetMapping("/local/{configId}/**")
+    @ApiOperation(value = "获取本地存储文件",notes = "权限:无")
+    public void localFile(HttpServletRequest request, HttpServletResponse response, @PathVariable("configId") String configId) throws IOException {
+        String servletPath = request.getServletPath();
+        String bizPath= StrUtil.subAfter(servletPath,configId+"/",false);
+        SysStorageConfigDTO storageConfig = storageConfigService.selectSysStorageConfigById(configId);
+        Map<String, Object> config = storageConfig.getConfig();
+        LocalFileClientConfig localFileClientConfig = JsonUtils.parseObject(JsonUtils.toJsonString(config), LocalFileClientConfig.class);
+        writeFile(response,FileUtil.getInputStream(FileUtil.file(localFileClientConfig.getBasePath()+ File.separator+configId+File.separator+bizPath)));
+    }
+
+    @GetMapping("/db/{configId}/**")
+    @ApiOperation(value = "获取DB存储文件",notes = "权限:无")
+    public void dbFile(HttpServletRequest request, HttpServletResponse response, @PathVariable("configId") String configId) throws Exception {
+        String servletPath = request.getServletPath();
+        String bizPath= StrUtil.subAfter(servletPath,configId+"/",false);
+        SysStorageConfigDTO storageConfig = storageConfigService.selectSysStorageConfigById(configId);
+        FileClient fileClient = fileClientFactory.createOrUpdateFileClient(storageConfig.getId(), storageConfig.getType(),parseClientConfig(storageConfig.getType(), storageConfig.getConfig()));
+        FileContent fileContent = fileClient.getContent(bizPath);
+        writeFile(response,IoUtil.toStream(fileContent.getContent()));
+    }
+
+
+    private void writeFile(HttpServletResponse response, InputStream in) throws IOException {
+        response.setContentType("application/octet-stream");
+        IoUtil.copy(in,response.getOutputStream());
+    }
+
+    private FileClientConfig parseClientConfig(String storage, Map<String, Object> config) {
+        Class<? extends FileClientConfig> configClass = FileStorageEnum.getByStorage(storage)
+                .getConfigClass();
+        config.put("@Clazz",configClass.getName());
+        return  JsonUtils.parseObject(JsonUtils.toJsonString(config), configClass);
+    }
+}

+ 62 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/controller/StorageFileController.java

@@ -0,0 +1,62 @@
+package cn.tr.module.sys.storage.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.io.IoUtil;
+import cn.tr.core.pojo.CommonResult;
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+import cn.tr.module.sys.storage.service.IStorageFileService;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.Collection;
+
+/**
+ * @ClassName : 文件上传下载操作
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年05月10日
+ */
+@Api(tags = "文件上传下载操作")
+@RestController
+@RequestMapping("/sys/storage/file")
+@AllArgsConstructor
+public class StorageFileController {
+    private final IStorageFileService fileService;
+
+    @ApiOperationSupport(author = "lf",order = 1)
+    @PostMapping("/upload")
+    @ApiOperation( value = "上传文件",notes = "权限:无")
+    public CommonResult<SysStorageRecordDTO> uploadFile(@RequestParam MultipartFile file,
+                                                        @RequestParam(required = false) String configId,
+                                                        @RequestParam(required = false) String cateId) throws Exception {
+        return CommonResult.success(fileService.upload(cateId,configId,file.getOriginalFilename(), IoUtil.readBytes(file.getInputStream())));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 2)
+    @PostMapping("/removeByIds")
+    @ApiOperation( value = "删除文件",notes = "权限:storage:file:remove")
+    @SaCheckPermission("storage:file:remove")
+    public CommonResult<Boolean> deleteFile(@RequestBody Collection<String> ids) throws Exception {
+        fileService.remove(ids);
+        return CommonResult.success(true);
+    }
+
+    @ApiOperationSupport(author = "lf",order = 3)
+    @GetMapping("/download/{recordId}")
+    @ApiOperation(value = "获取文件下载路径",notes = "权限:无")
+    public  CommonResult<String> download(@PathVariable("recordId") String recordId) throws Exception {
+        return CommonResult.success(fileService.obtainDownloadPath(recordId));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 4)
+    @GetMapping("/preview/{recordId}")
+    @ApiOperation(value = "获取文件预览路径",notes = "权限:无")
+    public  CommonResult<String> preview(@PathVariable("recordId") String recordId) throws Exception {
+        return CommonResult.success(fileService.obtainDownloadPath(recordId));
+    }
+
+
+}

+ 80 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/controller/SysStorageRecordController.java

@@ -0,0 +1,80 @@
+package cn.tr.module.sys.storage.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.tr.core.validation.Insert;
+import cn.tr.core.validation.Update;
+import cn.tr.core.pojo.CommonResult;
+import lombok.AllArgsConstructor;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+import cn.tr.module.sys.storage.service.ISysStorageRecordService;
+import cn.tr.module.sys.storage.dto.SysStorageRecordQueryDTO;
+import java.util.*;
+import cn.tr.plugin.mybatis.base.BaseController;
+import org.springframework.web.bind.annotation.*;
+import cn.tr.plugin.operatelog.annotation.OperateLog;
+import cn.tr.core.pojo.TableDataInfo;
+/**
+ * 存储记录控制器
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ */
+@Api(tags = "存储记录")
+@RestController
+@RequestMapping("/sys/storage/record")
+@AllArgsConstructor
+public class SysStorageRecordController extends BaseController{
+
+    private final ISysStorageRecordService sysStorageRecordService;
+
+    @ApiOperationSupport(author = "lf",order = 1)
+    @ApiOperation(value="根据条件查询存储记录",notes = "权限: 无")
+    @PostMapping("/query/page")
+    public TableDataInfo<SysStorageRecordDTO> selectList(@RequestBody SysStorageRecordQueryDTO query) {
+        startPage();
+        return getDataTable(sysStorageRecordService.selectSysStorageRecordList(query));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 2)
+    @ApiOperation(value = "根据id查询存储记录",notes = "权限: storage:record:query")
+    @GetMapping("/detail/{id}")
+    @SaCheckPermission("storage:record:query")
+    public CommonResult<SysStorageRecordDTO> findById(@PathVariable("id") String id){
+        return CommonResult.success(sysStorageRecordService.selectSysStorageRecordById(id));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 3)
+    @ApiOperation(value="添加存储记录",notes = "权限: storage:record:add")
+    @PostMapping("/add")
+    @OperateLog
+    @SaCheckPermission("storage:record:add")
+    public CommonResult<Boolean> add(@RequestBody@Validated(Insert.class) SysStorageRecordDTO source) {
+        return CommonResult.success(sysStorageRecordService.insertSysStorageRecord(source));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 4)
+    @ApiOperation(value="通过主键id编辑存储记录",notes = "权限: storage:record:edit")
+    @PostMapping("/edit")
+    @OperateLog
+    @SaCheckPermission("storage:record:edit")
+    public CommonResult<Boolean> edit(@RequestBody@Validated(Update.class) SysStorageRecordDTO source) {
+        return CommonResult.success(sysStorageRecordService.updateSysStorageRecordById(source));
+    }
+
+    @ApiOperationSupport(author = "lf",order = 5)
+    @ApiOperation(value="删除存储记录",notes = "权限: storage:record:remove")
+    @PostMapping("/removeByIds")
+    @OperateLog
+    @SaCheckPermission("storage:record:remove")
+    public CommonResult<Integer> delete(@RequestBody Collection<String> ids) {
+        return CommonResult.success(sysStorageRecordService.removeSysStorageRecordByIds(ids));
+    }
+}

+ 23 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/FileUploadDTO.java

@@ -0,0 +1,23 @@
+package cn.tr.module.sys.storage.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @ClassName : FileUploadDTO
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年05月11日
+ */
+@Data
+@ApiModel("文件上传")
+public class FileUploadDTO {
+    @ApiModelProperty("文件上传")
+    private MultipartFile file;
+    @ApiModelProperty("文件所属目录id")
+    private String cateId;
+    @ApiModelProperty("文件存储配置id")
+    private String configId;
+}

+ 6 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/SysStorageConfigDTO.java

@@ -36,12 +36,16 @@ public class SysStorageConfigDTO extends BaseDTO  {
     @NotNull  (message = "主配置不能为空",groups = {Update.class,Insert.class})
     private Boolean master;
 
-    @ApiModelProperty(value = "存储器类型", position = 4)
+    /**
+     * 存储器类型
+     * {@link cn.tr.plugin.file.enums.FileStorageEnum}
+     */
+    @ApiModelProperty(value = "存储器类型", position = 4,example = "ali")
     @NotBlank  (message = "存储器类型不能为空",groups = {Update.class,Insert.class})
     private String type;
 
     @ApiModelProperty(value = "文件配置", position = 5)
-    @NotBlank  (message = "文件配置不能为空",groups = {Update.class,Insert.class})
+    @NotNull  (message = "文件配置不能为空",groups = {Update.class,Insert.class})
     private Map<String, Object> config;
 
     @ApiModelProperty(value = "备注", position = 6)

+ 51 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/SysStorageRecordDTO.java

@@ -0,0 +1,51 @@
+package cn.tr.module.sys.storage.dto;
+
+import cn.tr.plugin.mybatis.pojo.BaseDTO;
+import lombok.*;
+import cn.tr.core.validation.Update;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.*;
+
+/**
+ * 存储记录传输对象
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ **/
+@Data
+@ApiModel("存储记录传输对象")
+@EqualsAndHashCode(callSuper = true)
+@ToString
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class SysStorageRecordDTO extends BaseDTO  {
+    private static final long serialVersionUID = 1L;
+    @ApiModelProperty(value = "存储记录id", position = 1)
+    @NotBlank  (message = "主键不能为空",groups = {Update.class})
+    private String id;
+
+    @ApiModelProperty(value = "文件真实名称", position = 2)
+    private String realName;
+
+    @ApiModelProperty(value = "文件业务名称", readOnly = true,position = 3)
+    private String bizName;
+
+    @ApiModelProperty(value = "绝对路径", position = 4)
+    private String absolutePath;
+
+    @ApiModelProperty(value = "存储配置id", position = 5)
+    private String configId;
+
+    @ApiModelProperty(value = "文件大小", position = 6)
+    private Integer size;
+
+    @ApiModelProperty(value = "文件后缀", position = 7)
+    private String suffix;
+
+    @ApiModelProperty(value = "所属目录id", position = 9)
+    private String cateId;
+
+}

+ 22 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/dto/SysStorageRecordQueryDTO.java

@@ -0,0 +1,22 @@
+package cn.tr.module.sys.storage.dto;
+
+import lombok.ToString;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 存储记录查询参数
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ **/
+@Data
+@ApiModel("存储记录查询参数")
+@ToString
+public class SysStorageRecordQueryDTO  {
+    private static final long serialVersionUID = 1L;
+    @ApiModelProperty(value = "文件名称", position = 2)
+    private String realName;
+
+}

+ 6 - 1
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/mapper/SysStorageConfigMapper.java

@@ -22,7 +22,12 @@ public interface SysStorageConfigMapper {
     @Mapping(target = "config", ignore = true)
     SysStorageConfigPO convertPO(SysStorageConfigDTO source);
 
-    @Mapping(target = "config", ignore = true)
+    @Mappings(
+            {
+                    @Mapping(target = "config", source ="configMap" ),
+            }
+    )
+
     SysStorageConfigDTO convertDto(SysStorageConfigPO source);
 
     List<SysStorageConfigDTO> convertDtoList(List<SysStorageConfigPO> source);

+ 28 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/mapper/SysStorageRecordMapper.java

@@ -0,0 +1,28 @@
+package cn.tr.module.sys.storage.mapper;
+
+import cn.tr.module.sys.storage.po.SysStorageRecordPO;
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+* 存储记录映射工具
+*
+* @author lf
+* @date  2023/05/10 14:55
+**/
+@Mapper
+public interface SysStorageRecordMapper {
+    SysStorageRecordMapper INSTANCE = Mappers.getMapper(SysStorageRecordMapper.class);
+
+    SysStorageRecordPO convertPO(SysStorageRecordDTO source);
+
+    SysStorageRecordDTO convertDto(SysStorageRecordPO source);
+
+    List<SysStorageRecordDTO> convertDtoList(List<SysStorageRecordPO> source);
+
+    List<SysStorageRecordPO> convertPOList(List<SysStorageRecordDTO> source);
+
+}

+ 12 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/po/SysStorageConfigPO.java

@@ -1,6 +1,7 @@
 package cn.tr.module.sys.storage.po;
 
 
+import cn.tr.core.utils.JsonUtils;
 import cn.tr.plugin.file.config.FileClientConfig;
 import cn.tr.plugin.mybatis.pojo.BasePO;
 import com.baomidou.mybatisplus.annotation.TableField;
@@ -13,6 +14,8 @@ import lombok.EqualsAndHashCode;
 import lombok.ToString;
 import lombok.experimental.Accessors;
 
+import java.util.Map;
+
 /**
  * 文件存储配置实体
  *
@@ -20,7 +23,7 @@ import lombok.experimental.Accessors;
  * @date  2023/05/09 14:29
  **/
 @Data
-@TableName("sys_storage_config")
+@TableName(value = "sys_storage_config",autoResultMap = true)
 @EqualsAndHashCode(callSuper = true)
 @ToString
 @Accessors(chain = true)
@@ -39,7 +42,10 @@ public class SysStorageConfigPO extends BasePO {
     @ApiModelProperty(value = "主配置", position = 3)
     private Boolean master;
 
-    /** 存储器类型 */
+    /**
+     * 存储器类型
+     * {@link cn.tr.plugin.file.enums.FileStorageEnum}
+     */
     @ApiModelProperty(value = "存储器类型", position = 4)
     private String type;
 
@@ -52,4 +58,8 @@ public class SysStorageConfigPO extends BasePO {
     @ApiModelProperty(value = "备注", position = 6)
     private String remark;
 
+
+    public Map<String,Object> getConfigMap() {
+        return JsonUtils.parseMap(JsonUtils.toJsonString(this.config));
+    }
 }

+ 34 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/po/SysStorageFilePO.java

@@ -0,0 +1,34 @@
+package cn.tr.module.sys.storage.po;
+
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.*;
+
+/**
+ * db类型文件存储实体
+ *
+ * @author lf
+ * @date  2023/05/11 16:14
+ **/
+@Data
+@TableName(value="sys_storage_file",autoResultMap = true)
+@ToString
+public class SysStorageFilePO {
+
+    /** id */
+    @TableId
+    @ApiModelProperty(value = "id", position = 1)
+    private String id;
+
+    /** content */
+    @ApiModelProperty(value = "文件存储内容", position = 2)
+    private byte[] content;
+
+    @ApiModelProperty(value = "文件存储配置id", position = 3)
+    private String configId;
+
+    @ApiModelProperty(value = "文件业务路径", position = 4)
+    private String bizName;
+}

+ 56 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/po/SysStorageRecordPO.java

@@ -0,0 +1,56 @@
+package cn.tr.module.sys.storage.po;
+
+import cn.tr.plugin.mybatis.pojo.TenantPO;   
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+/**
+ * 存储记录实体
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ **/
+@Data
+@TableName(value="sys_storage_record",autoResultMap = true)
+@EqualsAndHashCode(callSuper = true)
+@ToString
+public class SysStorageRecordPO extends TenantPO {
+
+    /** 存储记录id */
+    @TableId
+    @ApiModelProperty(value = "存储记录id", position = 1)
+    private String id;
+
+    /** 文件真实名称 */
+    @ApiModelProperty(value = "文件真实名称", position = 2)
+    private String realName;
+
+    /** 文件业务名称 */
+    @ApiModelProperty(value = "文件业务名称", position = 2)
+    private String bizName;
+
+    /** 绝对路径 */
+    @ApiModelProperty(value = "绝对路径", position = 3)
+    private String absolutePath;
+
+    /** 存储配置id */
+    @ApiModelProperty(value = "存储配置id", position = 6)
+    private String configId;
+
+    /** 文件大小 */
+    @ApiModelProperty(value = "文件大小", position = 7)
+    private Integer size;
+
+    /** 文件后缀 */
+    @ApiModelProperty(value = "文件后缀", position = 8)
+    private String suffix;
+
+    /** 所属目录id */
+    @ApiModelProperty(value = "所属目录id", position = 9)
+    private String cateId;
+
+}

+ 16 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/repository/SysStorageFileRepository.java

@@ -0,0 +1,16 @@
+package cn.tr.module.sys.storage.repository;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import cn.tr.module.sys.storage.po.SysStorageFilePO;
+/**
+ * db类型文件存储Mapper接口
+ *
+ * @author lf
+ * @date  2023/05/11 16:14
+ **/
+@Repository
+@Mapper
+public interface SysStorageFileRepository extends BaseMapper<SysStorageFilePO> {
+}

+ 16 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/repository/SysStorageRecordRepository.java

@@ -0,0 +1,16 @@
+package cn.tr.module.sys.storage.repository;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import cn.tr.module.sys.storage.po.SysStorageRecordPO;
+/**
+ * 存储记录Mapper接口
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ **/
+@Repository
+@Mapper
+public interface SysStorageRecordRepository extends BaseMapper<SysStorageRecordPO> {
+}

+ 43 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/IStorageFileService.java

@@ -0,0 +1,43 @@
+package cn.tr.module.sys.storage.service;
+
+
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+
+import java.util.*;
+
+/**
+ * @ClassName : IStorageFileService
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年05月10日
+ */
+
+public interface IStorageFileService {
+    /**
+     * 初始化默认配置
+     */
+    void initDefaultConfig();
+
+    /**
+     * 上传文件
+     * @param configId 存储配置id 当configId为空时,使用默认主存储配置
+     * @param cateId 文件所属目录id
+     * @param filename 文件名称
+     * @param content 文件内容
+     * @return
+     */
+    SysStorageRecordDTO upload(String configId, String cateId, String filename, byte[] content) throws Exception;
+
+    /**
+     * 删除文件
+     * @param recordIds
+     */
+    void remove(Collection<String> recordIds);
+
+    /**
+     * 获取下载路径
+     * @param recordId 文件存储id
+     * @return
+     */
+    String obtainDownloadPath(String recordId) throws Exception;
+}

+ 15 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/ISysStorageConfigService.java

@@ -28,6 +28,15 @@ public interface ISysStorageConfigService{
      */
     SysStorageConfigDTO selectSysStorageConfigById(String id);
 
+
+    /**
+     * 根据id查询文件存储配置
+     * @param    ids 主键id
+     * @author   lf
+     * @date      2023/05/09 14:29
+     */
+    List<SysStorageConfigDTO> selectSysStorageConfigByIds(Collection<String> ids);
+
     /**
      * 编辑文件存储配置
      * @param   source 编辑实体类
@@ -51,4 +60,10 @@ public interface ISysStorageConfigService{
      * @date    2023/05/09 14:29
      */
     int removeSysStorageConfigByIds(Collection<String> ids);
+
+    /**
+     * 查询默认配置
+     * @return
+     */
+    SysStorageConfigDTO selectDefault();
 }

+ 71 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/ISysStorageRecordService.java

@@ -0,0 +1,71 @@
+package cn.tr.module.sys.storage.service;
+
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+import cn.tr.module.sys.storage.dto.SysStorageRecordQueryDTO;
+import java.util.*;
+
+/**
+ * 存储记录Service接口
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ **/
+public interface ISysStorageRecordService{
+
+    /**
+     * 根据条件查询存储记录
+     * @param    query 查询参数
+     * @author   lf
+     * @date      2023/05/10 14:55
+     */
+    List<SysStorageRecordDTO> selectSysStorageRecordList(SysStorageRecordQueryDTO query);
+
+    /**
+     * 根据id查询存储记录
+     * @param    id 主键id
+     * @author   lf
+     * @date      2023/05/10 14:55
+     */
+    SysStorageRecordDTO selectSysStorageRecordById(String id);
+
+
+    /**
+     * 根据id查询存储记录
+     * @param    ids 主键集合
+     * @author   lf
+     * @date      2023/05/10 14:55
+     */
+    List<SysStorageRecordDTO>  selectSysStorageRecordByIds(Collection<String> ids);
+
+    /**
+     * 编辑存储记录
+     * @param   source 编辑实体类
+     * @author  lf
+     * @date     2023/05/10 14:55
+     */
+    boolean updateSysStorageRecordById(SysStorageRecordDTO source);
+
+    /**
+     * 新增存储记录
+     * @param   source 新增实体类
+     * @author lf
+     * @date  2023/05/10 14:55
+     */
+    boolean insertSysStorageRecord(SysStorageRecordDTO source);
+
+    /**
+     * 新增存储记录
+     * @param   source 新增实体类
+     * @author lf
+     * @date  2023/05/10 14:55
+     */
+    String insertSysStorageRecordReturnId(SysStorageRecordDTO source);
+
+    /**
+     * 删除存储记录详情
+     * @param  ids 删除主键集合
+     * @author lf
+     * @date    2023/05/10 14:55
+     */
+    int removeSysStorageRecordByIds(Collection<String> ids);
+}

+ 46 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/DbClientImpl.java

@@ -0,0 +1,46 @@
+package cn.tr.module.sys.storage.service.impl;
+
+import cn.tr.plugin.file.config.db.DbClientDAO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import cn.tr.module.sys.storage.repository.SysStorageFileRepository;
+import cn.tr.module.sys.storage.po.SysStorageFilePO;
+
+import java.util.Objects;
+
+/**
+ * db类型文件存储Service接口实现类
+ *
+ * @author lf
+ * @date  2023/05/11 16:14
+ **/
+@Service
+public class DbClientImpl implements  DbClientDAO {
+    @Autowired
+    private SysStorageFileRepository fileRepository;
+
+    @Override
+    public void upload(String clientId, String bizPath, String contentType, byte[] content) {
+        SysStorageFilePO storageFile = new SysStorageFilePO();
+        storageFile.setContent(content);
+        storageFile.setBizName(bizPath);
+        storageFile.setConfigId(clientId);
+        fileRepository.insert(storageFile);
+    }
+
+    @Override
+    public void delete(String clientId, String bizPath) {
+        fileRepository.delete(new LambdaQueryWrapper<SysStorageFilePO>()
+                .eq(SysStorageFilePO::getBizName,bizPath)
+                .eq(SysStorageFilePO::getConfigId,clientId));
+    }
+
+    @Override
+    public byte[] getContent(String clientId, String bizPath) {
+        SysStorageFilePO file = fileRepository.selectOne(new LambdaQueryWrapper<SysStorageFilePO>()
+                .eq(SysStorageFilePO::getBizName, bizPath)
+                .eq(SysStorageFilePO::getConfigId, clientId));
+        return Objects.isNull(file)?null:file.getContent();
+    }
+}

+ 122 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/StorageFileServiceImpl.java

@@ -0,0 +1,122 @@
+package cn.tr.module.sys.storage.service.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.tr.core.utils.JsonUtils;
+import cn.tr.module.sys.storage.dto.SysStorageConfigDTO;
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+import cn.tr.module.sys.storage.service.IStorageFileService;
+import cn.tr.module.sys.storage.service.ISysStorageConfigService;
+import cn.tr.module.sys.storage.service.ISysStorageRecordService;
+import cn.tr.plugin.file.config.FileClient;
+import cn.tr.plugin.file.config.FileClientConfig;
+import cn.tr.plugin.file.config.FileClientFactory;
+import cn.tr.plugin.file.enums.FileStorageEnum;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.PostConstruct;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName : StorageFileServiceImpl
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年05月10日
+ */
+@Service
+public class StorageFileServiceImpl implements IStorageFileService {
+    //默认配置
+    private SysStorageConfigDTO defaultConfig;
+
+    @Autowired
+    private FileClientFactory fileClientFactory;
+
+    @Autowired
+    @Lazy
+    private ISysStorageConfigService storageConfigService;
+
+    @Autowired
+    @Lazy
+    private ISysStorageRecordService storageRecordService;
+    @Override
+    @PostConstruct
+    public void initDefaultConfig() {
+        defaultConfig=storageConfigService.selectDefault();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public SysStorageRecordDTO upload(String configId,String cateId,String filename, byte[] content) throws Exception {
+        SysStorageConfigDTO config=defaultConfig;
+        if(StrUtil.isNotEmpty(configId)){
+            config=storageConfigService.selectSysStorageConfigById(configId);
+        }
+        String bizName = createBizName(filename);
+        String suffix = FileUtil.extName(filename);
+        FileClient fileClient = getClient(config);
+        fileClient.upload(content,bizName);
+        String downUrl = fileClient.downUrl(bizName);
+        SysStorageRecordDTO record = SysStorageRecordDTO.builder()
+                .realName(filename)
+                .bizName(bizName)
+                .absolutePath(downUrl)
+                .suffix(suffix)
+                .cateId(cateId)
+                .configId(defaultConfig.getId())
+                .size(content.length)
+                .build();
+        String recordId = storageRecordService.insertSysStorageRecordReturnId(record);
+        record.setId(recordId);
+        return record;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void remove(Collection<String> recordIds) {
+        List<SysStorageRecordDTO> records = storageRecordService.selectSysStorageRecordByIds(recordIds);
+        Map<String, List<SysStorageRecordDTO>> recordByConfigId = records.stream()
+                .collect(Collectors.groupingBy(SysStorageRecordDTO::getConfigId));
+        List<SysStorageConfigDTO> configs = storageConfigService.selectSysStorageConfigByIds(recordByConfigId.keySet());
+        configs.stream()
+                .map(config->getClient(config))
+                .forEach(client->{
+                    List<SysStorageRecordDTO> storageRecords = recordByConfigId.get(client.getId());
+                    for (SysStorageRecordDTO storageRecord : storageRecords) {
+                        client.delete(storageRecord.getBizName());
+                    }
+                });
+    }
+
+    @Override
+    public String obtainDownloadPath(String recordId) throws Exception {
+        SysStorageRecordDTO record = storageRecordService.selectSysStorageRecordById(recordId);
+        SysStorageConfigDTO config = storageConfigService.selectSysStorageConfigById(record.getConfigId());
+        FileClient fileClient = getClient(config);
+        return fileClient.downUrl(record.getBizName());
+    }
+
+
+    private FileClient getClient(SysStorageConfigDTO storageConfig){
+        return fileClientFactory.createOrUpdateFileClient(storageConfig.getId(), storageConfig.getType(),parseClientConfig(storageConfig.getType(), storageConfig.getConfig()));
+    }
+
+    private FileClientConfig parseClientConfig(String storage, Map<String, Object> config) {
+        Class<? extends FileClientConfig> configClass = FileStorageEnum.getByStorage(storage)
+                .getConfigClass();
+        config.put("@Clazz",configClass.getName());
+        return  JsonUtils.parseObject(JsonUtils.toJsonString(config), configClass);
+    }
+
+
+    private String createBizName(String realName){
+        return DateUtil.today() +"/"+ RandomUtil.randomString(4)+"-"+realName;
+    }
+}

+ 26 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/SysStorageConfigServiceImpl.java

@@ -19,6 +19,7 @@ import java.util.*;
 import cn.tr.module.sys.storage.service.ISysStorageConfigService;
 import cn.tr.module.sys.storage.mapper.SysStorageConfigMapper;
 
+import javax.validation.ValidationException;
 import javax.validation.Validator;
 
 /**
@@ -60,7 +61,14 @@ public class SysStorageConfigServiceImpl implements ISysStorageConfigService {
     @Override
     public SysStorageConfigDTO selectSysStorageConfigById(String id){
         return SysStorageConfigMapper.INSTANCE.convertDto(baseRepository.selectById(id));
-    };
+    }
+
+    @Override
+    public List<SysStorageConfigDTO> selectSysStorageConfigByIds(Collection<String> ids) {
+        return SysStorageConfigMapper.INSTANCE.convertDtoList(baseRepository.selectBatchIds(ids));
+    }
+
+    ;
 
     /**
      * 编辑文件存储配置
@@ -110,13 +118,29 @@ public class SysStorageConfigServiceImpl implements ISysStorageConfigService {
             throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"不可删除主配置");
         }
         return baseRepository.deleteBatchIds(ids);
-    };
+    }
+
+    @Override
+    public SysStorageConfigDTO selectDefault() {
+        return SysStorageConfigMapper.INSTANCE.convertDto(baseRepository.selectOne(new LambdaQueryWrapper<SysStorageConfigPO>()
+                .eq(SysStorageConfigPO::getMaster,true)
+                .last("limit 1")));
+    }
+
+    ;
 
 
     private FileClientConfig parseClientConfig(String storage, Map<String, Object> config) {
+        if(config==null||config.size()==0){
+            throw new ServiceException(TRExcCode.USER_ERROR_A0400,"存储配置不能为空");
+        }
         // 获取配置类
         Class<? extends FileClientConfig> configClass = FileStorageEnum.getByStorage(storage)
                 .getConfigClass();
+        if(configClass==null){
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,String.format("存储类型{%s}不存在",storage));
+        }
+        config.put("@Clazz",configClass.getName());
         FileClientConfig clientConfig = JsonUtils.parseObject(JsonUtils.toJsonString(config), configClass);
         // 参数校验
         ValidationUtils.validate(validator, clientConfig);

+ 106 - 0
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/storage/service/impl/SysStorageRecordServiceImpl.java

@@ -0,0 +1,106 @@
+package cn.tr.module.sys.storage.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import cn.tr.module.sys.storage.repository.SysStorageRecordRepository;
+import cn.tr.module.sys.storage.po.SysStorageRecordPO;
+import cn.tr.module.sys.storage.dto.SysStorageRecordDTO;
+import cn.tr.module.sys.storage.dto.SysStorageRecordQueryDTO;
+import java.util.*;
+import cn.tr.module.sys.storage.service.ISysStorageRecordService;
+import cn.tr.module.sys.storage.mapper.SysStorageRecordMapper;
+/**
+ * 存储记录Service接口实现类
+ *
+ * @author lf
+ * @date  2023/05/10 14:55
+ **/
+@Service
+public class SysStorageRecordServiceImpl implements ISysStorageRecordService {
+    @Autowired
+    private SysStorageRecordRepository baseRepository;
+
+
+    /**
+     * 根据条件查询存储记录
+     * @param    query 查询参数
+     * @author   lf
+     * @date      2023/05/10 14:55
+     */
+    @Override
+    public List<SysStorageRecordDTO> selectSysStorageRecordList(SysStorageRecordQueryDTO query){
+        return SysStorageRecordMapper.INSTANCE.convertDtoList(
+                baseRepository.selectList(new LambdaQueryWrapper<SysStorageRecordPO>()
+                        .like(StrUtil.isNotEmpty(query.getRealName()),SysStorageRecordPO::getRealName,
+                                query.getRealName())
+                )
+        );
+    };
+
+    /**
+     * 根据id查询存储记录
+     * @param    id 主键id
+     * @author   lf
+     * @date      2023/05/10 14:55
+     */
+    @Override
+    public SysStorageRecordDTO selectSysStorageRecordById(String id){
+        return SysStorageRecordMapper.INSTANCE.convertDto(baseRepository.selectById(id));
+    }
+
+    @Override
+    public List<SysStorageRecordDTO> selectSysStorageRecordByIds(Collection<String> ids) {
+        return SysStorageRecordMapper.INSTANCE.convertDtoList(baseRepository.selectBatchIds(ids));
+    }
+
+    ;
+
+    /**
+     * 编辑存储记录
+     * @param   source 编辑实体类
+     * @author  lf
+     * @date     2023/05/10 14:55
+     */
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean updateSysStorageRecordById(SysStorageRecordDTO source){
+        return baseRepository.updateById(SysStorageRecordMapper.INSTANCE.convertPO(source))!=0;
+    };
+
+    /**
+     * 新增存储记录
+     * @param   source 新增实体类
+     * @author lf
+     * @date  2023/05/10 14:55
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean insertSysStorageRecord(SysStorageRecordDTO source){
+        SysStorageRecordPO record = SysStorageRecordMapper.INSTANCE.convertPO(source);
+        return baseRepository.insert(record)!=0;
+    }
+
+    @Override
+    public String insertSysStorageRecordReturnId(SysStorageRecordDTO source) {
+        SysStorageRecordPO record = SysStorageRecordMapper.INSTANCE.convertPO(source);
+        baseRepository.insert(record);
+        return record.getId();
+    }
+
+    ;
+
+    /**
+     * 删除存储记录详情
+     * @param  ids 删除主键集合
+     * @author lf
+     * @date    2023/05/10 14:55
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int removeSysStorageRecordByIds(Collection<String> ids){
+        return baseRepository.deleteBatchIds(ids);
+    };
+}

+ 0 - 3
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/tenant/controller/SysTenantPackageController.java

@@ -2,7 +2,6 @@ package cn.tr.module.sys.tenant.controller;
 
 import cn.tr.core.pojo.TableDataInfo;
 import cn.tr.module.sys.tenant.dto.SysTenantPackageMenuAssignDTO;
-import cn.tr.module.sys.tenant.dto.SysTenantPackageMenuDTO;
 import cn.tr.module.sys.tenant.service.ISysTenantPackageMenuService;
 import cn.tr.module.sys.user.dto.SysMenuDTO;
 import cn.tr.module.sys.user.enums.CreateEnum;
@@ -24,8 +23,6 @@ import cn.tr.module.sys.tenant.dto.SysTenantPackageDTO;
 import cn.tr.module.sys.tenant.service.ISysTenantPackageService;
 import cn.tr.module.sys.tenant.dto.SysTenantPackageQueryDTO;
 import java.util.*;
-import java.util.stream.Collectors;
-
 import cn.tr.plugin.mybatis.base.BaseController;
 import org.springframework.web.bind.annotation.*;
 /**

+ 9 - 13
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/controller/SysPortalController.java

@@ -5,10 +5,7 @@ import cn.tr.core.pojo.CommonResult;
 import cn.tr.core.pojo.TableDataInfo;
 import cn.tr.core.validation.Insert;
 import cn.tr.core.validation.Update;
-import cn.tr.module.sys.user.dto.SysPortalDTO;
-import cn.tr.module.sys.user.dto.SysPortalMenuAssignDTO;
-import cn.tr.module.sys.user.dto.SysPortalMenuDTO;
-import cn.tr.module.sys.user.dto.SysPortalQueryDTO;
+import cn.tr.module.sys.user.dto.*;
 import cn.tr.module.sys.user.service.ISysPortalMenuService;
 import cn.tr.module.sys.user.service.ISysPortalService;
 import cn.tr.plugin.mybatis.base.BaseController;
@@ -36,20 +33,19 @@ import java.util.stream.Collectors;
 public class SysPortalController extends BaseController {
     private final ISysPortalService portalService;
     private final ISysPortalMenuService portalMenuService;
+
+    @GetMapping("/menu/list/{portalId}")
+    @ApiOperation(value = "查询门户下的权限信息",notes = "权限: 无")
+    public CommonResult<List<SysMenuDTO>> listMenu(@PathVariable("portalId") String portalId) {
+        return CommonResult.success(portalMenuService.findAllMenusByPortalId(portalId));
+    }
+
     @PostMapping("/assign")
     @ApiOperationSupport(author = "lf")
     @ApiOperation(value = "为门户分配菜单",notes = "权限: sys:portal:assign")
     @SaCheckPermission("sys:portal:assign")
     public CommonResult<Boolean> selectList(@RequestBody@Validated SysPortalMenuAssignDTO source){
-        portalMenuService.assignPortalMenu(source.getMenuIds()
-                .stream()
-                .map(menuId->{
-                    SysPortalMenuDTO result = new SysPortalMenuDTO();
-                    result.setMenuId(menuId);
-                    result.setPortalId(source.getPortalId());
-                    return result;
-                })
-                .collect(Collectors.toList()));
+        portalMenuService.assignPortalMenu(source.getPortalId(),source.getMenuIds());
         return CommonResult.success(true);
     }
 

+ 2 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/dto/SysPortalQueryDTO.java

@@ -17,9 +17,9 @@ import java.io.Serializable;
 public class SysPortalQueryDTO implements Serializable {
     private static final long serialVersionUID = -262693810220247854L;
     @ApiModelProperty(value = "门户编码")
-    private String portalCode;
+    private String code;
 
     @ApiModelProperty(value = "门户名称")
-    private String portalName;
+    private String name;
 
 }

+ 3 - 3
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/ISysPortalMenuService.java

@@ -20,10 +20,10 @@ public interface ISysPortalMenuService {
 
     /**
      * 为门户分配菜单
-     * @param source 门户菜单关联信息
+     * @param portalId 门户id
      * @return
      */
-    void assignPortalMenu(List<SysPortalMenuDTO> source);
+    void assignPortalMenu(String portalId,List<String> menuIds);
 
     /**
      * 找到所给门户下的所有菜单
@@ -35,7 +35,7 @@ public interface ISysPortalMenuService {
 
     /**
      * 删除门户菜单缓存
-     * {@link ISysPortalMenuService#assignPortalMenu(List)} (List)} /
+     * {@link ISysPortalMenuService#assignPortalMenu(String,List)} (List)} /
      * @param portalId
      */
     @CacheEvict(value = "sys:portal:menu",key = "#portalId")

+ 24 - 11
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPortalMenuServiceImpl.java

@@ -1,12 +1,13 @@
 package cn.tr.module.sys.user.service.impl;
 
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.tr.core.exception.ServiceException;
+import cn.tr.core.exception.TRExcCode;
 import cn.tr.module.sys.user.mapper.SysMenuMapper;
-import cn.tr.module.sys.user.mapper.SysPortalMenuMapper;
 import cn.tr.module.sys.tenant.service.ISysTenantService;
 import cn.tr.module.sys.user.dto.SysMenuDTO;
 import cn.tr.module.sys.user.dto.SysPortalDTO;
-import cn.tr.module.sys.user.dto.SysPortalMenuDTO;
 import cn.tr.module.sys.user.enums.CreateEnum;
 import cn.tr.module.sys.user.po.SysPortalMenuPO;
 import cn.tr.module.sys.user.repository.SysMenuRepository;
@@ -47,15 +48,27 @@ public class SysPortalMenuServiceImpl extends ServiceImpl<SysPortalMenuRepositor
     private ISysTenantService tenantService;
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void assignPortalMenu(List<SysPortalMenuDTO> source) {
-        List<SysPortalMenuPO> portalMenus = SysPortalMenuMapper.INSTANCE.toSysPortalMenuPOList(source);
-        Map<String, List<SysPortalMenuPO>> portalIdMap = portalMenus.stream()
-                .collect(Collectors.groupingBy(SysPortalMenuPO::getPortalId));
-        baseMapper.delete(new LambdaQueryWrapper<SysPortalMenuPO>().in(SysPortalMenuPO::getPortalId,portalIdMap.keySet()));
-        saveBatch(portalMenus);
-        portalIdMap.forEach((portalId,relations)->{
-            portalMenuService.delCacheMenusByPortalId(portalId);
-        });
+    public void assignPortalMenu(String portalId,List<String> menuIds) {
+        SysPortalDTO portal = portalService.selectSysPortalById(portalId);
+        if(StrUtil.equals(portal.getType(), CreateEnum.sys.name())){
+            throw new ServiceException(TRExcCode.SYSTEM_ERROR_B0001,"无法对系统门户进行操作");
+        }
+        baseMapper.delete(
+                new LambdaQueryWrapper<SysPortalMenuPO>().eq(SysPortalMenuPO::getPortalId,portalId)
+        );
+        if(CollectionUtil.isNotEmpty(menuIds)){
+            List<SysPortalMenuPO> packageMenus = menuIds
+                    .stream()
+                    .map(menuId -> {
+                        SysPortalMenuPO result = new SysPortalMenuPO();
+                        result.setMenuId(menuId);
+                        result.setPortalId(portalId);
+                        return result;
+                    })
+                    .collect(Collectors.toList());
+            this.saveBatch(packageMenus);
+        }
+        portalMenuService.delCacheMenusByPortalId(portalId);
     }
 
     @Override

+ 2 - 2
tr-modules/tr-module-system/src/main/java/cn/tr/module/sys/user/service/impl/SysPortalServiceImpl.java

@@ -40,8 +40,8 @@ public class SysPortalServiceImpl implements ISysPortalService {
     @Override
     public List<SysPortalDTO> selectSysPortalList(SysPortalQueryDTO query) {
         return SysPortalMapper.INSTANCE.toSysPortalDTOList(portalRepository.selectList(new LambdaQueryWrapper<SysPortalPO>()
-                .like(StrUtil.isNotEmpty(query.getPortalCode()),SysPortalPO::getCode,query.getPortalCode())
-                .like(StrUtil.isNotEmpty(query.getPortalName()),SysPortalPO::getName,query.getPortalName())
+                .like(StrUtil.isNotEmpty(query.getCode()),SysPortalPO::getCode,query.getCode())
+                .like(StrUtil.isNotEmpty(query.getName()),SysPortalPO::getName,query.getName())
         ));
     }
 

+ 0 - 7
tr-plugins/tr-spring-boot-starter-plugin-doc/src/main/java/cn/tr/plugin/doc/ModifyOkStatusCodeResponseMessageReader.java

@@ -1,18 +1,11 @@
 package cn.tr.plugin.doc;
 
-import cn.hutool.core.util.ReflectUtil;
 import lombok.NonNull;
-import org.springframework.http.HttpStatus;
-import springfox.documentation.builders.OperationBuilder;
-import springfox.documentation.schema.ModelRef;
-import springfox.documentation.service.ResponseMessage;
 import springfox.documentation.spi.DocumentationType;
 import springfox.documentation.spi.service.OperationBuilderPlugin;
 import springfox.documentation.spi.service.contexts.OperationContext;
 
 import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * 改变swagger中默认的200状态码

+ 10 - 10
tr-plugins/tr-spring-boot-starter-plugin-eventbus/pom.xml

@@ -19,16 +19,12 @@
         <dependency>
             <groupId>cn.tr</groupId>
             <artifactId>tr-framework</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>cn.tr</groupId>
-            <artifactId>tr-spring-boot-starter-plugin-flink</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.redisson</groupId>
-            <artifactId>redisson-spring-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                    <groupId>org.springframework.boot</groupId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <dependency>
@@ -37,5 +33,9 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 17 - 0
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/EvenBusApplication.java

@@ -0,0 +1,17 @@
+package cn.tr.plugin;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @ClassName : EvenBusApplication
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年05月11日
+ */
+@SpringBootApplication
+public class EvenBusApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(EvenBusApplication.class);
+    }
+}

+ 26 - 40
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/TrEventBusAutoConfiguration.java

@@ -2,45 +2,47 @@ package cn.tr.plugin.eventbus;
 
 
 import cn.tr.plugin.eventbus.config.EventBus;
+import cn.tr.plugin.eventbus.config.StdEventBus;
 import cn.tr.plugin.eventbus.config.SubscribeListenerAnnotationBeanPostProcessor;
-import cn.tr.plugin.eventbus.config.core.AbstractEvenBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.core.EventBusDataSourceEmitter;
-import cn.tr.plugin.eventbus.config.core.LocalEventBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.core.ShareEventBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.redission.RedissionEventBus;
-import cn.tr.plugin.eventbus.config.redission.RedissionEventBusDataSourceEmitter;
-import cn.tr.plugin.eventbus.urils.EventBusStrategy;
+import cn.tr.plugin.eventbus.mq.consumer.EvenBusConsumer;
+import cn.tr.plugin.eventbus.mq.message.EvenBusMessageEvent;
+import cn.tr.plugin.eventbus.mq.producer.EvenBusProducer;
+import cn.tr.plugin.eventbus.utils.EventBusStrategy;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
-import org.redisson.api.RedissonClient;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.cloud.bus.ServiceMatcher;
+import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 
-import java.util.*;
 /**
  * @ClassName : TrEventBusAutoConfiguration
  * @Description : 消息总线自动装配
  * @Author : LF
  * @Date: 2023年03月15日
  */
-@Import(TrEventBusAutoConfiguration.RedissionEventBusAutoConfiguration.class)
+@RemoteApplicationEventScan(basePackageClasses = EvenBusMessageEvent.class)
+@AutoConfigureAfter({ApplicationEventPublisher.class,ServiceMatcher.class})
 public class TrEventBusAutoConfiguration {
-    /**
-     * 本地订阅处理
-     */
+
+    @Value("${spring.application.name}")
+    protected String applicationName;
+
+    @Bean
+    public EvenBusConsumer evenBusConsumer(){
+        return new EvenBusConsumer();
+    }
+
     @Bean
-    public LocalEventBusDataRichSourceFunction localEventBusDataRichSourceFunction(){
-        return new LocalEventBusDataRichSourceFunction();
+    public EvenBusProducer evenBusProducer( ApplicationEventPublisher applicationEventPublisher,ServiceMatcher serviceMatcher){
+        return new EvenBusProducer(applicationEventPublisher,serviceMatcher,applicationName);
     }
 
-    /**
-     * 共享订阅处理
-     */
+
     @Bean
-    public ShareEventBusDataRichSourceFunction shareEventBusDataRichSourceFunction(){
-        return new ShareEventBusDataRichSourceFunction();
+    public EventBus eventBus(EvenBusConsumer evenBusConsumer, EvenBusProducer evenBusProducer){
+        return new StdEventBus(evenBusConsumer,evenBusProducer);
     }
 
     @Bean
@@ -48,20 +50,4 @@ public class TrEventBusAutoConfiguration {
         EventBusStrategy.tr.objectMapperSupplier=()->objectMapper;
         return new SubscribeListenerAnnotationBeanPostProcessor(eventBus);
     }
-
-    //todo 可根据配置进行配置
-    @Configuration
-    public static class RedissionEventBusAutoConfiguration{
-        @Bean
-        public EventBus redissionEventBus(StreamExecutionEnvironment ec,RedissonClient redissonClient,List<AbstractEvenBusDataRichSourceFunction> functions) throws Exception {
-            EventBusStrategy.tr.redissonClientSupplier=()->redissonClient;
-            return new RedissionEventBus(redissonClient,ec,functions);
-        }
-
-        @Bean(initMethod = "emitter")
-        public EventBusDataSourceEmitter redissionEventBusDataSourceEmitter(List<AbstractEvenBusDataRichSourceFunction> functions){
-            return new RedissionEventBusDataSourceEmitter(functions);
-        }
-
-    }
 }

+ 0 - 6
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/annotation/Subscribe.java

@@ -1,7 +1,5 @@
 package cn.tr.plugin.eventbus.annotation;
 
-import cn.tr.plugin.eventbus.bean.Subscription;
-import org.springframework.core.annotation.AliasFor;
 import java.lang.annotation.*;
 
 /**
@@ -19,8 +17,4 @@ public @interface Subscribe {
      * 订阅主题
      */
     String[] value() default {};
-
-    String id() default "";
-
-    Subscription.Feature feature() default Subscription.Feature.local;
 }

+ 0 - 141
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/bean/Subscription.java

@@ -1,141 +0,0 @@
-package cn.tr.plugin.eventbus.bean;
-
-import cn.tr.plugin.eventbus.urils.TopicUtils;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import org.springframework.util.Assert;
-
-import java.io.Serializable;
-import java.util.*;
-import java.util.stream.Collectors;
-
-@AllArgsConstructor
-@Getter
-public class Subscription implements Serializable {
-    private static final long serialVersionUID = -6849794470754667710L;
-
-    public static final Feature[] DEFAULT_FEATURES = Subscription.Feature.values();
-
-    /**
-     * 订阅者标识
-     */
-    private final String subscriber;
-
-    /**
-     * 订阅主题,主题以/分割,如: /device/TS-01/09012/message 支持通配符 /device/**
-     */
-    private final String[] topics;
-
-    /**
-     * 订阅特性
-     */
-    private final Feature feature;
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        Subscription that = (Subscription) o;
-        return getSubscriber().equals(that.getSubscriber()) &&
-                Arrays.equals(getTopics(), that.getTopics()) &&
-                getFeature() == that.getFeature();
-    }
-
-    @Override
-    public int hashCode() {
-        int result = Objects.hash(getSubscriber(), getFeature());
-        result = 31 * result + Arrays.hashCode(getTopics());
-        return result;
-    }
-
-    public static Subscription of(String subscriber, String topic, Feature feature) {
-        return of(subscriber,new String[]{topic},feature);
-    }
-    public static Subscription of(String subscriber, String[] topics, Feature features) {
-
-        return Subscription
-                .builder()
-                .subscriberId(subscriber)
-                .topics(topics)
-                .build();
-    }
-
-
-
-
-    @AllArgsConstructor
-    @Getter
-    public enum Feature {
-
-        //如果相同的订阅者,只有一个订阅者收到消息
-        shared("shared"),
-        //订阅本地消息
-        local("订阅本地消息");
-
-        private final String text;
-    }
-
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    public static class Builder {
-        //订阅者标识
-        private String subscriber;
-
-        //订阅主题,主题以/分割,如: /device/TS-01/09012/message 支持通配符 /device/**
-        private final Set<String> topics = new HashSet<>();
-
-        //订阅特性
-        private Feature feature;
-
-
-        public Builder randomSubscriberId() {
-            return subscriberId(UUID.randomUUID().toString());
-        }
-
-        public Builder subscriberId(String id) {
-            this.subscriber = id;
-            return this;
-        }
-
-        public Builder topics(String... topics) {
-            return topics(Arrays.asList(topics));
-        }
-
-        public Builder topics(Collection<String> topics) {
-            this.topics.addAll(topics.stream()
-                                     .flatMap(topic -> TopicUtils.expand(topic).stream())
-                                     .collect(Collectors.toSet()));
-            return this;
-        }
-
-        public Builder feature(Feature feature) {
-            this.feature=feature;
-            return this;
-        }
-
-        public Builder justLocal() {
-            return feature(Feature.local);
-        }
-
-
-        public Builder local() {
-            return feature(Feature.local);
-        }
-
-        public Builder shared() {
-            return feature(Feature.shared);
-        }
-
-        public Subscription build() {
-            if (feature==null) {
-                local();
-            }
-            Assert.notEmpty(topics, "topic cannot be empty");
-//            Assert.hasText(subscriber, "subscriber cannot be empty");
-            return new Subscription(subscriber, topics.toArray(new String[0]), feature);
-        }
-
-    }
-}

+ 17 - 20
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/EventBus.java

@@ -1,52 +1,49 @@
 package cn.tr.plugin.eventbus.config;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.tr.plugin.eventbus.proxy.ConsumerWrapper;
 import cn.tr.plugin.eventbus.proxy.ProxyMessageListener;
-import cn.tr.plugin.eventbus.bean.Subscription;
-import cn.tr.plugin.eventbus.bean.TopicPayload;
-import org.apache.commons.compress.utils.Sets;
+import cn.tr.plugin.eventbus.mq.message.TopicPayload;
 
 import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
-import java.util.stream.Collectors;
 
 /**
  * @ClassName : EventBus
- * @Description :
+ * @Description : 消息总线
  * @Author : LF
  * @Date: 2023年03月17日
  */
-
 public interface EventBus {
 
     /**
      * 订阅主题,由代理类消费
      * @param topic
      * @param messageConsumer
-     * @param <T>
+     * @param
      */
-    default  <T> void subscribe(Subscription topic, Consumer<String> messageConsumer){
-        subscribe(Sets.newHashSet(topic),messageConsumer);
+    default void subscribe(String topic, Consumer<String> messageConsumer){
+        subscribe(CollectionUtil.newHashSet(topic),messageConsumer);
     };
 
     /**
      * 订阅主题,由代理类消费
      * @param topic
      * @param messageListener
-     * @param <T>
+     * @param
      */
-    default  <T> void subscribe(Subscription topic, ProxyMessageListener messageListener){
-        subscribe(Sets.newHashSet(topic),messageListener);
+    default void subscribe(String topic, ProxyMessageListener messageListener){
+        subscribe(CollectionUtil.newHashSet(topic),messageListener);
     };
 
     /**
      * 订阅主题
      * @param topics 主题,支持正则
      * @param messageConsumer 所订阅的主题的消费者
-     * @param <T>
+     * @param
      */
-    default  <T> void subscribe(Set<Subscription> topics, Consumer<String> messageConsumer){
+    default void subscribe(Set<String> topics, Consumer<String> messageConsumer){
         ProxyMessageListener proxyMessageListener = new ProxyMessageListener(new ConsumerWrapper(messageConsumer),
                 ReflectUtil.getMethod(ConsumerWrapper.class, "accept", String.class));
         subscribe(topics,proxyMessageListener);
@@ -56,9 +53,9 @@ public interface EventBus {
      * 订阅主题,由代理类消费
      * @param topics
      * @param messageListener
-     * @param <T>
+     * @param
      */
-    public <T> void subscribe(Set<Subscription> topics, ProxyMessageListener messageListener);
+    void subscribe(Set<String> topics, ProxyMessageListener messageListener);
 
     /**
      * 向主题中发布消息
@@ -72,11 +69,11 @@ public interface EventBus {
     };
 
     default  <T> Long publish(String topic, T message){
-        return publish(Sets.newHashSet(topic),()->message);
+        return publish(CollectionUtil.newHashSet(topic),()->message);
     };
 
     default  <T> Long publish(String topic, Supplier<T> supplierMsg){
-        return publish(Sets.newHashSet(topic),supplierMsg);
+        return publish(CollectionUtil.newHashSet(topic),supplierMsg);
     };
 
     /**
@@ -97,9 +94,9 @@ public interface EventBus {
     /**
      * 向主题中发布消息
      * @param msgs 发布消息
-     * @param <T>
+     * @param
      * @return
      */
-    public <T> Long publish(TopicPayload msgs);
+    Long publish(TopicPayload msgs);
 
 }

+ 3 - 25
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/SubscribeListenerAnnotationBeanPostProcessor.java

@@ -1,10 +1,7 @@
 package cn.tr.plugin.eventbus.config;
 
 import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.tr.core.utils.JsonUtils;
 import cn.tr.plugin.eventbus.annotation.Subscribe;
-import cn.tr.plugin.eventbus.bean.Subscription;
 import cn.tr.plugin.eventbus.proxy.ProxyMessageListener;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.framework.Advised;
@@ -34,11 +31,6 @@ import java.util.stream.Stream;
 public class SubscribeListenerAnnotationBeanPostProcessor implements BeanPostProcessor {
     private final ConcurrentMap<Class<?>, TypeMetadata> typeCache = new ConcurrentHashMap<>();
 
-    /**
-     * 订阅者集合
-     */
-    private final static Set<Subscription> subscriptionSet=new HashSet<>();
-
     private final EventBus eventBus;
 
     public SubscribeListenerAnnotationBeanPostProcessor(EventBus eventBus) {
@@ -75,24 +67,10 @@ public class SubscribeListenerAnnotationBeanPostProcessor implements BeanPostPro
             throw new UnsupportedOperationException("The parameter of class :"+ objClass.getName()+"method : "+method.getName()+"   cannot be an array");
         }
         ProxyMessageListener proxyMessageListener = new ProxyMessageListener(bean, method);
-        Class<? extends Class> aClass = objClass.getClass();
-        Class<?>[] parameterTypes = method.getParameterTypes();
-        String id =subscribe.id();
-        if(StrUtil.isEmpty(id)){
-            id= aClass.getName() + method.getName() + (parameterTypes.length == 0 ? "" : parameterTypes[0].getName());
+        Set<String> topics = Stream.of(subscribe.value()).collect(Collectors.toSet());
+        for (String topic : topics) {
+            eventBus.subscribe(topic,proxyMessageListener);
         }
-        Subscription subscription = Subscription.builder()
-                .feature(subscribe.feature())
-                .topics(subscribe.value())
-                .subscriberId(id)
-                .build();
-        if (subscriptionSet.contains(subscription)) {
-            log.warn("subscription : [{}] has exist ,con't repeat register", JsonUtils.toJsonString(subscription));
-        }else {
-            eventBus.subscribe(subscription,proxyMessageListener);
-            subscriptionSet.add(subscription);
-        }
-
     }
 
 

+ 0 - 141
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/AbstractEvenBusDataRichSourceFunction.java

@@ -1,141 +0,0 @@
-package cn.tr.plugin.eventbus.config.core;
-
-import cn.hutool.core.date.DatePattern;
-import cn.hutool.core.date.DateTime;
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.util.IdUtil;
-import cn.tr.plugin.eventbus.bean.Subscription;
-import cn.tr.plugin.eventbus.bean.TopicPayload;
-import cn.tr.plugin.eventbus.urils.EventBusStrategy;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.flink.configuration.Configuration;
-import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
-import org.redisson.api.RBloomFilter;
-
-import java.time.Duration;
-import java.time.temporal.ChronoUnit;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.function.Consumer;
-
-/**
- * @ClassName : AbstractEvenBusDataRichSourceFunction
- * @Description : 消息总线数据流处理
- * @Author : LF
- * @Date: 2023年03月18日
- */
-@Slf4j
-public abstract class AbstractEvenBusDataRichSourceFunction extends RichSourceFunction<TopicPayload> {
-    private static final Map<String, RBloomFilter<Long>> bloomFilterMap=new ConcurrentHashMap<>();
-
-    private static final  ExecutorService executorService=Executors.newSingleThreadExecutor();
-
-    private static final Map<String, Consumer<TopicPayload>> consumerMap=new HashMap<>();
-    @Getter
-    private Boolean close=false;
-
-    private final String id;
-
-    public AbstractEvenBusDataRichSourceFunction() {
-        id= IdUtil.randomUUID();
-    }
-
-    static {
-        executorService.execute(()->{
-            Set<String> keySet = bloomFilterMap.keySet();
-            Date now = new Date();
-            for (String date : keySet) {
-                DateTime dateTime = DateUtil.parseDate(date);
-                if (DateUtil.between(dateTime,now, DateUnit.HOUR)>8) {
-                    RBloomFilter<Long> bloomFilter = bloomFilterMap.remove(date);
-                    if(bloomFilter!=null){
-                        try {
-                            bloomFilter.delete();
-                        }finally {
-                        }
-                    }
-                }
-            }
-        });
-    }
-
-    public abstract Subscription.Feature getFeature();
-    @Override
-    public void run(SourceContext<TopicPayload> ctx) throws Exception {
-        while (!getClose()){
-            //非关闭状态
-            consumerMap.putIfAbsent(id,msg->{
-                if(!checkMsg(msg)){
-                    return;
-                }
-                if (repeatConsumer(msg)) {
-                    //去重
-                    if(log.isDebugEnabled()){
-                        log.debug("[Pub message] : [{}] repeated",msg);
-                    }
-                    return;
-                }
-                ctx.collect(msg);
-            });
-        }
-    }
-
-    public Consumer<TopicPayload> getCtxConsumer(){
-        return consumerMap.get(id);
-    }
-    /**
-     * 检查消息是否合法
-     * @param msg
-     * @return
-     */
-    public boolean checkMsg(TopicPayload msg){
-        return true;
-    }
-
-    /**
-     * 判断当前消息是否被重复消息
-     * @param msg
-     * @return
-     */
-    public boolean repeatConsumer(TopicPayload msg){
-        RBloomFilter<Long> bloomFilter = finBloomFilter(msg);
-        return !bloomFilter.add(msg.getId());
-    }
-
-
-    private RBloomFilter<Long> finBloomFilter(TopicPayload msg){
-        //按照小时划分
-        String date = DateUtil.format(DateUtil.beginOfHour(new Date(msg.getCreateTime())), DatePattern.NORM_DATETIME_FORMAT);
-        return bloomFilterMap.compute(date, (k, bloomFilter) -> {
-            if(bloomFilter==null){
-                bloomFilter =  EventBusStrategy.tr.getRedissionClient() .getBloomFilter(date);
-                bloomFilter.tryInit(1000000,0);
-                //bitmap 7天自动过期释放内存
-                bloomFilter.expire(Duration.of(7, ChronoUnit.HOURS));
-            }
-            return bloomFilter;
-        });
-    }
-
-    @Override
-    public void open(Configuration parameters) throws Exception {
-        super.open(parameters);
-        this.close=false;
-    }
-
-    @Override
-    public void close() throws Exception {
-        this.close=true;
-    }
-
-    @Override
-    public void cancel() {
-    }
-}

+ 0 - 27
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/EventBusDataSourceEmitter.java

@@ -1,27 +0,0 @@
-package cn.tr.plugin.eventbus.config.core;
-
-import cn.hutool.core.collection.CollectionUtil;
-import lombok.Getter;
-
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * @ClassName : EventBusDataSourceEmitter
- * @Description : 消息总线消息发射器
- * @Author : LF
- * @Date: 2023年03月18日
- */
-
-public abstract class EventBusDataSourceEmitter implements Consumer<List<AbstractEvenBusDataRichSourceFunction>> {
-    @Getter
-    private final List<AbstractEvenBusDataRichSourceFunction> richSourceFunctions;
-
-    public EventBusDataSourceEmitter(List<AbstractEvenBusDataRichSourceFunction> richSourceFunctions) {
-        this.richSourceFunctions = richSourceFunctions;
-    }
-
-    public void emitter(){
-        accept(richSourceFunctions);
-    }
-}

+ 0 - 26
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/LocalEventBusDataRichSourceFunction.java

@@ -1,26 +0,0 @@
-package cn.tr.plugin.eventbus.config.core;
-
-
-import cn.tr.plugin.eventbus.bean.Subscription;
-import cn.tr.plugin.eventbus.bean.TopicPayload;
-
-/**
- * @ClassName : LocalEventBusDataRichSourceFunction
- * @Description : 本地消息总线 {@link cn.tr.plugin.eventbus.bean.Subscription.Feature#local}
- * @Author : LF
- * @Date: 2023年03月18日
- */
-
-public class LocalEventBusDataRichSourceFunction extends AbstractEvenBusDataRichSourceFunction {
-
-
-    @Override
-    public Subscription.Feature getFeature() {
-        return Subscription.Feature.local;
-    }
-
-    @Override
-    public boolean checkMsg(TopicPayload msg) {
-        return true;
-    }
-}

+ 0 - 19
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/core/ShareEventBusDataRichSourceFunction.java

@@ -1,19 +0,0 @@
-package cn.tr.plugin.eventbus.config.core;
-
-
-import cn.tr.plugin.eventbus.bean.Subscription;
-
-/**
- * @ClassName : ShareEventBusDataRichSourceFunction
- * @Description : 共享消息总线 {@link cn.tr.plugin.eventbus.bean.Subscription.Feature#shared}
- * @Author : LF
- * @Date: 2023年03月18日
- */
-
-public class ShareEventBusDataRichSourceFunction extends AbstractEvenBusDataRichSourceFunction {
-
-    @Override
-    public Subscription.Feature getFeature() {
-        return Subscription.Feature.shared;
-    }
-}

+ 0 - 102
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/redission/RedissionEventBus.java

@@ -1,102 +0,0 @@
-package cn.tr.plugin.eventbus.config.redission;
-
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.tr.plugin.eventbus.proxy.ProxyMessageListener;
-import cn.tr.plugin.eventbus.bean.Subscription;
-import cn.tr.plugin.eventbus.bean.TopicPayload;
-import cn.tr.plugin.eventbus.config.EventBus;
-import cn.tr.plugin.eventbus.config.core.AbstractEvenBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.constant.EventBusConstant;
-import cn.tr.plugin.eventbus.urils.TopicUtils;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
-import org.apache.flink.streaming.api.functions.sink.SinkFunction;
-import org.redisson.api.RTopic;
-import org.redisson.api.RedissonClient;
-import java.util.*;
-
-/**
- * @ClassName : RedissonEventBus
- * @Description : 订阅消息占用一个主线程进行通信,消费线程多个
- * @Author : LF
- * @Date: 2023年03月17日
- */
-@Slf4j
-public class RedissionEventBus implements EventBus {
-    private static final long serialVersionUID = 7277245154307718390L;
-
-    private final transient RTopic publishTopic;
-
-    private static final Map<Subscription.Feature,Map<String, List<ProxyMessageListener>>> subscriptionMap = new HashMap<>();
-
-    public RedissionEventBus(RedissonClient redissonClient, StreamExecutionEnvironment ec, List<AbstractEvenBusDataRichSourceFunction> dataSources) throws Exception {
-        this.publishTopic = redissonClient.getTopic(EventBusConstant.EVENT_BUS_TOPIC);
-        dataSources.forEach(dataSource->{
-            ec.addSource(dataSource)
-                    .filter(Objects::nonNull)
-                    .keyBy(TopicPayload::getTopic)
-                    .addSink(new RedissionEventBusSink(dataSource.getFeature()));
-        });
-        ec.executeAsync("tr-eventbus");
-    }
-
-    @Override
-    public <T> void subscribe(Set<Subscription> subscriptions, ProxyMessageListener messageListener) {
-        subscriptions.forEach(subscription -> {
-            String[] topics =subscription.getTopics();
-            Subscription.Feature feature = subscription.getFeature();
-            if(topics.length==0||feature==null){
-                return;
-            }
-            //保存订阅消息消费者
-            subscriptionMap.compute(feature,(k,topicMap)->{
-                if(topicMap==null){
-                    topicMap=new HashMap<>();
-                }
-                for (String topic : topics) {
-                    topicMap.compute(topic,(tp,listeners)->{
-                        if(listeners==null){
-                            listeners=new ArrayList<>();
-                        }
-                        listeners.add(messageListener);
-                        return listeners;
-                    });
-                }
-                return topicMap;
-            });
-        });
-    }
-
-    @Override
-    public <T> Long publish(TopicPayload msg) {
-        return publishTopic.publish(msg);
-    }
-
-
-    @AllArgsConstructor
-    static class RedissionEventBusSink implements SinkFunction<TopicPayload> {
-        private final Subscription.Feature feature;
-
-        @Override
-        public void invoke(TopicPayload payload, Context context) throws Exception {
-            String payloadTopic = payload.getTopic();
-            Map<String, List<ProxyMessageListener>> topicMap = subscriptionMap.get(feature);
-            if(CollectionUtil.isEmpty(topicMap)){
-                return;
-            }
-            topicMap.forEach((k,listeners)->{
-                if(TopicUtils.match(k,payloadTopic)){
-                    listeners.parallelStream().forEach(ln -> {
-                        try {
-                            ln.onMessage(payload);
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                        }
-                    });
-                }
-            });
-        }
-    }
-}

+ 0 - 45
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/config/redission/RedissionEventBusDataSourceEmitter.java

@@ -1,45 +0,0 @@
-package cn.tr.plugin.eventbus.config.redission;
-
-import cn.tr.plugin.eventbus.bean.TopicPayload;
-import cn.tr.plugin.eventbus.config.core.AbstractEvenBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.core.EventBusDataSourceEmitter;
-import cn.tr.plugin.eventbus.constant.EventBusConstant;
-import cn.tr.plugin.eventbus.urils.EventBusStrategy;
-import org.redisson.api.RTopic;
-import java.util.function.Consumer;
-import java.util.*;
-/**
- * @ClassName : RedissionEventBusDataSourceEmitter
- * @Description :
- * @Author : LF
- * @Date: 2023年03月18日
- */
-
-public class RedissionEventBusDataSourceEmitter extends EventBusDataSourceEmitter {
-    private static RTopic rTopic=null;
-    public RedissionEventBusDataSourceEmitter(List<AbstractEvenBusDataRichSourceFunction> richSourceFunctions) {
-        super(richSourceFunctions);
-    }
-
-    @Override
-    public void accept(List<AbstractEvenBusDataRichSourceFunction> richSourceFunction) {
-        if(rTopic==null){
-            synchronized (RedissionEventBusDataSourceEmitter.class){
-                if(rTopic==null){
-                    rTopic=EventBusStrategy.tr
-                            .getRedissionClient()
-                            .getTopic(EventBusConstant.EVENT_BUS_TOPIC);
-                    rTopic.addListener(TopicPayload.class,(channel,msg)->{
-                        for (AbstractEvenBusDataRichSourceFunction sourceFunction : richSourceFunction) {
-                            Consumer<TopicPayload> ctxConsumer = sourceFunction.getCtxConsumer();
-                            if(ctxConsumer!=null){
-                                ctxConsumer.accept(msg);
-                            }
-                        }
-                    });
-                }
-            }
-        }
-
-    }
-}

+ 0 - 15
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/constant/EventBusConstant.java

@@ -1,15 +0,0 @@
-package cn.tr.plugin.eventbus.constant;
-
-/**
- * @Interface : EventBusConstant
- * @Description :
- * @Author : LF
- * @Date: 2023年03月17日
- */
-
-public interface EventBusConstant {
-    String EVENT_BUS_TOPIC ="tr-eventbus";
-
-
-    String SUBSCRIBE_REGISTER_CENTER="eventbus-subscribe";
-}

+ 44 - 0
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/AbstractBusProducer.java

@@ -0,0 +1,44 @@
+package cn.tr.plugin.eventbus.mq;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.bus.ServiceMatcher;
+import org.springframework.cloud.bus.event.RemoteApplicationEvent;
+import org.springframework.context.ApplicationEventPublisher;
+
+import javax.annotation.Resource;
+
+/**
+ * 基于 Spring Cloud Bus 实现的 Producer 抽象类
+ *
+ * @author tr
+ */
+public abstract class AbstractBusProducer {
+
+    private final ApplicationEventPublisher applicationEventPublisher;
+
+    private final ServiceMatcher serviceMatcher;
+
+    private final String applicationName;
+
+    public AbstractBusProducer(ApplicationEventPublisher applicationEventPublisher, ServiceMatcher serviceMatcher, String applicationName) {
+        this.applicationEventPublisher = applicationEventPublisher;
+        this.serviceMatcher = serviceMatcher;
+        this.applicationName = applicationName;
+    }
+
+    protected void publishEvent(RemoteApplicationEvent event) {
+        applicationEventPublisher.publishEvent(event);
+    }
+
+    /**
+     * @return 只广播给自己服务的实例
+     */
+    protected String selfDestinationService() {
+        return applicationName + ":**";
+    }
+
+    protected String getBusId() {
+        return serviceMatcher.getBusId();
+    }
+
+}

+ 23 - 0
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/consumer/EvenBusConsumer.java

@@ -0,0 +1,23 @@
+package cn.tr.plugin.eventbus.mq.consumer;
+
+import cn.tr.plugin.eventbus.mq.message.EvenBusMessageEvent;
+import cn.tr.plugin.eventbus.mq.message.TopicPayload;
+import lombok.Getter;
+import org.springframework.context.event.EventListener;
+import reactor.core.publisher.Sinks;
+
+/**
+ * @ClassName : EvenBusConsumer
+ * @Description :
+ * @Author : LF
+ * @Date: 2023年05月11日
+ */
+public class EvenBusConsumer {
+    @Getter
+    private Sinks.Many<TopicPayload> msgSink = Sinks.many().unicast().onBackpressureBuffer();
+    @EventListener
+    public void evenBusListener(EvenBusMessageEvent evenBusMessageEvent){
+        TopicPayload payload = evenBusMessageEvent.getPayload();
+        msgSink.tryEmitNext(payload);
+    }
+}

+ 23 - 0
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/message/EvenBusMessageEvent.java

@@ -0,0 +1,23 @@
+package cn.tr.plugin.eventbus.mq.message;
+
+import lombok.Getter;
+import org.springframework.cloud.bus.event.RemoteApplicationEvent;
+
+/**
+ * @ClassName : EvenBusMessage
+ * @Description : 消息总线消息
+ * @Author : LF
+ * @Date: 2023年05月06日
+ */
+public class EvenBusMessageEvent extends RemoteApplicationEvent {
+    @Getter
+    private TopicPayload payload;
+
+    public EvenBusMessageEvent() {
+    }
+
+    public EvenBusMessageEvent(Object source, TopicPayload payload, String originService, String destinationService) {
+        super(source, originService, DEFAULT_DESTINATION_FACTORY.getDestination(destinationService));
+        this.payload=payload;
+    }
+}

+ 4 - 1
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/bean/TopicPayload.java → tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/message/TopicPayload.java

@@ -1,4 +1,4 @@
-package cn.tr.plugin.eventbus.bean;
+package cn.tr.plugin.eventbus.mq.message;
 
 import cn.hutool.core.util.IdUtil;
 import cn.tr.core.utils.JsonUtils;
@@ -19,6 +19,9 @@ public class TopicPayload implements Serializable {
     private long createTime;
     private String topic;
 
+    public TopicPayload() {
+    }
+
     public TopicPayload(Object payload, String topic) {
         this.id = IdUtil.getSnowflakeNextId();
         this.payload = JsonUtils.toJsonString(payload);

+ 27 - 0
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/mq/producer/EvenBusProducer.java

@@ -0,0 +1,27 @@
+package cn.tr.plugin.eventbus.mq.producer;
+
+import cn.tr.plugin.eventbus.mq.AbstractBusProducer;
+import cn.tr.plugin.eventbus.mq.message.EvenBusMessageEvent;
+import cn.tr.plugin.eventbus.mq.message.TopicPayload;
+import org.springframework.cloud.bus.ServiceMatcher;
+import org.springframework.context.ApplicationEventPublisher;
+
+/**
+ * @ClassName : EvenBusProducer
+ * @Description : 消息总线发布者
+ * @Author : LF
+ * @Date: 2023年04月25日
+ */
+public class EvenBusProducer extends AbstractBusProducer {
+
+    public EvenBusProducer(ApplicationEventPublisher applicationEventPublisher, ServiceMatcher serviceMatcher, String applicationName) {
+        super(applicationEventPublisher, serviceMatcher, applicationName);
+    }
+
+    /**
+     * 发送 {@link EvenBusMessageEvent} 消息
+     */
+    public void sendEvenBusMsg(TopicPayload topicPayload) {
+        publishEvent(new EvenBusMessageEvent(this,topicPayload, getBusId(), selfDestinationService()));
+    }
+}

+ 2 - 3
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/proxy/ProxyMessageListener.java

@@ -2,12 +2,11 @@ package cn.tr.plugin.eventbus.proxy;
 
 import cn.hutool.core.util.ModifierUtil;
 import cn.tr.core.utils.Proxy;
-import cn.tr.plugin.eventbus.bean.TopicPayload;
-import cn.tr.plugin.eventbus.urils.EventBusStrategy;
+import cn.tr.plugin.eventbus.mq.message.TopicPayload;
+import cn.tr.plugin.eventbus.utils.EventBusStrategy;
 import com.fasterxml.jackson.databind.ObjectReader;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.support.AopUtils;
-import org.springframework.util.SerializationUtils;
 
 import java.lang.reflect.Method;
 import java.util.*;

+ 1 - 8
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/urils/EventBusStrategy.java → tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/utils/EventBusStrategy.java

@@ -1,7 +1,6 @@
-package cn.tr.plugin.eventbus.urils;
+package cn.tr.plugin.eventbus.utils;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.redisson.api.RedissonClient;
 
 import java.util.function.Supplier;
 
@@ -15,15 +14,9 @@ import java.util.function.Supplier;
 public class EventBusStrategy {
     private EventBusStrategy() {
     }
-
-    public Supplier<RedissonClient> redissonClientSupplier=()->null;
     public Supplier<ObjectMapper> objectMapperSupplier=()->new ObjectMapper();
     public static EventBusStrategy tr =new EventBusStrategy();
 
-    public RedissonClient getRedissionClient(){
-        return redissonClientSupplier.get();
-    }
-
     public ObjectMapper getObjectMapper(){
         return objectMapperSupplier.get();
     }

+ 11 - 1
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/urils/TopicUtils.java → tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/java/cn/tr/plugin/eventbus/utils/TopicUtils.java

@@ -1,5 +1,6 @@
-package cn.tr.plugin.eventbus.urils;
+package cn.tr.plugin.eventbus.utils;
 
+import cn.hutool.core.util.StrUtil;
 import org.springframework.util.AntPathMatcher;
 import org.springframework.util.PathMatcher;
 
@@ -9,6 +10,15 @@ public class TopicUtils {
 
     private final static PathMatcher pathMatcher = new AntPathMatcher();
 
+    /**
+     * 判断主题是否为正则
+     * @param topic
+     * @return
+     */
+    public static boolean isRegex(String topic){
+        return StrUtil.contains(topic,"*");
+    }
+
     /**
      * 匹配topic
      *

+ 5 - 26
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/main/resources/application-unit-test.yml

@@ -5,29 +5,8 @@ spring:
     username: guest
     password: guest
     virtual-host: netpump
-    listener:
-      simple:
-        acknowledge-mode: none
-    #    publisher-confirms: true
-    publisher-returns: true
-  redis:
-    # 地址
-    host: 192.168.100.32
-    # 端口,默认为6379
-    port: 9736
-    # 数据库索引
-    database: 6
-    # 密码
-    password: 6E6985E1F7CB40F24A\.
-    # 连接超时时间
-    timeout: 30s
-    lettuce:
-      pool:
-        # 连接池中的最小空闲连接
-        min-idle: 16
-        # 连接池中的最大空闲连接
-        max-idle: 16
-        # 连接池的最大数据库连接数
-        max-active: 16
-        # #连接池最大阻塞等待时间(使用负值表示没有限制)
-        max-wait: -1ms
+  cloud:
+    bus:
+      enabled: true # 是否开启,默认为 true
+  application:
+    name: eventBus

+ 0 - 73
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/test/java/cn/tr/plugin/eventbus/RedissonTest.java

@@ -1,73 +0,0 @@
-package cn.tr.plugin.eventbus;
-
-import cn.tr.plugin.eventbus.bean.Subscription;
-import cn.tr.plugin.eventbus.config.core.AbstractEvenBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.core.LocalEventBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.core.ShareEventBusDataRichSourceFunction;
-import cn.tr.plugin.eventbus.config.redission.RedissionEventBus;
-import cn.tr.plugin.eventbus.config.redission.RedissionEventBusDataSourceEmitter;
-import cn.tr.plugin.eventbus.urils.EventBusStrategy;
-import cn.tr.plugin.test.ut.BaseRedisUnitTest;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.redisson.api.RedissonClient;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * @ClassName : RedissonTest
- * @Description :
- * @Author : LF
- * @Date: 2023年03月19日
- */
-@Slf4j
-public class RedissonTest extends BaseRedisUnitTest {
-    @Autowired
-    private RedissonClient redissonClient;
-    private RedissionEventBus eventBus;
-    private StreamExecutionEnvironment ec=StreamExecutionEnvironment.getExecutionEnvironment();
-
-    @BeforeEach
-    public void setIp() throws Exception {
-        EventBusStrategy.tr.objectMapperSupplier=()->new ObjectMapper();
-        EventBusStrategy.tr.redissonClientSupplier=()->redissonClient;
-        List<AbstractEvenBusDataRichSourceFunction> sources = Arrays.asList(new LocalEventBusDataRichSourceFunction(), new ShareEventBusDataRichSourceFunction());
-        RedissionEventBusDataSourceEmitter emitter = new RedissionEventBusDataSourceEmitter(sources);
-        emitter.emitter();
-        eventBus=new RedissionEventBus(redissonClient,ec, sources);
-
-
-
-    }
-    @Test
-    public void pubAndSubJustOne() throws InterruptedException {
-        AtomicInteger atomicInteger=new AtomicInteger(0);
-
-        eventBus.subscribe(Subscription.builder().topics("topic*","tes123").local().build(), msg->{
-            log.error(">>>>>>>>>>>>>>第次接收到消息:"+msg+"<<<<<<<<<<<<<<<<<<<<");
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-            atomicInteger.incrementAndGet();
-        });
-
-        Thread.sleep(1000);
-        for (int i = 0; i < 10; i++) {
-            for (int j = 0; j < 10; j++) {
-                eventBus.publish("topic"+i,"主题topic:"+i+",内容:"+j);
-            }
-        }
-        while (true){
-
-        }
-    }
-}

+ 8 - 6
tr-plugins/tr-spring-boot-starter-plugin-eventbus/src/test/java/cn/tr/plugin/eventbus/SpringBootSubPubTest.java

@@ -1,12 +1,10 @@
 package cn.tr.plugin.eventbus;
 
+import cn.tr.plugin.EvenBusApplication;
 import cn.tr.plugin.eventbus.annotation.Subscribe;
-import cn.tr.plugin.eventbus.bean.TopicPayload;
+import cn.tr.plugin.eventbus.mq.message.TopicPayload;
 import cn.tr.plugin.eventbus.config.EventBus;
 import cn.tr.plugin.eventbus.config.SubscribeListenerAnnotationBeanPostProcessor;
-import cn.tr.plugin.flink.TrFlinkAutoConfiguration;
-import cn.tr.plugin.test.ut.BaseRedisUnitTest;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -14,7 +12,9 @@ import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ActiveProfiles;
 
 import java.io.Serializable;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -25,8 +25,10 @@ import java.util.concurrent.atomic.AtomicInteger;
  * @Author : LF
  * @Date: 2023年03月19日
  */
-@Import({TrEventBusAutoConfiguration.class,TrEventBusAutoConfiguration.RedissionEventBusAutoConfiguration.class, TrFlinkAutoConfiguration.class, SpringBootSubPubTest.Sub.class, ObjectMapper.class})
-public class SpringBootSubPubTest extends BaseRedisUnitTest {
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = EvenBusApplication.class)
+@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
+@Import({ SpringBootSubPubTest.Sub.class})
+public class SpringBootSubPubTest  {
 
     @Autowired
     private EventBus eventBus;

+ 6 - 0
tr-plugins/tr-spring-boot-starter-plugin-file/pom.xml

@@ -22,6 +22,12 @@
             <artifactId>tr-framework</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
         <dependency>
             <groupId>cn.tr</groupId>
             <artifactId>tr-spring-boot-starter-plugin-test</artifactId>

+ 1 - 1
tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/AbstractFileClient.java

@@ -52,7 +52,7 @@ public abstract class AbstractFileClient<Config extends FileClientConfig> implem
      * @return
      */
     public String parseBizPath(String bizPath){
-        return bizPath.replaceAll("\\\\","#").replaceAll("/","-");
+        return bizPath;
     }
 }
 

+ 4 - 2
tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/FileClientConfig.java

@@ -1,5 +1,7 @@
 package cn.tr.plugin.file.config;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
 /**
@@ -8,7 +10,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
  * @Author : LF
  * @Date: 2023年03月07日
  */
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,property = "@Clazz")
 public interface FileClientConfig{
-
 }

+ 5 - 5
tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/ali/AliFileClientConfig.java

@@ -3,7 +3,7 @@ package cn.tr.plugin.file.config.ali;
 import cn.tr.plugin.file.config.FileClientConfig;
 import lombok.Data;
 
-import javax.validation.constraints.NotNull;
+import javax.validation.constraints.NotBlank;
 
 /**
  * @ClassName : AliFileClientConfig
@@ -16,25 +16,25 @@ public class AliFileClientConfig implements FileClientConfig {
     /**
      * accessKey
      */
-    @NotNull(message = "accessKey不能为空")
+    @NotBlank(message = "accessKey不能为空")
     private String accessKey;
 
     /**
      * accessSecret
      */
-    @NotNull(message = "accessSecret不能为空")
+    @NotBlank(message = "accessSecret不能为空")
     private String accessSecret;
 
     /**
      * 地域节点
      */
-    @NotNull(message = "地域节点不能为空")
+    @NotBlank(message = "地域节点不能为空")
     private String endpoint;
 
     /**
      * 桶名
      */
-    @NotNull(message = "桶名不能为空")
+    @NotBlank(message = "桶名称不能为空")
     private String bucketName;
 
 }

+ 5 - 4
tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/db/DbFileClient.java

@@ -1,5 +1,6 @@
 package cn.tr.plugin.file.config.db;
 
+import cn.hutool.extra.spring.SpringUtil;
 import cn.tr.core.utils.MediaTypeUtils;
 import cn.tr.plugin.file.config.AbstractFileClient;
 import cn.tr.plugin.file.config.FileContent;
@@ -16,9 +17,9 @@ import java.io.IOException;
 @Slf4j
 public class DbFileClient extends AbstractFileClient<DbFileClientConfig> {
     private final DbClientDAO clientDAO;
-    public DbFileClient(String id, DbFileClientConfig config,DbClientDAO clientDAO) {
+    public DbFileClient(String id, DbFileClientConfig config) {
         super(id, config);
-        this.clientDAO=clientDAO;
+        this.clientDAO= SpringUtil.getBean(DbClientDAO.class);
     }
 
     @Override
@@ -26,6 +27,7 @@ public class DbFileClient extends AbstractFileClient<DbFileClientConfig> {
         if (!config.getDomain().endsWith("/")) {
             config.setDomain(config.getDomain() + "/");
         }
+        config.setDomain(config.getDomain()+getId()+"/");
     }
 
     @Override
@@ -48,11 +50,10 @@ public class DbFileClient extends AbstractFileClient<DbFileClientConfig> {
         return FileContent.of(clientDAO.getContent(getId(),bizPath),MediaTypeUtils.parseContentType(bizPath));
     }
 
-    //todo
     @Override
     public String previewUrl(String bizPath) throws Exception {
         bizPath=parseBizPath(bizPath);
-        return null;
+        return  getConfig().getDomain()+bizPath;
     }
 
 

+ 4 - 2
tr-plugins/tr-spring-boot-starter-plugin-file/src/main/java/cn/tr/plugin/file/config/local/LocalFileClient.java

@@ -2,10 +2,12 @@ package cn.tr.plugin.file.config.local;
 
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.IoUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import cn.tr.core.utils.MediaTypeUtils;
 import cn.tr.plugin.file.config.AbstractFileClient;
 import cn.tr.plugin.file.config.FileContent;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
 
 import java.io.*;
 
@@ -68,13 +70,13 @@ public class LocalFileClient extends AbstractFileClient<LocalFileClientConfig> {
     @Override
     public String downUrl(String bizPath) {
         bizPath=parseBizPath(bizPath);
-        return getConfig().getDomain()+getId()+"/"+bizPath;
+        return getConfig().getDomain()+bizPath;
     }
 
     @Override
     public String previewUrl(String bizPath) {
         bizPath=parseBizPath(bizPath);
-        return  getConfig().getDomain()+getId()+"/"+bizPath;
+        return  getConfig().getDomain()+bizPath;
     }
 
     /**

+ 1 - 0
tr-plugins/tr-spring-boot-starter-plugin-file/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+cn.tr.plugin.file.config.LocalFileClientFactory

+ 7 - 5
tr-plugins/tr-spring-boot-starter-plugin-file/src/test/java/cn/tr/plugin/file/config/FileClientTest.java

@@ -37,7 +37,7 @@ public class FileClientTest extends BaseMockitoUnitTest {
 
     private byte[] content="text".getBytes();
     private String bizPath="file"+ File.separator+"/0d9768d743faf52558fa9451b853482.jpg";
-//    private String bizPath="ac785a4c5d1de17cc2e1b32b988bc00.png";
+//    private String bizName="ac785a4c5d1de17cc2e1b32b988bc00.png";
 
     @BeforeEach
     public void setUp() throws FileNotFoundException {
@@ -71,8 +71,9 @@ public class FileClientTest extends BaseMockitoUnitTest {
         String s = JsonUtils.toJsonString(clientConfig);
 
         fileClient=new LocalFileClient("local",(LocalFileClientConfig)clientConfig);
-        ((LocalFileClient) fileClient).init();
-        test();
+//        ((LocalFileClient) fileClient).init();
+        System.out.println(JsonUtils.toJsonString(clientConfig));
+//        test();
     }
 
     @Test
@@ -83,8 +84,9 @@ public class FileClientTest extends BaseMockitoUnitTest {
         ((MinIoFileClientConfig)clientConfig).setAccessSecret("tuoren123");
         ((MinIoFileClientConfig)clientConfig).setBucketName("local-test");
         fileClient=new MinIoFileClient("local",(MinIoFileClientConfig)clientConfig);
-        ((MinIoFileClient) fileClient).init();
-        test();
+        System.out.println(JsonUtils.toJsonString(clientConfig));
+//        ((MinIoFileClient) fileClient).init();
+//        test();
 
     }
 

+ 1 - 0
tr-plugins/tr-spring-boot-starter-plugin-numbering-strategy/pom.xml

@@ -27,6 +27,7 @@
         <dependency>
             <groupId>cn.tr</groupId>
             <artifactId>tr-spring-boot-starter-plugin-test</artifactId>
+            <scope>provided</scope>
         </dependency>
 
         <dependency>

+ 6 - 0
tr-plugins/tr-spring-boot-starter-plugin-test/pom.xml

@@ -28,6 +28,12 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                    <groupId>org.springframework.boot</groupId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <dependency>

+ 1 - 1
tr-plugins/tr-spring-boot-starter-plugin-test/src/main/java/cn/tr/plugin/test/ut/BaseRabbitMqUnitTest.java

@@ -15,7 +15,7 @@ import org.springframework.test.context.ActiveProfiles;
 @ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
 public class BaseRabbitMqUnitTest {
     @Import({
-            RabbitAutoConfiguration.class, // Spring Redis 自动配置类
+            RabbitAutoConfiguration.class, // Spring rabbitmq 自动配置类
     })
     public static class Application {
     }

+ 0 - 2
tr-plugins/tr-spring-boot-starter-plugin-test/src/main/java/cn/tr/plugin/test/ut/BaseRedisUnitTest.java

@@ -22,10 +22,8 @@ public class BaseRedisUnitTest {
             // Redis 配置类
 //            RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
             RedisAutoConfiguration.class, // Spring Redis 自动配置类
-//            YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
             RedissonAutoConfiguration.class, // Redisson 自动高配置类
     })
     public static class Application {
     }
-
 }

+ 3 - 0
tr-test/src/main/resources/application.yml

@@ -35,6 +35,7 @@ tr:
   satoken:
     enable: true
     ignore-urls:
+      - /error
       - /actuator/**
       - /druid/**
       - /*.html
@@ -45,6 +46,7 @@ tr:
       - /v2/api-docs
       - /webjars/**
       - /oauth2/psw/**
+      - /download/file/**
   tenant:
     ignore-tables:
       - gen_config
@@ -71,6 +73,7 @@ tr:
       - sys_job_log
 #      存储模块
       - sys_storage_config
+      - sys_storage_file
     ignore-urls:
       - /oauth2/psw/token
 sa-token: