fanxp 1 år sedan
incheckning
7aa76824ec
100 ändrade filer med 6528 tillägg och 0 borttagningar
  1. 72 0
      .drone.yml
  2. 38 0
      .gitignore
  3. 8 0
      Dockerfile
  4. 16 0
      Makefile
  5. 113 0
      README.md
  6. 16 0
      docker-build/Dockerfile
  7. 146 0
      docker-build/conf/application-dev.yml
  8. 23 0
      docker-compose.yml
  9. 556 0
      pom.xml
  10. 19 0
      src/main/java/com/xjrsoft/XjrSoftApplication.java
  11. 308 0
      src/main/java/com/xjrsoft/common/advice/TransResponseBodyAdvice.java
  12. 364 0
      src/main/java/com/xjrsoft/common/advice/WorkflowResponseBodyAdvice.java
  13. 13 0
      src/main/java/com/xjrsoft/common/annotation/DataPermission.java
  14. 32 0
      src/main/java/com/xjrsoft/common/annotation/Limit.java
  15. 47 0
      src/main/java/com/xjrsoft/common/annotation/Trans.java
  16. 12 0
      src/main/java/com/xjrsoft/common/annotation/UniqueNameGenerator.java
  17. 20 0
      src/main/java/com/xjrsoft/common/annotation/XjrLog.java
  18. 96 0
      src/main/java/com/xjrsoft/common/aspect/LimitAspect.java
  19. 123 0
      src/main/java/com/xjrsoft/common/aspect/XjrLogAspect.java
  20. 28 0
      src/main/java/com/xjrsoft/common/constant/FormComponentConstant.java
  21. 492 0
      src/main/java/com/xjrsoft/common/constant/GlobalConstant.java
  22. 40 0
      src/main/java/com/xjrsoft/common/enums/AuthorizeType.java
  23. 48 0
      src/main/java/com/xjrsoft/common/enums/CloudType.java
  24. 48 0
      src/main/java/com/xjrsoft/common/enums/CodeRuleTypeEnum.java
  25. 41 0
      src/main/java/com/xjrsoft/common/enums/DataAuthFieldTypeEnum.java
  26. 35 0
      src/main/java/com/xjrsoft/common/enums/DataAuthMethodEnum.java
  27. 43 0
      src/main/java/com/xjrsoft/common/enums/DataAuthScopeEnum.java
  28. 34 0
      src/main/java/com/xjrsoft/common/enums/DataAuthTypeEnum.java
  29. 80 0
      src/main/java/com/xjrsoft/common/enums/DbFieldsType.java
  30. 32 0
      src/main/java/com/xjrsoft/common/enums/DeleteMark.java
  31. 32 0
      src/main/java/com/xjrsoft/common/enums/EnabledMark.java
  32. 33 0
      src/main/java/com/xjrsoft/common/enums/FormTemplateType.java
  33. 31 0
      src/main/java/com/xjrsoft/common/enums/IsReadTypeEnum.java
  34. 44 0
      src/main/java/com/xjrsoft/common/enums/LogCategory.java
  35. 32 0
      src/main/java/com/xjrsoft/common/enums/LogCategoryEnum.java
  36. 33 0
      src/main/java/com/xjrsoft/common/enums/MenuType.java
  37. 43 0
      src/main/java/com/xjrsoft/common/enums/MessageType.java
  38. 80 0
      src/main/java/com/xjrsoft/common/enums/MySqlFieldsType.java
  39. 80 0
      src/main/java/com/xjrsoft/common/enums/OracleFieldsType.java
  40. 40 0
      src/main/java/com/xjrsoft/common/enums/ParamAssignmentType.java
  41. 80 0
      src/main/java/com/xjrsoft/common/enums/PostgreSqlFieldsType.java
  42. 36 0
      src/main/java/com/xjrsoft/common/enums/PublishStateType.java
  43. 77 0
      src/main/java/com/xjrsoft/common/enums/ResponseCode.java
  44. 65 0
      src/main/java/com/xjrsoft/common/enums/SmsCloudType.java
  45. 43 0
      src/main/java/com/xjrsoft/common/enums/SmsType.java
  46. 80 0
      src/main/java/com/xjrsoft/common/enums/SqlServerFieldsType.java
  47. 33 0
      src/main/java/com/xjrsoft/common/enums/StampEnum.java
  48. 60 0
      src/main/java/com/xjrsoft/common/enums/TransType.java
  49. 37 0
      src/main/java/com/xjrsoft/common/enums/TsColumnType.java
  50. 48 0
      src/main/java/com/xjrsoft/common/enums/WorkflowApproveType.java
  51. 33 0
      src/main/java/com/xjrsoft/common/enums/WorkflowAuth.java
  52. 42 0
      src/main/java/com/xjrsoft/common/enums/WorkflowAutoAgreeType.java
  53. 35 0
      src/main/java/com/xjrsoft/common/enums/WorkflowCallActivityType.java
  54. 34 0
      src/main/java/com/xjrsoft/common/enums/WorkflowEventExType.java
  55. 34 0
      src/main/java/com/xjrsoft/common/enums/WorkflowEventType.java
  56. 33 0
      src/main/java/com/xjrsoft/common/enums/WorkflowIsPrevChooseNextType.java
  57. 35 0
      src/main/java/com/xjrsoft/common/enums/WorkflowIsRecycleType.java
  58. 64 0
      src/main/java/com/xjrsoft/common/enums/WorkflowMemberType.java
  59. 36 0
      src/main/java/com/xjrsoft/common/enums/WorkflowMultiInstanceFinishType.java
  60. 37 0
      src/main/java/com/xjrsoft/common/enums/WorkflowMultiInstanceType.java
  61. 33 0
      src/main/java/com/xjrsoft/common/enums/WorkflowNoHandlerType.java
  62. 47 0
      src/main/java/com/xjrsoft/common/enums/WorkflowNoticePolicyType.java
  63. 33 0
      src/main/java/com/xjrsoft/common/enums/WorkflowOperationType.java
  64. 38 0
      src/main/java/com/xjrsoft/common/enums/WorkflowParamType.java
  65. 32 0
      src/main/java/com/xjrsoft/common/enums/WorkflowRelationAuthType.java
  66. 33 0
      src/main/java/com/xjrsoft/common/enums/YesOrNoEnum.java
  67. 86 0
      src/main/java/com/xjrsoft/common/exception/GlobalExceptionHandler.java
  68. 55 0
      src/main/java/com/xjrsoft/common/exception/MyException.java
  69. 66 0
      src/main/java/com/xjrsoft/common/factory/AliyunCloudStorageService.java
  70. 74 0
      src/main/java/com/xjrsoft/common/factory/CloudStorageService.java
  71. 64 0
      src/main/java/com/xjrsoft/common/factory/HwCloudStorageService.java
  72. 72 0
      src/main/java/com/xjrsoft/common/factory/MinioService.java
  73. 39 0
      src/main/java/com/xjrsoft/common/factory/OssFactory.java
  74. 96 0
      src/main/java/com/xjrsoft/common/factory/QcloudCloudStorageService.java
  75. 74 0
      src/main/java/com/xjrsoft/common/factory/QiniuCloudStorageService.java
  76. 32 0
      src/main/java/com/xjrsoft/common/handler/ClobTypeHandler.java
  77. 47 0
      src/main/java/com/xjrsoft/common/handler/EasyExcelLocalDateTimeConverter.java
  78. 35 0
      src/main/java/com/xjrsoft/common/handler/FormContentStyleStrategy.java
  79. 32 0
      src/main/java/com/xjrsoft/common/handler/MyBlobTypeHandler.java
  80. 39 0
      src/main/java/com/xjrsoft/common/handler/MyClobTypeHandler.java
  81. 55 0
      src/main/java/com/xjrsoft/common/handler/MyDataPermissionHandler.java
  82. 46 0
      src/main/java/com/xjrsoft/common/handler/MyLocalDateTimeTypeHandler.java
  83. 73 0
      src/main/java/com/xjrsoft/common/handler/MyMetaObjectHandler.java
  84. 39 0
      src/main/java/com/xjrsoft/common/handler/MyNVarCharTypeHandler.java
  85. 125 0
      src/main/java/com/xjrsoft/common/interceptor/DataScopeInnerInterceptor.java
  86. 67 0
      src/main/java/com/xjrsoft/common/interceptor/MagicApiRequestInterceptor.java
  87. 59 0
      src/main/java/com/xjrsoft/common/interceptor/MagicApiWebLoginInterceptor.java
  88. 43 0
      src/main/java/com/xjrsoft/common/license/LicenseTask.java
  89. 36 0
      src/main/java/com/xjrsoft/common/model/base/AuditEntity.java
  90. 65 0
      src/main/java/com/xjrsoft/common/model/datasource/MyColumnInfo.java
  91. 20 0
      src/main/java/com/xjrsoft/common/model/datasource/MyTableInfo.java
  92. 84 0
      src/main/java/com/xjrsoft/common/model/generator/ComponentConfig.java
  93. 82 0
      src/main/java/com/xjrsoft/common/model/generator/ComponentOptionConfig.java
  94. 47 0
      src/main/java/com/xjrsoft/common/model/generator/FormAttrConfig.java
  95. 29 0
      src/main/java/com/xjrsoft/common/model/generator/FormConfig.java
  96. 17 0
      src/main/java/com/xjrsoft/common/model/generator/LayoutOptionModel.java
  97. 85 0
      src/main/java/com/xjrsoft/common/model/result/R.java
  98. 38 0
      src/main/java/com/xjrsoft/common/model/tree/ITreeNode.java
  99. 118 0
      src/main/java/com/xjrsoft/common/mqtt/EmqClient.java
  100. 40 0
      src/main/java/com/xjrsoft/common/mqtt/MqttServiceLocator.java

+ 72 - 0
.drone.yml

@@ -0,0 +1,72 @@
+kind: pipeline
+type: docker
+name: dev
+
+node:
+  mode: test
+
+steps:
+  - name: build
+    image: docker:20.10.7
+    volumes:
+      - name: docker
+        path: /var/run/docker.sock
+    environment:
+      IMAGE: registry.yingcaibx.com/tl/api:latest
+    commands:
+      # 清理 docker 服务中不再使用的镜像、挂载、网络等资源
+      - docker system prune --force --volumes || true
+      - docker build -f ./docker-build/Dockerfile -t $IMAGE ./
+
+  - name: run
+    image: docker/compose
+    depends_on: [build]
+    volumes:
+      - name: docker
+        path: /var/run/docker.sock
+    commands:
+      - docker-compose -f docker-compose.yml up -d
+
+trigger:
+  branch:
+    - dev
+  event:
+    - push
+
+volumes:
+  - name: docker
+    host:
+      path: /var/run/docker.sock
+
+---
+kind: pipeline
+type: docker
+name: release
+
+node:
+  mode: test
+
+steps:
+  - name: push
+    image: docker:20.10.7
+    volumes:
+      - name: docker
+        path: /var/run/docker.sock
+    environment:
+      IMAGE: registry.yingcaibx.com/tl/api
+    depends_on: [clone]
+    commands:
+      - docker login -u yxt -p qwe123QWE registry.yingcaibx.com
+      - echo $DRONE_TAG
+      - docker build -f ./app/platform/Dockerfile -t $IMAGE:$DRONE_TAG ./
+      - docker push $IMAGE:$DRONE_TAG
+      - docker rmi $IMAGE:$DRONE_TAG
+
+trigger:
+  event:
+    - tag
+
+volumes:
+  - name: docker
+    host:
+      path: /var/run/docker.sock

+ 38 - 0
.gitignore

@@ -0,0 +1,38 @@
+HELP.md
+target/
+logs/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+.DS_Store
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+/src/main/java/com/xjrsoft/module/jinayi
+/src/main/java/com/xjrsoft/module/dev
+/logs/

+ 8 - 0
Dockerfile

@@ -0,0 +1,8 @@
+FROM openjdk:11-jre
+EXPOSE 8080
+# 设置容器时间
+ENV TZ=Asia/Shanghai
+RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+ADD target/xjrsoft-boot.jar  /app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]

+ 16 - 0
Makefile

@@ -0,0 +1,16 @@
+merge:
+	git checkout master;git merge dev;git push;git checkout dev;
+
+create-tag:
+	git checkout master;git tag v1.0.0;git push origin --tags;git checkout dev;
+
+remove-tag:
+	git tag -d v1.0.0;git push origin :refs/tags/v1.0.0;
+
+gen-rsaprivatekey:
+	openssl genrsa -out rsaprivatekey.pem 1024
+
+gen-rsapublickey:
+	openssl rsa -in rsaprivatekey.pem -out rsapublickey.pem -pubout
+
+.PHONY: merge create-tag

+ 113 - 0
README.md

