358 lines
11 KiB
Markdown
358 lines
11 KiB
Markdown
# 系统公共模块
|
||
系统公共模块主要对集群中的基础公共工具进行封装,提供更加高效的开发效率
|
||
|
||
## common-core
|
||
### 简介
|
||
对系统中的基础服务实体进行定义,基础的工具类进行定义.例如:list转Tree工具类,反射方式获取到用户信息等
|
||
|
||
### TreeUtil
|
||
自定义树形结构实体转换,可以将A对象结构具有树形关系的list转换成B对象的树形结构, 可以自定义A B两个对象之间的映射关系例如:
|
||
|
||
将Dept映射到OptionTree对象:
|
||
```javascript
|
||
//Dept 类
|
||
public class Dept extends BaseEntity {
|
||
private Long deptId;
|
||
private Long parentId;
|
||
private String ancestors;
|
||
@NotBlank(message = "部门名称不能为空!")
|
||
private String deptName;
|
||
@NotBlank(message = "显示顺序不能为空!")
|
||
private String orderNum;
|
||
@NotBlank(message = "负责人不能为空!")
|
||
private String leader;
|
||
@NotNull(message = "负责人id不能为空!")
|
||
private Long leaderId;
|
||
}
|
||
|
||
//OptionTree 目标对象
|
||
@Builder
|
||
@NoArgsConstructor
|
||
@AllArgsConstructor
|
||
public class OptionTree implements Serializable {
|
||
/**
|
||
* 节点ID
|
||
*/
|
||
private Object value;
|
||
/**
|
||
* 节点名称
|
||
*/
|
||
private String label;
|
||
/**
|
||
* 子节点
|
||
*/
|
||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||
private List<OptionTree> children;
|
||
}
|
||
|
||
//转换代码
|
||
List<OptionTree> optionTreeList = TreeUtil.build(deptList,OptionTree.class,(config)->{
|
||
config.setIdField("deptId");
|
||
config.setOption("deptId","deptName");
|
||
});
|
||
|
||
```
|
||
|
||
并且TreeUtil可以通过config进行自定义配置,配置项如下:
|
||
- 是否启用BeanUtils.copyProperties方法进行字段的copy(默认为ture)
|
||
- 父级关系字段名称定义
|
||
- id字段定义
|
||
- tree子级字段定义
|
||
- mapper其余字段关系映射
|
||
- exclude排除字段
|
||
|
||
## common-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
|
||
@PreAuthorize("@ss.hasPermission('admin:dept:add')")
|
||
@Log(title = "新增部门",businessType = BusinessType.INSERT)
|
||
public Result<Void> add(@RequestBody @Validated Dept dept){
|
||
if (UserConstants.DEPT_DISABLE.equals(deptService.checkDeptNameUnique(dept))){
|
||
return Result.error("新增部门: "+ dept.getDeptName() +"'失败,部门名称以存在!");
|
||
}
|
||
deptService.saveDept(dept);
|
||
return Result.ok();
|
||
}
|
||
```
|
||
通过LogAspect实现当前注解的apo切面,切面中将操作的日志封装成一个操作日志对象,然后使用spring的事件发布机制发布这个日志操作对象,再使用OperationLogListener异步监听到发布的事件,再通过rpc远程调用到umps中的日志存储接口,将当前对象落地到数据库
|
||
|
||
|
||
## common-mybatis
|
||
### 简介
|
||
对mybatis的分页插件进行封装,使用注解+aop+mybatis拦截器实现自动注入用户信息或者时间
|
||
|
||
### 分页操作
|
||
只需要在执行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:
|
||
store:
|
||
minio:
|
||
endpoint: endpoint
|
||
bucket: bucket
|
||
access-key: access-key
|
||
secret-key: secret-key@2023
|
||
aliyun:
|
||
endpoint: endpoint
|
||
#AccessId 和 AccessKey
|
||
access-key-id: access-key-id
|
||
secret-access-key: secret-access-key
|
||
#创建的Bucket
|
||
bucket: bucket
|
||
ftp:
|
||
address: address
|
||
port: port
|
||
username: username
|
||
password: password
|
||
encoding: UTF-8
|
||
# 静态资源路径
|
||
asset: asset
|
||
# 公共文件资源
|
||
pubfiles: pubfiles
|
||
# 需要保密的文件资源
|
||
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中`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+反射实现防重复提交和接口的分布式锁访问两大功能,并对提供封装好的分布式锁服务类
|
||
|
||
### 防重复提交
|
||
防重复提交是指在进行数据提交的过程中,防止用户重复提交相同的数据或者重复执行同一操作的一种技术手段。这种技术手段的主要目的是避免数据的重复录入或者重复操作所带来的不必要的麻烦和风险,同时也可以提高应用程序的稳定性和可靠性。系统使用后端校验+分布式锁的方式实现
|
||
|
||
### 使用
|
||
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. 拦截效果
|
||

|
||
|
||
### 通用分布式锁
|
||
通用分布式锁主要通过
|
||
|