Compare commits

...

3 Commits

Author SHA1 Message Date
clay 3601965980 clay commit : workflow查看
continuous-integration/drone/push Build is failing Details
2023-05-11 14:58:45 +08:00
clay 91325c062b clay commit : 新内容编写 2023-05-10 23:56:56 +08:00
clay ba068cd992 clay commit : @Excel使用 2023-05-07 16:31:09 +08:00
15 changed files with 372 additions and 124 deletions

View File

@ -61,6 +61,7 @@ module.exports = {
'/module/gateway/',
'/module/auth/',
'/module/umps/',
'/module/notice/',
'/module/visual/',
] // 根据自己的需求来订对应自己在docs下的文件夹名默认首页是README.md
},

View File

@ -1,26 +1,33 @@
# 模块信息
> 以下是security-cloud所以模块,本章节将对其中的每一个模块进行详细的介绍。
```lua
security-cloud
├── auth -- 授权服务模块
├── gateway -- 网关服务模块
├── auth -- 授权服务提供
└── common -- 系统公共模块
├── common-core -- 公共工具类核心包
├── common-dubbo -- dubbo rpc服务
├── common-email -- 邮件发送服务
├── common-file -- 分布式文件存储
├── common-mybatis -- mybatis 扩展封装
├── common-redis -- redis序列化封装
├── common-security -- 安全工具类
├── common-swagger -- 接口文档
├── common-feign -- feign 扩展封装
├── common-oss -- 阿里云oss封装
└── common-log -- 系统日志记录
├── common-swagger -- swagger接口文档
├── common-log -- 系统日志记录
└── common-websocket -- netty集群实现的websocket服务
└── notice -- 通用消息公告模块
├── notice-api -- 通用消息公告模块公共api模块
└── notice-biz -- 通用消息公告模块业务处理模块[5000]
└── upms -- 通用用户权限管理模块
├── upms-api -- 通用用户权限管理系统公共api模块
└── upms-biz -- 通用用户权限管理系统业务处理模块[4000]
└── visual -- 图形化管理模块
├── code-gen -- 分布式可视化代码生成
├── custom-query -- 自定义查询
├── flowable -- workflow工作流模块
├── code-gen -- 代码生成模块
├── custom-query -- 自定义查询模块
├── flowable -- flowable实现的workflow模块
├── monitor -- 服务监控
├── sentinel-dashboard -- sentinel监控面板
└── sentinel-dashboard-pro -- sentinel监控面板,配置规则同步到nacos管理
├── sentinel-dashboard -- sentinel 官方版
├── sentinel-dashboard-pro -- sentinel 线上版,集成nacos
└── xxl-job-admin -- 定时任务管理器
```

View File