@@ -0,0 +1,113 @@
+**项目说明** 
+
+- xjrsoft-boot是一个轻量级的,前后端分离的Java快速开发平台,能快速开发项目并交付
+- 支持MySQL、Oracle、SQL Server、PostgreSQL等主流数据库
+
+**具有如下特点** 
+
+- 友好的代码结构及注释,便于阅读及二次开发
+- 实现前后端分离,通过token进行数据交互,前端再也不用关注后端技术
+- 灵活的权限控制,可控制到菜单、列表、按钮、表单,满足绝大部分的权限需求
+- 配套前端框架使用Vue3.x,最新的技术,最好的性能、极大的提高了开发效率
+- 引入power-job定时任务,可动态完成任务的添加、修改、删除、暂停、恢复及日志查看等功能
+- 引入Hibernate Validator校验框架,轻松实现后端校验
+- 引入云存储服务,已支持:七牛云、阿里云、腾讯云、华为云、minio等
+- 引入knife4J文档支持,方便编写API接口文档
+- 引入sms4j支持,支持多种短信平台
+- 引入ureport报表支持
+- 引入liteflow框架 开发规则引擎功能
+- 引入magic-api 封装 实现在线开发接口
+- 引入hutool包 作为工具类 
+- 接入chatgpt,只需要配置中填写相应key 即可使用chatgpt赋能
+- 使用mybatisplusjoin 增强mybatisplus 实现多表联查功能
+- 使用satoken 作为权限框架 功能强大 好用
+- 完善的代码生成器,可以自动生成各种各样的代码,包括:DTO、VO、Service、Controller、Mapper、JavaBean、Swagger等
+- 支持一键发布docker镜像,方便快速部署
+- 完善的xss防御 sql注入防御 黑白名单 接口限流。
+- 使用camunda工作流引擎 为基础 实现符合中国的流程使用功能。
+- 项目中除了个别业务逻辑需要,使用ORM完全实现零SQL编程。可以无需再编写XML文件,更好的适配所有的数据库.
+
+**项目结构** 
+
+```
+xjrsoft-boot
+├─common 公共模块
+│  ├─annotation 常用注解
+│  ├─aspect 系统日志
+│  ├─exception 异常处理
+│  ├─enums 后台枚举
+│  ├─constant 后台常量
+│  ├─handler 处理器
+│  ├─model 常用数据模型
+│  │   ├─base 实体类父类
+│  │   ├─datasrouce 数据源有关模型封装
+│  │   ├─generator 代码生成器有关模型封装
+│  │   ├─result 返回值封装
+│  │   └─tree 树结构模型封装
+│  ├─page 分页工具类
+│  ├─satoken 权限框架注解鉴权实现类
+│  ├─tree 树结构接口  --用于限定数据结构
+│  ├─utils 各种工具类
+│  └─xss XSS过滤
+│ 
+├─config 配置信息
+│ 
+├─modules 功能模块
+│  ├─bi 数据大屏模块
+│  ├─generator 代码生成器模块
+│  ├─oss 文件服务模块
+│  ├─organization 组织架构模块
+│  ├─form 自定义表单模块
+│  ├─report 报表模块
+│  └─system 系统管理模块
+│ 
+├─XjrsoftApplication 项目启动类
+│  
+├──resources 
+│  ├─mapper SQL对应的XML文件 
+│  │─template freemark模板文件
+│  │─banner 启动banner图 
+│  └─logback 日志配置文件
+
+```
+
+<br/>
+
+**技术选型:** 
+
+- 项目 [jdk](https://www.oracle.com/java/technologies/downloads/)  采用  11 版本
+- 开发框架 采用 [springboot ](https://spring.io/projects/spring-boot)版本 2.7.5 +
+- ORM框架 采用 [mybatis-plus](https://baomidou.com/) 版本 3.5.2+
+- ORM动态数据源 采用 [dynamic-datasource](https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611) 版本 3.5.1
+- ORM多表联查工具类 采用 [mybatis-plus-join](https://https://gitee.com/best_handsome/mybatis-plus-join/wikis/%E5%AE%89%E8%A3%85) 版本 1.2.2+
+- ORM动态数据源 采用 [mybatis-plus-dynamic-datasource](https://gitee.com/baomidou/dynamic-datasource-spring-boot-starter) 版本 3.5.1
+- 数据库连接池框架采用 [druid](https://github.com/alibaba/druid) 版本 1.1.22+
+- 接口文档框架采用 [knife4j](https://doc.xiaominfo.com/) 版本 2.0.7+
+- json格式化工具 采用 [fastjson](https://github.com/alibaba/fastjson/wiki/Quick-Start-CN)等 版本 1.2.72+
+- 代码模板框架 采用 [Freemark](http://freemarker.foofun.cn/) 版本 2.3.30+
+- 权限框架采用 [sa-token](https://sa-token.dev33.cn/) 版本 1.29.0+
+- 常用工具类库 采用 [hutool](https://www.hutool.cn/) 版本5.7.20+
+- 注解验证 [hibernate-validator](https://hibernate.org/validator/) 版本 6.0.13.Final
+- 分布式定时任务框架 采用 [power-job](http://www.powerjob.tech/) 版本 4.3.2
+- 工作流引擎 采用 [camunda](https://camunda.com/) 版本 7.18.0
+- 在线接口 采用 [magic-api](https://www.ssssssss.org/magic-api/) 版本 2.1.1
+- 短信工具类库 采用 [sms4j](https://wind.kim/) 版本 2.1.0
+- java动态类库 采用 [javassist](http://www.javassist.org/) 版本 3.29.2-GA
+- 规则引擎 采用 [liteflow](https://liteflow.yomahub.com/) 版本 2.10.1
+- excel工具类库 采用 [easyexcel](https://github.com/alibaba/easyexcel) 版本 3.1.4
+- 云存储 适配 平台([minio](http://www.minio.org.cn/),阿里云,腾讯云,华为云,七牛云)
+
+**注意事项:**
+- idea 必须安装lombok插件使用
+- 开发或者部署 需要在application.yml 设置相应的 yml
+- idea 直接使用 dockerfile 打包上传到镜像 需要配置docker  docker所在服务器也需要打开2375端口
+- pom 里面docker-plugin 插件 用途在于 执行打包命令 会直接上传到docker  也需要打开2375端口
+- 代码生成器 如果想要拥有审计字段(create_user_id 等字段)自动填充功能 表结构必须要符合框架的约定 比需要拥有这些字段(create_user_id | create_date | modyfy_user_id | modify_date | delete_mark | enabled_mark)
+- 框架默认使用jdk11 您也可以自己修改为jdk8  原则上jdk版本 最低jdk8 上不封顶  。
+- 如果哪些接口您需要记录日志,请自行在控制器 controller 的方法上 添加 XjrLog注解 参数填写接口描述即可
+- 如果您需要放行某些接口 /src/main/java/com/xjrsoft/config/SaTokenConfig.java 文件 对应新增
+- 非数据优先的代码生成器功能  用户所配置的表结构 表名  字段名 如果配置的为大小写混用 默认会改为 蛇形命名法 而且默认全小写 (oracle  dm 等数据库默认全大写的除外)
+- 代码生成器-数据优先 模板  如果 子表的外键 关联 父表的非主键字段  级联删除会失效。 如果需要级联删除 请默认子表外键 关联 父表的主键
+- 如果需要使用定时任务 请根据 power-job 官网文档部署服务端  再来使用。 定时任务新增或者修改数据 将不会自动填充 审计字段
+- 前端想要内嵌其他url  需要把外链地址填写到组件地址栏
+- 工作流模块中 审批人、传阅人 数量不能超过21人

+ 16 - 0
docker-build/Dockerfile

@@ -0,0 +1,16 @@
+#FROM openjdk:11-jre
+#EXPOSE 8080
+#WORKDIR /app
+#COPY ./docker-build/xjrsoft-boot.jar /app/app.jar
+#COPY ./docker-build/conf/application-dev.yml  conf/application-dev.yml
+#ENTRYPOINT ["java","-jar","/app/app.jar"]
+#
+FROM maven:3.5.2-jdk-11-alpine AS MAVEN_BUILD
+COPY pom.xml /build/
+COPY src /build/src/
+WORKDIR /build/
+RUN mvn package
+FROM openjdk:11-jre-alpine
+WORKDIR /app
+COPY --from=MAVEN_BUILD /build/target/xjrsoft-boot.jar /app/app.jar
+ENTRYPOINT ["java", "-jar", "app.jar"]

+ 146 - 0
docker-build/conf/application-dev.yml

@@ -0,0 +1,146 @@
+spring:
+  autoconfigure:
+    #自动化配置 例外处理
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    dynamic:
+      primary: master
+      datasource:
+        master:
+          driver-class-name: com.mysql.cj.jdbc.Driver
+          url: jdbc:mysql://8.142.26.206:3306/xyc2023?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
+          username: root
+          password: Zwr~-f6H,u6QE^]C-AD_
+
+
+  redis:
+    database: 9
+    host: 8.142.26.206
+    port: 6379
+    password:    # 密码(默认为空)
+    timeout: 6000ms  # 连接超时时长(毫秒)
+    jedis:
+      pool:
+        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+        max-wait: -1ms      # 连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-idle: 10      # 连接池中的最大空闲连接
+        min-idle: 5       # 连接池中的最小空闲连接
+
+logging:
+  level:
+    org.camunda: debug #打印camunda 日志  一般用于 查看camunda  执行sql
+
+
+
+xjrsoft:
+  oss:
+    #enabled: true
+    cloud-type: minio
+    #    access-key: xjrsoft
+    #    secret-key: Xjrsoft9012@@
+    #    endpoint: http://47.106.153.7:9000
+    #    bucket-name: xjrsoft
+    #    prefix: xjr
+    #阿里云
+    access-key: ycbx
+    secret-key: qwe123QWE
+    endpoint: https://test.minio.yingcaibx.com
+    bucket-name: learun
+    prefix: xjr
+  generate:
+    webPath: E:\code\font\xjrsoft-vue3 #生成代码的路径
+    appPath: E:\code\uniapp\xjrsoft-uni   #前端app
+  common:
+    druid-account: admin # druid 监控账户
+    druid-password: admin # druid 监控密码
+    default-password: "000000" #默认密码(用户重置密码后为该密码)
+    white-list:
+      - 192.168.0.139
+    exclude-urls:
+      - /favicon.ico  #网站图标
+      - /webjars/**   #swagger(knife4j)  接口文档必要资源
+      - /swagger-resources/** #swagger(knife4j) 接口文档必要资源
+      - /v2/api-docs           #swagger(knife4j)  接口文档必要资源
+      - /doc.html              #swagger(knife4j) 接口文档必要资源
+      - /druid/**         #druid 监控
+      - /ureport/**
+      - /system/captcha    # 验证码
+      - /system/login      # 登录接口
+      - /system/logout     # 登出接口
+      - /camunda/**        # camunda工作台
+      - /language/**        # language
+      - /${magic-api.web}/**    # magic-api web
+      - /${magic-api.prefix}/** # magic-api 前缀
+      - /bi/project/info # 桌面
+  email:
+    host:  #邮件服务器的SMTP地址,可选,默认为smtp.<发件人邮箱后缀>
+    port:  # 邮件服务器的SMTP端口,可选,默认25
+    auth: true
+    from:  # 发件人(必须正确,否则发送失败
+    user: # 用户名,默认为发件人邮箱前缀
+    pass:       # 密码(注意,某些邮箱需要为SMTP服务单独设置授权码,详情查看相关帮助
+  enterpriseWeChat:
+    corpid: ww00ce9acc4f193f18
+    secret: 02YXuJw_vYYJiDQvG-eKlXCUTDAaAJ1z7m9t8_hqoa0
+    secret1: z3R17Od4ROW1zPisguiQmTfx0NvcYKmoIu19-82vdtU
+    agentid: 1000003
+  dingtalk:
+    appKey: dingaex2gok1rllumlqs
+    appSecret: Nv2pe-UoR0Z_Iw8d29laZfL3kH6ElmhZpRdPwI7SvmKJmaCI29qCrSlFEiMM88MB
+  ureport:
+    account: xjrsoft
+    password: 123456
+  keycloak:
+    url: http://192.168.0.221:12829/auth/
+    realm: test
+    client-id: tzx-java
+    secret: yo5kPZlHgmodz4vVASH61zq8i6gMhkk2
+    user-name: tzx  #如果不需要后端再次 可以不需要
+    password: "000000" #可以不需要
+    payload: code #从payload 某个key中取值 登录
+  chatgpt:
+    proxy-type: 0 # 不开启代理 == -1 http == 0   socket == 1
+    proxy: 192.168.0.220
+    port: 1081
+    api-key: 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   #your api-key. It can be generated in the link https://beta.openai.com/docs/quickstart/adjust-your-settings
+    # some properties as below have default values. Of course, you can change them.
+    max-tokens: 4000           # The maximum number of tokens to generate in the completion.The token count of your prompt plus max_tokens cannot exceed the model's context length. Most models have a context length of 2048 tokens (except for the newest models, which support 4096).
+  #  model: text-davinci-003   # GPT-3 models can understand and generate natural language. We offer four main models with different levels of power suitable for different tasks. Davinci is the most capable model, and Ada is the fastest.
+  #  temperature: 0.0          # What sampling temperature to use. Higher values means the model will take more risks. Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer.We generally recommend altering this or top_p but not both.
+  #  top-p: 1.0                # An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.We generally recommend altering this or temperature but not both.
+  sms:
+    platform: HW_CLOUD #默认使用短信服务商
+    captcha-sender: 8823053028920 #验证码通道号
+    captcha-template-id: 97c6fcf9fd0149b39c0ed0e53480116f # 验证码 模板id
+    notify-sender: 8823053111843 # 提示类提示短信 通道号
+    notify-template-id: d424de0f2a9244ac9d2f2685cd158635 #提示类短信 模板id
+    circulated-sender: 8823053111843 # 提示类传阅短信 通道号
+    circulated-template-id: 5c179070a72447c79568ac22371be803 #提示类传阅短信 模板id
+    timeout-sender: 8823053111843 # 提示类短超时信 通道号
+    timeout-template-id: 5c179070a72447c79568ac22371be803 #提示类超时短信 模板id
+  license:
+    enabled: false                  #是否需要验证
+    login-max: 100                  #最大登陆人数
+    start-time: 2023-07-01 00:00:00 #开始时间
+    end-time: 2023-07-03 17:00:00   #结束时间
+    company-name: xxx               #公司名
+    contact-number: xxx             #联系人
+
+sms:
+  huawei:
+    #华为短信appKey
+    appKey: 69s6YyLsrLgWW99BJ5K1K26WiF29
+    #华为短信appSecret
+    app-secret: RuE1YajkI6FC4Gh2WjVtOpychRGL
+    #短信签名
+    signature: 湘北智造
+    #通道号
+    sender: 8823053028920
+    #模板ID 如果使用自定义模板发送方法可不设定
+    template-id: 97c6fcf9fd0149b39c0ed0e53480116f
+    #华为回调地址,如不需要可不设置或为空
+    statusCallBack:
+    #华为分配的app请求地址
+    url: https://smsapi.cn-north-4.myhuaweicloud.com:443
+

+ 23 - 0
docker-compose.yml

@@ -0,0 +1,23 @@
+version: '3'
+
+services:
+  tl_api:
+    build:
+      context: .
+      dockerfile: ./docker-build/Dockerfile
+    image: registry.yingcaibx.com/tl/api:latest
+    restart: always
+    container_name: tl_api
+    environment:
+      - SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL=jdbc:mysql://172.28.175.70:3306/tl?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
+      - MQTT_CLIENT-ID=tl
+    networks:
+      - docker_networks_default
+    labels:
+      - "traefik.http.routers.tl_api.rule=Host(`test.tl.api.yingcaibx.com`)"
+      - "traefik.http.routers.tl_api.entrypoints=websecure"
+      - "traefik.http.routers.tl_api.tls.certresolver=yxt"
+
+networks:
+  docker_networks_default:
+    external: true

+ 556 - 0
pom.xml

@@ -0,0 +1,556 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.5</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.xjrsoft</groupId>
+    <artifactId>xjrsoft-boot</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <name>xjrsoft-boot</name>
+    <description>xjrsoft-boot</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>11</java.version>
+        <commons.lang.version>2.6</commons.lang.version>
+        <commons.fileupload.version>1.2.2</commons.fileupload.version>
+        <commons.io.version>2.5</commons.io.version>
+        <commons.codec.version>1.10</commons.codec.version>
+        <commons.configuration.version>1.10</commons.configuration.version>
+        <hutool.version>5.7.20</hutool.version>
+        <satoken.version>1.29.0</satoken.version>
+        <lombok.version>1.18.4</lombok.version>
+        <fastjson.version>1.2.83</fastjson.version>
+        <joda.time.version>2.9.9</joda.time.version>
+        <gson.version>2.8.5</gson.version>
+        <mybatisplus.join.version>1.4.2.2</mybatisplus.join.version>
+        <mybatisplus.version>3.5.1</mybatisplus.version>
+        <mybatisplus.generator.version>3.5.2</mybatisplus.generator.version>
+        <mybatisplus.dynamic.version>3.5.1</mybatisplus.dynamic.version>
+        <druid.version>1.1.22</druid.version>
+        <knife4j.version>2.0.7</knife4j.version>
+        <freemarker.version>2.3.30</freemarker.version>
+        <hibernatevalidator.version>6.0.13.Final</hibernatevalidator.version>
+        <qiniu.version>7.2.23</qiniu.version>
+        <aliyun.oss.version>2.8.3</aliyun.oss.version>
+        <qcloud.cos.version>4.4</qcloud.cos.version>
+        <huawei.obs.version>3.19.7</huawei.obs.version>
+        <minio.oss.version>7.1.0</minio.oss.version>
+        <jaxb.api.version>2.3.0</jaxb.api.version>
+        <log4j.core.version>2.17.2</log4j.core.version>
+        <screw.version>1.0.5</screw.version>
+        <ureport.version>2.2.9</ureport.version>
+        <camunda.version>7.18.0</camunda.version>
+        <groovy.version>3.0.17</groovy.version>
+        <javax.mail.version>1.6.2</javax.mail.version>
+        <magic.api.version>2.1.1</magic.api.version>
+        <keycloak.version>20.0.1</keycloak.version>
+        <aliyun.core.version>4.5.1</aliyun.core.version>
+        <tencentcloud.version>3.1.62</tencentcloud.version>
+        <chatgpt.java.version>1.0.6</chatgpt.java.version>
+        <okio.version>3.3.0</okio.version>
+        <easyexcel.version>3.1.4</easyexcel.version>
+        <poi.version>3.17</poi.version>
+        <ooxml.schemas.version>1.3</ooxml.schemas.version>
+        <javassist.version>3.29.2-GA</javassist.version>
+        <microsoft.version>8.4.1.jre8</microsoft.version>
+        <pinyin4j.version>2.5.1</pinyin4j.version>
+        <sms4j.version>2.1.0</sms4j.version>
+        <license.version>2.0</license.version>
+        <easy.captcha.version>1.6.2</easy.captcha.version>
+        <paho.mqttv5.version>1.2.5</paho.mqttv5.version>
+
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.eclipse.paho</groupId>
+            <artifactId>org.eclipse.paho.mqttv5.client</artifactId>
+            <version>${paho.mqttv5.version}</version>
+        </dependency>
+
+        <!--Java图形验证码,支持gif、中文、算术等类型:https://gitee.com/ele-admin/EasyCaptcha-->
+        <dependency>
+            <groupId>com.github.whvcse</groupId>
+            <artifactId>easy-captcha</artifactId>
+            <version>${easy.captcha.version}</version>
+        </dependency>
+
+        <!--引入MySql依赖-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <!--引入oracle依赖-->
+        <dependency>
+            <groupId>com.oracle</groupId>
+            <artifactId>ojdbc7</artifactId>
+            <version>12.1.0.1.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/main/resources/lib/ojdbc7.jar</systemPath>
+        </dependency>
+
+        <!--引入sqlserver依赖-->
+        <dependency>
+            <groupId>com.microsoft.sqlserver</groupId>
+            <artifactId>mssql-jdbc</artifactId>
+            <version>${microsoft.version}</version>
+        </dependency>
+
+        <!--引入hutool依赖-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+
+        <!--引入hutool依赖 邮件依赖-->
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
+            <version>${javax.mail.version}</version>
+        </dependency>
+
+        <!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-spring-boot-starter</artifactId>
+            <version>${satoken.version}</version>
+        </dependency>
+
+        <!-- Sa-Token 整合 Redis (使用jdk默认序列化方式) -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-dao-redis</artifactId>
+            <version>${satoken.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-temp-jwt</artifactId>
+            <version>${satoken.version}</version>
+        </dependency>
+
+
+        <!--引入Lombok依赖-->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok.version}</version>
+            <optional>true</optional>
+        </dependency>
+
+        <!--引入mybatis-plus依赖-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatisplus.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+            <version>${mybatisplus.generator.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+            <version>${knife4j.version}</version>
+        </dependency>
+
+        <!--引入fastjson依赖-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>${commons.lang.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>${commons.fileupload.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons.io.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>${commons.codec.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+            <version>${commons.configuration.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>${joda.time.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>${gson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${druid.version}</version>
+        </dependency>
+
+        <!--引入模板依赖-->
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+            <version>${freemarker.version}</version>
+        </dependency>
+
+        <!--引入注解验证依赖-->
+        <dependency>
+            <groupId>org.hibernate.validator</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <version>${hibernatevalidator.version}</version>
+        </dependency>
+
+        <!-- 动态数据源 -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>${mybatisplus.dynamic.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.qiniu</groupId>
+            <artifactId>qiniu-java-sdk</artifactId>
+            <version>${qiniu.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>${aliyun.oss.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.huaweicloud</groupId>
+            <artifactId>esdk-obs-java</artifactId>
+            <version>${huawei.obs.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.qcloud</groupId>
+            <artifactId>cos_api</artifactId>
+            <version>${qcloud.cos.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>${minio.oss.version}</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!--jdk8  可以不需要-->
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>${jaxb.api.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>${log4j.core.version}</version>
+        </dependency>
+
+        <!-- mybatis-plus 多表关联 -->
+        <dependency>
+            <groupId>com.github.yulichang</groupId>
+            <artifactId>mybatis-plus-join</artifactId>
+            <version>${mybatisplus.join.version}</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>cn.smallbun.screw</groupId>
+            <artifactId>screw-core</artifactId>
+            <version>${screw.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.syyai.spring.boot</groupId>
+            <artifactId>ureport-spring-boot-starter</artifactId>
+            <version>${ureport.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.camunda.bpm.springboot</groupId>
+            <artifactId>camunda-bpm-spring-boot-starter</artifactId>
+            <version>${camunda.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.camunda.bpm.springboot</groupId>
+            <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
+            <version>${camunda.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-all</artifactId>
+            <version>${groovy.version}</version>
+            <classifier>sources</classifier>
+            <type>java-source</type>
+        </dependency>
+
+        <!-- 钉钉用到的jar包 -->
+        <dependency>
+            <groupId>taobao-sdk-java-auto</groupId>
+            <artifactId>taobao-sdk-java-auto</artifactId>
+            <version>1.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/main/resources/lib/taobao-sdk-java-auto.jar</systemPath>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.ssssssss</groupId>
+            <artifactId>magic-api-spring-boot-starter</artifactId>
+            <version>${magic.api.version}</version>
+        </dependency>
+
+        <!-- 腾讯云短信 -->
+        <dependency>
+            <groupId>com.tencentcloudapi</groupId>
+            <artifactId>tencentcloud-sdk-java</artifactId>
+            <version>${tencentcloud.version}</version>
+        </dependency>
+
+        <!-- 阿里云短信 -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>${aliyun.core.version}</version>
+        </dependency>
+
+        <!-- keycloak -->
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-authz-client</artifactId>
+            <version>${keycloak.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.unfbx</groupId>
+            <artifactId>chatgpt-java</artifactId>
+            <version>${chatgpt.java.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.squareup.okio</groupId>
+            <artifactId>okio</artifactId>
+            <version>${okio.version}</version>
+        </dependency>
+
+        <!-- excel导入导出 -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>${easyexcel.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>${poi.version}</version>
+            <!--            <scope>provided</scope>-->
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>${poi.version}</version>
+            <!--            <scope>provided</scope>-->
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>ooxml-schemas</artifactId>
+            <version>${ooxml.schemas.version}</version>
+        </dependency>
+
+        <!--动态给类新增属性 的工具-->
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>${javassist.version}</version>
+        </dependency>
+
+        <!-- 第三方拼音依赖包,配合 hutool-all 包中的 PinyinUtil 拼音工具使用 start -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>${pinyin4j.version}</version>
+        </dependency>
+        <!-- 第三方拼音依赖包,配合 hutool-all 包中的 PinyinUtil 拼音工具使用 start -->
+
+        <dependency>
+            <groupId>org.dromara.sms4j</groupId>
+            <artifactId>sms4j-spring-boot-starter</artifactId>
+            <version>${sms4j.version}</version>
+        </dependency>
+
+
+
+        <dependency>
+            <groupId>org.smartboot.license</groupId>
+            <artifactId>license-client</artifactId>
+            <version>${license.version}</version>
+        </dependency>
+
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <!--解开以下注释可以指定jdk版本-->
+            <!--            <plugin>-->
+            <!--                <groupId>org.apache.maven.plugins</groupId>-->
+            <!--                <artifactId>maven-compiler-plugin</artifactId>-->
+            <!--                <version>3.8.1</version>-->
+            <!--                <configuration>-->
+            <!--                    <source>1.8</source>-->
+            <!--                    <target>1.8</target>-->
+            <!--                    <encoding>${project.build.sourceEncoding}</encoding>-->
+            <!--                </configuration>-->
+            <!--            </plugin>-->
+
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+            <!--解开以下注释  打包时 会使用 maven插件 上传到docker-->
+            <!--            &lt;!&ndash;使用docker-maven-plugin插件&ndash;&gt;-->
+            <!--            <plugin>-->
+            <!--                <groupId>com.spotify</groupId>-->
+            <!--                <artifactId>docker-maven-plugin</artifactId>-->
+            <!--                <version>1.2.2</version>-->
+            <!--                &lt;!&ndash;将插件绑定在某个phase执行&ndash;&gt;-->
+            <!--                <executions>-->
+            <!--                    <execution>-->
+            <!--                        <id>build-image</id>-->
+            <!--                        &lt;!&ndash;用户只需执行mvn package ,就会自动执行mvn docker:build&ndash;&gt;-->
+            <!--                        <phase>package</phase>-->
+            <!--                        <goals>-->
+            <!--                            <goal>build</goal>-->
+            <!--                        </goals>-->
+            <!--                    </execution>-->
+            <!--                </executions>-->
+            <!--                <configuration>-->
+            <!--                    &lt;!&ndash;指定生成的镜像名,这里是我们的作者名+项目名&ndash;&gt;-->
+            <!--                    <imageName>${project.artifactId}</imageName>-->
+            <!--                    &lt;!&ndash;指定标签 这里指定的是镜像的版本,我们默认版本是latest&ndash;&gt;-->
+            <!--                    <imageTags>-->
+            <!--                        <imageTag>latest</imageTag>-->
+            <!--                    </imageTags>-->
+            <!--                    &lt;!&ndash;指定基础镜像jdk11&ndash;&gt;-->
+            <!--                    <baseImage>openjdk:11-jre</baseImage>-->
+            <!--                    &lt;!&ndash;-->
+            <!--                    镜像制作人本人信息&ndash;&gt;-->
+            <!--                    <maintainer>343894036@email.com</maintainer>-->
+            <!--                    &lt;!&ndash;切换到ROOT目录&ndash;&gt;-->
+            <!--                    <workdir>/ROOT</workdir>-->
+            <!--                    &lt;!&ndash;查看我们的java版本&ndash;&gt;-->
+            <!--                    <cmd>["java", "-version"]</cmd>-->
+            <!--                    &lt;!&ndash;${project.build.finalName}.jar是打包后生成的jar包的名字&ndash;&gt;-->
+            <!--                    <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>-->
+            <!--                    &lt;!&ndash;指定远程 docker api地址&ndash;&gt;-->
+            <!--                    <dockerHost>http://47.106.153.7:2375</dockerHost>-->
+            <!--                    &lt;!&ndash; 这里是复制 jar 包到 docker 容器指定目录配置 &ndash;&gt;-->
+            <!--                    <resources>-->
+            <!--                        <resource>-->
+            <!--                            <targetPath>/</targetPath>-->
+            <!--                            &lt;!&ndash;jar 包所在的路径  此处配置的 即对应 target 目录&ndash;&gt;-->
+            <!--                            <directory>${project.build.directory}</directory>-->
+            <!--                            &lt;!&ndash;用于指定需要复制的文件 需要包含的 jar包 ,这里对应的是 Dockerfile中添加的文件名 &ndash;&gt;-->
+            <!--                            <include>${project.build.finalName}.jar</include>-->
+            <!--                        </resource>-->
+            <!--                    </resources>-->
+
+            <!--                </configuration>-->
+            <!--            </plugin>-->
+
+        </plugins>
+    </build>
+
+</project>

+ 19 - 0
src/main/java/com/xjrsoft/XjrSoftApplication.java

@@ -0,0 +1,19 @@
+package com.xjrsoft;
+
+import com.xjrsoft.common.annotation.UniqueNameGenerator;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+
+/**
+ * @author Zexy
+ */
+@SpringBootApplication
+@EnableAspectJAutoProxy(exposeProxy = true)
+@ComponentScan(nameGenerator = UniqueNameGenerator.class)
+public class XjrSoftApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(XjrSoftApplication.class, args);
+    }
+}

+ 308 - 0
src/main/java/com/xjrsoft/common/advice/TransResponseBodyAdvice.java

@@ -0,0 +1,308 @@
+package com.xjrsoft.common.advice;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.core.util.ClassUtil;
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.xjrsoft.common.annotation.Trans;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.enums.TransType;
+import com.xjrsoft.common.model.result.R;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.utils.RedisUtil;
+import com.xjrsoft.module.magicapi.service.IMagicApiService;
+import com.xjrsoft.module.organization.entity.Department;
+import com.xjrsoft.module.organization.entity.Post;
+import com.xjrsoft.module.organization.entity.User;
+import com.xjrsoft.module.system.entity.Area;
+import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.system.service.IAreaService;
+import lombok.AllArgsConstructor;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.ListUtils;
+import org.apache.commons.collections.MapUtils;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+import org.ssssssss.magicapi.modules.db.model.PageResult;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 接口返回值转换
+ * 例如: 列表中的 数据字典 用户 机构 岗位等值  使用id 转 name
+ * @Author: tzx
+ * @Date: 2023/1/11 14:42
+ */
+@Slf4j
+@RestControllerAdvice
+@AllArgsConstructor
+public class TransResponseBodyAdvice implements ResponseBodyAdvice<Object> {
+
+    private RedisUtil redisUtil;
+
+    private final IMagicApiService magicApiService;
+
+    private final IAreaService areaService;
+
+    @Override
+    public boolean supports(@NonNull MethodParameter returnType, @NonNull Class converterType) {
+        return true;
+    }
+
+    @Override
+    public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType, @NonNull Class selectedConverterType, @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
+
+        if (!(body instanceof R)) {
+            return body;
+        }
+
+        if (((R)body).getData() == null) {
+            return body;
+        }
+
+        //判断是否为分页返回值
+        if (ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true)) {
+            Object result = Convert.convert(R.class, body).getData();
+            PageOutput<?> pageOutput = Convert.convert(PageOutput.class, result);
+            List<?> listData = pageOutput.getList();
+            if (listData == null || listData.size() == 0) {
+                return body;
+            }
+            //默认取第一条数据 来获取是所有字段  以及 字段的 注解
+            Object firstData = listData.get(0);
+            Field[] fields = ReflectUtil.getFields(firstData.getClass());
+            //获取到所有字段的转换注解
+            List<Trans> transList = Arrays.stream(fields).filter(field -> field.isAnnotationPresent(Trans.class)).map(field -> field.getAnnotation(Trans.class)).collect(Collectors.toList());
+
+            //如果一个需要转换的都没  直接返回
+            if (transList.size() == 0) {
+                return body;
+            }
+
+            transData(listData, fields, transList);
+
+        }
+
+        //判断是否为不分页列表返回值
+        else if (ClassUtil.equals(((R) body).getData().getClass(), ArrayList.class.getName(), true)){
+            Object result = Convert.convert(R.class, body).getData();
+            List<?> listData = Convert.convert(List.class, result);
+            if (listData == null || listData.size() == 0) {
+                return body;
+            }
+            //默认取第一条数据 来获取是所有字段  以及 字段的 注解
+            Object firstData = listData.get(0);
+            Field[] fields = ReflectUtil.getFields(firstData.getClass());
+            //获取到所有字段的转换注解
+            List<Trans> transList = Arrays.stream(fields).filter(field -> field.isAnnotationPresent(Trans.class)).map(field -> field.getAnnotation(Trans.class)).collect(Collectors.toList());
+
+            //如果一个需要转换的都没  直接返回
+            if (transList.size() == 0) {
+                return body;
+            }
+            transData(listData, fields, transList);
+        }
+        //单个的返回值 (表单页面不需要 详情页面可以使用)
+        else {
+            Object result = Convert.convert(R.class, body).getData();
+
+            Field[] fields = ReflectUtil.getFields(result.getClass());
+            //获取到所有字段的转换注解
+            List<Trans> transList = Arrays.stream(fields).filter(field -> field.isAnnotationPresent(Trans.class)).map(field -> field.getAnnotation(Trans.class)).collect(Collectors.toList());
+
+            //如果一个需要转换的都没  直接返回
+            if (transList.size() == 0) {
+                return body;
+            }
+            List<Object> listData = new ArrayList<>();
+            listData.add(result);
+            transData(listData, fields, transList);
+        }
+        return body;
+    }
+
+    private void transData(List<?> listData, Field[] fields, List<Trans> transList) {
+        List<DictionaryDetail> detailList = getDictionaryDetails(transList);
+        List<User> userList = getUsers(transList);
+        List<Department> deptList = getDepts(transList);
+        List<Post> postList = getPosts(transList);
+//        List<Area> areaList = getAreas(transList);
+        Map<String, List<Map<String, Object>>> apiDataList = getApiData(transList);
+
+        for (Object data : listData) {
+            for (Field field : fields) {
+                Trans annotation = field.getAnnotation(Trans.class);
+                if (annotation == null) {
+                    continue;
+                }
+                try {
+                    field.setAccessible(true);
+                    Object value = field.get(data);
+                    if (StrUtil.isEmptyIfStr(value)) {
+                        continue;
+                    }
+                    List<String> values = annotation.isMulti() ? StrUtil.split(value.toString(), StringPool.COMMA) : Arrays.asList(value.toString());
+                    StringBuilder tranValue = new StringBuilder();
+                    //数据字典转换
+                    if (annotation.type() == TransType.DIC && detailList != null) {
+                        for (DictionaryDetail detail : detailList) {
+                            if (values.contains(detail.getValue())) {
+                                if (tranValue.length() > 0) {
+                                    tranValue.append(StringPool.COMMA);
+                                }
+                                tranValue.append(detail.getName());
+                                if (values.size() == 1) break;
+                            }
+                        }
+                    }
+                    // api数据转换
+                    if (annotation.type() == TransType.API && CollectionUtils.isNotEmpty(apiDataList)) {
+                        List<Map<String, Object>> dataList = apiDataList.get(annotation.id());
+                        for (Map<String, Object> item : dataList) {
+                            if (values.contains(MapUtils.getString(item, "value"))) {
+                                if (tranValue.length() > 0) {
+                                    tranValue.append(StringPool.COMMA);
+                                }
+                                tranValue.append(MapUtils.getString(item, "label"));
+                                if (values.size() == 1) break;
+                            }
+                        }
+                    }
+                    //用户转换
+                    if (annotation.type() == TransType.USER && userList != null) {
+                        values = StrUtil.split(value.toString(), StringPool.COMMA);
+                        for (User user : userList) {
+                            if (values.contains(user.getId().toString())) {
+                                if (tranValue.length() > 0) {
+                                    tranValue.append(StringPool.COMMA);
+                                }
+                                tranValue.append(user.getName());
+                                if (values.size() == 1) break;
+                            }
+                        }
+                    }
+                    //部门转换
+                    if (annotation.type() == TransType.DEPT && deptList != null) {
+                        for (Department department : deptList) {
+                            if (StrUtil.equals(department.getId().toString(), value.toString())) {
+                                tranValue.append(department.getName());
+                                break;
+                            }
+                        }
+                    }
+                    //岗位转换
+                    if (annotation.type() == TransType.POST && postList != null) {
+                        for (Post post : postList) {
+                            if (StrUtil.equals(value.toString(), post.getId().toString())) {
+                                tranValue.append(post.getName());
+                                break;
+                            }
+                        }
+                    }
+                    //行政区域
+                    if (annotation.type() == TransType.AREA) {
+                        values = StrUtil.split(value.toString(), StringPool.COMMA);
+                        for (String id : values) {
+                            Area area = areaService.getById(Long.valueOf(id));
+                            if (tranValue.length() > 0) {
+                                tranValue.append(StringPool.SLASH);
+                            }
+                            tranValue.append(area.getName());
+                        }
+                    }
+                    //级联
+                    if (annotation.type() == TransType.CASCADE && CollectionUtils.isNotEmpty(apiDataList)) {
+                        values = StrUtil.split(value.toString(), StringPool.COMMA);
+                        List<Map<String, Object>> tempList = apiDataList.get(annotation.id());
+                        boolean isShowAll = StrUtil.equalsIgnoreCase(annotation.showFormat(), "all");
+                        for (String savedValue : values) {
+                            for (Map<String, Object> item : tempList) {
+                                if (StrUtil.equals(savedValue, MapUtils.getString(item, "value"))) {
+                                    if (!isShowAll) {
+                                        tranValue.setLength(0);
+                                    }
+                                    if (tranValue.length() > 0) tranValue.append(annotation.separator());
+                                    tranValue.append(MapUtils.getString(item, "label"));
+                                    tempList = (List<Map<String, Object>>) item.get("children");
+                                }
+                            }
+                        }
+                    }
+                    if (tranValue.length() > 0) field.set(data, tranValue.toString());
+                } catch (Exception e) {
+                    log.warn(field.getName() + annotation.type().getValue() + "数据转换异常!");
+                }
+            }
+        }
+    }
+
+    private List<DictionaryDetail> getDictionaryDetails(List<Trans> transList) {
+
+        List<DictionaryDetail> detailList = new ArrayList<>();
+        //如果有需要转换的数据字典
+        if (transList.stream().anyMatch(t -> t.type() == TransType.DIC)) {
+            detailList = redisUtil.get(GlobalConstant.DIC_DETAIL_CACHE_KEY, new TypeReference<List<DictionaryDetail>>() {
+            });
+        }
+        return detailList;
+    }
+
+    private List<User> getUsers(List<Trans> transList) {
+        List<User> userList = new ArrayList<>();
+        //如果有需要转换的用户
+        if(transList.stream().anyMatch(t -> t.type() == TransType.USER)){
+            userList= redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
+            });
+        }
+        return userList;
+    }
+
+    private List<Department> getDepts(List<Trans> transList) {
+
+        List<Department> detailList = new ArrayList<>();
+        //如果有需要转换的部门
+        if (transList.stream().anyMatch(t -> t.type() == TransType.DEPT)) {
+            detailList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<Department>>() {
+            });
+        }
+        return detailList;
+    }
+
+    private List<Post> getPosts(List<Trans> transList) {
+        List<Post> userList = new ArrayList<>();
+        //如果有需要转换的用户
+        if(transList.stream().anyMatch(t -> t.type() == TransType.POST)){
+            userList= redisUtil.get(GlobalConstant.POST_CACHE_KEY, new TypeReference<List<Post>>() {
+            });
+        }
+        return userList;
+    }
+
+    private Map<String, List<Map<String, Object>>> getApiData(List<Trans> transList) {
+        Map<String, List<Map<String, Object>>> resultMap = new HashMap<>();
+        for (Trans trans : transList) {
+            if (trans.type() == TransType.API || trans.type() == TransType.CASCADE) {
+                Object apiDataList = magicApiService.executeApi(trans.id());
+                if (apiDataList instanceof PageResult) {
+                    resultMap.put(trans.id(), (List<Map<String, Object>>) ((PageResult) apiDataList).getList());
+                } else if (apiDataList instanceof List) {
+                    resultMap.put(trans.id(), (List<Map<String, Object>>) apiDataList);
+                }
+            }
+        }
+        return resultMap;
+    }
+}

+ 364 - 0
src/main/java/com/xjrsoft/common/advice/WorkflowResponseBodyAdvice.java

@@ -0,0 +1,364 @@
+package com.xjrsoft.common.advice;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.*;
+import cn.hutool.db.Entity;
+import cn.hutool.extra.servlet.ServletUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.xjrsoft.common.enums.WorkflowIsRecycleType;
+import com.xjrsoft.common.enums.YesOrNoEnum;
+import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.model.result.R;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.utils.RedisUtil;
+import com.xjrsoft.module.workflow.constant.WorkflowConstant;
+import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
+import com.xjrsoft.module.workflow.entity.WorkflowSchema;
+import com.xjrsoft.module.workflow.model.WorkflowListResult;
+import com.xjrsoft.module.workflow.service.IWorkflowFormRelationService;
+import com.xjrsoft.module.workflow.service.IWorkflowSchemaService;
+import javassist.*;
+import lombok.AllArgsConstructor;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+import org.camunda.bpm.engine.HistoryService;
+import org.camunda.bpm.engine.TaskService;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
+import org.camunda.bpm.engine.task.Task;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.http.server.ServletServerHttpRequest;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 工作流 模板 绑定菜单 返回值新增工作流的相关属性
+ *
+ * @Author: tzx
+ * @Date: 2023/3/27 14:24
+ */
+@Slf4j
+@RestControllerAdvice
+@AllArgsConstructor
+public class WorkflowResponseBodyAdvice implements ResponseBodyAdvice<Object> {
+
+
+    private RedisUtil redisUtil;
+
+    private IWorkflowFormRelationService formRelationService;
+
+    private HistoryService historyService;
+
+    private IWorkflowSchemaService workflowSchemaService;
+
+    private TaskService taskService;
+
+    private static final Map<String, Constructor<?>> cacheClass = new HashMap<>();
+
+    private static final String FORM_ID_KEY = "FormId";
+
+    private static final String KEY_VALUE_KEY = "PK";
+
+    private static final String FIELD_STRING = "private Object workflowData;";
+
+    private static final String GET_MOTHOD_STRING = "public Object getWorkflowData(){ return this.workflowData; }";
+
+    private static final String RESULT_KEY = "workflowData";
+
+    @Override
+    public boolean supports(@NonNull MethodParameter returnType, @NonNull Class converterType) {
+        return true;
+    }
+
+
+    @Override
+    public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType, @NonNull Class selectedConverterType, @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
+
+        if (!(body instanceof R)) {
+            return body;
+        }
+
+        if (((R) body).getData() == null) {
+            return body;
+        }
+
+        //先从header里面获取formId  如果能获取到 就证明是自定义表单
+        String headerFormId = ServletUtil.getHeader(((ServletServerHttpRequest) request).getServletRequest(), FORM_ID_KEY, CharsetUtil.UTF_8);
+        String headerKey = ServletUtil.getHeader(((ServletServerHttpRequest) request).getServletRequest(), KEY_VALUE_KEY, CharsetUtil.UTF_8);
+
+
+        //如果是自定义表单 需要获取 工作流数据
+        if(StrUtil.isNotBlank(headerFormId)){
+            if (ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true)){
+                return formTemplateGetWorkflowDataHandler(body, headerFormId, headerKey);
+            }
+        }
+
+
+        String formId = ((ServletServerHttpRequest) request).getServletRequest().getParameter(FORM_ID_KEY);
+
+        if (StrUtil.isBlank(formId)) {
+            return body;
+        }
+        String key = ((ServletServerHttpRequest) request).getServletRequest().getParameter(KEY_VALUE_KEY);
+
+        if (StrUtil.isBlank(key)) {
+            return body;
+        }
+
+        //如果是代码生成器表单 需要获取 工作流数据
+        return codeGetWorkflowDataHandler(body, formId, key);
+    }
+
+    private Object formTemplateGetWorkflowDataHandler(Object body, String headerFormId, String headerKey) {
+
+        List<Object> keyValueFormList = new ArrayList<>();
+        List<?> listData = null;
+        if (ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true)){
+            Object result = Convert.convert(R.class, body).getData();
+            PageOutput<?> pageOutput = Convert.convert(PageOutput.class, result);
+            listData = pageOutput.getList();
+            if (listData == null || listData.size() == 0) {
+                return body;
+            }
+
+        }
+        else if (ClassUtil.equals(((R) body).getData().getClass(), ArrayList.class.getName(), true)){
+            Object result = Convert.convert(R.class, body).getData();
+            listData = Convert.convert(List.class, result);
+            if (listData == null || listData.size() == 0) {
+                return body;
+            }
+        }
+        else {
+            return body;
+        }
+
+        for (Object data : listData) {
+            Entity rowValue = Convert.convert(Entity.class, data);
+            Object keyValue = rowValue.get(headerKey);
+            keyValueFormList.add(keyValue);
+        }
+
+        WorkflowSchema schema = workflowSchemaService.getOne(Wrappers.lambdaQuery(WorkflowSchema.class).eq(WorkflowSchema::getFormId, headerFormId).select(WorkflowSchema::getId));
+        //获取到所有关联的 流程id
+        List<WorkflowFormRelation> relations = formRelationService.list(Wrappers.lambdaQuery(WorkflowFormRelation.class).eq(WorkflowFormRelation::getFormId, headerFormId).in(WorkflowFormRelation::getFormKeyValue, keyValueFormList).select(WorkflowFormRelation::getProcessId, WorkflowFormRelation::getFormKeyValue));
+
+        Set<String> processIds = relations.stream().map(WorkflowFormRelation::getProcessId).collect(Collectors.toSet());
+        List<HistoricProcessInstance> processInstanceList;
+        if (processIds.size() == 0) {
+            processInstanceList = new ArrayList<>();
+        } else {
+            processInstanceList = historyService.createHistoricProcessInstanceQuery().processInstanceIds(processIds).list();
+        }
+
+        //找到当前所有流程的 所在执行的任务list
+        String[] processIdArrays = relations.stream().map(WorkflowFormRelation::getProcessId).toArray(String[]::new);
+
+        List<Task> taskList;
+        if (processIdArrays.length > 0) {
+            taskList = taskService.createTaskQuery()
+                    .active()
+                    .processInstanceIdIn(processIdArrays)
+                    .taskVariableValueEquals(WorkflowConstant.TASK_IS_APPOINT_APPROVE, YesOrNoEnum.NO.getCode())
+                    .processVariableValueEquals(WorkflowConstant.PROCESS_ISRECYCLE_FLAG_KEY, WorkflowIsRecycleType.NO.getCode())
+                    .taskVariableValueLike(WorkflowConstant.TASK_ASSIGNEE_VAR_KEY, StringPool.PERCENT + StpUtil.getLoginIdAsString() + StringPool.PERCENT)
+                    .list();
+        } else {
+            taskList = new ArrayList<>();
+        }
+
+        for (Object data : listData) {
+            Entity rowValue = Convert.convert(Entity.class, data);
+            Object keyValue = rowValue.get(headerKey);
+
+            Optional<WorkflowFormRelation> thisRelationOp = relations.stream().filter(x -> x.getFormKeyValue().equals(keyValue)).findFirst();
+
+            WorkflowListResult workflowListResult = new WorkflowListResult();
+
+            thisRelationOp.ifPresent(r -> {
+                HistoricProcessInstance historicProcessInstance = processInstanceList.stream().filter(p -> p.getId().equals(r.getProcessId())).findFirst().orElse(null);
+
+                if (ObjectUtil.isNotNull(historicProcessInstance)) {
+                    assert historicProcessInstance != null;
+                    workflowListResult.setStatus(historicProcessInstance.getState());
+                    workflowListResult.setProcessId(historicProcessInstance.getId());
+                }
+
+                //获取到当前数据 所关联的 的流程 正在执行的 任务
+                List<Task> thisDataTask = taskList.stream().filter(x -> x.getProcessInstanceId().equals(r.getProcessId())).collect(Collectors.toList());
+                if (thisDataTask.size() > 0) {
+                    workflowListResult.setTaskIds(thisDataTask.stream().map(Task::getId).collect(Collectors.toList()));
+                }
+            });
+
+            if (ObjectUtil.isNotNull(schema)) {
+                workflowListResult.setSchemaId(schema.getId());
+            } else {
+                workflowListResult.setEnabled(Boolean.FALSE);
+            }
+            rowValue.set(RESULT_KEY, workflowListResult);
+        }
+        return body;
+    }
+
+    private Object codeGetWorkflowDataHandler(Object body,String formId, String key) {
+        WorkflowSchema schema = workflowSchemaService.getOne(Wrappers.lambdaQuery(WorkflowSchema.class).eq(WorkflowSchema::getFormId, formId).select(WorkflowSchema::getId));
+
+        List<Object> keyValueList = new ArrayList<>();
+
+        List<?> listData;
+
+        //判断是否为分页返回值
+        boolean isPage = ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true);
+        R r = Convert.convert(R.class, body);
+        Object resultData = r.getData();
+        if (isPage) {
+            PageOutput<?> pageOutput = Convert.convert(PageOutput.class, resultData);
+            listData = pageOutput.getList();
+            if (listData == null || listData.size() == 0) {
+                return body;
+            }
+
+            for (Object data : listData) {
+                Object keyValue = ReflectUtil.getFieldValue(data, key);
+                keyValueList.add(keyValue);
+            }
+        }
+        //判断是否为不分页列表返回值
+        else if (ClassUtil.equals(((R) body).getData().getClass(), ArrayList.class.getName(), true)) {
+            listData = Convert.convert(List.class, resultData);
+
+            if (listData == null || listData.size() == 0) {
+                return body;
+            }
+
+            for (Object data : listData) {
+                Object keyValue = ReflectUtil.getFieldValue(data, key);
+                keyValueList.add(keyValue);
+            }
+        } else {
+            return body;
+        }
+
+
+        //获取到所有关联的 流程id
+        List<WorkflowFormRelation> relations = formRelationService.list(Wrappers.lambdaQuery(WorkflowFormRelation.class).eq(WorkflowFormRelation::getFormId, formId).in(WorkflowFormRelation::getFormKeyValue, keyValueList).select(WorkflowFormRelation::getProcessId, WorkflowFormRelation::getFormKeyValue));
+//        if (relations.size() == 0) {
+//            return body;
+//        }
+        Set<String> processIds = relations.stream().map(WorkflowFormRelation::getProcessId).collect(Collectors.toSet());
+        List<HistoricProcessInstance> processInstanceList;
+        if (processIds.size() == 0) {
+            processInstanceList = new ArrayList<>();
+        } else {
+            processInstanceList = historyService.createHistoricProcessInstanceQuery().processInstanceIds(processIds).list();
+        }
+
+        //找到当前所有流程的 所在执行的任务list
+        String[] processIdArrays = relations.stream().map(WorkflowFormRelation::getProcessId).toArray(String[]::new);
+
+        List<Task> taskList;
+        if (processIdArrays.length > 0) {
+            taskList = taskService.createTaskQuery()
+                    .active()
+                    .processInstanceIdIn(processIdArrays)
+                    .taskVariableValueEquals(WorkflowConstant.TASK_IS_APPOINT_APPROVE, YesOrNoEnum.NO.getCode())
+                    .processVariableValueEquals(WorkflowConstant.PROCESS_ISRECYCLE_FLAG_KEY, WorkflowIsRecycleType.NO.getCode())
+                    .taskVariableValueLike(WorkflowConstant.TASK_ASSIGNEE_VAR_KEY, StringPool.PERCENT + StpUtil.getLoginIdAsString() + StringPool.PERCENT)
+                    .list();
+        } else {
+            taskList = new ArrayList<>();
+        }
+
+        ClassPool pool = new ClassPool(true);
+
+        List<Object> result = new ArrayList<>();
+        try {
+            CtClass ctClass = pool.get(listData.get(0).getClass().getName());
+
+            try {
+                CtField workflowField = CtField.make(FIELD_STRING, ctClass);
+
+                ctClass.addField(workflowField);
+
+                CtMethod workflowMethod = CtMethod.make(GET_MOTHOD_STRING, ctClass);
+                ctClass.addMethod(workflowMethod);
+
+            } catch (CannotCompileException e) {
+                e.printStackTrace();
+            }
+
+            Constructor<?> declaredConstructor;
+            if (!cacheClass.containsKey(ctClass.getName())) {
+                declaredConstructor = ctClass.toClass().getDeclaredConstructor();
+                cacheClass.put(ctClass.getName(), declaredConstructor);
+            } else {
+                declaredConstructor = cacheClass.get(ctClass.getName());
+            }
+
+
+            for (Object data : listData) {
+                Object keyValue = ReflectUtil.getFieldValue(data, key);
+
+                Optional<WorkflowFormRelation> thisRelationOp = relations.stream().filter(x -> x.getFormKeyValue().equals(keyValue)).findFirst();
+
+                Object newObject = declaredConstructor.newInstance();
+
+                result.add(newObject);
+                BeanUtil.copyProperties(data, newObject);
+
+                WorkflowListResult workflowListResult = new WorkflowListResult();
+
+                thisRelationOp.ifPresent(relation -> {
+                    HistoricProcessInstance historicProcessInstance = processInstanceList.stream().filter(p -> p.getId().equals(relation.getProcessId())).findFirst().orElse(null);
+
+                    if (ObjectUtil.isNotNull(historicProcessInstance)) {
+                        assert historicProcessInstance != null;
+                        workflowListResult.setStatus(historicProcessInstance.getState());
+                        workflowListResult.setProcessId(historicProcessInstance.getId());
+                    }
+
+                    //获取到当前数据 所关联的 的流程 正在执行的 任务
+                    List<Task> thisDataTask = taskList.stream().filter(x -> x.getProcessInstanceId().equals(relation.getProcessId())).collect(Collectors.toList());
+                    if (thisDataTask.size() > 0) {
+                        workflowListResult.setTaskIds(thisDataTask.stream().map(Task::getId).collect(Collectors.toList()));
+                    }
+                });
+
+                if (ObjectUtil.isNotNull(schema)) {
+                    workflowListResult.setSchemaId(schema.getId());
+                } else {
+                    workflowListResult.setEnabled(Boolean.FALSE);
+                }
+
+                ReflectUtil.setFieldValue(newObject, RESULT_KEY, workflowListResult);
+            }
+
+            ctClass.detach();
+        } catch (NotFoundException | CannotCompileException | NoSuchMethodException | InvocationTargetException |
+                InstantiationException | IllegalAccessException e) {
+            e.printStackTrace();
+            throw new MyException("表单发起流程数据转换出错,请联系管理员!" );
+        }
+
+        if (isPage) {
+            ((PageOutput) (r.getData())).setList(result);
+        } else{
+            r.put("data", result);
+        }
+
+        return body;
+    }
+
+}

+ 13 - 0
src/main/java/com/xjrsoft/common/annotation/DataPermission.java

@@ -0,0 +1,13 @@
+package com.xjrsoft.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/2/28 10:52
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface DataPermission {
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/annotation/Limit.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/2/6 16:54
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface Limit {
+
+    // 资源名称
+    String name() default "";
+
+    // 资源key
+    String key() default "";
+
+    // 前缀
+    String prefix() default "";
+
+    // 时间
+    int time();
+
+    // 最多访问次数
+    int count();
+
+    // 提示信息
+    String msg() default "系统繁忙,请稍后再试";
+}

+ 47 - 0
src/main/java/com/xjrsoft/common/annotation/Trans.java

@@ -0,0 +1,47 @@
+package com.xjrsoft.common.annotation;
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.enums.TransType;
+
+import java.lang.annotation.*;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/1/11 14:17
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Trans {
+
+    /**
+     * 转换类型
+     * @return 转换类型
+     */
+    TransType type();
+
+    /**
+     * 如果转换类型是  Api
+     * @return Api 的 id
+     */
+    String id() default "";
+
+    /**
+     * 是否多个值
+     * @return true or false
+     */
+    boolean isMulti() default false;
+
+    /**
+     * 多个值分隔符
+     * @return 分隔符
+     */
+    String separator() default StringPool.SLASH;
+
+    /**
+     * 多个值显示格式
+     * @return 显示格式
+     */
+    String showFormat() default "all";
+
+}

+ 12 - 0
src/main/java/com/xjrsoft/common/annotation/UniqueNameGenerator.java

@@ -0,0 +1,12 @@
+package com.xjrsoft.common.annotation;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.AnnotationBeanNameGenerator;
+
+public class UniqueNameGenerator extends AnnotationBeanNameGenerator {
+
+    @Override
+    protected String buildDefaultBeanName(BeanDefinition definition) {
+        return definition.getBeanClassName();
+    }
+}

+ 20 - 0
src/main/java/com/xjrsoft/common/annotation/XjrLog.java

@@ -0,0 +1,20 @@
+package com.xjrsoft.common.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 系统日志注解
+ *
+ * @author tzx
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface XjrLog {
+
+	String value() default "";
+}

+ 96 - 0
src/main/java/com/xjrsoft/common/aspect/LimitAspect.java

@@ -0,0 +1,96 @@
+package com.xjrsoft.common.aspect;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.annotation.Limit;
+import com.xjrsoft.common.exception.MyException;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.data.redis.serializer.GenericToStringSerializer;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+@Slf4j
+@Aspect
+@Configuration
+public class LimitAspect {
+
+    private final RedisTemplate<String, Object> redisTemplate;
+
+    public LimitAspect(RedisTemplate<String, Object> redisTemplate) {
+        this.redisTemplate = redisTemplate;
+    }
+
+    @Around("@annotation(com.xjrsoft.common.annotation.Limit)")
+    public Object around(ProceedingJoinPoint pjp){
+        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
+        Method method = methodSignature.getMethod();
+        Limit annotation = method.getAnnotation(Limit.class);
+
+        String key = annotation.key();
+        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+        String allKey = key + StringPool.COLON + ServletUtil.getClientIP(request);
+
+
+        int time = annotation.time();
+        int count = annotation.count();
+
+        try {
+            String luaScript = buildLuaScript();
+            RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
+            // execute使用的redis的默认的序列化方式,需要设置参数--arg的序列化方式,以及result结果的序列化方式
+            // 此处传参只要能转为Object就行(因为数字不能直接强转为String,所以不能用String序列化)
+            // 结果的类型需要根据脚本定义,此处是数字--定义的是Long类型
+            Long result = redisTemplate.execute(redisScript, new GenericToStringSerializer<>(Object.class),
+                    new GenericToStringSerializer<>(Long.class), ListUtil.toList(allKey), time, count);
+
+            // 使用lua脚本执行,保证原子性,进行请求次数限制
+            assert result != null;
+            boolean isOutOfLimit = result.equals(1L);
+            if(!isOutOfLimit){
+                throw new MyException(annotation.msg());
+            }
+            else {
+               return pjp.proceed();
+            }
+
+        }catch (Throwable e){
+            if(e instanceof MyException){
+                log.debug("令牌桶={},获取令牌失败",allKey);
+                throw new MyException(e.getLocalizedMessage());
+            }
+            e.printStackTrace();
+            throw new MyException("服务器异常");
+        }
+    }
+
+    public String buildLuaScript(){
+
+        //lua 脚本,进行请求次数的叠加,并判断请求次数是否超过限制
+        return "local val = redis.call('incr', KEYS[1]) " +
+                "local expire = tonumber(ARGV[1]) " +
+                "if val == 1 " +
+                "then redis.call('expire', KEYS[1], expire) " +
+                "else if redis.call('ttl', KEYS[1]) == -1 " +
+                "then redis.call('expire', KEYS[1], expire) " +
+                "end " +
+                "end " +
+                "if val > tonumber(ARGV[2]) " +
+                "then return 0 " +
+                "end " +
+                "return 1";
+    }
+
+}

+ 123 - 0
src/main/java/com/xjrsoft/common/aspect/XjrLogAspect.java

@@ -0,0 +1,123 @@
+package com.xjrsoft.common.aspect;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import com.google.gson.Gson;
+import com.xjrsoft.common.annotation.XjrLog;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.enums.LogCategoryEnum;
+import com.xjrsoft.common.utils.HttpContextUtils;
+import com.xjrsoft.module.organization.entity.User;
+import com.xjrsoft.module.system.entity.Log;
+import com.xjrsoft.module.system.mapper.LogMapper;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.time.LocalDateTime;
+
+
+/**
+ * 日志切面
+ *
+ * @author tzx
+ */
+@Aspect
+@Component
+public class XjrLogAspect {
+
+	@Autowired
+	private LogMapper logMapper;
+
+	
+	@Pointcut("@annotation(com.xjrsoft.common.annotation.XjrLog)")
+	public void logPointCut() { 
+		
+	}
+
+
+	@Around("logPointCut()")
+	public Object around(ProceedingJoinPoint point) throws Throwable {
+		long beginTime = System.currentTimeMillis();
+		//执行方法
+		Object result = point.proceed();
+		//执行时长(毫秒)
+		long time = System.currentTimeMillis() - beginTime;
+
+		//保存日志
+		insertLog(point, time);
+
+		return result;
+	}
+
+	private void insertLog(ProceedingJoinPoint joinPoint, long time) {
+		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+		Method method = signature.getMethod();
+
+		Log logEntity = new Log();
+		XjrLog xjrLog = method.getAnnotation(XjrLog.class);
+		if(xjrLog != null){
+			//注解上的描述
+			logEntity.setOperation(xjrLog.value());
+		}
+
+		//请求的方法名
+		String className = joinPoint.getTarget().getClass().getName();
+		String methodName = signature.getName();
+		logEntity.setMethod(className + "." + methodName + "()");
+
+		//请求的参数
+		Object[] args = joinPoint.getArgs();
+		try{
+			String params = new Gson().toJson(args);
+			if (params.length() < 4000) {
+				logEntity.setParams(params);
+			}
+		}catch (Exception e){
+
+		}
+
+		//获取request
+		HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
+		//设置IP地址
+		logEntity.setIp(ServletUtil.getClientIP(request));
+
+		//用户名
+		//判断是否已登录,如果已登录了,就获取token时间,未登录状态直接放行
+		if(StpUtil.isLogin()){
+			SaSession tokenSession = StpUtil.getTokenSession();
+			User user = tokenSession.get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());
+			logEntity.setUsername(user.getUserName());
+			logEntity.setTime(time);
+			logEntity.setCategory(getCategory(request));
+			logEntity.setCreateTime(LocalDateTime.now());
+			//保存系统日志
+			logMapper.insert(logEntity);
+		}
+	}
+
+	/**
+	 * @title 获取日志分类
+	 * @create 2020年11月11日 19:23:30
+	 * */
+	private int getCategory(HttpServletRequest request){
+		if(request.getRequestURI().equalsIgnoreCase("/system/login")){
+			return LogCategoryEnum.LOGIN.getCode();
+		}
+		else if (request.getMethod().toLowerCase().equals("get")){
+			return  LogCategoryEnum.GET.getCode();
+		}
+		else if(request.getMethod().toLowerCase().equals("post") || request.getMethod().toLowerCase().equals("put") || request.getMethod().toLowerCase().equals("patch") || request.getMethod().toLowerCase().equals("delete")) {
+			return  LogCategoryEnum.OPERAT.getCode();
+		}
+		else
+			return  LogCategoryEnum.EXCEPTION.getCode();
+	}
+}

+ 28 - 0
src/main/java/com/xjrsoft/common/constant/FormComponentConstant.java

@@ -0,0 +1,28 @@
+package com.xjrsoft.common.constant;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/5/17 9:31
+ */
+public interface FormComponentConstant {
+    /**
+     * 子表单组件type 值
+     */
+    String FORM_COMPONENT_TYPE = "form";
+
+    /**
+     * 选项卡组件 type 值
+     */
+    String TAB_COMPONENT_TYPE = "tab";
+
+    /**
+     * 布局组件 type 值
+     */
+    String GRID_COMPONENT_TYPE = "grid";
+
+    /**
+     * 卡片组件 type 值
+     */
+    String CARD_COMPONENT_TYPE = "card";
+
+}

+ 492 - 0
src/main/java/com/xjrsoft/common/constant/GlobalConstant.java

@@ -0,0 +1,492 @@
+package com.xjrsoft.common.constant;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/3 16:35
+ */
+public interface GlobalConstant {
+
+
+    /**
+     * 超级管理员角色id
+     */
+    Long SUPER_ADMIN_ROLE_ID = 1L;
+
+    /**
+     * 超级管理员用户默认id
+     */
+    Long SUPER_ADMIN_USER_ID = 1000000000000000000L;
+
+    /**
+     * 框架 约定 默认数据源的名称
+     */
+    String DEFAULT_DATASOURCE_KEY = "master";
+
+
+    /**
+     * 框架 约定 默认数据库连接的id
+     */
+    Long DEFAULT_DATABASELINKID= 0L;
+
+    /**
+     * @des 账户加密字符串
+     * */
+    String SECRET_KEY = "xxxxxxxxxxxxxxxx";
+
+    /**
+     * ureport http-basic 验证 账号密码
+     */
+    String UREPORT_ACCOUNT = "xjrsoft";
+
+    /**
+     * ureport http-basic 验证 账号密码
+     */
+    String UREPORT_PASSWORD = "123456";
+
+    /**
+     * @des 登录界面返回前端 token 的 key
+     * */
+    String TOKEN_KEY = "token";
+
+    /**
+     * @des sa-token 登陆人信息key
+     *
+     * */
+    String LOGIN_USER_INFO_KEY = "LOGIN_USER_INFO_KEY";
+
+    /**
+     * @des sa-token 登陆人权限Code key
+     * */
+    String LOGIN_USER_AUTH_CODE_KEY = "LOGIN_USER_AUTH_CODE_KEY";
+
+    /**
+     * @des sa-token 登陆人自定义接口权限Code key
+     * */
+    String LOGIN_USER_INTERFACE_AUTH_CODE_KEY = "LOGIN_USER_INTERFACE_AUTH_CODE_KEY";
+
+    /**
+     * @des sa-token 登陆人角色Code key
+     * */
+    String LOGIN_USER_ROLE_CODE_KEY = "LOGIN_USER_ROLE_CODE_KEY";
+
+    /**
+     * @des sa-token 登陆人角色ID key
+     * */
+    String LOGIN_USER_ROLE_ID_KEY = "LOGIN_USER_ROLE_ID_KEY";
+
+    /**
+     * @des sa-token 登陆人当前部门信息 key
+     * */
+    String LOGIN_USER_DEPT_INFO_KEY = "LOGIN_USER_DEPT_INFO_KEY";
+
+    /**
+     * @des sa-token 登陆人所有部门集合 key
+     * */
+    String LOGIN_USER_DEPT_LIST_KEY = "LOGIN_USER_DEPT_LIST_KEY";
+
+    /**
+     * @des sa-token 登陆人当前岗位信息 key
+     * */
+    String LOGIN_USER_POST_INFO_KEY = "LOGIN_USER_POST_INFO_KEY";
+
+    /**
+     * @des sa-token 登陆人所有岗位集合 key
+     * */
+    String LOGIN_USER_POST_LIST_KEY = "LOGIN_USER_POST_LIST_KEY";
+
+    /**
+     * @des 系统功能模块 前缀
+     * */
+    String SYSTEM_MODULE_PREFIX = "/system";
+
+    /**
+     * @des bi功能模块 前缀
+     * */
+    String BI_MODULE_PREFIX = "/bi";
+
+    /**
+     * @des 组织架构模块 前缀
+     * */
+    String ORGANIZATION_MODULE_PREFIX = "/organization";
+
+    /**
+     * @des 表单模块 前缀
+     * */
+    String FORM_MODULE_PREFIX = "/form";
+
+    /**
+     * @des 工作流模块 前缀
+     * */
+    String WORKFLOW_MODULE_PREFIX = "/workflow";
+
+    /**
+     * @des 打印模块 前缀
+     * */
+    String PRINT_MODULE_PREFIX = "/print";
+
+
+    /**
+     * @des 报表模块 前缀
+     * */
+    String REPORT_MODULE_PREFIX = "/report";
+
+    /**
+     * @des OA模块 前缀
+     * */
+    String OA_MODULE_PREFIX = "/oa";
+	
+    /**
+     * @Des 翻译管理模块
+     */
+    String LANGUAGE_MODULE_PREFIX = "/language";
+
+    /**
+     * @Des magic-api模块
+     */
+    String MAGICAPI_MODULE_PREFIX = "/interface";
+
+    /**
+     * @Des liteflow模块
+     */
+    String LITEFLOW_MODULE_PREFIX = "/liteflow";
+
+    /**
+     * @Des 桌面设计模块
+     */
+    String DESKTOP_MODULE_PREFIX = "/desktop";
+
+    /**
+     * @Des 数据权限模块模块
+     */
+    String AUTHORITY_MODULE_PREFIX = "/authority";
+
+    /**
+     * ERP_Unit模块
+     */
+    String CASE_ERP_UNIT = "/caseErpUnit";
+
+    /**
+     * ERP_Material模块
+     */
+    String CASE_ERP_MATERIAL = "/caseErpMaterial";
+
+    /**
+     * ERP_Bom模块
+     */
+    String CASE_ERP_BOM = "/caseErpBom";
+
+    /**
+     * ERP_Device模块
+     */
+    String CASE_ERP_DEVICE = "/caseErpDevice";
+
+    /**
+     * caseErpSupplier模块
+     */
+    String CASE_ERP_SUPPLIER = "/caseErpSupplier";
+
+    /**
+     * caseErpCustomer
+     */
+    String CASE_ERP_CUSTOMER = "/caseErpCustomer";
+    /**
+     * caseErpSale模块
+     */
+    String CASE_ERP_SALE = "/caseErpSale";
+
+    /**
+     * caseErpPurchase模块
+     */
+    String CASE_ERP_PURCHASE = "/caseErpPurchase";
+
+    /**
+     * caseErpStore模块
+     */
+    String CASE_ERP_STOR_RECCCEIPT = "/caseErpStoreReceipt";
+
+    /**
+     * caseErpPurchaseApply模块
+     */
+    String CASE_ERP_PURCHASE_APPLY = "/caseErpPurchaseApply";
+
+    /**
+     * appModel模块
+     */
+    String APP_MODEL = "/app";
+
+    /**
+     * @des 排序  降序
+     * */
+
+    String ORDER_DESC = "descend";
+
+    /**
+     * 代码生成器 默认生成路劲
+     */
+    String GENERATOR_DEFAULT_PATH = "com.xjrsoft.module";
+
+
+    /**
+     * 数据库表 固定审计字段 创建人id
+     */
+    String CREATE_USER_ID = "create_user_id";
+
+    /**
+     * 数据库表 固定审计属性 创建人id
+     */
+    String CREATE_USER_ID_PROPERTY = "createUserId";
+
+    /**
+     * 数据库表 固定审计字段 创建时间
+     */
+    String CREATE_DATE = "create_date";
+
+    /**
+     * 数据库表 固定审计属性 创建时间
+     */
+    String CREATE_DATE_PROPERTY = "createDate";
+
+    /**
+     * 数据库表 固定审计字段 修改人id
+     */
+    String MODIFY_USER_ID = "modify_user_id";
+
+    /**
+     * 数据库表 固定审计属性 修改人id
+     */
+    String MODIFY_USER_ID_PROPERTY = "modifyUserId";
+
+    /**
+     * 数据库表 固定审计字段 修改人时间
+     */
+    String MODIFY_DATE = "modify_date";
+
+    /**
+     * 数据库表 固定审计属性 修改人时间
+     */
+    String MODIFY_DATE_PROPERTY = "modifyDate";
+
+    /**
+     * 数据库表 固定审计字段 删除标记
+     */
+    String DELETE_MARK = "delete_mark";
+
+    /**
+     * 数据库表 固定审计属性 删除标记
+     */
+    String DELETE_MARK_PROPERTY = "deleteMark";
+
+    /**
+     * 数据库表 固定审计字段 修改标记
+     */
+    String ENABLED_MARK = "enabled_mark";
+
+
+    /**
+     * 数据库表 固定审计属性 修改标记
+     */
+    String ENABLED_MARK_PROPERTY = "enabledMark";
+
+    /**
+     * 数据库表 数据权限字段
+     */
+    String AUTH_USER_ID = "rule_user_id";
+
+    /**
+     * 数据库表 数据权限属性名字
+     */
+    String AUTH_USER_ID_PROPERTY = "ruleUserId";
+
+    /**
+     * 自动填充的字段
+     */
+    List<String> AUTO_INSERT = Arrays.asList(CREATE_USER_ID, CREATE_DATE, DELETE_MARK, ENABLED_MARK, AUTH_USER_ID);
+
+    /**
+     * 自动填充的字段
+     */
+    List<String> AUTO_UPDATE = Arrays.asList(MODIFY_USER_ID, MODIFY_DATE);
+
+    /**
+     * 新增自动填充的属性
+     */
+    List<String> AUTO_INSERT_PROPERTY = Arrays.asList(CREATE_USER_ID_PROPERTY, CREATE_DATE_PROPERTY, DELETE_MARK_PROPERTY, ENABLED_MARK_PROPERTY);
+
+    /**
+     * 修改自动填充的属性
+     */
+    List<String> AUTO_UPDATE_PROPERTY = Arrays.asList(MODIFY_USER_ID_PROPERTY, MODIFY_DATE_PROPERTY);
+
+    /**
+     * 数据库排序 关键字
+     */
+    String ORDER_BY = "ORDER BY";
+
+    /**
+     * 数据库 约定 自定义表单 代码生成器 生成 时间区间的字段  开始时间后缀
+     */
+    String START_TIME_SUFFIX = "Start";
+
+    /**
+     * 数据库 约定 自定义表单 代码生成器 生成 时间区间的字段  结束时间后缀
+     */
+    String END_TIME_SUFFIX = "End";
+
+    /**
+     * 框架 约定 代码生成器 生成 数据库表 默认主键名
+     */
+    String DEFAULT_PK = "id";
+
+    /**
+     * 框架 约定 代码生成器 生成 数据库表 默认主键类型
+     */
+    String DEFAULT_PK_TYPE = "Long";
+
+    /**
+     * 框架 约定 代码生成器 生成 数据库表 父子表 关联字段
+     */
+    String DEFAULT_FK = "parent_id";
+
+    /**
+     * 框架 约定 代码生成器 生成 数据库表 默认 文本类型长度
+     */
+    String DEFAULT_TEXT_LENGTH = "50";
+
+    /**
+     * 框架约定树结构的根节点parentId 统一设置为0
+     */
+    String  FIRST_NODE_VALUE  = "0";
+
+    /**
+     * 框架用户表缓存key
+     */
+    String  USER_CACHE_KEY  = "ALL_USER";
+
+
+    /**
+     * 框架角色缓存key
+     */
+    String  ROLE_CACHE_KEY  = "ALL_ROLE";
+
+    /**
+     * 框架部门缓存key
+     */
+    String  DEP_CACHE_KEY  = "ALL_DEP";
+
+    /**
+     * 用户-角色 关联数据 数据 缓存key
+     */
+    String  USER_ROLE_RELATION_CACHE_KEY  = "ALL_USER_ROLE_RELATION";
+
+    /**
+     * 用户-岗位 关联数据 数据 缓存key
+     */
+    String  USER_POST_RELATION_CACHE_KEY  = "ALL_USER_POST_RELATION";
+
+    /**
+     * 用户-组织 关联数据 数据 缓存key
+     */
+    String  USER_DEPT_RELATION_CACHE_KEY  = "ALL_USER_DEPT_RELATION";
+
+    /**
+     * 框架岗位缓存key
+     */
+    String  POST_CACHE_KEY  = "ALL_POST";
+
+    /**
+     * 数据字典分类
+     */
+    String  DIC_ITEM_CACHE_KEY  = "ALL_DIC_ITEM";
+
+
+    /**
+     * 数据字典详情
+     */
+    String  DIC_DETAIL_CACHE_KEY  = "ALL_DIC_DETAIL";
+
+    /**
+     * 数据权限
+     */
+    String  DATA_AUTH_CACHE_KEY  = "ALL_DATA_AUTH";
+
+
+    /**
+     * 数据权限 配置
+     */
+    String  DATA_AUTH_CONFIG_CACHE_KEY  = "ALL_DATA_AUTH_CONFIG";
+
+
+    /**
+     * 数据权限 关联
+     */
+    String  DATA_AUTH_RELATION_CACHE_KEY  = "ALL_DATA_AUTH_RELATION";
+
+    /**
+     * 数据权限 与表 关联
+     */
+    String  DATA_AUTH_TABLE_RELATION_CACHE_KEY  = "ALL_DATA_AUTH_TABLE_RELATION";
+
+
+    /**
+     * yyyy-MM-dd HH:mm:ss 24小时制
+     */
+    String YYYY_MM_DD_HH_MM_SS_24 = "yyyy-MM-dd HH:mm:ss";
+
+    /**
+     * yyyy-MM-dd hh:mm:ss 12小时制
+     */
+    String YYYY_MM_DD_HH_MM_SS_12 = "yyyy-MM-dd hh:mm:ss";
+
+
+    /**
+     * yyyy-MM-dd
+     */
+    String YYYY_MM_DD = "yyyy-MM-dd";
+
+    /**
+     *  HH:mm:ss 24小时制
+     */
+    String HH_MM_SS_24 = "HH:mm:ss";
+
+    /**
+     * yyyy-hh:mm:ss 12小时制-dd
+     */
+    String HH_MM_SS_12 = "hh:mm:ss";
+
+
+
+    /**
+     * 验证码
+     */
+    String CAPTCHA =  "captcha";
+
+
+    /**
+     * chatgpt 缓存前缀
+     */
+    String CHATGPT_PREFIX =  "chatgpt-";
+
+    /**
+     * 登录身份的缓存key 前缀
+     */
+    String LOGIN_IDENTITY_CACHE_PREFIX =  "identityCache:";
+
+    /**
+     * 登录人权限的缓存key 前缀
+     */
+    String PERMISSION_CACHE_PREFIX =  "permission:";
+    /**
+     * 登录验证码换成key前缀
+     */
+    String LOGIN_IMG_CAPTCHA = "imgCaptcha:";
+
+
+    /**
+     * mqtt 请求参数前缀
+     */
+    String MQTT_REQUEST_ID =  "mqttrequestid:";
+}

+ 40 - 0
src/main/java/com/xjrsoft/common/enums/AuthorizeType.java

@@ -0,0 +1,40 @@
+package com.xjrsoft.common.enums;
+
+
+/**
+ * @author Zexy
+ */
+public enum AuthorizeType {
+    /**
+     * 菜单
+     */
+    MENU(0, "菜单"),
+    /**
+     * 按钮
+     */
+    BUTTON(1, "按钮"),
+    /**
+     * 列表
+     */
+    COLUMN(2, "列表"),
+    /**
+     * 表单
+     */
+    FORM(3, "表单");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    AuthorizeType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 48 - 0
src/main/java/com/xjrsoft/common/enums/CloudType.java

@@ -0,0 +1,48 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/8 9:15
+ */
+public enum CloudType {
+    /**
+     * 七牛云
+     * */
+    QINIUCLOUD(1, "七牛云"),
+
+    /**
+     * 阿里云
+     * */
+    ALICLOUD(2, "阿里云"),
+
+    /**
+     * 腾讯云
+     * */
+    QCLOUD(3, "腾讯云"),
+
+    /**
+     * 华为云
+     * */
+    HWCLOUD(4, "华为云"),
+
+    /**
+     * Minio
+     * */
+    MINIO(5, "Minio");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    CloudType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 48 - 0
src/main/java/com/xjrsoft/common/enums/CodeRuleTypeEnum.java

@@ -0,0 +1,48 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/6/27 14:19
+ */
+public enum CodeRuleTypeEnum {
+    /**
+     * 字符串
+     */
+    CUSTOM(0, "自定义"),
+    /**
+     * 日期
+     */
+    DATE(1, "日期"),
+    /**
+     * 流水号
+     */
+    SERIAL(2, "流水号"),
+    /**
+     * 部门
+     */
+    DEPARTMENT(3, "部门"),
+    /**
+     * 用户
+     */
+    USER(4, "用户"),
+    /**
+     * 公司
+     */
+    COMPANY(5, "公司");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    CodeRuleTypeEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 41 - 0
src/main/java/com/xjrsoft/common/enums/DataAuthFieldTypeEnum.java

@@ -0,0 +1,41 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/3/1 15:12
+ */
+public enum DataAuthFieldTypeEnum {
+
+    STRING(0, "文本/字符串"),
+
+    INT(1, "数字类型"),
+
+    LOGIN_USER_ID(2, "登陆人id"),
+
+    LOGIN_DEP_ID(3, "登陆人组织架构id"),
+
+    LOGIN_DEP_CHILD_ID(4, "登陆人组织架构 和 下属组织架构 id"),
+
+    LOGIN_USER_NAME(5, "登陆人账户id"),
+
+    LOGIN_POST_ID(6, "登陆人岗位id"),
+
+    LOGIN_ROLE_ID(7, "登陆人角色id");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    DataAuthFieldTypeEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 35 - 0
src/main/java/com/xjrsoft/common/enums/DataAuthMethodEnum.java

@@ -0,0 +1,35 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/2/27 15:22
+ */
+public enum DataAuthMethodEnum {
+    /*
+     *
+     *  简易
+     * */
+    SIMPLE(0, "简易"),
+    /*
+     *  自定义
+     * */
+    CUSTOM(1, "自定义");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    DataAuthMethodEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+
+}

+ 43 - 0
src/main/java/com/xjrsoft/common/enums/DataAuthScopeEnum.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/2/28 16:19
+ */
+public enum DataAuthScopeEnum {
+
+
+    MY(0, "仅查看登录人数据"),
+
+    MY_AND_POST(1, "仅查看登录人同岗位数据"),
+
+    MY_AND_CHILD_POST(2, "仅查看登录人及所有下属岗位数据"),
+
+    MY_AND_POST_AND_CHILD_POST(3, "仅查看登录人同岗位及所有下属岗位数据"),
+
+    MY_AND_ORG(4, "仅查看登录人同组织架构人员数据"),
+
+    MY_AND_CHILD_ORG(5, "仅查看登录人及所有下属组织架构人员数据"),
+
+    MY_AND_ORG_AND_CHILD_ORG(6, "仅查看登录人同组织架构人员及所有下属组织架构人员数据"),
+
+    ROLE(7, "仅查看登录人同角色数据");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    DataAuthScopeEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+
+}

+ 34 - 0
src/main/java/com/xjrsoft/common/enums/DataAuthTypeEnum.java

@@ -0,0 +1,34 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/2/27 15:20
+ */
+public enum DataAuthTypeEnum {
+    /*
+     *
+     *  角色
+     * */
+    ROLE(0, "角色"),
+    /*
+    *  用户
+    * */
+    USER(1, "用户");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    DataAuthTypeEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 80 - 0
src/main/java/com/xjrsoft/common/enums/DbFieldsType.java

@@ -0,0 +1,80 @@
+package com.xjrsoft.common.enums;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/5/5 19:07
+ */
+public enum DbFieldsType {
+    /**
+     * 短文本
+     * */
+    VARCHAR(0, "短文本"),
+
+    /**
+     * 阿里云
+     * */
+    VARCHARMAX(1, "长文本"),
+
+    /**
+     * 数字类型
+     * */
+    INT(2, "数字"),
+
+    /**
+     * 小数
+     * */
+    FLOAT(3, "小数"),
+
+    /**
+     * 日期
+     * */
+    DATE(4, "日期"),
+
+    /**
+     * 日期时间类型
+     * */
+    DATETIME(5, "日期时间"),
+    /**
+     * 主表主键
+     * */
+    FK(6, "主表主键"),
+    /**
+     * 长整数
+     * */
+    LONG(7, "长整数"),
+    /**
+     * 时间
+     * */
+    TIME(8, "时间");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    public static DbFieldsType getFieldType(Integer fieldType) {
+        DbFieldsType[] var1 = values();
+        int var2 = var1.length;
+
+        for (DbFieldsType type : var1) {
+            if (type.code == fieldType) {
+                return type;
+            }
+        }
+
+        return VARCHAR;
+    }
+
+    DbFieldsType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/enums/DeleteMark.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/4 17:04
+ */
+public enum DeleteMark {
+    /*
+     *  未启用
+     * */
+    NODELETE(0, "未删除"),
+    /*
+     *  启用
+     * */
+    DELETED(1, "已删除");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    DeleteMark(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/enums/EnabledMark.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/3 16:37
+ */
+public enum EnabledMark {
+    /*
+    *  未启用
+    * */
+    DISABLED(0, "未启用"),
+    /*
+     *  启用
+     * */
+    ENABLED(1, "已启用");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    EnabledMark(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/FormTemplateType.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/5/10 10:36
+ */
+public enum FormTemplateType {
+
+    /**
+     * 自定义表单
+     */
+    CUSTOM(1, "自定义表单"),
+    /*
+     *  系统表单
+     */
+    SYSTEM(0, "系统表单");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    FormTemplateType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 31 - 0
src/main/java/com/xjrsoft/common/enums/IsReadTypeEnum.java

@@ -0,0 +1,31 @@
+package com.xjrsoft.common.enums;
+
+public enum IsReadTypeEnum {
+    /**
+     * 未读
+     */
+    UNREAD(0, "未读"),
+    /**
+     * 已读
+     */
+    READ(1, "已读");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    IsReadTypeEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+
+
+
+}

+ 44 - 0
src/main/java/com/xjrsoft/common/enums/LogCategory.java

@@ -0,0 +1,44 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/3 16:37
+ */
+public enum  LogCategory {
+
+    /**
+     * 登录
+     * */
+    LOGIN(1, "登录"),
+
+    /**
+     * 登录
+     * */
+    GET(2, "访问"),
+
+    /**
+     * 登录
+     * */
+    OPERAT(3, "操作"),
+
+    /**
+     * 登录
+     * */
+    EXCEPTION(4, "异常");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    LogCategory(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/enums/LogCategoryEnum.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.enums;
+
+public enum LogCategoryEnum {
+
+    LOGIN(1, "登录"),
+
+    GET(2, "访问"),
+
+    OPERAT(3, "操作"),
+
+    EXCEPTION(4, "异常"),
+
+    INTERFACE(5,"接口"),
+
+    FORM(6,"表单");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    private LogCategoryEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/MenuType.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/8/17 15:00
+ */
+public enum MenuType {
+    /**
+     * 字符串
+     */
+    MENU(0, "菜单"),
+    /**
+     * 数字
+     */
+    FUNCTION(1, "功能");
+
+    final int code;
+    final String value;
+
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    MenuType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 43 - 0
src/main/java/com/xjrsoft/common/enums/MessageType.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 消息类型
+ * @Author: tzx
+ * @Date: 2022/10/26 16:12
+ */
+public enum MessageType {
+    /**
+     * 日程
+     */
+    SCHEDULE(0, "日程"),
+    /**
+     * 工作流审批
+     */
+    APPROVE(1, "工作流审批"),
+    /**
+     * 工作流审批
+     */
+    CIRCULATED(2, "工作流传阅"),
+
+    /**
+     * 工作流审批
+     */
+    TIMEOUT(3, "超时");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    MessageType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 80 - 0
src/main/java/com/xjrsoft/common/enums/MySqlFieldsType.java

@@ -0,0 +1,80 @@
+package com.xjrsoft.common.enums;
+
+public enum MySqlFieldsType {
+    /**
+     * 短文本
+     * */
+    VARCHAR(0, "varchar", "短文本"),
+
+    /**
+     * 阿里云
+     * */
+    VARCHARMAX(1, "longtext", "长文本"),
+
+    /**
+     * 数字类型
+     * */
+    INT(2, "int", "数字"),
+
+    /**
+     * 小数
+     * */
+    FLOAT(3, "double", "小数"),
+
+    /**
+     * 日期
+     * */
+    DATE(4, "date", "日期"),
+
+    /**
+     * 日期时间类型
+     * */
+    DATETIME(5, "datetime", "日期时间"),
+    /**
+     * 主表主键
+     * */
+    FK(6, "bigint", "主表主键"),
+    /**
+     * 长整数
+     * */
+    LONG(7, "bigint", "长整数"),
+    /**
+     * 时间
+     * */
+    TIME(8, "time", "时间");
+
+    final int code;
+    final String type;
+    final String message;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public static MySqlFieldsType getFieldType(Integer fieldType) {
+        MySqlFieldsType[] var1 = values();
+        int var2 = var1.length;
+
+        for (MySqlFieldsType type : var1) {
+            if (type.code == fieldType) {
+                return type;
+            }
+        }
+
+        return VARCHAR;
+    }
+
+    MySqlFieldsType(final int code, final String type, final String message) {
+        this.code = code;
+        this.type = type;
+        this.message = message;
+    }
+}

+ 80 - 0
src/main/java/com/xjrsoft/common/enums/OracleFieldsType.java

@@ -0,0 +1,80 @@
+package com.xjrsoft.common.enums;
+
+public enum OracleFieldsType {
+    /**
+     * 短文本
+     * */
+    VARCHAR(0, "VARCHAR2", "短文本"),
+
+    /**
+     * 阿里云
+     * */
+    VARCHARMAX(1, "NCLOB", "长文本"),
+
+    /**
+     * 数字类型
+     * */
+    INT(2, "NUMBER", "数字"),
+
+    /**
+     * 小数
+     * */
+    FLOAT(3, "NUMBER", "小数"),
+
+    /**
+     * 日期
+     * */
+    DATE(4, "TIMESTAMP", "日期"),
+
+    /**
+     * 日期时间类型
+     * */
+    DATETIME(5, "TIMESTAMP", "日期时间"),
+    /**
+     * 主表主键
+     * */
+    FK(6, "VARCHAR2", "主表主键"),
+    /**
+     * 长整数
+     * */
+    LONG(7, "NUMBER", "长整数"),
+    /**
+     * 时间
+     * */
+    TIME(8, "TIME", "时间");
+
+    final int code;
+    final String type;
+    final String message;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public static OracleFieldsType getFieldType(Integer fieldType) {
+        OracleFieldsType[] var1 = values();
+        int var2 = var1.length;
+
+        for (OracleFieldsType type : var1) {
+            if (type.code == fieldType) {
+                return type;
+            }
+        }
+
+        return VARCHAR;
+    }
+
+    OracleFieldsType(final int code, final String type, final String message) {
+        this.code = code;
+        this.type = type;
+        this.message = message;
+    }
+}

+ 40 - 0
src/main/java/com/xjrsoft/common/enums/ParamAssignmentType.java

@@ -0,0 +1,40 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/10/17 14:59
+ */
+public enum ParamAssignmentType {
+    /**
+     * 值
+     */
+    VALUE(0, "值"),
+    /**
+     * 变量
+     */
+    VAR(1, "流程变量"),
+    /**
+     * api
+     */
+    API(2, "API"),
+    /**
+     * 变量
+     */
+    FORM(3, "表单");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    ParamAssignmentType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 80 - 0
src/main/java/com/xjrsoft/common/enums/PostgreSqlFieldsType.java

@@ -0,0 +1,80 @@
+package com.xjrsoft.common.enums;
+
+public enum PostgreSqlFieldsType {
+    /**
+     * 短文本
+     * */
+    VARCHAR(0, "varchar", "短文本"),
+
+    /**
+     * 阿里云
+     * */
+    VARCHARMAX(1, "text", "长文本"),
+
+    /**
+     * 数字类型
+     * */
+    INT(2, "bigint", "数字"),
+
+    /**
+     * 小数
+     * */
+    FLOAT(3, "float8", "小数"),
+
+    /**
+     * 日期
+     * */
+    DATE(4, "timestamp", "日期"),
+
+    /**
+     * 日期时间类型
+     * */
+    DATETIME(5, "timestamp", "日期时间"),
+    /**
+     * 主表主键
+     * */
+    FK(6, "bigint", "主表主键"),
+    /**
+     * 长整数
+     * */
+    LONG(7, "bigint", "长整数"),
+    /**
+     * 时间
+     * */
+    TIME(8, "time", "时间");
+
+    final int code;
+    final String type;
+    final String message;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public static PostgreSqlFieldsType getFieldType(Integer fieldType) {
+        PostgreSqlFieldsType[] var1 = values();
+        int var2 = var1.length;
+
+        for (PostgreSqlFieldsType type : var1) {
+            if (type.code == fieldType) {
+                return type;
+            }
+        }
+
+        return VARCHAR;
+    }
+
+    PostgreSqlFieldsType(final int code, final String type, final String message) {
+        this.code = code;
+        this.type = type;
+        this.message = message;
+    }
+}

+ 36 - 0
src/main/java/com/xjrsoft/common/enums/PublishStateType.java

@@ -0,0 +1,36 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/5/24 16:13
+ */
+public enum PublishStateType {
+    /*
+     * 未发布菜单
+     * */
+    NO(0, "未发布菜单"),
+    /*
+     * 正在发布
+     * */
+    ING(1, "正在发布"),
+    /*
+     * 发布过已经取消
+     * */
+    PT(2, "发布过已经取消");
+
+    final int code;
+    final String message;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    PublishStateType(final int code, final String message) {
+        this.code = code;
+        this.message = message;
+    }
+}

+ 77 - 0
src/main/java/com/xjrsoft/common/enums/ResponseCode.java

@@ -0,0 +1,77 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/3 15:49
+ */
+public enum ResponseCode {
+
+    /*
+    * 成功
+    * */
+    SUCCESS(0, "操作成功"),
+    /*
+     * 业务异常
+     * */
+    FAILURE(10400, "业务异常"),
+    /*
+     * 请求未授权
+     * */
+    UN_AUTHORIZED(10401, "请求未授权"),
+    /*
+     * 404 没找到资源
+     * */
+    NOT_FOUND(10404, "404 没找到资源"),
+    /*
+     * 消息不能读取
+     * */
+    MSG_NOT_READABLE(10400, "消息不能读取"),
+    /*
+     * 不支持当前请求方法
+     * */
+    METHOD_NOT_SUPPORTED(10405, "不支持当前请求方法"),
+    /*
+     * 不支持当前媒体类型
+     * */
+    MEDIA_TYPE_NOT_SUPPORTED(10415, "不支持当前媒体类型"),
+    /*
+     * 请求被拒绝
+     * */
+    REQ_REJECT(10403, "请求被拒绝"),
+    /*
+     * 服务器异常
+     * */
+    INTERNAL_SERVER_ERROR(10500, "服务器异常"),
+    /*
+     * 缺少必要的请求参数
+     * */
+    PARAM_MISS(10400, "缺少必要的请求参数"),
+    /*
+     * 请求参数类型错误
+     * */
+    PARAM_TYPE_ERROR(10400, "请求参数类型错误"),
+    /*
+     * 请求参数绑定错误
+     * */
+    PARAM_BIND_ERROR(10400, "请求参数绑定错误"),
+    /*
+     * 参数校验失败
+     * */
+    PARAM_VALID_ERROR(10400, "参数校验失败");
+
+    final int code;
+    final String message;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    ResponseCode(final int code, final String message) {
+        this.code = code;
+        this.message = message;
+    }
+}

+ 65 - 0
src/main/java/com/xjrsoft/common/enums/SmsCloudType.java

@@ -0,0 +1,65 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/6/6 10:24
+ */
+public enum SmsCloudType {
+    /**
+     * 阿里云
+     * */
+    ALI_CLOUD(1, "阿里云"),
+    /**
+     * 腾讯 短信
+     * */
+    TENCENT_CLOUD(2, "腾讯"),
+    /**
+     * 华为云
+     * */
+    HW_CLOUD(3, "华为云"),
+    /**
+     * 合一 短信
+     * */
+    HEYI_CLOUD(4, "合一"),
+
+    /**
+     * 京东 短信
+     * */
+    JD_CLOUD(5, "京东"),
+
+    /**
+     * 容联 短信
+     * */
+    RONGLIAN_CLOUD(6, "容联"),
+
+    /**
+     * 亿美 短信
+     * */
+    YIMEI_CLOUD(7, "亿美"),
+
+    /**
+     * 天翼云 短信
+     * */
+    TIANYI_CLOUD(8, "天翼云"),
+
+    /**
+     * 云片短信
+     * */
+    YUNPIAN_CLOUD(9, "云片");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    SmsCloudType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 43 - 0
src/main/java/com/xjrsoft/common/enums/SmsType.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/7/6 10:32
+ */
+public enum SmsType {
+    /**
+     * 验证码
+     */
+    CAPTCHA(0, "验证码"),
+
+    /**
+     * 消息通知
+     */
+    NOTIFY(1, "消息通知"),
+
+    /**
+     * 传阅通知
+     */
+    CIRCULATED(2, "传阅通知"),
+
+    /**
+     * 超时提醒
+     */
+    TIMEOUT(3, "超时提醒");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    SmsType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 80 - 0
src/main/java/com/xjrsoft/common/enums/SqlServerFieldsType.java

@@ -0,0 +1,80 @@
+package com.xjrsoft.common.enums;
+
+public enum SqlServerFieldsType {
+    /**
+     * 短文本
+     * */
+    VARCHAR(0, "nvarchar", "短文本"),
+
+    /**
+     * 阿里云
+     * */
+    VARCHARMAX(1, "nvarchar", "长文本"),
+
+    /**
+     * 数字类型
+     * */
+    INT(2, "NUMBER", "数字"),
+
+    /**
+     * 小数
+     * */
+    FLOAT(3, "float", "小数"),
+
+    /**
+     * 日期
+     * */
+    DATE(4, "datetime", "日期"),
+
+    /**
+     * 日期时间类型
+     * */
+    DATETIME(5, "datetime", "日期时间"),
+    /**
+     * 主表主键
+     * */
+    FK(6, "bigint", "主表主键"),
+    /**
+     * 长整数
+     * */
+    LONG(7, "bigint", "长整数"),
+    /**
+     * 时间
+     * */
+    TIME(8, "time", "时间");
+
+    final int code;
+    final String type;
+    final String message;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getMessage() {
+        return this.message;
+    }
+
+    public static SqlServerFieldsType getFieldType(Integer fieldType) {
+        SqlServerFieldsType[] var1 = values();
+        int var2 = var1.length;
+
+        for (SqlServerFieldsType type : var1) {
+            if (type.code == fieldType) {
+                return type;
+            }
+        }
+
+        return VARCHAR;
+    }
+
+    SqlServerFieldsType(final int code, final String type, final String message) {
+        this.code = code;
+        this.type = type;
+        this.message = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/StampEnum.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/2/21 14:09
+ */
+public enum StampEnum {
+    /**
+     * 私人签章
+     */
+    PRIVATE(0, "私人签章"),
+
+    /**
+     * 公共签章
+     */
+    PUBLIC(1, "公共签章");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    StampEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 60 - 0
src/main/java/com/xjrsoft/common/enums/TransType.java

@@ -0,0 +1,60 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/1/11 14:27
+ */
+public enum TransType {
+    /**
+     * 数据字典
+     */
+    DIC(0, "数据字典"),
+
+    /**
+     * 用户
+     */
+    USER(1, "用户"),
+    /**
+     * 机构
+     */
+    DEPT(2, "机构"),
+
+    /**
+     * 机构
+     */
+    POST(3, "岗位"),
+
+
+    /**
+     * API
+     */
+    API(4, "API"),
+
+
+    /**
+     * 行政区域
+     */
+    AREA(5, "行政区域"),
+
+
+    /**
+     * 级联
+     */
+    CASCADE(6, "级联");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    TransType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 37 - 0
src/main/java/com/xjrsoft/common/enums/TsColumnType.java

@@ -0,0 +1,37 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * typescript 字段类型美剧
+ * @Author: tzx
+ * @Date: 2022/5/27 9:44
+ */
+public enum TsColumnType {
+    /**
+     * 字符串
+     */
+    STRING(0, "字符串"),
+    /**
+     * 数字
+     */
+    NUMBER(1, "数字"),
+    /**
+     * 布尔
+     */
+    BOOL(2, "布尔");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    TsColumnType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 48 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowApproveType.java

@@ -0,0 +1,48 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/10/12 16:07
+ */
+public enum WorkflowApproveType {
+    /**
+     * 同意
+     */
+    AGREE(0, "同意"),
+    /**
+     * 拒绝
+     */
+    DISAGREE(1, "拒绝"),
+    /**
+     * 指定
+     */
+    REJECT(2, "驳回"),
+
+    /**
+     * 结束
+     */
+    FINISH(3, "结束"),
+
+    /**
+     * 其他(用户自定义)
+     */
+    OTHER(4, "其他(用户自定义)");
+
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowApproveType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowAuth.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 工作流人员权限配置
+ * @Author: tzx
+ * @Date: 2022/9/26 15:58
+ */
+public enum WorkflowAuth {
+    /**
+     * 全部
+     */
+    ALL(0, "全部"),
+    /**
+     * 指定
+     */
+    ASSIGN(1, "指定");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowAuth(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 42 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowAutoAgreeType.java

@@ -0,0 +1,42 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/10/18 14:32
+ */
+public enum WorkflowAutoAgreeType {
+    /**
+     * 无
+     */
+    NONE(0, "无"),
+    /**
+     * 候选审批人包含流程任务发起人
+     */
+    APPROVED_INCLUDE_INITIATOR(1, "候选审批人包含流程任务发起人"),
+
+    /**
+     * 候选审批人包含上一节点审批人
+     */
+    APPROVED_INCLUDE_PREV(2, "候选审批人包含上一节点审批人"),
+
+    /**
+     * 候选审批人在流传中审批过
+     */
+    APPROVED_IN_PROCESS(3, "候选审批人在流传中审批过");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowAutoAgreeType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 35 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowCallActivityType.java

@@ -0,0 +1,35 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/11/18 15:56
+ */
+public enum WorkflowCallActivityType  {
+
+    /**
+     * 单个
+     */
+    SINGLE(0,"单实例"),
+
+    /**
+     * 多实例
+     */
+    MULTI(1,"多实例");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowCallActivityType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 34 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowEventExType.java

@@ -0,0 +1,34 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 工作流事件 执行类型
+ * @Author: tzx
+ * @Date: 2023/6/7 14:10
+ */
+public enum WorkflowEventExType {
+    /**
+     * API
+     */
+    API(0, "API"),
+
+    /**
+     * 规则
+     */
+    LITEFLOW(1, "规则");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowEventExType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 34 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowEventType.java

@@ -0,0 +1,34 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 工作流事件类型
+ * @Author: tzx
+ * @Date: 2023/6/7 14:15
+ */
+public enum WorkflowEventType {
+    /**
+     * 开始事件
+     */
+    START(0, "start"),
+
+    /**
+     * 结束事件
+     */
+    END(1, "end");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowEventType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowIsPrevChooseNextType.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/12/12 18:44
+ */
+public enum WorkflowIsPrevChooseNextType {
+
+    /**
+     * 超级管理员处理
+     */
+    NONE(0, "无"),
+    /**
+     * 上节点审批人指定
+     */
+    PREV(1, "上节点审批人指定");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowIsPrevChooseNextType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 35 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowIsRecycleType.java

@@ -0,0 +1,35 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/11/1 10:48
+ */
+public enum WorkflowIsRecycleType {
+
+    /**
+     * 未移到回收站
+     */
+    NO(0,"未移到回收站"),
+
+    /**
+     * 已移到回收站
+     */
+    YES(1,"已移到回收站");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowIsRecycleType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 64 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowMemberType.java

@@ -0,0 +1,64 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 工作流成员配置类型枚举
+ * @Author: tzx
+ * @Date: 2022/9/26 16:01
+ */
+public enum WorkflowMemberType {
+    /**
+     * 用户
+     */
+    USER(0, "用户"),
+    /**
+     * 角色
+     */
+    ROLE(1, "角色"),
+
+    /**
+     * 岗位
+     */
+    POST(2, "岗位"),
+
+    /**
+     * 指定节点审批人
+     */
+    APPROVE(3,"指定节点审批人"),
+
+    /**
+     * 上级领导
+     */
+    LEADER(4,"上级领导"),
+
+    /**
+     * 表单字段
+     */
+    FORM_FIELD(5,"表单字段"),
+
+    /***
+     * API
+     */
+     API(6,"api接口"),
+
+    /**
+     * sql指定
+     */
+    SQL(7,"sql指定");
+
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowMemberType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 36 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowMultiInstanceFinishType.java

@@ -0,0 +1,36 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/5/29 16:41
+ */
+public enum WorkflowMultiInstanceFinishType {
+    /**
+     * 全部
+     */
+    ALL(0, "全部"),
+    /**
+     * 单个
+     */
+    SINGLE(1, "单个"),
+    /**
+     * 百分比
+     */
+    PERCENTAGE(2, "百分比");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowMultiInstanceFinishType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 37 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowMultiInstanceType.java

@@ -0,0 +1,37 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 工作流多实例类型
+ * @Author: tzx
+ * @Date: 2022/10/19 14:41
+ */
+public enum WorkflowMultiInstanceType {
+    /**
+     * 无
+     */
+    NONE(0, "无"),
+    /**
+     * 同步执行(并行)
+     */
+    PARALLEL(1, "同步执行(并行)"),
+    /**
+     * 顺序执行(串行)
+     */
+    SEQUENTIAL(2, "顺序执行(串行)");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowMultiInstanceType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowNoHandlerType.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 无对应处理人 类型
+ * @Author: tzx
+ * @Date: 2022/10/18 16:10
+ */
+public enum WorkflowNoHandlerType {
+    /**
+     * 超级管理员处理
+     */
+    ADMIN(0, "超级管理员处理"),
+    /**
+     * 上节点审批人指定
+     */
+    PREV(1, "上节点审批人指定");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowNoHandlerType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 47 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowNoticePolicyType.java

@@ -0,0 +1,47 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 通知策略
+ * @Author: tzx
+ * @Date: 2022/10/26 15:14
+ */
+public enum WorkflowNoticePolicyType {
+    /**
+     * 系统消息
+     */
+    SYSTEM(0, "系统消息"),
+    /**
+     * 短信
+     */
+    SMS(1, "短信"),
+    /**
+     * 企业微信
+     */
+    WECHAT(2, "企业微信"),
+
+    /**
+     * 钉钉
+     */
+    DING(3, "钉钉"),
+
+    /**
+     * 邮箱
+     */
+    EMAIL(4, "邮箱");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowNoticePolicyType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowOperationType.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 参数操作类型
+ * @Author: tzx
+ * @Date: 2022/10/14 15:49
+ */
+public enum WorkflowOperationType {
+    /*
+     *  未启用
+     * */
+    FORM(0, "表单赋值"),
+    /*
+     *  启用
+     * */
+    PARAM(1, "参数赋值");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowOperationType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 38 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowParamType.java

@@ -0,0 +1,38 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * 流程参数类型
+ * @Author: tzx
+ * @Date: 2022/9/27 11:18
+ */
+public enum WorkflowParamType {
+    /**
+     * 值
+     */
+    VALUE(0, "值"),
+    /**
+     * 变量
+     */
+    VAR(1, "变量"),
+
+    /**
+     * API
+     */
+    API(2, "API");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowParamType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/enums/WorkflowRelationAuthType.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/10/27 14:53
+ */
+public enum WorkflowRelationAuthType {
+    /**
+     * 限发起人发起的此模板任务
+     */
+    ORIGINATOR(0, "限发起人发起的此模板任务"),
+    /**
+     * 所有此模板发起的任务
+     */
+    ALL(1, "所有此模板发起的任务");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    WorkflowRelationAuthType(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 33 - 0
src/main/java/com/xjrsoft/common/enums/YesOrNoEnum.java

@@ -0,0 +1,33 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/12/16 10:06
+ */
+public enum YesOrNoEnum {
+    /**
+     * 值
+     */
+    NO(0, "否"),
+
+    /**
+     * API
+     */
+    YES(1, "是");
+
+    final int code;
+    final String value;
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    YesOrNoEnum(final int code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 86 - 0
src/main/java/com/xjrsoft/common/exception/GlobalExceptionHandler.java

@@ -0,0 +1,86 @@
+package com.xjrsoft.common.exception;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.exception.NotPermissionException;
+import com.xjrsoft.common.enums.ResponseCode;
+import com.xjrsoft.common.model.result.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.BindException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import javax.naming.NoPermissionException;
+import java.util.List;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/3 15:38
+ */
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler {
+
+    /**
+     * 全局异常处理
+     *
+     * @Author: tzx
+     */
+    @ExceptionHandler(Exception.class)
+    @ResponseBody
+    public R globalExceptionHandler(Exception e){
+        log.error(e.getMessage(), e);
+        return R.error(ResponseCode.INTERNAL_SERVER_ERROR.getCode(),e.getMessage());
+    }
+
+
+    /**
+     * 未登录异常处理
+     *
+     * @Author: tzx
+     */
+    @ExceptionHandler(NotLoginException.class)
+    @ResponseBody
+    public R notLoginExceptionHandler(NotLoginException e){
+        log.error(e.getMessage(), e);
+        return R.error(ResponseCode.UN_AUTHORIZED.getCode(),ResponseCode.UN_AUTHORIZED.getMessage());
+    }
+
+    /**
+     * 权限异常
+     *
+     * @Author: tzx
+     */
+    @ExceptionHandler(NotPermissionException.class)
+    @ResponseBody
+    public R notPermissionExceptionHandler(NotPermissionException e){
+        log.error(e.getMessage(), e);
+        return R.error(ResponseCode.UN_AUTHORIZED.getCode(),e.getMessage());
+    }
+
+    /**
+     * 参数错误异常
+     *
+     * @Author: tzx
+     */
+    @ResponseBody
+    @ExceptionHandler({BindException.class})
+    public R paramExceptionHandler(BindException e) {
+        log.error(e.getMessage(), e);
+        BindingResult exceptions = e.getBindingResult();
+        // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
+        if (exceptions.hasErrors()) {
+            List<ObjectError> errors = exceptions.getAllErrors();
+            if (!errors.isEmpty()) {
+                // 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
+                FieldError fieldError = (FieldError) errors.get(0);
+                return R.error(fieldError.getDefaultMessage());
+            }
+        }
+        return R.error("请求参数错误");
+    }
+
+}

+ 55 - 0
src/main/java/com/xjrsoft/common/exception/MyException.java

@@ -0,0 +1,55 @@
+package com.xjrsoft.common.exception;
+
+import com.xjrsoft.common.enums.ResponseCode;
+
+/**
+ * 自定义异常
+ * @author Zexy
+ * @version 1.0
+ */
+public class MyException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+	
+    private String msg;
+    private int code = ResponseCode.INTERNAL_SERVER_ERROR.getCode();
+    
+    public MyException(String msg) {
+		super(msg);
+		this.msg = msg;
+	}
+	
+	public MyException(String msg, Throwable e) {
+		super(msg, e);
+		this.msg = msg;
+	}
+	
+	public MyException(String msg, int code) {
+		super(msg);
+		this.msg = msg;
+		this.code = code;
+	}
+	
+	public MyException(String msg, int code, Throwable e) {
+		super(msg, e);
+		this.msg = msg;
+		this.code = code;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	public void setCode(int code) {
+		this.code = code;
+	}
+	
+	
+}

+ 66 - 0
src/main/java/com/xjrsoft/common/factory/AliyunCloudStorageService.java

@@ -0,0 +1,66 @@
+package com.xjrsoft.common.factory;
+
+import com.aliyun.oss.OSSClient;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.config.OSSConfig;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * 阿里云存储
+ *
+ * @author tzx
+ */
+public class AliyunCloudStorageService extends CloudStorageService {
+    private OSSClient client;
+
+    public AliyunCloudStorageService(OSSConfig config){
+        this.config = config;
+
+        //初始化
+        init();
+    }
+
+    private void init(){
+        client = new OSSClient(config.getEndpoint(), config.getAccessKey(),
+                config.getSecretKey());
+    }
+
+    @Override
+    public String upload(byte[] data, String path) {
+        return upload(new ByteArrayInputStream(data), path);
+    }
+
+    @Override
+    public String upload(InputStream inputStream, String path) {
+        try {
+            client.putObject(config.getBucketName(), path, inputStream);
+        } catch (Exception e){
+            client.putObject(config.getBucketName(), path, inputStream);
+            throw new RuntimeException("上传文件失败,请检查配置信息", e);
+        }
+        return   "https://" + config.getBucketName() + StringPool.DOT + config.getEndpoint() + StringPool.SLASH + path;
+    }
+
+    @Override
+    public String uploadSuffix(byte[] data, String suffix) {
+        return upload(data, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public String uploadSuffix(InputStream inputStream, String suffix) {
+        return upload(inputStream, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public boolean delete(String objectName) {
+        try {
+            String[] split = objectName.split(config.getBucketName() + StringPool.DOT + config.getEndpoint() + StringPool.SLASH);
+            client.deleteObject(config.getBucketName(),split[1]);
+        } catch (Exception e){
+            throw new RuntimeException("删除文件失败,请检查配置信息", e);
+        }
+        return true;
+    }
+}

+ 74 - 0
src/main/java/com/xjrsoft/common/factory/CloudStorageService.java

@@ -0,0 +1,74 @@
+package com.xjrsoft.common.factory;
+
+
+import com.xjrsoft.common.utils.DateUtils;
+import com.xjrsoft.config.OSSConfig;
+import org.apache.commons.lang.StringUtils;
+
+import java.io.InputStream;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * 云存储(支持七牛、阿里云、腾讯云、华为)
+ *
+ * @author tzx
+ */
+public abstract class CloudStorageService {
+    /** 云存储配置信息 */
+    OSSConfig config;
+
+    /**
+     * 文件路径
+     * @param prefix 前缀
+     * @param suffix 后缀
+     * @return 返回上传路径
+     */
+    public String getPath(String prefix, String suffix) {
+        //生成uuid
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        //文件路径
+        String path = DateUtils.format(new Date(), "yyyyMMdd") + "/" + uuid;
+
+        if(StringUtils.isNotBlank(prefix)){
+            path = prefix + "/" + path;
+        }
+
+        return path + suffix;
+    }
+
+    /**
+     * 文件上传
+     * @param data    文件字节数组
+     * @param path    文件路径,包含文件名
+     * @return        返回http地址
+     */
+    public abstract String upload(byte[] data, String path);
+
+    /**
+     * 文件上传
+     * @param data     文件字节数组
+     * @param suffix   后缀
+     * @return         返回http地址
+     */
+    public abstract String uploadSuffix(byte[] data, String suffix);
+
+    /**
+     * 文件上传
+     * @param inputStream   字节流
+     * @param path          文件路径,包含文件名
+     * @return              返回http地址
+     */
+    public abstract String upload(InputStream inputStream, String path);
+
+    /**
+     * 文件上传
+     * @param inputStream  字节流
+     * @param suffix       后缀
+     * @return             返回http地址
+     */
+    public abstract String uploadSuffix(InputStream inputStream, String suffix);
+
+
+    public abstract boolean  delete(String objectName );
+}

+ 64 - 0
src/main/java/com/xjrsoft/common/factory/HwCloudStorageService.java

@@ -0,0 +1,64 @@
+package com.xjrsoft.common.factory;
+
+import com.obs.services.ObsClient;
+import com.xjrsoft.config.OSSConfig;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * @Author: tzx
+ * @Date:2022/3/8 10:52
+ */
+public class HwCloudStorageService extends CloudStorageService {
+    private ObsClient client;
+
+    public HwCloudStorageService(OSSConfig config){
+        this.config = config;
+
+        //初始化
+        init();
+    }
+
+    private void init(){
+        client = new ObsClient(config.getAccessKey(),
+                config.getSecretKey(),config.getEndpoint());
+    }
+
+    @Override
+    public String upload(byte[] data, String path) {
+        return upload(new ByteArrayInputStream(data), path);
+    }
+
+    @Override
+    public String upload(InputStream inputStream, String path) {
+        try {
+            client.putObject(config.getBucketName(), path, inputStream);
+        } catch (Exception e){
+            throw new RuntimeException("上传文件失败,请检查配置信息", e);
+        }
+
+        return config.getEndpoint() + "/" + path;
+    }
+
+    @Override
+    public String uploadSuffix(byte[] data, String suffix) {
+        return upload(data, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public String uploadSuffix(InputStream inputStream, String suffix) {
+        return upload(inputStream, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public boolean delete(String objectName) {
+        try {
+            client.deleteObject(config.getBucketName(), objectName);
+        } catch (Exception e){
+            throw new RuntimeException("删除文件失败,请检查配置信息", e);
+        }
+        return true;
+    }
+
+}

+ 72 - 0
src/main/java/com/xjrsoft/common/factory/MinioService.java

@@ -0,0 +1,72 @@
+package com.xjrsoft.common.factory;
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.config.OSSConfig;
+import io.minio.MinioClient;
+import io.minio.PutObjectArgs;
+import lombok.SneakyThrows;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/**
+ * @author : tzx
+ */
+public class MinioService extends CloudStorageService {
+    private MinioClient client;
+
+    public MinioService(OSSConfig config){
+        this.config = config;
+
+        //初始化
+        init();
+    }
+
+    @SneakyThrows
+    private void init(){
+        client = MinioClient.builder().endpoint(config.getEndpoint()).credentials(config.getAccessKey(),config.getSecretKey()).build();
+    }
+
+    @Override
+    public String upload(byte[] data, String path) {
+        return upload(new ByteArrayInputStream(data), path);
+    }
+
+    @Override
+    public String upload(InputStream inputStream, String path) {
+        try {
+            PutObjectArgs args = PutObjectArgs.builder()
+                            .bucket(config.getBucketName())
+                                    .object(path).stream(inputStream,inputStream.available(), -1).build();
+            client.putObject(args);
+        } catch (Exception e){
+            throw new RuntimeException("上传文件失败,请检查配置信息", e);
+        }
+
+        return config.getEndpoint() + StringPool.SLASH + config.getBucketName() +  StringPool.SLASH + path;
+    }
+
+    @Override
+    public String uploadSuffix(byte[] data, String suffix) {
+        return upload(data, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public String uploadSuffix(InputStream inputStream, String suffix) {
+        return upload(inputStream, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public boolean delete(String objectName) {
+        try {
+            PutObjectArgs args = PutObjectArgs.builder()
+                    .bucket(config.getBucketName())
+                    .object(objectName).build();
+            client.putObject(args);
+        } catch (Exception e){
+            throw new RuntimeException("删除文件失败,请检查配置信息", e);
+        }
+        return true;
+    }
+}
+

+ 39 - 0
src/main/java/com/xjrsoft/common/factory/OssFactory.java

@@ -0,0 +1,39 @@
+
+package com.xjrsoft.common.factory;
+
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.xjrsoft.common.enums.CloudType;
+import com.xjrsoft.config.OSSConfig;
+
+/**
+ * 文件上传Factory
+ *
+ * @author tzx
+ */
+public final class OssFactory {
+
+    private static final OSSConfig OSS_CONFIG;
+
+
+    static {
+        OSS_CONFIG = SpringUtil.getBean(OSSConfig.class);
+    }
+
+    public static CloudStorageService build(){
+
+        if(OSS_CONFIG.getCloudType().getCode() == CloudType.QINIUCLOUD.getCode()){
+            return new QiniuCloudStorageService(OSS_CONFIG);
+        }else if(OSS_CONFIG.getCloudType().getCode() == CloudType.ALICLOUD.getCode()){
+            return new AliyunCloudStorageService(OSS_CONFIG);
+        }else if(OSS_CONFIG.getCloudType().getCode() == CloudType.QCLOUD.getCode()){
+            return new QcloudCloudStorageService(OSS_CONFIG);
+        }else if(OSS_CONFIG.getCloudType().getCode() == CloudType.HWCLOUD.getCode()){
+            return new HwCloudStorageService(OSS_CONFIG);
+        }else if(OSS_CONFIG.getCloudType().getCode() == CloudType.MINIO.getCode()){
+            return new MinioService(OSS_CONFIG);
+        }
+        return null;
+    }
+
+}

+ 96 - 0
src/main/java/com/xjrsoft/common/factory/QcloudCloudStorageService.java

@@ -0,0 +1,96 @@
+package com.xjrsoft.common.factory;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.qcloud.cos.COSClient;
+import com.qcloud.cos.ClientConfig;
+import com.qcloud.cos.request.DelFileRequest;
+import com.qcloud.cos.request.UploadFileRequest;
+import com.qcloud.cos.sign.Credentials;
+import com.xjrsoft.config.OSSConfig;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 腾讯云存储
+ *
+ * @author tzx
+ */
+public class QcloudCloudStorageService extends CloudStorageService {
+    private COSClient client;
+
+    public QcloudCloudStorageService(OSSConfig config) {
+        this.config = config;
+
+        //初始化
+        init();
+    }
+
+    private void init() {
+        Credentials credentials = new Credentials(config.getAppId(), config.getAccessKey(),
+                config.getSecretKey());
+
+        //初始化客户端配置
+        ClientConfig clientConfig = new ClientConfig();
+        //设置bucket所在的区域,华南:gz 华北:tj 华东:sh
+        clientConfig.setRegion(config.getRegion());
+
+        client = new COSClient(clientConfig, credentials);
+    }
+
+    @Override
+    public String upload(byte[] data, String path) {
+        //腾讯云必需要以"/"开头
+        if (!path.startsWith("/")) {
+            path = "/" + path;
+        }
+
+        //上传到腾讯云
+        UploadFileRequest request = new UploadFileRequest(config.getBucketName(), path, data);
+        String response = client.uploadFile(request);
+
+        JSONObject jsonObject = JSONObject.parseObject(response);
+        if (jsonObject.getInteger("code") != 0) {
+            throw new RuntimeException("文件上传失败," + jsonObject.getString("message"));
+        }
+
+        return config.getPrefix() + path;
+    }
+
+    @Override
+    public String upload(InputStream inputStream, String path) {
+        try {
+            byte[] data = IOUtils.toByteArray(inputStream);
+            return this.upload(data, path);
+        } catch (IOException e) {
+            throw new RuntimeException("上传文件失败", e);
+        }
+    }
+
+    @Override
+    public String uploadSuffix(byte[] data, String suffix) {
+        return upload(data, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public String uploadSuffix(InputStream inputStream, String suffix) {
+        return upload(inputStream, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public boolean delete(String objectName) {
+        try {
+            DelFileRequest request = new DelFileRequest(config.getBucketName(), objectName);
+            String response = client.delFile(request);
+            JSONObject jsonObject = JSONObject.parseObject(response);
+            if (jsonObject.getInteger("code") != 0) {
+                throw new RuntimeException("文件上传失败," + jsonObject.getString("message"));
+            }
+        }catch (Exception e){
+            throw new RuntimeException("文件上传失败,请检查配置" );
+        }
+        return true;
+    }
+}

+ 74 - 0
src/main/java/com/xjrsoft/common/factory/QiniuCloudStorageService.java

@@ -0,0 +1,74 @@
+package com.xjrsoft.common.factory;
+
+import com.qiniu.common.Zone;
+import com.qiniu.http.Response;
+import com.qiniu.storage.Configuration;
+import com.qiniu.storage.UploadManager;
+import com.qiniu.util.Auth;
+import com.xjrsoft.config.OSSConfig;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 七牛云存储
+ *
+ * @author tzx
+ */
+public class QiniuCloudStorageService extends CloudStorageService {
+    private UploadManager uploadManager;
+    private String token;
+
+    public QiniuCloudStorageService(OSSConfig config) {
+        this.config = config;
+
+        //初始化
+        init();
+    }
+
+    private void init() {
+        uploadManager = new UploadManager(new Configuration(Zone.autoZone()));
+        token = Auth.create(config.getAccessKey(), config.getSecretKey()).
+                uploadToken(config.getBucketName());
+    }
+
+    @Override
+    public String upload(byte[] data, String path) {
+        try {
+            Response res = uploadManager.put(data, path, token);
+            if (!res.isOK()) {
+                throw new RuntimeException("上传七牛出错:" + res);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("上传文件失败,请核对七牛配置信息", e);
+        }
+
+        return config.getEndpoint() + "/" + path;
+    }
+
+    @Override
+    public String upload(InputStream inputStream, String path) {
+        try {
+            byte[] data = IOUtils.toByteArray(inputStream);
+            return this.upload(data, path);
+        } catch (IOException e) {
+            throw new RuntimeException("上传文件失败", e);
+        }
+    }
+
+    @Override
+    public String uploadSuffix(byte[] data, String suffix) {
+        return upload(data, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public String uploadSuffix(InputStream inputStream, String suffix) {
+        return upload(inputStream, getPath(config.getPrefix(), suffix));
+    }
+
+    @Override
+    public boolean delete(String objectName) {
+        return false;
+    }
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/handler/ClobTypeHandler.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedTypes;
+import org.springframework.stereotype.Component;
+
+import java.sql.*;
+
+@Component
+@MappedTypes(Clob.class)
+public class ClobTypeHandler extends BaseTypeHandler<Clob> {
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Clob parameter, JdbcType jdbcType) throws SQLException {
+        ps.setCharacterStream(i, parameter.getCharacterStream());
+    }
+
+    @Override
+    public Clob getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return rs.getClob(columnName);
+    }
+
+    @Override
+    public Clob getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return rs.getClob(columnIndex);
+    }
+
+    @Override
+    public Clob getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return cs.getClob(columnIndex);
+    }
+}

+ 47 - 0
src/main/java/com/xjrsoft/common/handler/EasyExcelLocalDateTimeConverter.java

@@ -0,0 +1,47 @@
+package com.xjrsoft.common.handler;
+
+import cn.hutool.core.date.DatePattern;
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+ 
+ @Component
+public class EasyExcelLocalDateTimeConverter implements Converter<LocalDateTime> {
+ 
+    @Override
+    public Class<LocalDateTime> supportJavaTypeKey() {
+        return LocalDateTime.class;
+    }
+ 
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return CellDataTypeEnum.STRING;
+    }
+ 
+    @Override
+    public LocalDateTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern(getFormat(contentProperty)));
+    }
+ 
+    @Override
+    public WriteCellData<LocalDateTime> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
+        return new WriteCellData<>(value.format(DateTimeFormatter.ofPattern(getFormat(contentProperty))));
+    }
+
+    private String getFormat(ExcelContentProperty contentProperty) {
+        JsonFormat annotation = contentProperty.getField().getAnnotation(JsonFormat.class);
+        String format = DatePattern.NORM_DATETIME_PATTERN;
+        if (annotation != null) {
+            format = annotation.pattern();
+        }
+        return format;
+    }
+}

+ 35 - 0
src/main/java/com/xjrsoft/common/handler/FormContentStyleStrategy.java

@@ -0,0 +1,35 @@
+package com.xjrsoft.common.handler;
+
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.metadata.data.DataFormatData;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.style.AbstractVerticalCellStyleStrategy;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class FormContentStyleStrategy extends AbstractVerticalCellStyleStrategy {
+
+//    private List<String> columnTypeList;
+//
+//    public FormContentStyleStrategy(List<String> columnTypeList) {
+//        this.columnTypeList = columnTypeList;
+//    }
+
+    @Override
+    protected WriteCellStyle contentCellStyle(Head head) {
+        WriteCellStyle style = new WriteCellStyle();
+//        for (int i = 0; i < columnTypeList.size(); i++) {
+//            if (head.getColumnIndex() == i) {
+//            }
+//        }
+        DataFormatData dataFormatData = new DataFormatData();
+        dataFormatData.setIndex((short)49);
+        style.setDataFormatData(dataFormatData);
+        return style;
+    }
+
+
+}

+ 32 - 0
src/main/java/com/xjrsoft/common/handler/MyBlobTypeHandler.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.common.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedTypes;
+import org.springframework.stereotype.Component;
+
+import java.sql.*;
+
+@MappedTypes(Blob.class)
+@Component
+public class MyBlobTypeHandler extends BaseTypeHandler<Blob> {
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Blob parameter, JdbcType jdbcType) throws SQLException {
+        ps.setBinaryStream(i, parameter.getBinaryStream());
+    }
+
+    @Override
+    public Blob getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return rs.getBlob(columnName);
+    }
+
+    @Override
+    public Blob getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return rs.getBlob(columnIndex);
+    }
+
+    @Override
+    public Blob getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return cs.getBlob(columnIndex);
+    }
+}

+ 39 - 0
src/main/java/com/xjrsoft/common/handler/MyClobTypeHandler.java

@@ -0,0 +1,39 @@
+package com.xjrsoft.common.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.springframework.stereotype.Component;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@MappedJdbcTypes(value = {JdbcType.CLOB, JdbcType.NCLOB})
+@Component
+public class MyClobTypeHandler extends BaseTypeHandler<String> {
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
+            throws SQLException {
+        ps.setNString(i, parameter);
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, String columnName)
+            throws SQLException {
+        return rs.getNString(columnName);
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, int columnIndex)
+            throws SQLException {
+        return rs.getNString(columnIndex);
+    }
+
+    @Override
+    public String getNullableResult(CallableStatement cs, int columnIndex)
+            throws SQLException {
+        return cs.getNString(columnIndex);
+    }
+}

+ 55 - 0
src/main/java/com/xjrsoft/common/handler/MyDataPermissionHandler.java

@@ -0,0 +1,55 @@
+package com.xjrsoft.common.handler;
+
+import com.baomidou.mybatisplus.extension.plugins.handler.DataPermissionHandler;
+import com.xjrsoft.common.annotation.DataPermission;
+import com.xjrsoft.module.authority.entity.DataAuth;
+import com.xjrsoft.module.authority.service.IDataAuthService;
+import net.sf.jsqlparser.expression.Expression;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+/**
+ * @Description 自定义数据权限处理
+ * @Author: tzx
+ * @Date: 2023/2/6 16:54
+ */
+public class MyDataPermissionHandler implements DataPermissionHandler {
+
+
+
+    @Override
+    public Expression getSqlSegment(Expression where, String mappedStatementId) {
+        try {
+            Class<?> clazz = Class.forName(mappedStatementId.substring(0, mappedStatementId.lastIndexOf(".")));
+            DataPermission mapperAnnotation = clazz.getAnnotation(DataPermission.class);
+
+            //如果mapper 没有数据权限注解 不需要设置
+            if(mapperAnnotation == null){
+                return where;
+            }
+
+
+
+
+//            String methodName = mappedStatementId.substring(mappedStatementId.lastIndexOf(".") + 1);
+//            Method[] methods = clazz.getDeclaredMethods();
+//            for (Method method : methods) {
+//                if (!methodName.equals(method.getName())) {
+//                    continue;
+//                }
+//                // 获取自定义注解,无此注解则不控制数据权限
+//                DataPermission annotation = method.getAnnotation(DataPermission.class);
+//                if (annotation == null) {
+//                    continue;
+//                }
+//
+//            }
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        }
+        return where;
+    }
+}

+ 46 - 0
src/main/java/com/xjrsoft/common/handler/MyLocalDateTimeTypeHandler.java

@@ -0,0 +1,46 @@
+package com.xjrsoft.common.handler;
+
+import oracle.sql.TIMESTAMP;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.LocalDateTimeTypeHandler;
+
+import java.sql.*;
+import java.time.LocalDateTime;
+
+public class MyLocalDateTimeTypeHandler extends LocalDateTimeTypeHandler {
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType)
+            throws SQLException {
+        ps.setObject(i, Timestamp.valueOf(parameter));
+    }
+
+    @Override
+    public LocalDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        Object object = rs.getObject(columnName);
+        return getLocalDateTime(object);
+    }
+
+    @Override
+    public LocalDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        Object object = rs.getObject(columnIndex);
+        return getLocalDateTime(object);
+    }
+
+    @Override
+    public LocalDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        Object object = cs.getObject(columnIndex);
+        return getLocalDateTime(object);
+    }
+
+    private static LocalDateTime getLocalDateTime(Object object) throws SQLException {
+        if (object instanceof LocalDateTime) {
+            return (LocalDateTime) object;
+        } else if(object instanceof Timestamp){//在这里强行转换,将sql的时间转换为LocalDateTime
+            return ((Timestamp)object).toLocalDateTime();
+        } else  if (object instanceof TIMESTAMP) {
+            return ((TIMESTAMP) object).timestampValue().toLocalDateTime();
+        }
+        return null;
+    }
+}

+ 73 - 0
src/main/java/com/xjrsoft/common/handler/MyMetaObjectHandler.java

@@ -0,0 +1,73 @@
+package com.xjrsoft.common.handler;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.enums.DeleteMark;
+import com.xjrsoft.common.enums.EnabledMark;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+
+/**
+ * @title 数据审计处理器
+ * @desc  用于新增或者更新  自动插入 相应字段
+ * @author tzx
+ * @create 2020年11月9日 11:30:59
+ * */
+@Slf4j
+@Component
+public class MyMetaObjectHandler implements MetaObjectHandler {
+
+    /**
+     * @title 新增自动填充
+     * @desc  fieldName 使用实体类字段名 而不是数据库字段名
+     * */
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        long userId = 0L;
+        try {
+            userId = StpUtil.getLoginIdAsLong();
+        }
+        catch (Exception e) {
+            log.error("获取当前登录用户Id失败", e);
+        }
+
+        //默认插入创建人Id
+        this.strictInsertFill(metaObject, GlobalConstant.CREATE_USER_ID_PROPERTY, Long.class, userId);
+        //默认插入创建时间
+        this.strictInsertFill(metaObject, GlobalConstant.CREATE_DATE_PROPERTY, LocalDateTime.class, LocalDateTime.now());
+        //默认插入未删除
+        this.strictInsertFill(metaObject, GlobalConstant.DELETE_MARK_PROPERTY, Integer.class, DeleteMark.NODELETE.getCode());
+        //默认插入已启用
+        this.strictInsertFill(metaObject, GlobalConstant.ENABLED_MARK_PROPERTY, Integer.class, EnabledMark.ENABLED.getCode());
+        //权限所属人id
+        this.strictInsertFill(metaObject, GlobalConstant.AUTH_USER_ID_PROPERTY, Long.class, userId);
+
+    }
+
+
+    /**
+     * @title 修改自动填充
+     * @desc  fieldName 使用实体类字段名 而不是数据库字段名
+     * */
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        long userId = 0L;
+        try {
+            userId = StpUtil.getLoginIdAsLong();
+        }
+        catch (Exception e) {
+            log.error("获取当前登录用户Id失败", e);
+        }
+        //默认插入修改人Id
+        this.strictUpdateFill(metaObject, GlobalConstant.MODIFY_USER_ID_PROPERTY, Long.class, userId);
+        //默认插入修改时间
+        this.strictUpdateFill(metaObject, GlobalConstant.MODIFY_DATE_PROPERTY, LocalDateTime.class, LocalDateTime.now());
+    }
+
+
+}

+ 39 - 0
src/main/java/com/xjrsoft/common/handler/MyNVarCharTypeHandler.java

@@ -0,0 +1,39 @@
+package com.xjrsoft.common.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.springframework.stereotype.Component;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@MappedJdbcTypes(value = JdbcType.NVARCHAR)
+@Component
+public class MyNVarCharTypeHandler extends BaseTypeHandler<String> {
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
+            throws SQLException {
+        ps.setNString(i, parameter);
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, String columnName)
+            throws SQLException {
+        return rs.getString(columnName);
+    }
+
+    @Override
+    public String getNullableResult(ResultSet rs, int columnIndex)
+            throws SQLException {
+        return rs.getNString(columnIndex);
+    }
+
+    @Override
+    public String getNullableResult(CallableStatement cs, int columnIndex)
+            throws SQLException {
+        return cs.getNString(columnIndex);
+    }
+}

+ 125 - 0
src/main/java/com/xjrsoft/common/interceptor/DataScopeInnerInterceptor.java

@@ -0,0 +1,125 @@
+package com.xjrsoft.common.interceptor;
+
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.lang.TypeReference;
+import cn.hutool.core.util.EnumUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
+import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
+import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.enums.DataAuthMethodEnum;
+import com.xjrsoft.common.enums.DataAuthScopeEnum;
+import com.xjrsoft.common.enums.DataAuthTypeEnum;
+import com.xjrsoft.common.utils.RedisUtil;
+import com.xjrsoft.config.OSSConfig;
+import com.xjrsoft.module.authority.entity.DataAuth;
+import com.xjrsoft.module.authority.entity.DataAuthRelation;
+import com.xjrsoft.module.authority.entity.DataAuthTableRelation;
+import com.xjrsoft.module.authority.utils.AuthorityUtil;
+import com.xjrsoft.module.organization.entity.Department;
+import com.xjrsoft.module.organization.entity.Post;
+import com.xjrsoft.module.organization.entity.User;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.Setter;
+import lombok.SneakyThrows;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.Parenthesis;
+import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
+import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
+import net.sf.jsqlparser.schema.Table;
+import net.sf.jsqlparser.statement.select.*;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * 数据权限处理器
+ *
+ * @author tzx
+ * @Date: 2023/2/21 16:11
+ * @since 3.4.1 +
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class DataScopeInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
+
+//    private DataPermissionHandler dataPermissionHandler;
+
+    @Setter
+    private static RedisUtil redisUtil;
+
+
+    @Override
+    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
+        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) return;
+        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
+        mpBs.sql(parserSingle(mpBs.sql(), ms.getId()));
+    }
+
+    @Override
+    protected void processSelect(Select select, int index, String sql, Object obj) {
+        SelectBody selectBody = select.getSelectBody();
+        if (selectBody instanceof PlainSelect) {
+            this.setWhere((PlainSelect) selectBody, (String) obj);
+        } else if (selectBody instanceof SetOperationList) {
+            SetOperationList setOperationList = (SetOperationList) selectBody;
+            List<SelectBody> selectBodyList = setOperationList.getSelects();
+            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
+        }
+    }
+
+    /**
+     * 设置 where 条件
+     *
+     * @param plainSelect  查询对象
+     * @param whereSegment 查询条件片段
+     */
+
+    protected void setWhere(PlainSelect plainSelect, String whereSegment) {
+        //有可能是没有登录的非web请求(定时任务,初始运行) 所以必须要try catch一下
+        try {
+            //首先必须要登录 才需要判断数据权限的问题
+            if (!StpUtil.isLogin()) {
+                return;
+            }
+        } catch (Exception ignored) {
+            return;
+        }
+
+
+        FromItem fromItem = plainSelect.getFromItem();
+        Table fromTable = (Table) fromItem;
+
+        String alias = null;
+        if (ObjectUtil.isNotNull(fromTable.getAlias())) {
+            alias = fromTable.getAlias().getName();
+        }
+
+        Expression dataAuthExpression = AuthorityUtil.getDataAuthExpressionByTableName(fromTable.getName(), alias);
+
+        Expression currentExpression = plainSelect.getWhere();
+        if (ObjectUtil.isNotNull(dataAuthExpression)) {
+            if(currentExpression == null){
+                currentExpression = dataAuthExpression;
+            }
+            else {
+                currentExpression = new AndExpression(currentExpression, dataAuthExpression);
+            }
+            plainSelect.setWhere(currentExpression);
+        }
+    }
+
+}

+ 67 - 0
src/main/java/com/xjrsoft/common/interceptor/MagicApiRequestInterceptor.java

@@ -0,0 +1,67 @@
+package com.xjrsoft.common.interceptor;
+
+import cn.dev33.satoken.exception.NotPermissionException;
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.dev33.satoken.strategy.SaStrategy;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.enums.ResponseCode;
+import com.xjrsoft.common.model.result.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.ssssssss.magicapi.core.context.RequestEntity;
+import org.ssssssss.magicapi.core.interceptor.RequestInterceptor;
+import org.ssssssss.magicapi.core.model.ApiInfo;
+import org.ssssssss.script.MagicScriptContext;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * magic-api 接口鉴权
+ *
+ * @author tzx
+ */
+@Component
+@Slf4j
+public class MagicApiRequestInterceptor implements RequestInterceptor {
+
+	/***
+	 * 接口请求之前
+	 * @param requestEntity
+	 * @return
+	 */
+	@Override
+	public Object preHandle(RequestEntity requestEntity) {
+
+		if(!StpUtil.isLogin()){
+			return R.error(ResponseCode.UN_AUTHORIZED.getCode(),ResponseCode.UN_AUTHORIZED.getMessage());
+		}
+		SaSession tokenSession = StpUtil.getTokenSession();
+		List<Long> roleIds = tokenSession.get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
+		//非管理员需要进行权限验证
+		if(!roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID)) {
+			if (!SaStrategy.me.hasElement.apply(tokenSession.get(GlobalConstant.LOGIN_USER_INTERFACE_AUTH_CODE_KEY, new ArrayList<>()), requestEntity.getApiInfo().getId())) {
+				throw new NotPermissionException(requestEntity.getApiInfo().getName(), StpUtil.getLoginType());
+			}
+		}
+		return null;
+	}
+
+
+	/**
+	 * 接口执行之后
+	 * @param requestEntity
+	 * @param returnValue
+	 * @return
+	 */
+	@Override
+	public Object postHandle(RequestEntity requestEntity, Object returnValue) {
+		log.info("{} 执行完毕,返回结果:{}", requestEntity.getApiInfo().getName(), returnValue);
+		return null;
+	}
+
+
+}

+ 59 - 0
src/main/java/com/xjrsoft/common/interceptor/MagicApiWebLoginInterceptor.java

@@ -0,0 +1,59 @@
+package com.xjrsoft.common.interceptor;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.net.url.UrlBuilder;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.enums.ResponseCode;
+import com.xjrsoft.common.exception.MyException;
+import com.xjrsoft.common.model.result.R;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Enumeration;
+
+/**
+ * magicapi web页面 使用系统的登录
+ *
+ * @Author: tzx
+ * @Date: 2022/11/1 12:16
+ */
+@Component
+public class MagicApiWebLoginInterceptor implements HandlerInterceptor {
+
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+
+        // 根据parameter 判断是否有权限
+        String parameter = request.getParameter(StpUtil.getTokenName());
+
+        if (StrUtil.isBlank(parameter)) {
+            //根据Referer 判断是否有权限
+            String refererKey = "Referer";
+            String referer = request.getHeader(refererKey);
+
+            if (StrUtil.isBlank(referer)) {
+                return false;
+            } else {
+                UrlBuilder urlBuilder = UrlBuilder.ofHttp(referer, CharsetUtil.CHARSET_UTF_8);
+                CharSequence param = urlBuilder.getQuery().get(StpUtil.getTokenName());
+                if (StrUtil.isBlank(param)) {
+                    return false;
+                } else {
+                    Object loginIdByToken = StpUtil.getLoginIdByToken(param.toString());
+                    return !ObjectUtil.isNull(loginIdByToken);
+                }
+            }
+        }
+        else {
+            Object loginIdByToken = StpUtil.getLoginIdByToken(parameter);
+            return !ObjectUtil.isNull(loginIdByToken);
+        }
+
+//        return true;
+
+    }
+}

+ 43 - 0
src/main/java/com/xjrsoft/common/license/LicenseTask.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.common.license;
+
+import com.xjrsoft.common.utils.LicenseUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.Properties;
+
+/**
+ * @Author: tzx
+ * @Date: 2023/7/3 13:49
+ */
+@Component
+@EnableScheduling
+@ConditionalOnProperty(prefix = "xjrsoft.license", name = "enabled", havingValue = "true")
+public class LicenseTask  {
+
+    @Autowired
+    private ApplicationContext applicationContext;
+
+    /**
+     * 60秒检查一次
+     */
+    @Scheduled(fixedRate = 60 * 1000)
+    private void check(){
+        try {
+            LicenseUtil.loadLicense(new Properties());
+        }
+        catch (Exception e){
+            System.out.println("当前授权已经过期 请联系管理员!");
+
+            ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) applicationContext;
+            ctx.close();
+        }
+
+
+    }
+}

+ 36 - 0
src/main/java/com/xjrsoft/common/model/base/AuditEntity.java

@@ -0,0 +1,36 @@
+package com.xjrsoft.common.model.base;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 审计字段
+ * @Author: tzx
+ * @Date: 2022/5/9 14:35
+ */
+@Data
+public class AuditEntity {
+
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUserId;
+
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createDate;
+
+    @TableField(fill = FieldFill.UPDATE)
+    private Long modifyUserId;
+
+    @TableField(fill = FieldFill.UPDATE)
+    private LocalDateTime modifyDate;
+
+    @TableLogic
+    @TableField(fill = FieldFill.INSERT)
+    private Integer deleteMark;
+
+    @TableField(fill = FieldFill.INSERT)
+    private Integer enabledMark;
+}

+ 65 - 0
src/main/java/com/xjrsoft/common/model/datasource/MyColumnInfo.java

@@ -0,0 +1,65 @@
+package com.xjrsoft.common.model.datasource;
+
+import lombok.Data;
+
+/**
+ * 字段信息
+ * @Author: tzx
+ * @Date: 2022/4/25 11:46
+ */
+@Data
+public class MyColumnInfo {
+
+    /**
+     * 数据库字段名
+     */
+    private String column;
+
+    /**
+     * entity 属性名
+     */
+    private String property;
+
+    /**
+     * entity 属性类型
+     */
+    private String propertyType;
+
+    /**
+     * 数据库字段类型
+     */
+    private String dataType;
+
+
+    /**
+     * 字段长度
+     */
+    private Integer dataLength;
+
+    /**
+     * 是否为空
+     */
+    private Boolean nullable;
+
+    /**
+     * 是否为主键
+     */
+    private Boolean primaryKey;
+
+    /**
+     * 是否为自增
+     */
+    private Boolean autoIncrement;
+
+    /**
+     * 字段注释
+     */
+    private String columnComment;
+
+    /**
+     * 字段默认值
+     */
+    private String columnDefault;
+
+
+}

+ 20 - 0
src/main/java/com/xjrsoft/common/model/datasource/MyTableInfo.java

@@ -0,0 +1,20 @@
+package com.xjrsoft.common.model.datasource;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 表信息
+ * @Author: tzx
+ * @Date: 2022/4/25 11:45
+ */
+@Data
+public class MyTableInfo {
+    private String tableName;
+    private String tableComment;
+    private String pkField;
+    private String pkType;
+
+
+}

+ 84 - 0
src/main/java/com/xjrsoft/common/model/generator/ComponentConfig.java

@@ -0,0 +1,84 @@
+package com.xjrsoft.common.model.generator;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 表单组件配置
+ * @Author: tzx
+ * @Date: 2022/5/11 15:45
+ */
+@Data
+public class ComponentConfig {
+
+    /**
+     * label标签
+     */
+    private String label;
+
+    /**
+     * 组件类型
+     */
+    private String type;
+
+    /**
+     * 组件随机表示
+     */
+    private String key;
+
+    /**
+     * 绑定表名
+     */
+    private String bindTable;
+
+    /**
+     * 绑定表字段
+     */
+    private String bindField;
+
+    /**
+     * 验证
+     */
+    private List<Map<String,Object>> rules;
+
+    /**
+     * 子表单   的子组件
+     */
+    private List<ComponentConfig> children;
+
+
+    /**
+     * 栅格布局 选项卡  的子组件 特有属性
+     */
+    private List<LayoutOptionModel> layout;
+
+    /**
+     * 各组件 特殊配置信息  具体配置信息
+     */
+    private Map<String,Object> options;
+
+    /**
+     * range特有 绑定开始字段
+     */
+    private String bindStartTime;
+
+    /**
+     * range特有 绑定结束字段
+     */
+    private String bindEndTime;
+
+
+    /**
+     * 隐藏组件特有 值
+     */
+    private String value;
+
+    /**
+     * 隐藏组件特有 编码
+     */
+    private String code;
+
+    private Boolean isSubFormChild;
+}

+ 82 - 0
src/main/java/com/xjrsoft/common/model/generator/ComponentOptionConfig.java

@@ -0,0 +1,82 @@
+package com.xjrsoft.common.model.generator;
+
+import lombok.Data;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/5/11 15:55
+ */
+@Data
+public class ComponentOptionConfig {
+
+    /**
+     * 宽度
+     */
+    private String width;
+
+    /**
+     * 默认值
+     */
+    private String defaultValue;
+
+    /**
+     * 提示
+     */
+    private String placeholder;
+
+    /**
+     * 最大长度
+     */
+    private Integer maxlength;
+
+    /**
+     * 前缀
+     */
+    private String prefix;
+
+    /**
+     * 后缀
+     */
+    private String suffix;
+
+    /**
+     * 前标签
+     */
+    private String addonBefore;
+
+    /**
+     * 后标签
+     */
+    private String addonAfter;
+
+
+    /**
+     * 是否不可操作
+     */
+    private Boolean disabled;
+
+    /**
+     * 是否显示清除
+     */
+    private Boolean allowClear;
+
+    /**
+     * 是否只读
+     */
+    private Boolean readonly;
+
+    /**
+     * 远程数据的类型  可分为 静态  数据字典    数据源   接口
+     */
+    private String remoteType;
+
+    /**
+     * 数据源id
+     */
+    private String sourceId;
+
+    /**
+     * 字典id
+     */
+    private String itemId;
+}

+ 47 - 0
src/main/java/com/xjrsoft/common/model/generator/FormAttrConfig.java

@@ -0,0 +1,47 @@
+package com.xjrsoft.common.model.generator;
+
+import lombok.Data;
+
+import java.util.Map;
+
+/**
+ * 表单组件属性配置
+ * @Author: tzx
+ * @Date: 2022/5/11 15:45
+ */
+@Data
+public class FormAttrConfig {
+    /**
+     * 表单类型,modal,drawer
+     */
+    private String formType;
+    /**
+     * 表单大小 根据antd表单属性来 large  medium  small default
+     */
+    private String size;
+
+    /**
+     * 是否隐藏表单必填标记
+     */
+    private Boolean hideRequiredMark;
+
+    /**
+     * 表单布局方式 根据antd表单布局来 horizontal  vertical  inline
+     */
+    private String layout;
+
+    /**
+     * 表单标签位置 根据antd 属性来 left  right
+     */
+    private String labelAlign;
+
+    /**
+     * 表单的样式(标题宽度)
+     */
+    private Map<String, Object> labelCol;
+
+    /**
+     * 弹窗宽度
+     */
+    private Integer formWidth;
+}

+ 29 - 0
src/main/java/com/xjrsoft/common/model/generator/FormConfig.java

@@ -0,0 +1,29 @@
+package com.xjrsoft.common.model.generator;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 表单配置
+ * @Author: tzx
+ * @Date: 2022/5/11 15:43
+ */
+@Data
+public class FormConfig {
+    /**
+     * 所有组件配置
+     */
+    private List<ComponentConfig> list;
+
+    /**
+     * 表单属性配置
+     */
+    private FormAttrConfig config;
+
+    /**
+     * 隐藏组件
+     */
+    private List<Map<String, Object>> hiddenComponent;
+}

+ 17 - 0
src/main/java/com/xjrsoft/common/model/generator/LayoutOptionModel.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.common.model.generator;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 布局组件子级  tab  和   grid
+ * @Author: tzx
+ * @Date: 2022/5/25 17:54
+ */
+@Data
+public class LayoutOptionModel {
+    private String name;
+    private Integer span;
+    private List<ComponentConfig> list;
+}

+ 85 - 0
src/main/java/com/xjrsoft/common/model/result/R.java

@@ -0,0 +1,85 @@
+
+package com.xjrsoft.common.model.result;
+
+import com.xjrsoft.common.enums.ResponseCode;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+
+import java.util.HashMap;
+
+/**
+ * 返回数据
+ *
+ * @author tzx
+ */
+public class R extends HashMap<String, Object> {
+	private static final long serialVersionUID = 1L;
+	
+	public R() {
+		put("code", 0);
+		put("success", true);
+		put("msg", "");
+	}
+	
+	public static R error() {
+		return error(ResponseCode.INTERNAL_SERVER_ERROR.getCode(), "未知异常,请联系管理员");
+	}
+	
+	public static R error(String msg) {
+		return error(ResponseCode.INTERNAL_SERVER_ERROR.getCode(), msg);
+	}
+	
+	public static R error(int code, String msg) {
+		R r = new R();
+		r.put("code", code);
+		r.put("msg", msg);
+		r.put("data",null);
+		return r;
+	}
+
+	public static R ok(String msg,Object result) {
+		R r = new R();
+		r.put("msg", msg);
+		r.put("data",result);
+		return r;
+	}
+
+	public static R ok(Object result) {
+		R r = new R();
+		r.put("msg", "");
+		r.put("data",result);
+		return r;
+	}
+	
+//	public static R ok(Map<String, Object> map) {
+//		R r = new R();
+//		r.put("data",map);
+//		return r;
+//	}
+	
+	public static R ok() {
+		return new R().put("data",null);
+	}
+
+	public static ResponseEntity<byte[]> fileStream(byte[] bot, String fileName) {
+
+		HttpHeaders headers = new HttpHeaders();
+		headers.setContentDispositionFormData("attachment", fileName);
+		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
+
+		return new ResponseEntity<byte[]>(bot, headers, HttpStatus.OK);
+	}
+
+	@Override
+	public R put(String key, Object value) {
+		super.put(key, value);
+		return this;
+	}
+
+	public Object getData(){
+		return this.get("data");
+	}
+
+}

+ 38 - 0
src/main/java/com/xjrsoft/common/model/tree/ITreeNode.java

@@ -0,0 +1,38 @@
+package com.xjrsoft.common.model.tree;
+
+import java.util.List;
+
+/**
+ * @Author: tzx
+ * @Date: 2022/3/7 15:46
+ */
+public interface ITreeNode<T extends ITreeNode<T, V>, V > {
+    /**
+     * 获取id
+     *
+     * @return
+     */
+    V getId();
+
+    /**
+     * 获取父级id
+     *
+     * @return
+     */
+    V getParentId();
+
+    /**
+     * 获取子级
+     *
+     * @return
+     */
+    List<T> getChildren();
+
+    /**
+     * 设置子级
+     *
+     * @param children
+     */
+    void setChildren(List<T> children);
+
+}

+ 118 - 0
src/main/java/com/xjrsoft/common/mqtt/EmqClient.java

@@ -0,0 +1,118 @@
+package com.xjrsoft.common.mqtt;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.utils.RedisUtil;
+import com.xjrsoft.config.MqttConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.mqttv5.client.IMqttMessageListener;
+import org.eclipse.paho.mqttv5.client.MqttClient;
+import org.eclipse.paho.mqttv5.client.MqttConnectionOptions;
+import org.eclipse.paho.mqttv5.client.persist.MemoryPersistence;
+import org.eclipse.paho.mqttv5.common.MqttException;
+import org.eclipse.paho.mqttv5.common.MqttMessage;
+import org.eclipse.paho.mqttv5.common.MqttSubscription;
+import org.eclipse.paho.mqttv5.common.packet.MqttProperties;
+import org.eclipse.paho.mqttv5.common.packet.UserProperty;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * mqtt 链接
+ */
+@Component
+@Slf4j
+public class EmqClient {
+    private MqttClient mqttClient;
+
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    /**
+     * 获取所有实现了IMqttMessageListener接口的类
+     */
+    @Autowired
+    private MqttServiceLocator mqttServiceLocator;
+
+    @PostConstruct
+    private void init() {
+
+        MqttConfig mqttConfig = SpringUtil.getBean(MqttConfig.class);
+
+        if (mqttConfig.getServer() == null) {
+            return;
+        }
+
+        MemoryPersistence persistence = new MemoryPersistence();
+        try {
+            mqttClient = new MqttClient(mqttConfig.getServer(), "tl" + IdUtil.simpleUUID(), persistence);
+            //Paho Mqtt 连接参数
+            MqttConnectionOptions connOpts = new MqttConnectionOptions();
+            connOpts.setCleanStart(true);
+            connOpts.setKeepAliveInterval(180);
+            if (mqttConfig.getUsername() != null) {
+                connOpts.setUserName(mqttConfig.getUsername());
+                connOpts.setPassword(mqttConfig.getPassword().getBytes());
+            }
+            //Paho Mqtt5 设备上报QoS1&QoS2消息流控
+            connOpts.setReceiveMaximum(5);
+            //自动重连
+            connOpts.setAutomaticReconnect(true);
+
+            //Paho Mqtt5 设备接收的最大报文长度
+//            connOpts.setMaximumPacketSize(1024L);
+
+            mqttClient.connectWithResult(connOpts);
+
+            // 订阅已实现的topic
+            Map<String, IMqttMessageListener> allTopic = mqttServiceLocator.getMap();
+
+            allTopic.forEach((k, v) -> {
+                MqttSubscription[] subscriptions = new MqttSubscription[]{new MqttSubscription(k)};
+                IMqttMessageListener[] subscriptionListeners = new IMqttMessageListener[]{v};
+                try {
+                    mqttClient.subscribe(subscriptions, subscriptionListeners);
+                } catch (MqttException e) {
+                    log.error(e.getMessage(), "mqtt 错误!");
+                }
+            });
+        } catch (Exception e) {
+            log.error(e.getMessage(), "mqtt 连接失败!");
+        }
+    }
+
+    // 发送消息
+    public void publish(String topic, Object msg) throws MqttException {
+        if (mqttClient != null) {
+            // 组装参数
+            String msgStr = JSONUtil.toJsonStr(msg);
+            MqttMessage message = new MqttMessage(msgStr.getBytes());
+            message.setQos(1);
+
+            String requestId = IdUtil.simpleUUID();
+
+            MqttProperties properties = new MqttProperties();
+            properties.setCorrelationData(requestId.getBytes());
+            message.setProperties(properties);
+
+            // 参数存入redis中
+            redisUtil.set(GlobalConstant.MQTT_REQUEST_ID + requestId, msgStr, 86400);
+
+            mqttClient.publish(topic, message);
+        }
+    }
+
+    // 根据请求编号获取参数
+    public String getRequestParams(String requestId) {
+        return redisUtil.get(GlobalConstant.MQTT_REQUEST_ID + requestId);
+    }
+}

+ 40 - 0
src/main/java/com/xjrsoft/common/mqtt/MqttServiceLocator.java

@@ -0,0 +1,40 @@
+package com.xjrsoft.common.mqtt;
+
+import org.eclipse.paho.mqttv5.client.IMqttMessageListener;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 获取所有实现了IMqttMessageListener接口的类
+ */
+@Component
+public class MqttServiceLocator implements ApplicationContextAware {
+
+    public Map<String, IMqttMessageListener> getMap() {
+        return map;
+    }
+
+    /**
+     * 用于保存接口实现类名及对应的类
+     */
+    private Map<String, IMqttMessageListener> map;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        //根据接口类型返回相应的所有bean
+        map = applicationContext.getBeansOfType(IMqttMessageListener.class);
+    }
+
+    /**
+     * 获取对应服务
+     * @param key
+     * @return
+     */
+    public IMqttMessageListener getService(String key) {
+        return map.get(key);
+    }
+}

Vissa filer visades inte eftersom för många filer har ändrats