# 后台手册
# 分页实现
# 前端调用实现
# 后台逻辑实现
# 导入导出
在实际开发中经常需要使用导入导出功能来加快数据的操作。在项目中可以使用注解来完成此项功能。
在需要被导入导出的实体类属性添加@Excel
注解,目前支持参数如下:
# 注解参数说明
参数 | 类型 | 默认值 | 描述 |
---|---|---|---|
sort | int | Integer.MAX_VALUE | 导出时在excel中排序,值越小越靠前 |
name | String | 空 | 导出到Excel中的名字 |
dateFormat | String | 空 | 日期格式, 如: yyyy-MM-dd |
readConverterExp | String | 空 | 读取内容转表达式 (如: 0=男,1=女,2=未知) |
separator | String | , | 分隔符,读取字符串组内容 |
scale | int | -1 | BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) |
roundingMode | int | BigDecimal.ROUND_HALF_EVEN | BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN |
celltype | Enum | Type.STRING | 导出类型(0数字 1字符串 2图片) |
height | String | 14 | 导出时在excel中每个列的高度 单位为字符 |
width | String | 16 | 导出时在excel中每个列的宽 单位为字符 |
suffix | String | 空 | 文字后缀,如% 90 变成90% |
defaultValue | String | 空 | 当值为空时,字段的默认值 |
prompt | String | 空 | 提示信息 |
combo | String | Null | 设置只能选择不能输入的列内容 |
comboReadDict | boolean | false | 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解. |
headerBackgroundColor | Enum | IndexedColors.GREY_50_PERCENT | 导出列头背景色IndexedColors.XXXX |
headerColor | Enum | IndexedColors.WHITE | 导出列头字体颜色IndexedColors.XXXX |
backgroundColor | Enum | IndexedColors.WHITE | 导出单元格背景色IndexedColors.XXXX |
color | Enum | IndexedColors.BLACK | 导出单元格字体颜色IndexedColors.XXXX |
targetAttr | String | 空 | 另一个类中的属性名称,支持多级获取,以小数点隔开 |
isStatistics | boolean | false | 是否自动统计数据,在最后追加一行统计数据总和 |
type | Enum | Type.ALL | 字段类型(0:导出导入;1:仅导出;2:仅导入) |
align | Enum | HorizontalAlignment.CENTER | 导出对齐方式HorizontalAlignment.XXXX |
handler | Class | ExcelHandlerAdapter.class | 自定义数据处理器 |
args | String[] | {} | 自定义数据处理器参数 |
# 导出实现流程
1、前端调用方法(参考如下)
// 查询参数 queryParams
queryParams: {
pageNum: 1,
pageSize: 10,
userName: undefined
},
/** 导出按钮操作 */
handleExport() {
this.download('system/xxxx/export', {
...this.queryParams
}, `post_${new Date().getTime()}.xlsx`)
}
2
3
4
5
6
7
8
9
10
11
12
13
2、添加导出按钮事件
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
2
3
4
5
6
3、在实体变量上添加@Excel注解
@Excel(name = "用户序号", prompt = "用户编号")
private Long userId;
@Excel(name = "用户名称")
private String userName;
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
@Excel(name = "最后登陆时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date loginDate;
2
3
4
5
6
7
8
9
10
11
4、在Controller添加导出方法
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@PreAuthorize(hasPermi = "system:user:export")
@PostMapping("/export")
public void export(HttpServletResponse response, SysUser user) throws IOException
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.exportExcel(response, list, "用户数据");
}
2
3
4
5
6
7
8
9
# 导入实现流程
# 自定义标题信息
# 自定义数据处理器
# 自定义隐藏属性列
# 导出对象的子列表
# 上传下载
首先创建一张上传文件的表,例如:
drop table if exists sys_file_info;
create table sys_file_info (
file_id int(11) not null auto_increment comment '文件id',
file_name varchar(50) default '' comment '文件名称',
file_path varchar(255) default '' comment '文件路径',
primary key (file_id)
) engine=innodb auto_increment=1 default charset=utf8 comment = '文件信息表';
2
3
4
5
6
7
# 上传实现流程
# 下载实现流程
# 权限注解
认证注解权限控制
@RequiresLogin
登录认证:只有登录之后才能进入该方法。@RequiresPermissions
权限认证:必须具有指定权限才能进入该方法。@RequiresRoles
角色认证:必须具有指定角色标识才能进入该方法
# @RequiresRoles
@RequiresRoles
注解用于配置接口要求用户拥有某(些)角色才可访问,它拥有两个参数
参数 | 类型 | 描述 |
---|---|---|
value | String[] | 角色列表 |
logical | Logical | 角色之间的判断关系,默认为Logical.AND |
示例1: 以下代码表示必须拥有admin
角色才可访问
@RequiresRoles("admin")
public AjaxResult save(...)
{
return AjaxResult.success(...);
}
2
3
4
5
示例2: 以下代码表示必须拥有admin
和common
角色才可访问
@RequiresRoles({"admin", "common"})
public AjaxResult save(...)
{
return AjaxResult.success(...);
}
2
3
4
5
示例3: 以下代码表示需要拥有admin
或common
角色才可访问
@RequiresRoles(value = {"admin", "common"}, logical = Logical.OR)
public AjaxResult save(...)
{
return AjaxResult.success(...);
}
2
3
4
5
# @RequiresPermissions
@RequiresPermissions
注解用于配置接口要求用户拥有某(些)权限才可访问,它拥有两个参数
参数 | 类型 | 描述 |
---|---|---|
value | String[] | 权限列表 |
logical | Logical | 权限之间的判断关系,默认为Logical.AND |
示例1: 以下代码表示必须拥有system:user:add
权限才可访问
@RequiresPermissions("system:user:add")
public AjaxResult save(...)
{
return AjaxResult.success(...);
}
2
3
4
5
示例2: 以下代码表示必须拥有system:user:add
和system:user:update
权限才可访问
@RequiresPermissions({"system:user:add", "system:user:update"})
public AjaxResult save(...)
{
return AjaxResult.success(...);
}
2
3
4
5
示例3: 以下代码表示需要拥有system:user:add
或system:user:update
权限才可访问
@RequiresPermissions(value = {"system:user:add", "system:user:update"}, logical = Logical.OR)
public AjaxResult save(...)
{
return AjaxResult.success(...);
}
2
3
4
5
提示
认证注解处理是有内定的处理顺序的,如果有个多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关)
RequiresLogin、RequiresRoles、RequiresPermissions。
例如:你同时声明了RequiresRoles
和RequiresPermissions
,那就要求拥有此角色的同时还得拥有相应的权限。
旧版使用方法
- 数据权限示例。
// 符合system:user:list权限要求
@PreAuthorize(hasPermi = "system:user:list")
// 不符合system:user:list权限要求
@PreAuthorize(lacksPermi = "system:user:list")
// 符合system:user:add或system:user:edit权限要求即可
@PreAuthorize(hasAnyPermi = { "system:user:add", "system:user:edit" })
2
3
4
5
6
7
8
- 角色权限示例。
// 属于user角色
@PreAuthorize(hasRole = "user")
// 不属于user角色
@PreAuthorize(lacksRole = "user")
// 属于user或者admin之一
@PreAuthorize(hasAnyRoles = { "user", "admin" })
2
3
4
5
6
7
8
# 编程式判断资源访问权限
示例: 编程式判断是否有资源权限
if (AuthUtil.hasPermi("sys:user:edit"))
{
System.out.println("当前用户有编辑用户权限");
}
2
3
4
示例: 编程式判断是否有角色权限
if (AuthUtil.hasRole("admin"))
{
System.out.println("当前用户有admin角色权限");
}
2
3
4
# 事务管理
# 异常处理
# 参数验证
# 数据脱敏
对应业务模块pom.xml
加入ruoyi-common-sensitive
依赖
<!-- RuoYi Common Sensitive -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-sensitive</artifactId>
</dependency>
2
3
4
5
# 系统日志
# 数据权限
# 多数据源
在实际开发中,经常可能遇到在一个应用中可能需要访问多个数据库的情况,微服务版本采用了dynamic-datasource
动态多数据源组件,使用参考:
1、对应业务模块pom.xml
加入ruoyi-common-datasource
依赖
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-datasource</artifactId>
</dependency>
2
3
4
5
2、以ruoyi-system
模块集成druid
为例,配置主从数据库,其他数据源可以参考组件文档。
# spring配置
spring:
datasource:
druid:
stat-view-servlet:
enabled: true
loginUsername: admin
loginPassword: 123456
dynamic:
druid:
initial-size: 5
min-idle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
filters: stat,wall,slf4j
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
# 主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: password
# 从库数据源
# slave:
# url:
# username:
# password:
# driver-class-name:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
3、ruoyi-common-datasource
定义数据源注解,对应datasource
配置的不同数据源节点
项目默认了主Master
从Slave
注解可以直接使用,其他的可以根据项目实际情况去添加。
4、使用注解在需要切换数据源的方法上或类上。
@Master
public void insertA()
{
return xxxxMapper.insertXxxx();
}
@Slave
public void insertB()
{
return xxxxMapper.insertXxxx();
}
2
3
4
5
6
7
8
9
10
11
在某些情况您可能需要手动切换数据源
DynamicDataSourceContextHolder.push("slave"); // 手动切换
....业务逻辑
DynamicDataSourceContextHolder.clear();
2
3
# 代码生成
# 定时任务
# 系统接口
# 国际化支持
# 后台国际化流程
# 前端国际化流程
# 新建子模块
Maven多模块下新建子模块流程案例。
1、在ruoyi-modules
下新建业务模块目录,例如:ruoyi-test
。
2、在ruoyi-test
业务模块下新建pom.xml
文件以及src\main\java
,src\main\resources
目录。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId>
<version>x.x.x</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-modules-test</artifactId>
<description>
ruoyi-modules-test系统模块
</description>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- Ruoyi Common Security -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-security</artifactId>
</dependency>
<!-- Ruoyi Common Swagger -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-swagger</artifactId>
</dependency>
<!-- RuoYi Common Log -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
3、在ruoyi-modules
目录下pom.xml
模块节点modules添加业务模块
<module>ruoyi-test</module>
4、src/main/resources
添加bootstrap.yml
文件
# Tomcat
server:
port: 9301
# Spring
spring:
application:
# 应用名称
name: ruoyi-test
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
5、com.ruoyi.test包下添加启动类
package com.ruoyi.test;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import com.ruoyi.common.security.annotation.EnableCustomConfig;
import com.ruoyi.common.security.annotation.EnableRyFeignClients;
import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
/**
* 测试模块
*
* @author ruoyi
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringCloudApplication
public class RuoYiTestApplication
{
public static void main(String[] args)
{
SpringApplication.run(RuoYiTestApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 测试模块启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34