@ -1,8 +1,9 @@
# 系统公共模块
系统公共模块主要对集群中的基础公共工具进行封装,现阶段对如需模块进行封装:
系统公共模块主要对集群中的基础公共工具进行封装,提供更加高效的开发效率
## common-core 基础核心组件
对系统中的基础服务实体进行定义,基础的工具类进行定义.例如:
## common-core
### 简介
对系统中的基础服务实体进行定义,基础的工具类进行定义.例如:list转Tree工具类,反射方式获取到用户信息等
### TreeUtil
自定义树形结构实体转换,可以将A对象结构具有树形关系的list转换成B对象的树形结构, 可以自定义A B两个对象之间的映射关系例如:
@ -61,10 +62,22 @@ List<OptionTree> optionTreeList = TreeUtil.build(deptList,OptionTree.class,(conf
- exclude排除字段
## common-dubbo
对dubbo的基础依赖
### 简介
对dubbo的基础依赖进行引入,后期进行全局的dubbo功能封装
## common-log
自定义操作日志模块,完成使用自定义注解实现操作日志的记录
### 简介
自定义操作日志模块,完成使用自定义注解`@Log`实现操作日志的记录
`@Log`注解参数说明
| 参数 | 类型 | 默认 | 描述|
| :-- | :-- | :-- | :-- |
| title | String | 空 | 日志记录名称 |
| businessType | BusinessType | OTHER | 功能,具体操作有 OTHER,INSERT,UPDATE,DELETE,GRANT,EXPORT,IMPORT,FORCE,GENCODE,CLEAN,BIND |
| operatorType | OperateType | MANAGE | 操作人类别 |
| isSaveRequestData | boole | 空 | 是否保存请求的参数 |
### 使用
```javascript
@ApiOperation("新增部门")
@PostMapping
@ -80,116 +93,68 @@ public Result<Void> add(@RequestBody @Validated Dept dept){
```
通过LogAspect实现当前注解的apo切面,切面中将操作的日志封装成一个操作日志对象,然后使用spring的事件发布机制发布这个日志操作对象,再使用OperationLogListener异步监听到发布的事件,再通过rpc远程调用到umps中的日志存储接口,将当前对象落地到数据库
`@Log`注解参数说明
|参数 | 类型 | 默认 | 描述|
| :-- | :-- | :-- | :-- |
| title | String | 空 | 日志记录名称 |
| businessType | BusinessType | OTHER | 功能,具体操作有 OTHER,INSERT,UPDATE,DELETE,GRANT,EXPORT,IMPORT,FORCE,GENCODE,CLEAN,BIND |
| operatorType | OperateType | MANAGE | 操作人类别 |
| isSaveRequestData | boole | 空 | 是否保存请求的参数 |
## common-mybatis
为了更加方便的使用系统分页,我们对mybatis的pageHelper做了一些封装
### PageUtils类
```javascript
/**
* 分页工具类
*
* @author Clay
* @date 2022/10/30
*/
public class PageUtils extends PageHelper {
### 简介
对mybatis的分页插件进行封装,使用注解+aop+mybatis拦截器实现自动注入用户信息或者时间
/**
* 设置请求分页
*/
public static void startPage() {
Page page = TableSupport.buildPageRequest();
Integer pageNum = page.getPageNum();
Integer pageSize = page.getPageSize();
String orderBy = SqlUtil.escapeOrderBySql(page.getOrderBy());
Boolean reasonable = page.getReasonable();
PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);
}
/**
* 开始的Size
*
* @param page
* @return
*/
public static Integer getStartSize(Page page) {
return (page.getPageNum() - 1) * page.getPageNum();
}
public static Integer getStartSize() {
Page page = TableSupport.buildPageRequest();
return (page.getPageNum() - 1) * page.getPageSize();
}
/**
* 获取到分页后的数据信息
*
* @param list
* @param <T>
* @return
*/
public static <T> TableDataInfo<T> getDataTable(List<T> list) {
if (null == list) {
return new TableDataInfo<>(new ArrayList<>(), 0);
}
TableDataInfo<T> tableDataInfo = new TableDataInfo<>();
tableDataInfo.setRows(list);
tableDataInfo.setTotal(getTotal(list));
return tableDataInfo;
}
/**
* 获取到分页的总数
*
* @param list
* @return
*/
public static Long getTotal(List<?> list) {
long total = new PageInfo<>(list).getTotal();
clearPage();
return total;
}
/**
* 转换为TableDataInfo对象
*
* @param list
* @param count
* @param <T>
* @return
*/
public static <T> TableDataInfo<T> convertDataTable(List<T> list, Long count) {
if (null == list) {
return new TableDataInfo<>(new ArrayList<>(), 0);
}
TableDataInfo<T> tableDataInfo = new TableDataInfo<>();
tableDataInfo.setRows(list);
tableDataInfo.setTotal(count);
return tableDataInfo;
}
/**
* 清理分页的线程变量
*/
public static void clearPage() {
PageHelper.clearPage();
}
}
```
### 分页操作
只需要在执行SQL的Mapper之前调用`PageUtils.startPage()`方法,然后调用SQL执行方法,再使用获取到的数组调用PageUtils.getDataTable(list)方法获取到封装好的返回结果对象即。
- 代码演示
```java
@Override
public TableDataInfo<DemoVo> searchDemoList(DemoQuery query) {
PageUtils.startPage();
List<Demo> list = demoMapper.selectDemoList(query);
Long total = PageUtils.getTotal(list);
List<DemoVo> convertList = list.stream().map(DemoVo::toDemoVo).collect(Collectors.toList());
return PageUtils.convertDataTable(convertList, total);
}
```
> 注意,上方代码为需要将Demo 转换为 DemoVo 如果无需转换,则可直接调用`PageUtils.getDataTable(list)`方法
### 自动注入能力
自动注入使用场景为,当实体累中在特定的时间或者业务之下,需要设置一些固定的参数时,可以使用到此功能,列如当实体类中存在createBy,createTime,updateBy,updateTime等固定字段,在创建和更新的时候都需要固定的设置参数时,可以使用到此功能
- `@EnableAutoField` 开启mybatis的自动注入能力
- `@GenerateId` 自动生成id并注入
- `@AutoUser` 自动注入一些用户信息
- `@AutoTime` 自动注入时间
#### `@GenerateId`注解参数说明
|参数 | 类型 | 默认 | 描述|
| :-- | :-- | :-- | :-- |
| idType | GenIdEnum | UUID | 需要生成的id类型 |
`@GenerateId`为实现需要指定id时候使用,可以自动生成指定类型的id,并注入其中,支持UUID的生成
#### `@AutoUser`注解参数说明
|参数 | 类型 | 默认 | 描述|
| :-- | :-- | :-- | :-- |
| value | AutoUserEnum | USER_NAME | 需要注入的用户信息 |
| method | MethodEnum | 空 | 指定SQL执行方法下进行自动注入 |
`@AutoUser`可以根据用户需要设置那种用户信息和具体SQL执行的那种类型的方法情况下自动注入需要的信息
#### `@AutoTime`注解参数说明
|参数 | 类型 | 默认 | 描述|
| :-- | :-- | :-- | :-- |
| method | MethodEnum | 空 | 指定SQL执行方法下进行自动注入 |
`@AutoTime`可以根据SQL执行的方法类型进行匹配,自动创建时间对象并注入
## common-file
### 简介
在集群环境下文件不能够单独放置在某一个单一节点执行需要集中存储起来我们提供了阿里云的oss自建服务的minio以及轻量化的ftp三种模式
### 使用
1. 将依赖引入到对应的pom.xml中
```xml
<!--文件组件-->
<dependency>
<groupId>cn.odliken</groupId>
<artifactId>common-file</artifactId>
</dependency>
```
2. 在yml文件中配置好信息
```yml
file:
@ -219,20 +184,202 @@ file:
# 需要保密的文件资源
prifiles: prifiles
```
3. 注入`FileStoreService`接口,需要指定使用那种类型的文件储存,也可以直接注入具体的实现类
```java
/**
* 文件存储服务接口类
*
* @author Clay
* @date 2023-02-16
*/
public interface FileStoreService {
/**
* 创建文件桶
*
* @param bucketName 桶名
* @return 创建结果
*/
Boolean createBucket(String bucketName);
/**
* 删除文件桶
*
* @param bucketName 桶名
* @return 删除结果
*/
Boolean deleteBucket(String bucketName);
/**
* 上传文件
*
* @param file 文件对象
* @return FileInfo对象
*/
FileInfo upload(MultipartFile file);
/**
* 上传文件
*
* @param bucket 文件桶名
* @param file 文件对象
* @return FileInfo对象
*/
FileInfo upload(String bucket, MultipartFile file);
/**
* 下载文件
*
* @param fileUri 文件的资源定位符
* @return 文件流
*/
InputStream download(String fileUri);
/**
* 下载文件
*
* @param bucket 文件桶名
* @param fileUri 文件的资源定位符
* @return 文件流
*/
InputStream download(String bucket, String fileUri);
/**
* 删除文件
*
* @param fileUri 文件的资源定位符
* @return 删除状态
*/
Boolean delete(String fileUri);
/**
* 删除文件
*
* @param bucket 文件桶名
* @param fileUri 文件的资源定位符
* @return 删除状态
*/
Boolean delete(String bucket, String fileUri) throws IOException;
}
```
4. `FileStoreCombinationService`类可以直线多种对象存储混合使用,只需要在方法上添加上需要指定的储存类型枚举即可
## common-redis
使redis使用FastJson序列化,对RedisTemplate进行进一步的函数封装
### 简介
对redis中`RedisTemplate`进行了fastjson序列化的封装,也保留了原本的Java序列化方式
对fastjson序列化封装的`RedisTemplate`进行了进一步的封装实现了`RedisService`,让开发者更方便的使用
## common-security
### 简介
集群中最核心的部分,spring security 安全校验封装,自定义PermissionService实现spring security自定校验方法,实现自定义校验逻辑,使用Inner注解实现集群内rpc远程调用接口的区分
## common-swagger
### 简介
swagger接口文档配置,通过SwaggerConfig类从nacos中获取到当前服务对应的swagger配置信息,生成当前服务的swagger接口文档数据,配合gateway swagger聚合生成集群的swagger聚合文档
解决swagger聚合文档请求/v3/doc-api接口时,swaggerui无法发起请求的bug
### 使用
1. 引入配置
```xml
<!--swagger文档-->
<dependency>
<groupId>cn.odliken</groupId>
<artifactId>common-swagger</artifactId>
</dependency>
```
2. 在yml中填写好配置信息
```yaml
swagger:
title: 演示api文档
description: 演示api文档
```
## common-email
### 简介
为系统提供最基础的邮件发送功能,其中实现同步邮件发送和异步邮件发送两种功能实现
### 使用
1. 引入依赖
```xml
<!--邮件发送组件-->
<dependency>
<groupId>cn.odliken</groupId>
<artifactId>common-email</artifactId>
</dependency>
```
2. 在yml中填写好配置信息
```yaml
email:
sender: 发送人邮箱
personal: 发送人名称
email-smtp-host: 邮件服务器
email-smtp-port: 邮件服务器端口
username: 发送人用户名
password: 发送人密码
encryption: 加密协议
```
3. 使用
注入`EmailService`后,使用`EmailService`中的同步发送邮件或者异步发送邮件即可进行邮件发送
## common-lock
### 简介
为系统提供分布式锁的能力,采用的是redisson实现,其中使用注解+aop+反射实现防重复提交和接口的分布式锁访问两大功能,并对提供封装好的分布式锁服务类
### 防重复提交
防重复提交是指在进行数据提交的过程中,防止用户重复提交相同的数据或者重复执行同一操作的一种技术手段。这种技术手段的主要目的是避免数据的重复录入或者重复操作所带来的不必要的麻烦和风险,同时也可以提高应用程序的稳定性和可靠性。系统使用后端校验+分布式锁的方式实现
### 锁的唯一性
锁的唯一性保证是通过用户登录后的token(匿名用户则使用客户端ip)+加上uri+方法请求类型+需要使用的请求参数组成的key保证锁的唯一性
### 使用
1. 引入依赖
```xml
<dependency>
<groupId>cn.odliken</groupId>
<artifactId>common-lock</artifactId>
</dependency>
```
2. 在接口上添加注解
```java
@PostMapping
@ResubmitLock
public Result<String> login(@Validated @RequestBody LoginBody login) {
return Result.ok("操作成功");
}
```
3. 拦截效果
![img.png](./img.png)
### 通用分布式锁
通用分布式锁主要通过
### 分布式锁
分布式锁的实现与防重复提交实现原理相似,也是采用注解+aop+反射实现
## common-websocket
### 简介
该模块使用Netty搭建websocket服务,并将websocket服务注册到nacos实现Netty集群,之后可以使用Gateway实现代理和负载均衡
### 使用
1. 引入依赖
```xml
<dependency>
<groupId>cn.odliken</groupId>
<artifactId>common-websocket</artifactId>
</dependency>
```
2. 配置yml文件
```yaml
websocket:
application-name: netty-application-name
port: 8080
path: /websocket
```

BIN
docs/module/common/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,32 @@
# 通用消息公告模块
## 简介
痛用消息模块使用netty实现的websocket,引入common-websocket模块进行实现,基于netty集群+rabbitmq实现集群模式下的消息精准推送功能。
通用消息模块可为系统任意模块提供消息发布和websocket消息推送功能,并对外提供rpc消息发送功能。
消息推送时可以指定发送到指定用户,发送到指定角色,发送到指定部门或者全部发送四大模式。
在用户侧websocket不作为用户与service进行消息发送的桥梁,websocket只会进行消息的推送和授权,消息的发送则是使用消息发送接口进行。
## 消息推送时序图
![img.png](./img.png)
## 消息发送确认机制
![img_1.png](./img_1.png)
- 当用户发送消息后,消息首选会数据库进行持久化,持久化成功推送至mq,若消息推送失败则发生数据库回滚。
- mq接受到消息之后,向netty的监听服务发起事件,netty进行消费,消费成功手动ack确认,若3次消费失败,则认为当前服务消费失败,手动ack确认消息消费失败,并删除mq中的消息。
## websocket连接与授权
连接: websocket请求url为http://gateway-service/notice-ws/notice。
授权: 授权需要获取到用户登录时获取到的token,并按照规定数据格式在连接成功websocket之后发送授权信息。
```json
{
"token": "用户令牌",
"cluster": "消息群组"
}
```
## notice服务实现模块分离
在notice服务中,消息体或者websocket连接用户授权是都需要指定到消息群组(cluster),notice服务则通过cluster区分消息群组,并对其用户的websocket连接进行隔离。

BIN
docs/module/notice/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -17,10 +17,71 @@
## custom-query(正在规划)
将ebts中的自定义查询和er可视化查询集群化,ebts网站:https://demo.ebts.top/
## flowable(收尾中)
使用flowable实现workflow的开发,新阶段实现了json转bnpm,流程发布,流程流转,流程流转的位置等
## flowable
### 简介
flowable模块为系统提供工作流的服务支撑前端采用开源的防钉钉bpmn编辑器并对前端编辑器进行升级和自定义功能的开发
demo(访问时提示无权限时请刷新,刷新后正常使用): http://workflow.mytwins.top/
### 实现功能
- 流程发布
- 自定义表单
- 表单节点权限控制
- 流程流转
- 全新的日志记录
- 发起流程时全新的全局流程
- 流程流转是邮件提醒
- 自定义监听器
- 触发器http请求js可编程影响流程流转结果
- 流程自定义任意节点回滚
- 表单编辑器可自定义组件开发
### 1. 流程发布
流程发布为workflow第一个步骤需要用户自定义流程配置审批表单并且可以对表单权限与节点权限进行控制
#### 审批流程
审批流程共实现如下节点
- 审批人:审批节点,可以选择指定用户对本次流程进行审批
- 抄送人:将当前流程抄送给设置的用户进行查看
- 条件分支:可以设置对条件影响流程的执行,其中可使用表单中的参数
- 并行分支:可以同时执行两条或多条审批路线
- 延时等待:可以让流程在指定时间或者指定等待时间执行
- 触发器可以发起http请求或者邮件
#### 审批人
审批人实现多种方式指定审批人,配置下图所示:
![img.png](./img.png)
当用户选择了对应的审批对象后,系统则会根据对应的审批对象去获取对应的审批人,加入到审批流程中,并且还对其审批人为和审批期限进行辅助
#### 抄送人
抄送人节点只需要选择对应的抄送人即可,后续可扩展和审批人相同的选择审批对象
#### 条件分支
条件分支节点下可以设置多种条件,条件可以进行多种自定义组合,实现用户指定的流程流转方向
#### 触发器
触发器可以发起http请求或者email邮件发起http请求的时候可以编写自定义脚本来处理http的响应结果并可以影响到整个流程的流程
#### 流程简单demo
![img_1.png](./img_1.png)
### 自定义表单
自定义表单实现为拖拽的方式进行表单的自定义设计,这样用户就可以制作任意业务需求的表单满足所以的业务场景
![img_2.png](./img_2.png)
### 发起流程
流程发起提供左右两个区域,左侧区域为表单输入位置,右侧为流程的预览,此处可以看到流程执行情况以及当前流程对应的审批人
![img_3.png](./img_3.png)
### 查看流程
到我的处理页面即可查看到需要当前登录用户处理的流,点击之后就可以看到流程的信息,此处定制开发流程的日志信息
![img_4.png](./img_4.png)
### 我发起的流程
登录用户查看我发起的,当前页面可以查看到流程当前的节点,当前的审批人,流程状态等,点击流程就可以查看到流程的详细情况,详细情况和查看流程完全一样,并且新增全局的流程信息
![img_5.png](./img_5.png)
![img_6.png](./img_6.png)
流程全局预览和日志记录可以记录每个操作的情况,列如那些用户没有审批,那些节点处于审批状态,那个节点被拒绝,并且拒绝的用户是谁等都可以记录下来,方便后续精准的定位人员
## sentinel-dashboard
sentinel的控制面板

BIN
docs/module/visual/img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB