Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-api-boot
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-api-boot
Commits
bb485532
提交
bb485532
authored
3月 30, 2022
作者:
方治民
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'master' 到 'master'
Master 查看合并请求 chemical-kesai/kshg-api!3
上级
981cce06
bd9022ba
隐藏空白字符变更
内嵌
并排
正在显示
25 个修改的文件
包含
550 行增加
和
69 行删除
+550
-69
README.md
README.md
+3
-2
build.gradle
app/build.gradle
+3
-0
GlobalExceptionHandler.java
...in/java/com/yiring/app/config/GlobalExceptionHandler.java
+17
-9
application-mock.yml
app/src/main/resources/application-mock.yml
+1
-1
application.yml
app/src/main/resources/application.yml
+1
-1
build.gradle
basic-auth/build.gradle
+3
-0
Permission.java
...in/java/com/yiring/auth/domain/permission/Permission.java
+37
-0
User.java
...-auth/src/main/java/com/yiring/auth/domain/user/User.java
+2
-2
RegisterParam.java
...c/main/java/com/yiring/auth/param/auth/RegisterParam.java
+3
-3
PermissionParam.java
...ava/com/yiring/auth/param/permission/PermissionParam.java
+14
-5
Permissions.java
...-auth/src/main/java/com/yiring/auth/util/Permissions.java
+41
-0
LoginVo.java
...c-auth/src/main/java/com/yiring/auth/vo/auth/LoginVo.java
+6
-0
MenuVo.java
...h/src/main/java/com/yiring/auth/vo/permission/MenuVo.java
+58
-0
PermissionVo.java
...main/java/com/yiring/auth/vo/permission/PermissionVo.java
+4
-0
UserInfoVo.java
...uth/src/main/java/com/yiring/auth/vo/user/UserInfoVo.java
+4
-18
UserMenuListVo.java
...src/main/java/com/yiring/auth/vo/user/UserMenuListVo.java
+53
-0
UserVo.java
basic-auth/src/main/java/com/yiring/auth/vo/user/UserVo.java
+1
-1
AuthController.java
...rc/main/java/com/yiring/auth/web/auth/AuthController.java
+2
-2
UserController.java
...rc/main/java/com/yiring/auth/web/user/UserController.java
+46
-14
application-auth.yml
basic-auth/src/main/resources/application-auth.yml
+2
-3
init-test-mysql.sql
basic-auth/src/main/resources/init-test-mysql.sql
+146
-0
build.gradle
basic-common/core/build.gradle
+4
-2
RequestAspect.java
...src/main/java/com/yiring/common/aspect/RequestAspect.java
+3
-3
FailStatusException.java
...java/com/yiring/common/exception/FailStatusException.java
+31
-0
Commons.java
...on/util/src/main/java/com/yiring/common/util/Commons.java
+65
-3
没有找到文件。
README.md
浏览文件 @
bb485532
...
...
@@ -24,8 +24,9 @@
## TODO
<!-- prettier-ignore -->
-
[
x
]
项目构建
-
[
x
]
用户及权限模块(菜单/按钮)
-
[
x
]
完成项目构建,开发文档编写
-
[
x
]
[
conventional-changelog
]
(https://www.cnblogs.com/mengfangui/p/12634845.html)
-
[
x
]
用户及权限模块(目录/菜单/按钮),预览初始化权限配置
[
SQL 脚本
](
./basic-auth/src/main/resources/init-test-mysql.sql
)
-
[
x
]
通用文件上传模块
-
[
]
通用字典管理模块
-
[
]
XXL-JOB 定时任务模块
app/build.gradle
浏览文件 @
bb485532
...
...
@@ -30,4 +30,7 @@ dependencies {
implementation
project
(
":basic-common:minio"
)
// FIX: minio dep
implementation
"com.squareup.okhttp3:okhttp:${okhttpVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
}
app/src/main/java/com/yiring/app/config/GlobalExceptionHandler.java
浏览文件 @
bb485532
...
...
@@ -6,6 +6,7 @@ import com.yiring.app.constant.Code;
import
com.yiring.app.exception.CodeException
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.exception.FailStatusException
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.validation.ConstraintViolationException
;
import
lombok.extern.slf4j.Slf4j
;
...
...
@@ -33,7 +34,7 @@ public class GlobalExceptionHandler {
* 参数校验异常
*
* @param e 异常信息
* @return 统一的校验失败信息 {@link Status#
BAD_REQUEST
* @return 统一的校验失败信息 {@link Status#
EXPECTATION_FAILED
*/
@ExceptionHandler
(
value
=
{
BindException
.
class
,
MethodArgumentNotValidException
.
class
,
ConstraintViolationException
.
class
}
...
...
@@ -57,7 +58,7 @@ public class GlobalExceptionHandler {
}
}
return
Result
.
no
(
Status
.
BAD_REQUEST
,
error
);
return
Result
.
no
(
Status
.
EXPECTATION_FAILED
,
error
);
}
/**
...
...
@@ -74,7 +75,6 @@ public class GlobalExceptionHandler {
/**
* 未登录异常(鉴权失败)
*
* @param e 异常信息
* @return 异常信息反馈 {@link Status#UNAUTHORIZED
*/
@ExceptionHandler
(
value
=
NotLoginException
.
class
)
...
...
@@ -83,12 +83,6 @@ public class GlobalExceptionHandler {
}
/**
* 取消请求异常(忽略)
*/
@ExceptionHandler
(
value
=
ClientAbortException
.
class
)
public
void
clientAbortExceptionHandler
()
{}
/**
* 自定义业务异常
*/
@ExceptionHandler
(
value
=
CodeException
.
class
)
...
...
@@ -98,6 +92,20 @@ public class GlobalExceptionHandler {
}
/**
* 失败状态异常
*/
@ExceptionHandler
(
value
=
FailStatusException
.
class
)
public
Result
<
String
>
customCodeExceptionHandler
(
FailStatusException
e
)
{
return
Result
.
no
(
e
.
getStatus
());
}
/**
* 取消请求异常(忽略)
*/
@ExceptionHandler
(
value
=
ClientAbortException
.
class
)
public
void
clientAbortExceptionHandler
()
{}
/**
* 其他异常
*
* @param e 异常信息
...
...
app/src/main/resources/application-mock.yml
浏览文件 @
bb485532
spring
:
datasource
:
url
:
jdbc:h2:
mem:mockdb
;DB_CLOSE_ON_EXIT=FALSE
url
:
jdbc:h2:
file:~/h2_basic
;DB_CLOSE_ON_EXIT=FALSE
username
:
sa
password
:
123456
jpa
:
...
...
app/src/main/resources/application.yml
浏览文件 @
bb485532
server
:
port
:
8181
servlet
:
context-path
:
/
basic-
api
context-path
:
/api
spring
:
application
:
...
...
basic-auth/build.gradle
浏览文件 @
bb485532
...
...
@@ -17,4 +17,7 @@ dependencies {
// hutool-core
implementation
"cn.hutool:hutool-core:${hutoolVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
}
basic-auth/src/main/java/com/yiring/auth/domain/permission/Permission.java
浏览文件 @
bb485532
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
domain
.
permission
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
java.io.Serializable
;
import
javax.persistence.*
;
import
lombok.*
;
...
...
@@ -61,6 +63,9 @@ public class Permission implements Serializable {
@Comment
(
"路径"
)
String
path
;
@Comment
(
"重定向"
)
String
redirect
;
@Comment
(
"组件"
)
String
component
;
...
...
@@ -79,9 +84,22 @@ public class Permission implements Serializable {
@Comment
(
"树节点标识"
)
String
tree
;
/**
* 可用于扩展一些前端可能用到的路由参数
*/
@Comment
(
"扩展元数据信息"
)
@Lob
@Column
(
columnDefinition
=
"JSON"
)
String
meta
;
@SuppressWarnings
({
"unused"
})
public
enum
Type
{
/**
* 目录/平台
*/
DIR
,
/**
* 菜单
*/
MENU
,
...
...
@@ -91,4 +109,23 @@ public class Permission implements Serializable {
*/
BUTTON
,
}
/**
* 获取权限的元数据信息,通常是根据前端所需来输出,可自定义调整
* @return JSON 格式 Meta 元数据
*/
public
JSONObject
getMetaJson
()
{
JSONObject
meta
=
new
JSONObject
();
meta
.
put
(
"title"
,
this
.
name
);
meta
.
put
(
"icon"
,
this
.
icon
);
meta
.
put
(
"orderNo"
,
this
.
serial
);
meta
.
put
(
"hideMenu"
,
this
.
hidden
);
try
{
String
raw
=
this
.
meta
.
replace
(
"\\"
,
""
).
replaceAll
(
"^\"(.*)\"$"
,
"$1"
);
meta
.
putAll
(
JSON
.
parseObject
(
raw
));
}
catch
(
Exception
ignored
)
{}
return
meta
;
}
}
basic-auth/src/main/java/com/yiring/auth/domain/user/User.java
浏览文件 @
bb485532
...
...
@@ -68,8 +68,8 @@ public class User implements Serializable {
@Comment
(
"密码"
)
String
password
;
@Comment
(
"
职称
"
)
String
title
;
@Comment
(
"
简介
"
)
String
introduction
;
@Comment
(
"头像"
)
String
avatar
;
...
...
basic-auth/src/main/java/com/yiring/auth/param/auth/RegisterParam.java
浏览文件 @
bb485532
...
...
@@ -43,14 +43,14 @@ public class RegisterParam implements Serializable {
@Pattern
(
regexp
=
"^1[0-9]{10}$"
,
message
=
"手机号码格式不正确"
)
String
mobile
;
@ApiModelProperty
(
value
=
"头像"
,
example
=
"http
://img.ifzm.cn/cat
.jpg"
)
@ApiModelProperty
(
value
=
"头像"
,
example
=
"http
s://s1.ax1x.com/2022/03/30/qggJH0
.jpg"
)
String
avatar
;
@ApiModelProperty
(
value
=
"邮箱"
,
example
=
"developer@yiring.com"
)
String
email
;
@ApiModelProperty
(
value
=
"
职称
"
,
example
=
"平台管理员"
)
String
title
;
@ApiModelProperty
(
value
=
"
简介
"
,
example
=
"平台管理员"
)
String
introduction
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"true"
)
Boolean
enable
;
...
...
basic-auth/src/main/java/com/yiring/auth/param/permission/PermissionParam.java
浏览文件 @
bb485532
...
...
@@ -36,21 +36,24 @@ public class PermissionParam implements Serializable {
@ApiModelProperty
(
value
=
"序号"
,
example
=
"1"
)
Integer
serial
;
@ApiModelProperty
(
value
=
"标识"
,
example
=
"
home
"
,
required
=
true
)
@ApiModelProperty
(
value
=
"标识"
,
example
=
"
Dashboard
"
,
required
=
true
)
@NotEmpty
(
message
=
"权限标识不能为空"
)
String
uid
;
@ApiModelProperty
(
value
=
"名称"
,
example
=
"
主页
"
,
required
=
true
)
@ApiModelProperty
(
value
=
"名称"
,
example
=
"
Dashboard
"
,
required
=
true
)
@NotEmpty
(
message
=
"权限名称不能为空"
)
String
name
;
@ApiModelProperty
(
value
=
"路径"
,
example
=
"/"
)
@ApiModelProperty
(
value
=
"路径"
,
example
=
"/
dashboard
"
)
String
path
;
@ApiModelProperty
(
value
=
"组件"
,
example
=
"/home"
)
@ApiModelProperty
(
value
=
"重定向"
,
example
=
"/dashboard/workbench"
)
String
redirect
;
@ApiModelProperty
(
value
=
"组件"
,
example
=
"LAYOUT"
)
String
component
;
@ApiModelProperty
(
value
=
"图标"
,
example
=
"
menu
"
)
@ApiModelProperty
(
value
=
"图标"
,
example
=
"
ion:grid-outline
"
)
String
icon
;
@ApiModelProperty
(
value
=
"是否隐藏"
,
example
=
"false"
)
...
...
@@ -62,4 +65,10 @@ public class PermissionParam implements Serializable {
@ApiModelProperty
(
value
=
"父级ID"
,
example
=
"0"
)
@Builder
.
Default
Long
pid
=
0L
;
@ApiModelProperty
(
value
=
"元数据"
,
example
=
"{\"title\": \"routes.dashboard.dashboard\", \"hideChildrenInMenu\": true}"
)
String
meta
;
}
basic-auth/src/main/java/com/yiring/auth/util/Permissions.java
浏览文件 @
bb485532
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
util
;
import
com.sun.istack.Nullable
;
import
com.yiring.auth.domain.permission.Permission
;
import
com.yiring.auth.domain.role.Role
;
import
com.yiring.auth.vo.permission.MenuVo
;
import
com.yiring.auth.vo.permission.PermissionVo
;
import
com.yiring.auth.vo.role.RoleVo
;
import
com.yiring.common.util.Commons
;
import
java.util.*
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
import
lombok.NonNull
;
import
lombok.experimental.UtilityClass
;
...
...
@@ -39,6 +43,41 @@ public class Permissions {
}
/**
* 将权限集合转换成菜单树
* @param permissions 权限集合
* @return 菜单树
*/
public
static
List
<
MenuVo
>
toMenuTreeVo
(
@Nullable
List
<
Permission
>
permissions
)
{
List
<
MenuVo
>
list
=
Commons
.
transform
(
permissions
,
MenuVo
.
class
,
(
source
,
target
)
->
target
.
setMeta
(
source
.
getMetaJson
()),
Permission
.
Fields
.
meta
);
// 返回的树
ArrayList
<
MenuVo
>
roots
=
new
ArrayList
<>();
// 将数据添加到 Map
Map
<
Long
,
MenuVo
>
map
=
list
.
stream
().
collect
(
Collectors
.
toMap
(
MenuVo:
:
getId
,
Function
.
identity
()));
list
.
forEach
(
entity
->
{
MenuVo
menu
=
map
.
get
(
entity
.
getPid
());
if
(
null
==
menu
)
{
roots
.
add
(
map
.
get
(
entity
.
getId
()));
}
else
{
if
(
menu
.
getChildren
()
==
null
)
{
menu
.
setChildren
(
new
ArrayList
<>());
}
menu
.
getChildren
().
add
(
entity
);
}
});
return
roots
;
}
/**
* 将权限集合转换成 Vo 集合
* @param permissions 权限集合
* @return vos
...
...
@@ -49,6 +88,7 @@ public class Permissions {
.
map
(
permission
->
{
PermissionVo
vo
=
new
PermissionVo
();
BeanUtils
.
copyProperties
(
permission
,
vo
);
vo
.
setMeta
(
permission
.
getMetaJson
());
return
vo
;
})
.
collect
(
Collectors
.
toList
());
...
...
@@ -82,6 +122,7 @@ public class Permissions {
.
map
(
permission
->
{
PermissionVo
vo
=
new
PermissionVo
();
BeanUtils
.
copyProperties
(
permission
,
vo
);
vo
.
setMeta
(
permission
.
getMetaJson
());
vo
.
setChildren
(
toTree
(
permissions
,
permission
.
getId
()));
return
vo
;
})
...
...
basic-auth/src/main/java/com/yiring/auth/vo/auth/LoginVo.java
浏览文件 @
bb485532
/* (C) 2021 YiRing, Inc. */
package
com
.
yiring
.
auth
.
vo
.
auth
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
...
...
@@ -25,6 +27,10 @@ public class LoginVo implements Serializable {
private
static
final
long
serialVersionUID
=
-
8690942241103456896L
;
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
@ApiModelProperty
(
value
=
"主键"
,
example
=
"1"
)
Long
userId
;
@ApiModelProperty
(
value
=
"token"
,
example
=
"c68ca9c8c04b4a59afeafd2fb7c04741"
)
String
token
;
}
basic-auth/src/main/java/com/yiring/auth/vo/permission/MenuVo.java
0 → 100644
浏览文件 @
bb485532
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
vo
.
permission
;
import
com.alibaba.fastjson.JSONObject
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
com.fasterxml.jackson.annotation.JsonInclude
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
java.util.List
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 菜单输出类
* @author Jim
* @version 0.1
* 2022/3/25 17:09
*/
@JsonInclude
(
JsonInclude
.
Include
.
NON_NULL
)
@ApiModel
(
"MenuVo"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
MenuVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
9139328772148985141L
;
@JsonIgnore
Long
id
;
@JsonIgnore
Long
pid
;
@ApiModelProperty
(
value
=
"名称"
,
example
=
"Dashboard"
)
String
name
;
@ApiModelProperty
(
value
=
"路径"
,
example
=
"/dashboard"
)
String
path
;
@ApiModelProperty
(
value
=
"重定向"
,
example
=
"/dashboard/workbench"
)
String
redirect
;
@ApiModelProperty
(
value
=
"组件"
,
example
=
"LAYOUT"
)
String
component
;
@ApiModelProperty
(
value
=
"元数据"
,
example
=
"{\"title\": \"routes.dashboard.dashboard\", \"hideChildrenInMenu\": true}"
)
JSONObject
meta
;
@ApiModelProperty
(
value
=
"子权限"
)
List
<
MenuVo
>
children
;
}
basic-auth/src/main/java/com/yiring/auth/vo/permission/PermissionVo.java
浏览文件 @
bb485532
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
vo
.
permission
;
import
com.alibaba.fastjson.JSONObject
;
import
com.fasterxml.jackson.annotation.JsonInclude
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
...
...
@@ -64,6 +65,9 @@ public class PermissionVo implements Serializable {
@ApiModelProperty
(
value
=
"父级ID"
,
example
=
"0"
)
Long
pid
;
@ApiModelProperty
(
value
=
"元数据"
,
example
=
"{}"
)
JSONObject
meta
;
@ApiModelProperty
(
value
=
"子权限"
)
List
<
PermissionVo
>
children
;
}
basic-auth/src/main/java/com/yiring/auth/vo/user/UserInfoVo.java
浏览文件 @
bb485532
...
...
@@ -3,7 +3,6 @@ package com.yiring.auth.vo.user;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.yiring.auth.vo.permission.PermissionVo
;
import
com.yiring.auth.vo.role.RoleVo
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
...
...
@@ -39,29 +38,16 @@ public class UserInfoVo implements Serializable {
@ApiModelProperty
(
value
=
"用户名"
,
example
=
"admin"
)
String
username
;
@ApiModelProperty
(
value
=
"
手机号"
,
example
=
"13012345678
"
)
String
mobile
;
@ApiModelProperty
(
value
=
"
介绍"
,
example
=
"系统管理员
"
)
String
desc
;
@ApiModelProperty
(
value
=
"邮箱"
,
example
=
"developer@yiring.com"
)
String
email
;
@ApiModelProperty
(
value
=
"职称"
,
example
=
"系统管理员"
)
String
title
;
@ApiModelProperty
(
value
=
"头像"
,
example
=
"http://img.ifzm.cn/cat.jpg"
)
@ApiModelProperty
(
value
=
"头像"
,
example
=
"https://s1.ax1x.com/2022/03/30/qggJH0.jpg"
)
String
avatar
;
@ApiModelProperty
(
"角色"
)
@Builder
.
Default
List
<
RoleVo
>
roles
=
new
ArrayList
<>(
0
);
@ApiModelProperty
(
"权限"
)
@Builder
.
Default
List
<
PermissionVo
>
permissions
=
new
ArrayList
<>(
0
);
/**
* 通常用于前端决定登录成功后跳转到哪个模块页面
*/
@ApiModelProperty
(
value
=
"主页地址"
,
example
=
"/"
)
@ApiModelProperty
(
value
=
"用户主页"
,
example
=
"/dashboard/workbench"
)
String
homePath
;
}
basic-auth/src/main/java/com/yiring/auth/vo/user/UserMenuListVo.java
0 → 100644
浏览文件 @
bb485532
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
auth
.
vo
.
user
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.fasterxml.jackson.databind.ser.std.ToStringSerializer
;
import
com.yiring.auth.vo.role.RoleVo
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.List
;
import
lombok.*
;
import
lombok.experimental.FieldDefaults
;
/**
* 用户信息
* @author ifzm
* 2022/03/03 10:35
**/
@ApiModel
(
"UserInfo"
)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
UserMenuListVo
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
5319037883240327088L
;
@JsonSerialize
(
using
=
ToStringSerializer
.
class
)
@ApiModelProperty
(
value
=
"主键"
,
example
=
"1"
)
Long
userId
;
@ApiModelProperty
(
value
=
"真实姓名"
,
example
=
"超级用户"
)
String
realName
;
@ApiModelProperty
(
value
=
"用户名"
,
example
=
"admin"
)
String
username
;
@ApiModelProperty
(
value
=
"介绍"
,
example
=
"系统管理员"
)
String
desc
;
@ApiModelProperty
(
value
=
"头像"
,
example
=
"https://s1.ax1x.com/2022/03/30/qggJH0.jpg"
)
String
avatar
;
@ApiModelProperty
(
"角色"
)
@Builder
.
Default
List
<
RoleVo
>
roles
=
new
ArrayList
<>(
0
);
@ApiModelProperty
(
value
=
"用户主页"
,
example
=
"/dashboard/workbench"
)
String
homePath
;
}
basic-auth/src/main/java/com/yiring/auth/vo/user/UserVo.java
浏览文件 @
bb485532
...
...
@@ -45,7 +45,7 @@ public class UserVo implements Serializable {
@ApiModelProperty
(
value
=
"职称"
,
example
=
"系统管理员"
)
String
title
;
@ApiModelProperty
(
value
=
"头像"
,
example
=
"http
://img.ifzm.cn/cat
.jpg"
)
@ApiModelProperty
(
value
=
"头像"
,
example
=
"http
s://s1.ax1x.com/2022/03/30/qggJH0
.jpg"
)
String
avatar
;
@ApiModelProperty
(
value
=
"是否启用"
,
example
=
"true"
)
...
...
basic-auth/src/main/java/com/yiring/auth/web/auth/AuthController.java
浏览文件 @
bb485532
...
...
@@ -70,7 +70,7 @@ public class AuthController {
// 构建用户信息写入数据库
User
user
=
User
.
builder
()
.
title
(
param
.
getTitle
())
.
introduction
(
param
.
getIntroduction
())
.
avatar
(
param
.
getAvatar
())
.
mobile
(
param
.
getMobile
())
.
realName
(
param
.
getRealName
())
...
...
@@ -120,7 +120,7 @@ public class AuthController {
userRepository
.
saveAndFlush
(
user
);
// 构建用户所需信息
LoginVo
vo
=
LoginVo
.
builder
().
token
(
StpUtil
.
getTokenValue
()).
build
();
LoginVo
vo
=
LoginVo
.
builder
().
userId
(
user
.
getId
()).
token
(
StpUtil
.
getTokenValue
()).
build
();
return
Result
.
ok
(
vo
);
}
...
...
basic-auth/src/main/java/com/yiring/auth/web/user/UserController.java
浏览文件 @
bb485532
...
...
@@ -2,21 +2,25 @@
package
com
.
yiring
.
auth
.
web
.
user
;
import
cn.dev33.satoken.stp.StpUtil
;
import
com.yiring.auth.domain.permission.Permission
;
import
com.yiring.auth.domain.role.Role
;
import
com.yiring.auth.domain.role.RoleRepository
;
import
com.yiring.auth.domain.user.User
;
import
com.yiring.auth.domain.user.UserRepository
;
import
com.yiring.auth.param.IdsParam
;
import
com.yiring.auth.util.Permissions
;
import
com.yiring.auth.vo.permission.MenuVo
;
import
com.yiring.auth.vo.user.UserInfoVo
;
import
com.yiring.auth.vo.user.UserVo
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.core.Status
;
import
com.yiring.common.exception.FailStatusException
;
import
com.yiring.common.param.IdParam
;
import
com.yiring.common.param.PageParam
;
import
com.yiring.common.vo.PageVo
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.Set
;
...
...
@@ -54,30 +58,43 @@ public class UserController {
RoleRepository
roleRepository
;
@ApiOperation
(
value
=
"获取登录用户信息"
)
@GetMapping
(
"info"
)
public
Result
<
UserInfoVo
>
info
()
{
Long
id
=
StpUtil
.
getLoginIdAsLong
();
Optional
<
User
>
optional
=
userRepository
.
findById
(
id
);
if
(
optional
.
isEmpty
())
{
StpUtil
.
logout
(
id
);
return
Result
.
no
(
Status
.
UNAUTHORIZED
);
}
User
user
=
optional
.
get
();
@GetMapping
(
"getUserInfo"
)
public
Result
<
UserInfoVo
>
getUserInfo
()
{
User
user
=
getLoginUser
();
UserInfoVo
userInfoVo
=
UserInfoVo
.
builder
()
.
userId
(
user
.
getId
())
.
username
(
user
.
getUsername
())
.
realName
(
user
.
getRealName
())
.
avatar
(
user
.
getAvatar
())
.
title
(
user
.
getTitle
())
.
desc
(
user
.
getIntroduction
())
.
roles
(
Permissions
.
toRoleVos
(
user
.
getRoles
()))
.
permissions
(
Permissions
.
toTree
(
Permissions
.
toPermissions
(
user
.
getRoles
()),
0L
))
// 默认跳转到用户看板
.
homePath
(
"/dashboard/workbench"
)
.
build
();
return
Result
.
ok
(
userInfoVo
);
}
@ApiOperation
(
value
=
"获取用户菜单"
)
@GetMapping
(
"getMenuList"
)
public
Result
<
ArrayList
<
MenuVo
>>
getMenuList
()
{
User
user
=
getLoginUser
();
List
<
Permission
>
permissions
=
Permissions
.
toPermissions
(
user
.
getRoles
())
.
stream
()
.
filter
(
permission
->
!
Permission
.
Type
.
BUTTON
.
equals
(
permission
.
getType
()))
.
collect
(
Collectors
.
toList
());
List
<
MenuVo
>
vos
=
Permissions
.
toMenuTreeVo
(
permissions
);
return
Result
.
ok
((
ArrayList
<
MenuVo
>)
vos
);
}
@ApiOperation
(
value
=
"获取用户权限"
)
@GetMapping
(
"getPermCode"
)
public
Result
<
ArrayList
<
String
>>
getPermCode
()
{
User
user
=
getLoginUser
();
List
<
Permission
>
permissions
=
Permissions
.
toPermissions
(
user
.
getRoles
());
List
<
String
>
codes
=
permissions
.
stream
().
map
(
Permission:
:
getUid
).
collect
(
Collectors
.
toList
());
return
Result
.
ok
((
ArrayList
<
String
>)
codes
);
}
@ApiOperation
(
value
=
"分配角色"
)
@PostMapping
(
"/manage/assign"
)
public
Result
<
String
>
assign
(
@Valid
IdParam
idParam
,
@Valid
IdsParam
idsParam
)
{
...
...
@@ -115,4 +132,19 @@ public class UserController {
PageVo
<
UserVo
>
vo
=
PageVo
.
build
(
data
,
page
.
getTotalElements
());
return
Result
.
ok
(
vo
);
}
/**
* 获取登录用户信息
* @return 用户信息
*/
private
User
getLoginUser
()
{
Long
id
=
StpUtil
.
getLoginIdAsLong
();
Optional
<
User
>
optional
=
userRepository
.
findById
(
id
);
if
(
optional
.
isPresent
())
{
return
optional
.
get
();
}
StpUtil
.
logout
(
id
);
throw
new
FailStatusException
(
Status
.
UNAUTHORIZED
);
}
}
basic-auth/src/main/resources/application-auth.yml
浏览文件 @
bb485532
# Sa-Token配置
sa-token
:
# token名称 (同时也是cookie名称)
token-name
:
satoke
n
token-name
:
Authorizatio
n
# token有效期,单位s 默认30天, -1代表永不过期
timeout
:
2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
...
...
@@ -15,4 +15,4 @@ sa-token:
# 是否输出操作日志
is-log
:
false
# 是否在初始化配置时打印版本字符画
is-print
:
false
\ No newline at end of file
is-print
:
false
basic-auth/src/main/resources/init-test-mysql.sql
0 → 100644
浏览文件 @
bb485532
/*
Navicat Premium Data Transfer
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80025
Source Host : 127.0.0.1:3306
Source Schema : basic_app
Target Server Type : MySQL
Target Server Version : 80025
File Encoding : 65001
Date: 30/03/2022 17:11:44
*/
SET
NAMES
utf8mb4
;
SET
FOREIGN_KEY_CHECKS
=
0
;
-- ----------------------------
-- Table structure for sys_permission
-- ----------------------------
DROP
TABLE
IF
EXISTS
`sys_permission`
;
CREATE
TABLE
`sys_permission`
(
`id`
bigint
NOT
NULL
,
`component`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`enable`
bit
(
1
)
NULL
DEFAULT
NULL
,
`hidden`
bit
(
1
)
NULL
DEFAULT
NULL
,
`icon`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`meta`
json
NULL
,
`name`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`path`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`pid`
bigint
NULL
DEFAULT
NULL
,
`serial`
int
NULL
DEFAULT
NULL
,
`tree`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`type`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`uid`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NOT
NULL
,
`redirect`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
PRIMARY
KEY
(
`id`
)
USING
BTREE
,
UNIQUE
INDEX
`UK_n5idwm5pmlgfwvau5vrwf65ai`
(
`uid`
)
USING
BTREE
,
UNIQUE
INDEX
`UKn5idwm5pmlgfwvau5vrwf65ai`
(
`uid`
)
USING
BTREE
,
INDEX
`IDXfgtwjg4pmylcko0v6ate29j2x`
(
`type`
)
USING
BTREE
,
INDEX
`IDXcj5qpen847f3vkcgy7lsmqyug`
(
`pid`
)
USING
BTREE
,
INDEX
`IDXckpwmqmt2tsu8fyefxpgwypmr`
(
`tree`
)
USING
BTREE
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
ROW_FORMAT
=
Dynamic
;
-- ----------------------------
-- Records of sys_permission
-- ----------------------------
INSERT
INTO
`sys_permission`
VALUES
(
1509081714683547648
,
'LAYOUT'
,
b
'1'
,
NULL
,
'ion:grid-outline'
,
'{
\"
title
\"
:
\"
routes.dashboard.dashboard
\"
,
\"
hideChildrenInMenu
\"
: true}'
,
'Dashboard'
,
'/dashboard'
,
0
,
1
,
'0'
,
'MENU'
,
'Dashboard'
,
'/dashboard/workbench'
);
INSERT
INTO
`sys_permission`
VALUES
(
1509082383666647040
,
'/dashboard/workbench/index'
,
b
'1'
,
b
'1'
,
NULL
,
'{
\"
title
\"
:
\"
routes.dashboard.workbench
\"
,
\"
hideBreadcrumb
\"
: true,
\"
currentActiveMenu
\"
:
\"
/dashboard
\"
}'
,
'Workbench'
,
'workbench'
,
1509081714683547648
,
NULL
,
'0.1509081714683547648'
,
'MENU'
,
'Workbench'
,
NULL
);
INSERT
INTO
`sys_permission`
VALUES
(
1509082892188258304
,
'LAYOUT'
,
b
'1'
,
NULL
,
'simple-icons:about-dot-me'
,
'{
\"
title
\"
:
\"
routes.dashboard.about
\"
,
\"
hideChildrenInMenu
\"
: true}'
,
'About'
,
'/about'
,
0
,
100000
,
'0'
,
'MENU'
,
'About'
,
'/about/index'
);
INSERT
INTO
`sys_permission`
VALUES
(
1509083350738931712
,
'/sys/about/index'
,
b
'1'
,
NULL
,
'simple-icons:about-dot-me'
,
'{
\"
title
\"
:
\"
routes.dashboard.about
\"
,
\"
hideMenu
\"
: true}'
,
'AboutPage'
,
'index'
,
1509082892188258304
,
NULL
,
'0.1509082892188258304'
,
'MENU'
,
'AboutPage'
,
NULL
);
-- ----------------------------
-- Table structure for sys_role
-- ----------------------------
DROP
TABLE
IF
EXISTS
`sys_role`
;
CREATE
TABLE
`sys_role`
(
`id`
bigint
NOT
NULL
,
`name`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`uid`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NOT
NULL
,
PRIMARY
KEY
(
`id`
)
USING
BTREE
,
UNIQUE
INDEX
`UK_o928jdlxprqf5qyw6rvor4lse`
(
`uid`
)
USING
BTREE
,
UNIQUE
INDEX
`UKo928jdlxprqf5qyw6rvor4lse`
(
`uid`
)
USING
BTREE
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
ROW_FORMAT
=
Dynamic
;
-- ----------------------------
-- Records of sys_role
-- ----------------------------
INSERT
INTO
`sys_role`
VALUES
(
1509083443323998208
,
'管理员'
,
'admin'
);
-- ----------------------------
-- Table structure for sys_role_permissions
-- ----------------------------
DROP
TABLE
IF
EXISTS
`sys_role_permissions`
;
CREATE
TABLE
`sys_role_permissions`
(
`role_id`
bigint
NOT
NULL
,
`permissions_id`
bigint
NOT
NULL
,
PRIMARY
KEY
(
`role_id`
,
`permissions_id`
)
USING
BTREE
,
INDEX
`FKrg8k5oymm622ik067yjss31co`
(
`permissions_id`
)
USING
BTREE
,
CONSTRAINT
`FKaa4k4qhr2qdj6br8p5nrb2lhb`
FOREIGN
KEY
(
`role_id`
)
REFERENCES
`sys_role`
(
`id`
)
ON
DELETE
RESTRICT
ON
UPDATE
RESTRICT
,
CONSTRAINT
`FKrg8k5oymm622ik067yjss31co`
FOREIGN
KEY
(
`permissions_id`
)
REFERENCES
`sys_permission`
(
`id`
)
ON
DELETE
RESTRICT
ON
UPDATE
RESTRICT
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
ROW_FORMAT
=
Dynamic
;
-- ----------------------------
-- Records of sys_role_permissions
-- ----------------------------
INSERT
INTO
`sys_role_permissions`
VALUES
(
1509083443323998208
,
1509081714683547648
);
INSERT
INTO
`sys_role_permissions`
VALUES
(
1509083443323998208
,
1509082383666647040
);
INSERT
INTO
`sys_role_permissions`
VALUES
(
1509083443323998208
,
1509082892188258304
);
INSERT
INTO
`sys_role_permissions`
VALUES
(
1509083443323998208
,
1509083350738931712
);
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP
TABLE
IF
EXISTS
`sys_user`
;
CREATE
TABLE
`sys_user`
(
`id`
bigint
NOT
NULL
,
`avatar`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`create_time`
datetime
NULL
DEFAULT
NULL
,
`deleted`
bit
(
1
)
NULL
DEFAULT
NULL
,
`email`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`enabled`
bit
(
1
)
NULL
DEFAULT
NULL
,
`introduction`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`last_login_ip`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`last_login_time`
datetime
NULL
DEFAULT
NULL
,
`mobile`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`password`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`real_name`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
`username`
varchar
(
255
)
CHARACTER
SET
utf8mb4
COLLATE
utf8mb4_0900_ai_ci
NULL
DEFAULT
NULL
,
PRIMARY
KEY
(
`id`
)
USING
BTREE
,
UNIQUE
INDEX
`UK_ahtq5ew3v0kt1n7hf1sgp7p8l`
(
`email`
)
USING
BTREE
,
UNIQUE
INDEX
`UK_cvv4commjv5h4bai0h4vuqvkd`
(
`mobile`
)
USING
BTREE
,
UNIQUE
INDEX
`UK_51bvuyvihefoh4kp5syh2jpi4`
(
`username`
)
USING
BTREE
,
UNIQUE
INDEX
`UKcvv4commjv5h4bai0h4vuqvkd`
(
`mobile`
)
USING
BTREE
,
UNIQUE
INDEX
`UK51bvuyvihefoh4kp5syh2jpi4`
(
`username`
)
USING
BTREE
,
UNIQUE
INDEX
`UKahtq5ew3v0kt1n7hf1sgp7p8l`
(
`email`
)
USING
BTREE
,
INDEX
`IDXeyi36w6acltgl5j4ujw0wlsyt`
(
`enabled`
)
USING
BTREE
,
INDEX
`IDXner7sjf2kjerehlptwipdlst9`
(
`deleted`
)
USING
BTREE
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
ROW_FORMAT
=
Dynamic
;
-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT
INTO
`sys_user`
VALUES
(
1509080860341571584
,
'https://s1.ax1x.com/2022/03/30/qggJH0.jpg'
,
'2022-03-30 16:11:29'
,
b
'0'
,
NULL
,
b
'1'
,
'平台管理员'
,
'0:0:0:0:0:0:0:1'
,
'2022-03-30 16:55:40'
,
'13012345678'
,
'8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'
,
'管理员'
,
'admin'
);
-- ----------------------------
-- Table structure for sys_user_roles
-- ----------------------------
DROP
TABLE
IF
EXISTS
`sys_user_roles`
;
CREATE
TABLE
`sys_user_roles`
(
`user_id`
bigint
NOT
NULL
,
`role_id`
bigint
NOT
NULL
,
PRIMARY
KEY
(
`role_id`
,
`user_id`
)
USING
BTREE
,
INDEX
`FKp2804vh0ea810pitigxq5n6pn`
(
`user_id`
)
USING
BTREE
,
CONSTRAINT
`FKp2804vh0ea810pitigxq5n6pn`
FOREIGN
KEY
(
`user_id`
)
REFERENCES
`sys_user`
(
`id`
)
ON
DELETE
RESTRICT
ON
UPDATE
RESTRICT
,
CONSTRAINT
`FKqwiuml6b7mjmk48u5b9hmk853`
FOREIGN
KEY
(
`role_id`
)
REFERENCES
`sys_role`
(
`id`
)
ON
DELETE
RESTRICT
ON
UPDATE
RESTRICT
)
ENGINE
=
InnoDB
CHARACTER
SET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
ROW_FORMAT
=
Dynamic
;
-- ----------------------------
-- Records of sys_user_roles
-- ----------------------------
INSERT
INTO
`sys_user_roles`
VALUES
(
1509080860341571584
,
1509083443323998208
);
SET
FOREIGN_KEY_CHECKS
=
1
;
basic-common/core/build.gradle
浏览文件 @
bb485532
...
...
@@ -8,9 +8,11 @@ dependencies {
// swagger annotations
implementation
"io.swagger:swagger-annotations:${swaggerAnnotationsVersion}"
implementation
"org.hibernate.validator:hibernate-validator:${hibernateValidatorVersion}"
// hutool-extra
implementation
"cn.hutool:hutool-extra:${hutoolVersion}"
// hutool-json
implementation
"cn.hutool:hutool-json:${hutoolVersion}"
// fastjson
implementation
"com.alibaba:fastjson:${fastJsonVersion}"
}
basic-common/core/src/main/java/com/yiring/common/aspect/RequestAspect.java
浏览文件 @
bb485532
...
...
@@ -2,7 +2,7 @@
package
com
.
yiring
.
common
.
aspect
;
import
cn.hutool.extra.servlet.ServletUtil
;
import
c
n.hutool.
json.JSONObject
;
import
c
om.alibaba.fast
json.JSONObject
;
import
com.yiring.common.constant.DateFormatter
;
import
com.yiring.common.core.Result
;
import
com.yiring.common.util.Commons
;
...
...
@@ -52,8 +52,8 @@ public class RequestAspect {
// Print Request Log (Optional Replace: MDC)
String
extra
=
""
;
if
(
Boolean
.
TRUE
.
equals
(
debug
))
{
extra
+=
String
.
format
(
"\nHeaders: %s"
,
new
JSONObject
(
ServletUtil
.
getHeaderMap
(
request
)).
toStringPretty
(
));
extra
+=
String
.
format
(
"\nParams: %s"
,
new
JSONObject
(
ServletUtil
.
getParamMap
(
request
)).
toStringPretty
(
));
extra
+=
String
.
format
(
"\nHeaders: %s"
,
JSONObject
.
toJSONString
(
ServletUtil
.
getHeaderMap
(
request
),
true
));
extra
+=
String
.
format
(
"\nParams: %s"
,
JSONObject
.
toJSONString
(
ServletUtil
.
getParamMap
(
request
),
true
));
if
(
result
instanceof
Result
)
{
extra
+=
String
.
format
(
...
...
basic-common/core/src/main/java/com/yiring/common/exception/FailStatusException.java
0 → 100644
浏览文件 @
bb485532
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
exception
;
import
com.yiring.common.core.Status
;
import
lombok.AccessLevel
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.FieldDefaults
;
/**
* Status 异常(用于快速失败,会进行全局异常拦截)
*
* @author Jim
* @version 0.1
* 2022/3/28 11:36
*/
@EqualsAndHashCode
(
callSuper
=
true
)
@Data
@AllArgsConstructor
@FieldDefaults
(
level
=
AccessLevel
.
PRIVATE
)
public
class
FailStatusException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
-
4226669531686389671L
;
/**
* 状态
*/
Status
status
;
}
basic-common/util/src/main/java/com/yiring/common/util/Commons.java
浏览文件 @
bb485532
/* (C) 2021 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
;
import
java.util.Collection
;
import
java.util.Map
;
import
java.util.UUID
;
import
java.lang.reflect.Constructor
;
import
java.util.*
;
import
javax.servlet.http.HttpServletRequest
;
import
lombok.NonNull
;
import
lombok.experimental.UtilityClass
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.BeanUtils
;
/**
* 公共工具类
...
...
@@ -15,6 +17,7 @@ import lombok.experimental.UtilityClass;
*/
@SuppressWarnings
({
"unused"
})
@Slf4j
@UtilityClass
public
class
Commons
{
...
...
@@ -79,4 +82,63 @@ public class Commons {
public
boolean
isNullOrEmpty
(
Map
<?,
?>
map
)
{
return
map
==
null
||
map
.
isEmpty
();
}
/**
* 将集合通过 BeanUtils 反射转换成指定类型集合
* @param list 原始数据集合
* @param type 目标类型
* @param ignoreProperties 忽略属性
* @param <T> 目标类型集合
* @param <S> 原类型集合
* @return 目标集合
*/
public
<
T
,
S
>
List
<
T
>
transform
(
@NonNull
List
<
S
>
list
,
Class
<
T
>
type
,
String
...
ignoreProperties
)
{
return
transform
(
list
,
type
,
null
,
ignoreProperties
);
}
/**
* 将集合通过 BeanUtils 反射转换成指定类型集合
* @param list 原始数据集合
* @param type 目标类型
* @param fn 自定义处理函数
* @param ignoreProperties 忽略属性
* @param <T> 目标类型集合
* @param <S> 原类型集合
* @return 目标集合
*/
public
<
T
,
S
>
List
<
T
>
transform
(
@NonNull
List
<
S
>
list
,
Class
<
T
>
type
,
CallbackFunction
<
S
,
T
>
fn
,
String
...
ignoreProperties
)
{
try
{
Constructor
<
T
>
declaredConstructor
=
type
.
getDeclaredConstructor
();
List
<
T
>
targets
=
new
ArrayList
<>();
for
(
S
source
:
list
)
{
// 实例化
T
target
=
declaredConstructor
.
newInstance
();
// 使用 BeanUtils 进行数据拷贝
BeanUtils
.
copyProperties
(
source
,
target
,
ignoreProperties
);
// 通过自定义实现补充转换
if
(
fn
!=
null
)
{
fn
.
apply
(
source
,
target
);
}
targets
.
add
(
target
);
}
return
targets
;
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
@FunctionalInterface
public
interface
CallbackFunction
<
S
,
T
>
{
void
apply
(
S
s
,
T
t
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论