Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jinli gu
RuoYi Vue
Commits
bcee37b8
Commit
bcee37b8
authored
Nov 11, 2019
by
RuoYi
Browse files
若依 1.1
parent
85c17f45
Changes
93
Expand all
Hide whitespace changes
Inline
Side-by-side
ruoyi-ui/src/views/system/post/index.vue
View file @
bcee37b8
<
template
>
<div
class=
"app-container"
>
<el-form
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"岗位编码"
>
<el-form
:model=
"queryParams"
ref=
"queryForm"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"岗位编码"
prop=
"postCode"
>
<el-input
v-model=
"queryParams.postCode"
placeholder=
"请输入岗位编码"
...
...
@@ -10,7 +10,7 @@
@
keyup.enter.native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"岗位名称"
>
<el-form-item
label=
"岗位名称"
prop=
"postName"
>
<el-input
v-model=
"queryParams.postName"
placeholder=
"请输入岗位名称"
...
...
@@ -19,7 +19,7 @@
@
keyup.enter.native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"岗位状态"
clearable
size=
"small"
>
<el-option
v-for=
"dict in statusOptions"
...
...
@@ -31,11 +31,53 @@
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"el-icon-search"
size=
"mini"
@
click=
"handleQuery"
>
搜索
</el-button>
<el-button
type=
"primary"
icon=
"el-icon-
plus
"
size=
"mini"
@
click=
"
handleAdd"
v-hasPermi=
"['system:post:add']"
>
新增
</el-button>
<el-button
icon=
"el-icon-
refresh
"
size=
"mini"
@
click=
"
resetQuery"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading=
"loading"
:data=
"postList"
>
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
icon=
"el-icon-plus"
size=
"mini"
@
click=
"handleAdd"
v-hasPermi=
"['system:post:add']"
>
新增
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"success"
icon=
"el-icon-edit"
size=
"mini"
:disabled=
"single"
@
click=
"handleUpdate"
v-hasPermi=
"['system:post:edit']"
>
修改
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"multiple"
@
click=
"handleDelete"
v-hasPermi=
"['system:post:remove']"
>
删除
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"warning"
icon=
"el-icon-download"
size=
"mini"
@
click=
"handleExport"
v-hasPermi=
"['system:post:export']"
>
导出
</el-button>
</el-col>
</el-row>
<el-table
v-loading=
"loading"
:data=
"postList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
align=
"center"
/>
<el-table-column
label=
"岗位编号"
align=
"center"
prop=
"postId"
/>
<el-table-column
label=
"岗位编码"
align=
"center"
prop=
"postCode"
/>
<el-table-column
label=
"岗位名称"
align=
"center"
prop=
"postName"
/>
...
...
@@ -48,10 +90,10 @@
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
slot-scope=
"scope"
>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-edit"
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-edit"
@
click=
"handleUpdate(scope.row)"
v-hasPermi=
"['system:post:edit']"
>
修改
</el-button>
...
...
@@ -65,7 +107,7 @@
</
template
>
</el-table-column>
</el-table>
<pagination
v-show=
"total>0"
:total=
"total"
...
...
@@ -108,13 +150,19 @@
</template>
<
script
>
import
{
listPost
,
getPost
,
delPost
,
addPost
,
updatePost
}
from
"
@/api/system/post
"
;
import
{
listPost
,
getPost
,
delPost
,
addPost
,
updatePost
,
exportPost
}
from
"
@/api/system/post
"
;
export
default
{
data
()
{
return
{
// 遮罩层
loading
:
true
,
// 选中数组
ids
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 总条数
total
:
0
,
// 岗位表格数据
...
...
@@ -191,6 +239,17 @@ export default {
this
.
queryParams
.
pageNum
=
1
;
this
.
getList
();
},
/** 重置按钮操作 */
resetQuery
()
{
this
.
resetForm
(
"
queryForm
"
);
this
.
handleQuery
();
},
// 多选框选中数据
handleSelectionChange
(
selection
)
{
this
.
ids
=
selection
.
map
(
item
=>
item
.
postId
)
this
.
single
=
selection
.
length
!=
1
this
.
multiple
=
!
selection
.
length
},
/** 新增按钮操作 */
handleAdd
()
{
this
.
reset
();
...
...
@@ -200,7 +259,8 @@ export default {
/** 修改按钮操作 */
handleUpdate
(
row
)
{
this
.
reset
();
getPost
(
row
.
postId
).
then
(
response
=>
{
const
postId
=
row
.
postId
||
this
.
ids
getPost
(
postId
).
then
(
response
=>
{
this
.
form
=
response
.
data
;
this
.
open
=
true
;
this
.
title
=
"
修改岗位
"
;
...
...
@@ -236,16 +296,30 @@ export default {
},
/** 删除按钮操作 */
handleDelete
(
row
)
{
this
.
$confirm
(
'
是否确认删除岗位名称为"
'
+
row
.
postName
+
'
"的数据项?
'
,
"
警告
"
,
{
const
postIds
=
row
.
postId
||
this
.
ids
;
this
.
$confirm
(
'
是否确认删除岗位编号为"
'
+
postIds
+
'
"的数据项?
'
,
"
警告
"
,
{
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
"
取消
"
,
type
:
"
warning
"
}).
then
(
function
()
{
return
delPost
(
row
.
postId
);
return
delPost
(
postId
s
);
}).
then
(()
=>
{
this
.
getList
();
this
.
msgSuccess
(
"
删除成功
"
);
}).
catch
(
function
()
{});
},
/** 导出按钮操作 */
handleExport
()
{
const
queryParams
=
this
.
queryParams
;
this
.
$confirm
(
'
是否确认导出所有岗位数据项?
'
,
"
警告
"
,
{
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
"
取消
"
,
type
:
"
warning
"
}).
then
(
function
()
{
return
exportPost
(
queryParams
);
}).
then
(
response
=>
{
this
.
download
(
response
.
msg
);
}).
catch
(
function
()
{});
}
}
};
...
...
ruoyi-ui/src/views/system/role/index.vue
View file @
bcee37b8
<
template
>
<div
class=
"app-container"
>
<el-form
:inline=
"true"
>
<el-form-item
label=
"角色名称"
>
<el-form
:model=
"queryParams"
ref=
"queryForm"
:inline=
"true"
>
<el-form-item
label=
"角色名称"
prop=
"roleName"
>
<el-input
v-model=
"queryParams.roleName"
placeholder=
"请输入角色名称"
...
...
@@ -11,7 +11,7 @@
@
keyup.enter.native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"权限字符"
>
<el-form-item
label=
"权限字符"
prop=
"roleKey"
>
<el-input
v-model=
"queryParams.roleKey"
placeholder=
"请输入权限字符"
...
...
@@ -21,7 +21,7 @@
@
keyup.enter.native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"角色状态"
...
...
@@ -51,6 +51,12 @@
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"el-icon-search"
size=
"mini"
@
click=
"handleQuery"
>
搜索
</el-button>
<el-button
icon=
"el-icon-refresh"
size=
"mini"
@
click=
"resetQuery"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
icon=
"el-icon-plus"
...
...
@@ -58,15 +64,45 @@
@
click=
"handleAdd"
v-hasPermi=
"['system:role:add']"
>
新增
</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"success"
icon=
"el-icon-edit"
size=
"mini"
:disabled=
"single"
@
click=
"handleUpdate"
v-hasPermi=
"['system:role:edit']"
>
修改
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"multiple"
@
click=
"handleDelete"
v-hasPermi=
"['system:role:remove']"
>
删除
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"warning"
icon=
"el-icon-download"
size=
"mini"
@
click=
"handleExport"
v-hasPermi=
"['system:post:export']"
>
导出
</el-button>
</el-col>
</el-row>
<el-table
v-loading=
"loading"
:data=
"roleList"
>
<el-table
v-loading=
"loading"
:data=
"roleList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"55"
align=
"center"
/>
<el-table-column
label=
"角色编号"
prop=
"roleId"
width=
"120"
/>
<el-table-column
label=
"角色名称"
prop=
"roleName"
:show-overflow-tooltip=
"true"
width=
"150"
/>
<el-table-column
label=
"权限字符"
prop=
"roleKey"
:show-overflow-tooltip=
"true"
width=
"1
8
0"
/>
<el-table-column
label=
"显示顺序"
prop=
"roleSort"
width=
"1
2
0"
/>
<el-table-column
label=
"状态"
align=
"center"
width=
"1
2
0"
>
<el-table-column
label=
"权限字符"
prop=
"roleKey"
:show-overflow-tooltip=
"true"
width=
"1
5
0"
/>
<el-table-column
label=
"显示顺序"
prop=
"roleSort"
width=
"1
0
0"
/>
<el-table-column
label=
"状态"
align=
"center"
width=
"1
0
0"
>
<template
slot-scope=
"scope"
>
<el-switch
v-model=
"scope.row.status"
...
...
@@ -197,7 +233,7 @@
</template>
<
script
>
import
{
listRole
,
getRole
,
delRole
,
addRole
,
updateRole
,
dataScope
,
changeRoleStatus
}
from
"
@/api/system/role
"
;
import
{
listRole
,
getRole
,
delRole
,
addRole
,
updateRole
,
exportRole
,
dataScope
,
changeRoleStatus
}
from
"
@/api/system/role
"
;
import
{
treeselect
as
menuTreeselect
,
roleMenuTreeselect
}
from
"
@/api/system/menu
"
;
import
{
treeselect
as
deptTreeselect
,
roleDeptTreeselect
}
from
"
@/api/system/dept
"
;
...
...
@@ -206,6 +242,12 @@ export default {
return
{
// 遮罩层
loading
:
true
,
// 选中数组
ids
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 总条数
total
:
0
,
// 角色表格数据
...
...
@@ -384,6 +426,18 @@ export default {
this
.
queryParams
.
pageNum
=
1
;
this
.
getList
();
},
/** 重置按钮操作 */
resetQuery
()
{
this
.
dateRange
=
[];
this
.
resetForm
(
"
queryForm
"
);
this
.
handleQuery
();
},
// 多选框选中数据
handleSelectionChange
(
selection
)
{
this
.
ids
=
selection
.
map
(
item
=>
item
.
roleId
)
this
.
single
=
selection
.
length
!=
1
this
.
multiple
=
!
selection
.
length
},
/** 新增按钮操作 */
handleAdd
()
{
this
.
reset
();
...
...
@@ -394,10 +448,11 @@ export default {
/** 修改按钮操作 */
handleUpdate
(
row
)
{
this
.
reset
();
const
roleId
=
row
.
roleId
||
this
.
ids
this
.
$nextTick
(()
=>
{
this
.
getRoleMenuTreeselect
(
row
.
roleId
);
this
.
getRoleMenuTreeselect
(
roleId
);
});
getRole
(
row
.
roleId
).
then
(
response
=>
{
getRole
(
roleId
).
then
(
response
=>
{
this
.
form
=
response
.
data
;
this
.
open
=
true
;
this
.
title
=
"
修改角色
"
;
...
...
@@ -462,16 +517,30 @@ export default {
},
/** 删除按钮操作 */
handleDelete
(
row
)
{
this
.
$confirm
(
'
是否确认删除名称为"
'
+
row
.
roleName
+
'
"的数据项?
'
,
"
警告
"
,
{
const
roleIds
=
row
.
roleId
||
this
.
ids
;
this
.
$confirm
(
'
是否确认删除角色编号为"
'
+
roleIds
+
'
"的数据项?
'
,
"
警告
"
,
{
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
"
取消
"
,
type
:
"
warning
"
}).
then
(
function
()
{
return
delRole
(
row
.
roleId
);
return
delRole
(
roleId
s
);
}).
then
(()
=>
{
this
.
getList
();
this
.
msgSuccess
(
"
删除成功
"
);
}).
catch
(
function
()
{});
},
/** 导出按钮操作 */
handleExport
()
{
const
queryParams
=
this
.
queryParams
;
this
.
$confirm
(
'
是否确认导出所有角色数据项?
'
,
"
警告
"
,
{
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
"
取消
"
,
type
:
"
warning
"
}).
then
(
function
()
{
return
exportRole
(
queryParams
);
}).
then
(
response
=>
{
this
.
download
(
response
.
msg
);
}).
catch
(
function
()
{});
}
}
};
...
...
ruoyi-ui/src/views/system/user/index.vue
View file @
bcee37b8
...
...
@@ -27,8 +27,8 @@
</el-col>
<!--用户数据-->
<el-col
:span=
"20"
:xs=
"24"
>
<el-form
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"用户名称"
>
<el-form
:model=
"queryParams"
ref=
"queryForm"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"用户名称"
prop=
"userName"
>
<el-input
v-model=
"queryParams.userName"
placeholder=
"请输入用户名称"
...
...
@@ -38,7 +38,7 @@
@
keyup.enter.native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"手机号码"
>
<el-form-item
label=
"手机号码"
prop=
"phonenumber"
>
<el-input
v-model=
"queryParams.phonenumber"
placeholder=
"请输入手机号码"
...
...
@@ -48,7 +48,7 @@
@
keyup.enter.native=
"handleQuery"
/>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-form-item
label=
"状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"用户状态"
...
...
@@ -78,11 +78,53 @@
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
icon=
"el-icon-search"
size=
"mini"
@
click=
"handleQuery"
>
搜索
</el-button>
<el-button
type=
"primary"
icon=
"el-icon-
plus
"
size=
"mini"
@
click=
"
handleAdd"
v-hasPermi=
"['system:user:add']"
>
新增
</el-button>
<el-button
icon=
"el-icon-
refresh
"
size=
"mini"
@
click=
"
resetQuery"
>
重置
</el-button>
</el-form-item>
</el-form>
<el-table
v-loading=
"loading"
:data=
"userList"
>
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
icon=
"el-icon-plus"
size=
"mini"
@
click=
"handleAdd"
v-hasPermi=
"['system:user:add']"
>
新增
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"success"
icon=
"el-icon-edit"
size=
"mini"
:disabled=
"single"
@
click=
"handleUpdate"
v-hasPermi=
"['system:user:edit']"
>
修改
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"danger"
icon=
"el-icon-delete"
size=
"mini"
:disabled=
"multiple"
@
click=
"handleDelete"
v-hasPermi=
"['system:user:remove']"
>
删除
</el-button>
</el-col>
<el-col
:span=
"1.5"
>
<el-button
type=
"warning"
icon=
"el-icon-download"
size=
"mini"
@
click=
"handleExport"
v-hasPermi=
"['system:user:export']"
>
导出
</el-button>
</el-col>
</el-row>
<el-table
v-loading=
"loading"
:data=
"userList"
@
selection-change=
"handleSelectionChange"
>
<el-table-column
type=
"selection"
width=
"40"
align=
"center"
/>
<el-table-column
label=
"用户编号"
align=
"center"
prop=
"userId"
/>
<el-table-column
label=
"用户名称"
align=
"center"
prop=
"userName"
/>
<el-table-column
label=
"用户昵称"
align=
"center"
prop=
"nickName"
/>
...
...
@@ -246,7 +288,7 @@
</template>
<
script
>
import
{
listUser
,
getUser
,
delUser
,
addUser
,
updateUser
,
resetUserPwd
,
changeUserStatus
}
from
"
@/api/system/user
"
;
import
{
listUser
,
getUser
,
delUser
,
addUser
,
updateUser
,
exportUser
,
resetUserPwd
,
changeUserStatus
}
from
"
@/api/system/user
"
;
import
{
treeselect
}
from
"
@/api/system/dept
"
;
import
{
listPost
}
from
"
@/api/system/post
"
;
import
{
listRole
}
from
"
@/api/system/role
"
;
...
...
@@ -259,6 +301,12 @@ export default {
return
{
// 遮罩层
loading
:
true
,
// 选中数组
ids
:
[],
// 非单个禁用
single
:
true
,
// 非多个禁用
multiple
:
true
,
// 总条数
total
:
0
,
// 用户表格数据
...
...
@@ -430,6 +478,18 @@ export default {
this
.
queryParams
.
page
=
1
;
this
.
getList
();
},
/** 重置按钮操作 */
resetQuery
()
{
this
.
dateRange
=
[];
this
.
resetForm
(
"
queryForm
"
);
this
.
handleQuery
();
},
// 多选框选中数据
handleSelectionChange
(
selection
)
{
this
.
ids
=
selection
.
map
(
item
=>
item
.
userId
)
this
.
single
=
selection
.
length
!=
1
this
.
multiple
=
!
selection
.
length
},
/** 新增按钮操作 */
handleAdd
()
{
this
.
reset
();
...
...
@@ -446,7 +506,8 @@ export default {
this
.
getTreeselect
();
this
.
getPosts
();
this
.
getRoles
();
getUser
(
row
.
userId
).
then
(
response
=>
{
const
userId
=
row
.
userId
||
this
.
ids
getUser
(
userId
).
then
(
response
=>
{
this
.
form
=
response
.
data
;
this
.
form
.
postIds
=
response
.
postIds
;
this
.
form
.
roleIds
=
response
.
roleIds
;
...
...
@@ -500,16 +561,30 @@ export default {
},
/** 删除按钮操作 */
handleDelete
(
row
)
{
this
.
$confirm
(
'
是否确认删除名称为"
'
+
row
.
userName
+
'
"的数据项?
'
,
"
警告
"
,
{
const
userIds
=
row
.
userId
||
this
.
ids
;
this
.
$confirm
(
'
是否确认删除用户编号为"
'
+
userIds
+
'
"的数据项?
'
,
"
警告
"
,
{
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
"
取消
"
,
type
:
"
warning
"
}).
then
(
function
()
{
return
delUser
(
row
.
userId
);
return
delUser
(
userId
s
);
}).
then
(()
=>
{
this
.
getList
();
this
.
msgSuccess
(
"
删除成功
"
);
}).
catch
(
function
()
{});
},
/** 导出按钮操作 */
handleExport
()
{
const
queryParams
=
this
.
queryParams
;
this
.
$confirm
(
'
是否确认导出所有用户数据项?
'
,
"
警告
"
,
{
confirmButtonText
:
"
确定
"
,
cancelButtonText
:
"
取消
"
,
type
:
"
warning
"
}).
then
(
function
()
{
return
exportUser
(
queryParams
);
}).
then
(
response
=>
{
this
.
download
(
response
.
msg
);
}).
catch
(
function
()
{});
}
}
};
...
...
ruoyi-ui/vue.config.js
View file @
bcee37b8
...
...
@@ -17,7 +17,7 @@ module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
publicPath
:
process
.
env
.
NODE_ENV
===
"
production
"
?
"
.
/
"
:
"
/
"
,
publicPath
:
process
.
env
.
NODE_ENV
===
"
production
"
?
"
/
"
:
"
/
"
,
// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
outputDir
:
'
dist
'
,
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
...
...
ruoyi/pom.xml
View file @
bcee37b8
...
...
@@ -5,7 +5,7 @@
<groupId>
com.ruoyi
</groupId>
<artifactId>
ruoyi
</artifactId>
<version>
1.
0
</version>
<version>
1.
1
</version>
<packaging>
jar
</packaging>
<name>
ruoyi
</name>
...
...
@@ -32,6 +32,7 @@
<bitwalker.version>
1.19
</bitwalker.version>
<jwt.version>
0.9.0
</jwt.version>
<swagger.version>
2.9.2
</swagger.version>
<poi.version>
3.17
</poi.version>
<oshi.version>
3.9.1
</oshi.version>
</properties>
...
...
@@ -223,6 +224,13 @@
<groupId>
net.java.dev.jna
</groupId>
<artifactId>
jna-platform
</artifactId>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>
org.apache.poi
</groupId>
<artifactId>
poi-ooxml
</artifactId>
<version>
${poi.version}
</version>
</dependency>
</dependencies>
...
...
ruoyi/sql/ry_20191
008
.sql
→
ruoyi/sql/ry_20191
111
.sql
View file @
bcee37b8
...
...
@@ -136,7 +136,7 @@ create table sys_menu (
path
varchar
(
200
)
default
''
comment
'路由地址'
,
component
varchar
(
255
)
default
null
comment
'组件路径'
,
is_frame
int
(
1
)
default
1
comment
'是否为外链(0是 1否)'
,
menu_type
char
(
1
)
default
''
comment
'菜单类型(
0
目录
1
菜单
2
按钮)'
,
menu_type
char
(
1
)
default
''
comment
'菜单类型(
M
目录
C
菜单
F
按钮)'
,
visible
char
(
1
)
default
0
comment
'菜单状态(0显示 1隐藏)'
,
perms
varchar
(
100
)
default
null
comment
'权限标识'
,
icon
varchar
(
100
)
default
'#'
comment
'菜单图标'
,
...
...
@@ -152,10 +152,10 @@ create table sys_menu (
-- 初始化-菜单信息表数据
-- ----------------------------
-- 一级菜单
insert
into
sys_menu
values
(
'1'
,
'系统管理'
,
'0'
,
'1'
,
'system'
,
null
,
1
,
'M'
,
'0'
,
''
,
'system'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'系统管理目录'
);
insert
into
sys_menu
values
(
'2'
,
'系统监控'
,
'0'
,
'2'
,
'monitor'
,
null
,
1
,
'M'
,
'0'
,
''
,
'monitor'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'系统监控目录'
);
insert
into
sys_menu
values
(
'3'
,
'系统工具'
,
'0'
,
'3'
,
'tool'
,
null
,
1
,
'M'
,
'0'
,
''
,
'tool'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'系统工具目录'
);
INSERT
INTO
sys_menu
VALUES
(
'4'
,
'若依官网'
,
'0'
,
'4'
,
'http://ruoyi.vip'
,
NULL
,
0
,
'M'
,
'0'
,
''
,
'guide'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'若依官网'
);
insert
into
sys_menu
values
(
'1'
,
'系统管理'
,
'0'
,
'1'
,
'system'
,
null
,
1
,
'M'
,
'0'
,
''
,
'system'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'系统管理目录'
);
insert
into
sys_menu
values
(
'2'
,
'系统监控'
,
'0'
,
'2'
,
'monitor'
,
null
,
1
,
'M'
,
'0'
,
''
,
'monitor'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'系统监控目录'
);
insert
into
sys_menu
values
(
'3'
,
'系统工具'
,
'0'
,
'3'
,
'tool'
,
null
,
1
,
'M'
,
'0'
,
''
,
'tool'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'系统工具目录'
);
insert
into
sys_menu
values
(
'4'
,
'若依官网'
,
'0'
,
'4'
,
'http://ruoyi.vip'
,
null
,
0
,
'M'
,
'0'
,
''
,
'guide'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'若依官网
地址
'
);
-- 二级菜单
insert
into
sys_menu
values
(
'100'
,
'用户管理'
,
'1'
,
'1'
,
'user'
,
'system/user/index'
,
1
,
'C'
,
'0'
,
'system:user:list'
,
'user'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'用户管理菜单'
);
insert
into
sys_menu
values
(
'101'
,
'角色管理'
,
'1'
,
'2'
,
'role'
,
'system/role/index'
,
1
,
'C'
,
'0'
,
'system:role:list'
,
'peoples'
,
'admin'
,
'2018-03-16 11-33-00'
,
'ry'
,
'2018-03-16 11-33-00'
,
'角色管理菜单'
);
...
...
@@ -550,27 +550,7 @@ create table sys_logininfor (
-- ----------------------------
-- 15、在线用户记录
-- ----------------------------
drop
table
if
exists
sys_user_online
;
create
table
sys_user_online
(
sessionId
varchar
(
50
)
default
''
comment
'用户会话id'
,
user_name
varchar
(
50
)
default
''
comment
'用户账号'
,
dept_name
varchar
(
50
)
default
''
comment
'部门名称'
,
ipaddr
varchar
(
50
)
default
''
comment
'登录IP地址'
,
login_location
varchar
(
255
)
default
''
comment
'登录地点'
,
browser
varchar
(
50
)
default
''
comment
'浏览器类型'
,
os
varchar
(
50
)
default
''
comment
'操作系统'
,
status
varchar
(
10
)
default
''
comment
'在线状态on_line在线off_line离线'
,
start_timestamp
datetime
comment
'session创建时间'
,
last_access_time
datetime
comment
'session最后访问时间'
,
expire_time
int
(
5
)
default
0
comment
'超时时间,单位为分钟'
,
primary
key
(
sessionId
)
)
engine
=
innodb
comment
=
'在线用户记录'
;
-- ----------------------------
-- 16、定时任务调度表
-- 15、定时任务调度表
-- ----------------------------
drop
table
if
exists
sys_job
;
create
table
sys_job
(
...
...
@@ -596,7 +576,7 @@ insert into sys_job values(3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryM
-- ----------------------------
-- 1
7
、定时任务调度日志表
-- 1
6
、定时任务调度日志表
-- ----------------------------
drop
table
if
exists
sys_job_log
;
create
table
sys_job_log
(
...
...
@@ -613,7 +593,7 @@ create table sys_job_log (
-- ----------------------------
-- 1
8
、通知公告表
-- 1
7
、通知公告表
-- ----------------------------
drop
table
if
exists
sys_notice
;
create
table
sys_notice
(
...
...
@@ -638,7 +618,7 @@ insert into sys_notice values('2', '维护通知:2018-07-01 若依系统凌晨
-- ----------------------------
-- 1
9
、代码生成业务表
-- 1
8
、代码生成业务表
-- ----------------------------
drop
table
if
exists
gen_table
;
create
table
gen_table
(
...
...
@@ -663,7 +643,7 @@ create table gen_table (
-- ----------------------------
--
20
、代码生成业务表字段
--
19
、代码生成业务表字段
-- ----------------------------
drop
table
if
exists
gen_table_column
;
create
table
gen_table_column
(
...
...
ruoyi/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
0 → 100644
View file @
bcee37b8
This diff is collapsed.
Click to expand it.
ruoyi/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
0 → 100644
View file @
bcee37b8
package
com.ruoyi.common.utils.reflect
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.util.Date
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.Validate
;
import
org.apache.poi.ss.usermodel.DateUtil
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
com.ruoyi.common.core.text.Convert
;
import
com.ruoyi.common.utils.DateUtils
;
/**
* 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*
* @author ruoyi
*/
@SuppressWarnings
(
"rawtypes"
)
public
class
ReflectUtils
{
private
static
final
String
SETTER_PREFIX
=
"set"
;
private
static
final
String
GETTER_PREFIX
=
"get"
;
private
static
final
String
CGLIB_CLASS_SEPARATOR
=
"$$"
;
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ReflectUtils
.
class
);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeGetter
(
Object
obj
,
String
propertyName
)
{
Object
object
=
obj
;
for
(
String
name
:
StringUtils
.
split
(
propertyName
,
"."
))
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
name
);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
return
(
E
)
object
;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public
static
<
E
>
void
invokeSetter
(
Object
obj
,
String
propertyName
,
E
value
)
{
Object
object
=
obj
;
String
[]
names
=
StringUtils
.
split
(
propertyName
,
"."
);
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
if
(
i
<
names
.
length
-
1
)
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
else
{
String
setterMethodName
=
SETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
invokeMethodByName
(
object
,
setterMethodName
,
new
Object
[]
{
value
});
}
}
}
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
getFieldValue
(
final
Object
obj
,
final
String
fieldName
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
null
;
}
E
result
=
null
;
try
{
result
=
(
E
)
field
.
get
(
obj
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常{}"
,
e
.
getMessage
());
}
return
result
;
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public
static
<
E
>
void
setFieldValue
(
final
Object
obj
,
final
String
fieldName
,
final
E
value
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
;
}
try
{
field
.
set
(
obj
,
value
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常: {}"
,
e
.
getMessage
());
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>[]
parameterTypes
,
final
Object
[]
args
)
{
if
(
obj
==
null
||
methodName
==
null
)
{
return
null
;
}
Method
method
=
getAccessibleMethod
(
obj
,
methodName
,
parameterTypes
);
if
(
method
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethodByName
(
final
Object
obj
,
final
String
methodName
,
final
Object
[]
args
)
{
Method
method
=
getAccessibleMethodByName
(
obj
,
methodName
,
args
.
length
);
if
(
method
==
null
)
{
// 如果为空不报错,直接返回空。
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
// 类型转换(将参数数据类型转换为目标方法参数类型)
Class
<?>[]
cs
=
method
.
getParameterTypes
();
for
(
int
i
=
0
;
i
<
cs
.
length
;
i
++)
{
if
(
args
[
i
]
!=
null
&&
!
args
[
i
].
getClass
().
equals
(
cs
[
i
]))
{
if
(
cs
[
i
]
==
String
.
class
)
{
args
[
i
]
=
Convert
.
toStr
(
args
[
i
]);
if
(
StringUtils
.
endsWith
((
String
)
args
[
i
],
".0"
))
{
args
[
i
]
=
StringUtils
.
substringBefore
((
String
)
args
[
i
],
".0"
);
}
}
else
if
(
cs
[
i
]
==
Integer
.
class
)
{
args
[
i
]
=
Convert
.
toInt
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Long
.
class
)
{
args
[
i
]
=
Convert
.
toLong
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Double
.
class
)
{
args
[
i
]
=
Convert
.
toDouble
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Float
.
class
)
{
args
[
i
]
=
Convert
.
toFloat
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Date
.
class
)
{
if
(
args
[
i
]
instanceof
String
)
{
args
[
i
]
=
DateUtils
.
parseDate
(
args
[
i
]);
}
else
{
args
[
i
]
=
DateUtil
.
getJavaDate
((
Double
)
args
[
i
]);
}
}
}
}
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
*/
public
static
Field
getAccessibleField
(
final
Object
obj
,
final
String
fieldName
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
fieldName
,
"fieldName can't be blank"
);
for
(
Class
<?>
superClass
=
obj
.
getClass
();
superClass
!=
Object
.
class
;
superClass
=
superClass
.
getSuperclass
())
{
try
{
Field
field
=
superClass
.
getDeclaredField
(
fieldName
);
makeAccessible
(
field
);
return
field
;
}
catch
(
NoSuchFieldException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 匹配函数名+参数类型。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>...
parameterTypes
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
())
{
try
{
Method
method
=
searchType
.
getDeclaredMethod
(
methodName
,
parameterTypes
);
makeAccessible
(
method
);
return
method
;
}
catch
(
NoSuchMethodException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 只匹配函数名。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethodByName
(
final
Object
obj
,
final
String
methodName
,
int
argsNum
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
())
{
Method
[]
methods
=
searchType
.
getDeclaredMethods
();
for
(
Method
method
:
methods
)
{
if
(
method
.
getName
().
equals
(
methodName
)
&&
method
.
getParameterTypes
().
length
==
argsNum
)
{
makeAccessible
(
method
);
return
method
;
}
}
}
return
null
;
}
/**
* 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Method
method
)
{
if
((!
Modifier
.
isPublic
(
method
.
getModifiers
())
||
!
Modifier
.
isPublic
(
method
.
getDeclaringClass
().
getModifiers
()))
&&
!
method
.
isAccessible
())
{
method
.
setAccessible
(
true
);
}
}
/**
* 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Field
field
)
{
if
((!
Modifier
.
isPublic
(
field
.
getModifiers
())
||
!
Modifier
.
isPublic
(
field
.
getDeclaringClass
().
getModifiers
())
||
Modifier
.
isFinal
(
field
.
getModifiers
()))
&&
!
field
.
isAccessible
())
{
field
.
setAccessible
(
true
);
}
}
/**
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
Class
<
T
>
getClassGenricType
(
final
Class
clazz
)
{
return
getClassGenricType
(
clazz
,
0
);
}
/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*/
public
static
Class
getClassGenricType
(
final
Class
clazz
,
final
int
index
)
{
Type
genType
=
clazz
.
getGenericSuperclass
();
if
(!(
genType
instanceof
ParameterizedType
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
"'s superclass not ParameterizedType"
);
return
Object
.
class
;
}
Type
[]
params
=
((
ParameterizedType
)
genType
).
getActualTypeArguments
();
if
(
index
>=
params
.
length
||
index
<
0
)
{
logger
.
debug
(
"Index: "
+
index
+
", Size of "
+
clazz
.
getSimpleName
()
+
"'s Parameterized Type: "
+
params
.
length
);
return
Object
.
class
;
}
if
(!(
params
[
index
]
instanceof
Class
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
" not set the actual class on superclass generic parameter"
);
return
Object
.
class
;
}
return
(
Class
)
params
[
index
];
}
public
static
Class
<?>
getUserClass
(
Object
instance
)
{
if
(
instance
==
null
)
{
throw
new
RuntimeException
(
"Instance must not be null"
);
}
Class
clazz
=
instance
.
getClass
();
if
(
clazz
!=
null
&&
clazz
.
getName
().
contains
(
CGLIB_CLASS_SEPARATOR
))
{
Class
<?>
superClass
=
clazz
.
getSuperclass
();
if
(
superClass
!=
null
&&
!
Object
.
class
.
equals
(
superClass
))
{
return
superClass
;
}
}
return
clazz
;
}
/**
* 将反射时的checked exception转换为unchecked exception.
*/
public
static
RuntimeException
convertReflectionExceptionToUnchecked
(
String
msg
,
Exception
e
)
{
if
(
e
instanceof
IllegalAccessException
||
e
instanceof
IllegalArgumentException
||
e
instanceof
NoSuchMethodException
)
{
return
new
IllegalArgumentException
(
msg
,
e
);
}
else
if
(
e
instanceof
InvocationTargetException
)
{
return
new
RuntimeException
(
msg
,
((
InvocationTargetException
)
e
).
getTargetException
());
}
return
new
RuntimeException
(
msg
,
e
);
}
}
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excel.java
0 → 100644
View file @
bcee37b8
package
com.ruoyi.framework.aspectj.lang.annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* 自定义导出Excel数据注解
*
* @author ruoyi
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
FIELD
)
public
@interface
Excel
{
/**
* 导出到Excel中的名字.
*/
public
String
name
()
default
""
;
/**
* 日期格式, 如: yyyy-MM-dd
*/
public
String
dateFormat
()
default
""
;
/**
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/
public
String
readConverterExp
()
default
""
;
/**
* 导出类型(0数字 1字符串)
*/
public
ColumnType
cellType
()
default
ColumnType
.
STRING
;
/**
* 导出时在excel中每个列的高度 单位为字符
*/
public
double
height
()
default
14
;
/**
* 导出时在excel中每个列的宽 单位为字符
*/
public
double
width
()
default
16
;
/**
* 文字后缀,如% 90 变成90%
*/
public
String
suffix
()
default
""
;
/**
* 当值为空时,字段的默认值
*/
public
String
defaultValue
()
default
""
;
/**
* 提示信息
*/
public
String
prompt
()
default
""
;
/**
* 设置只能选择不能输入的列内容.
*/
public
String
[]
combo
()
default
{};
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
public
boolean
isExport
()
default
true
;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public
String
targetAttr
()
default
""
;
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
Type
type
()
default
Type
.
ALL
;
public
enum
Type
{
ALL
(
0
),
EXPORT
(
1
),
IMPORT
(
2
);
private
final
int
value
;
Type
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
return
this
.
value
;
}
}
public
enum
ColumnType
{
NUMERIC
(
0
),
STRING
(
1
);
private
final
int
value
;
ColumnType
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
return
this
.
value
;
}
}
}
\ No newline at end of file
ruoyi/src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Excels.java
0 → 100644
View file @
bcee37b8
package
com.ruoyi.framework.aspectj.lang.annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Excel注解集
*
* @author ruoyi
*/
@Target
(
ElementType
.
FIELD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
Excels
{
Excel
[]
value
();
}
\ No newline at end of file
ruoyi/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
View file @
bcee37b8
...
...
@@ -98,6 +98,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
"/**/*.js"
).
permitAll
()
.
antMatchers
(
"/profile/**"
).
anonymous
()
.
antMatchers
(
"/common/download**"
).
anonymous
()
.
antMatchers
(
"/swagger-ui.html"
).
anonymous
()
.
antMatchers
(
"/swagger-resources/**"
).
anonymous
()
.
antMatchers
(
"/webjars/**"
).
anonymous
()
...
...
ruoyi/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
View file @
bcee37b8
package
com.ruoyi.framework.config
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
...
...
@@ -8,8 +10,12 @@ import springfox.documentation.builders.ApiInfoBuilder;
import
springfox.documentation.builders.PathSelectors
;
import
springfox.documentation.builders.RequestHandlerSelectors
;
import
springfox.documentation.service.ApiInfo
;
import
springfox.documentation.service.ApiKey
;
import
springfox.documentation.service.AuthorizationScope
;
import
springfox.documentation.service.Contact
;
import
springfox.documentation.service.SecurityReference
;
import
springfox.documentation.spi.DocumentationType
;
import
springfox.documentation.spi.service.contexts.SecurityContext
;
import
springfox.documentation.spring.web.plugins.Docket
;
import
springfox.documentation.swagger2.annotations.EnableSwagger2
;
...
...
@@ -33,6 +39,7 @@ public class SwaggerConfig
public
Docket
createRestApi
()
{
return
new
Docket
(
DocumentationType
.
SWAGGER_2
)
.
pathMapping
(
"/dev-api"
)
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
.
apiInfo
(
apiInfo
())
// 设置哪些接口暴露给Swagger展示
...
...
@@ -43,7 +50,47 @@ public class SwaggerConfig
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.
paths
(
PathSelectors
.
any
())
.
build
();
.
build
()
/* 设置安全模式,swagger可以设置访问token */
.
securitySchemes
(
securitySchemes
())
.
securityContexts
(
securityContexts
());
}
/**
* 安全模式,这里指定token通过Authorization头请求头传递
*/
private
List
<
ApiKey
>
securitySchemes
()
{
List
<
ApiKey
>
apiKeyList
=
new
ArrayList
<
ApiKey
>();
apiKeyList
.
add
(
new
ApiKey
(
"Authorization"
,
"Authorization"
,
"header"
));
return
apiKeyList
;
}
/**
* 安全上下文
*/
private
List
<
SecurityContext
>
securityContexts
()
{
List
<
SecurityContext
>
securityContexts
=
new
ArrayList
<>();
securityContexts
.
add
(
SecurityContext
.
builder
()
.
securityReferences
(
defaultAuth
())
.
forPaths
(
PathSelectors
.
regex
(
"^(?!auth).*$"
))
.
build
());
return
securityContexts
;
}
/**
* 默认的安全上引用
*/
private
List
<
SecurityReference
>
defaultAuth
()
{
AuthorizationScope
authorizationScope
=
new
AuthorizationScope
(
"global"
,
"accessEverything"
);
AuthorizationScope
[]
authorizationScopes
=
new
AuthorizationScope
[
1
];
authorizationScopes
[
0
]
=
authorizationScope
;
List
<
SecurityReference
>
securityReferences
=
new
ArrayList
<>();
securityReferences
.
add
(
new
SecurityReference
(
"Authorization"
,
authorizationScopes
));
return
securityReferences
;
}
/**
...
...
@@ -54,7 +101,7 @@ public class SwaggerConfig
// 用ApiInfoBuilder进行定制
return
new
ApiInfoBuilder
()
// 设置标题
.
title
(
"标题:
余心
管理系统_接口文档"
)
.
title
(
"标题:
若依
管理系统_接口文档"
)
// 描述
.
description
(
"描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块..."
)
// 作者信息
...
...
ruoyi/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
View file @
bcee37b8
...
...
@@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory;
import
org.springframework.security.access.AccessDeniedException
;
import
org.springframework.security.authentication.AccountExpiredException
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.validation.BindException
;
import
org.springframework.web.bind.MethodArgumentNotValidException
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.RestControllerAdvice
;
import
org.springframework.web.servlet.NoHandlerFoundException
;
...
...
@@ -82,6 +84,28 @@ public class GlobalExceptionHandler
return
AjaxResult
.
error
(
e
.
getMessage
());
}
/**
* 自定义验证异常
*/
@ExceptionHandler
(
BindException
.
class
)
public
AjaxResult
validatedBindException
(
BindException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
String
message
=
e
.
getAllErrors
().
get
(
0
).
getDefaultMessage
();
return
AjaxResult
.
error
(
message
);
}
/**
* 自定义验证异常
*/
@ExceptionHandler
(
MethodArgumentNotValidException
.
class
)
public
Object
validExceptionHandler
(
MethodArgumentNotValidException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
String
message
=
e
.
getBindingResult
().
getFieldError
().
getDefaultMessage
();
return
AjaxResult
.
error
(
message
);
}
/**
* 演示模式异常
*/
...
...
ruoyi/src/main/java/com/ruoyi/project/common/CommonController.java
View file @
bcee37b8
package
com.ruoyi.project.common
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.multipart.MultipartFile
;
import
com.ruoyi.common.utils.StringUtils
;
import
com.ruoyi.common.utils.file.FileUploadUtils
;
import
com.ruoyi.common.utils.file.FileUtils
;
import
com.ruoyi.framework.config.RuoYiConfig
;
import
com.ruoyi.framework.config.ServerConfig
;
import
com.ruoyi.framework.web.domain.AjaxResult
;
...
...
@@ -17,9 +24,45 @@ import com.ruoyi.framework.web.domain.AjaxResult;
@RestController
public
class
CommonController
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
CommonController
.
class
);
@Autowired
private
ServerConfig
serverConfig
;
/**
* 通用下载请求
*
* @param fileName 文件名称
* @param delete 是否删除
*/
@GetMapping
(
"common/download"
)
public
void
fileDownload
(
String
fileName
,
Boolean
delete
,
HttpServletResponse
response
,
HttpServletRequest
request
)
{
try
{
if
(!
FileUtils
.
isValidFilename
(
fileName
))
{
throw
new
Exception
(
StringUtils
.
format
(
"文件名称({})非法,不允许下载。 "
,
fileName
));
}
String
realFileName
=
System
.
currentTimeMillis
()
+
fileName
.
substring
(
fileName
.
indexOf
(
"_"
)
+
1
);
String
filePath
=
RuoYiConfig
.
getDownloadPath
()
+
fileName
;
response
.
setCharacterEncoding
(
"utf-8"
);
response
.
setContentType
(
"multipart/form-data"
);
response
.
setHeader
(
"Content-Disposition"
,
"attachment;fileName="
+
FileUtils
.
setFileDownloadHeader
(
request
,
realFileName
));
FileUtils
.
writeBytes
(
filePath
,
response
.
getOutputStream
());
if
(
delete
)
{
FileUtils
.
deleteFile
(
filePath
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"下载文件失败"
,
e
);
}
}
/**
* 通用上传请求
*/
...
...
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysLogininforController.java
View file @
bcee37b8
...
...
@@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.DeleteMapping
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
com.ruoyi.common.utils.poi.ExcelUtil
;
import
com.ruoyi.framework.aspectj.lang.annotation.Log
;
import
com.ruoyi.framework.aspectj.lang.enums.BusinessType
;
import
com.ruoyi.framework.web.controller.BaseController
;
import
com.ruoyi.framework.web.domain.AjaxResult
;
import
com.ruoyi.framework.web.page.TableDataInfo
;
import
com.ruoyi.project.monitor.domain.SysLogininfor
;
import
com.ruoyi.project.monitor.service.ISysLogininforService
;
...
...
@@ -31,4 +37,31 @@ public class SysLogininforController extends BaseController
List
<
SysLogininfor
>
list
=
logininforService
.
selectLogininforList
(
logininfor
);
return
getDataTable
(
list
);
}
@Log
(
title
=
"登陆日志"
,
businessType
=
BusinessType
.
EXPORT
)
@PreAuthorize
(
"@ss.hasPermi('monitor:logininfor:export')"
)
@GetMapping
(
"/export"
)
public
AjaxResult
export
(
SysLogininfor
logininfor
)
{
List
<
SysLogininfor
>
list
=
logininforService
.
selectLogininforList
(
logininfor
);
ExcelUtil
<
SysLogininfor
>
util
=
new
ExcelUtil
<
SysLogininfor
>(
SysLogininfor
.
class
);
return
util
.
exportExcel
(
list
,
"登陆日志"
);
}
@PreAuthorize
(
"@ss.hasPermi('monitor:logininfor:remove')"
)
@Log
(
title
=
"登陆日志"
,
businessType
=
BusinessType
.
DELETE
)
@DeleteMapping
(
"/{infoIds}"
)
public
AjaxResult
remove
(
@PathVariable
Long
[]
infoIds
)
{
return
toAjax
(
logininforService
.
deleteLogininforByIds
(
infoIds
));
}
@PreAuthorize
(
"@ss.hasPermi('monitor:logininfor:remove')"
)
@Log
(
title
=
"登陆日志"
,
businessType
=
BusinessType
.
CLEAN
)
@DeleteMapping
(
"/clean"
)
public
AjaxResult
clean
()
{
logininforService
.
cleanLogininfor
();
return
AjaxResult
.
success
();
}
}
ruoyi/src/main/java/com/ruoyi/project/monitor/controller/SysOperlogController.java
View file @
bcee37b8
...
...
@@ -3,10 +3,16 @@ package com.ruoyi.project.monitor.controller;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.DeleteMapping
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
com.ruoyi.common.utils.poi.ExcelUtil
;
import
com.ruoyi.framework.aspectj.lang.annotation.Log
;
import
com.ruoyi.framework.aspectj.lang.enums.BusinessType
;
import
com.ruoyi.framework.web.controller.BaseController
;
import
com.ruoyi.framework.web.domain.AjaxResult
;
import
com.ruoyi.framework.web.page.TableDataInfo
;
import
com.ruoyi.project.monitor.domain.SysOperLog
;
import
com.ruoyi.project.monitor.service.ISysOperLogService
;
...
...
@@ -31,4 +37,30 @@ public class SysOperlogController extends BaseController
List
<
SysOperLog
>
list
=
operLogService
.
selectOperLogList
(
operLog
);
return
getDataTable
(
list
);
}
@Log
(
title
=
"操作日志"
,
businessType
=
BusinessType
.
EXPORT
)
@PreAuthorize
(
"@ss.hasPermi('monitor:operlog:export')"
)
@GetMapping
(
"/export"
)
public
AjaxResult
export
(
SysOperLog
operLog
)
{
List
<
SysOperLog
>
list
=
operLogService
.
selectOperLogList
(
operLog
);
ExcelUtil
<
SysOperLog
>
util
=
new
ExcelUtil
<
SysOperLog
>(
SysOperLog
.
class
);
return
util
.
exportExcel
(
list
,
"操作日志"
);
}
@PreAuthorize
(
"@ss.hasPermi('monitor:operlog:remove')"
)
@DeleteMapping
(
"/{operIds}"
)
public
AjaxResult
remove
(
@PathVariable
Long
[]
operIds
)
{
return
toAjax
(
operLogService
.
deleteOperLogByIds
(
operIds
));
}
@Log
(
title
=
"操作日志"
,
businessType
=
BusinessType
.
CLEAN
)
@PreAuthorize
(
"@ss.hasPermi('monitor:operlog:remove')"
)
@DeleteMapping
(
"/clean"
)
public
AjaxResult
clean
()
{
operLogService
.
cleanOperLog
();
return
AjaxResult
.
success
();
}
}
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysLogininfor.java
View file @
bcee37b8
package
com.ruoyi.project.monitor.domain
;
import
java.util.Date
;
import
com.ruoyi.framework.aspectj.lang.annotation.Excel
;
import
com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType
;
import
com.ruoyi.framework.web.domain.BaseEntity
;
/**
...
...
@@ -13,30 +15,39 @@ public class SysLogininfor extends BaseEntity
private
static
final
long
serialVersionUID
=
1L
;
/** ID */
@Excel
(
name
=
"序号"
,
cellType
=
ColumnType
.
NUMERIC
)
private
Long
infoId
;
/** 用户账号 */
@Excel
(
name
=
"用户账号"
)
private
String
userName
;
/** 登录状态 0成功 1失败 */
@Excel
(
name
=
"登录状态"
,
readConverterExp
=
"0=成功,1=失败"
)
private
String
status
;
/** 登录IP地址 */
@Excel
(
name
=
"登录地址"
)
private
String
ipaddr
;
/** 登录地点 */
@Excel
(
name
=
"登录地点"
)
private
String
loginLocation
;
/** 浏览器类型 */
@Excel
(
name
=
"浏览器"
)
private
String
browser
;
/** 操作系统 */
@Excel
(
name
=
"操作系统"
)
private
String
os
;
/** 提示消息 */
@Excel
(
name
=
"提示消息"
)
private
String
msg
;
/** 访问时间 */
@Excel
(
name
=
"访问时间"
,
width
=
30
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
loginTime
;
public
Long
getInfoId
()
...
...
ruoyi/src/main/java/com/ruoyi/project/monitor/domain/SysOperLog.java
View file @
bcee37b8
package
com.ruoyi.project.monitor.domain
;
import
java.util.Date
;
import
com.ruoyi.framework.aspectj.lang.annotation.Excel
;
import
com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType
;
import
com.ruoyi.framework.web.domain.BaseEntity
;
/**
...
...
@@ -13,54 +15,70 @@ public class SysOperLog extends BaseEntity
private
static
final
long
serialVersionUID
=
1L
;
/** 日志主键 */
@Excel
(
name
=
"操作序号"
,
cellType
=
ColumnType
.
NUMERIC
)
private
Long
operId
;
/** 操作模块 */
@Excel
(
name
=
"操作模块"
)
private
String
title
;
/** 业务类型(0其它 1新增 2修改 3删除) */
@Excel
(
name
=
"业务类型"
,
readConverterExp
=
"0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据"
)
private
Integer
businessType
;
/** 业务类型数组 */
private
Integer
[]
businessTypes
;
/** 请求方法 */
@Excel
(
name
=
"请求方法"
)
private
String
method
;
/** 请求方式 */
@Excel
(
name
=
"请求方式"
)
private
String
requestMethod
;
/** 操作类别(0其它 1后台用户 2手机端用户) */
@Excel
(
name
=
"操作类别"
,
readConverterExp
=
"0=其它,1=后台用户,2=手机端用户"
)
private
Integer
operatorType
;
/** 操作人员 */
@Excel
(
name
=
"操作人员"
)
private
String
operName
;
/** 部门名称 */
@Excel
(
name
=
"部门名称"
)
private
String
deptName
;
/** 请求url */
@Excel
(
name
=
"请求地址"
)
private
String
operUrl
;
/** 操作地址 */
@Excel
(
name
=
"操作地址"
)
private
String
operIp
;
/** 操作地点 */
@Excel
(
name
=
"操作地点"
)
private
String
operLocation
;
/** 请求参数 */
@Excel
(
name
=
"请求参数"
)
private
String
operParam
;
/** 返回参数 */
@Excel
(
name
=
"返回参数"
)
private
String
jsonResult
;
/** 操作状态(0正常 1异常) */
@Excel
(
name
=
"状态"
,
readConverterExp
=
"0=正常,1=异常"
)
private
Integer
status
;
/** 错误消息 */
@Excel
(
name
=
"错误消息"
)
private
String
errorMsg
;
/** 操作时间 */
@Excel
(
name
=
"操作时间"
,
width
=
30
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
operTime
;
public
Long
getOperId
()
...
...
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysLogininforMapper.java
View file @
bcee37b8
...
...
@@ -28,10 +28,10 @@ public interface SysLogininforMapper
/**
* 批量删除系统登录日志
*
* @param ids 需要删除的
数据
* @param i
nfoI
ds 需要删除的
登录日志ID
* @return 结果
*/
public
int
deleteLogininforByIds
(
Stri
ng
[]
ids
);
public
int
deleteLogininforByIds
(
Lo
ng
[]
i
nfoI
ds
);
/**
* 清空系统登录日志
...
...
ruoyi/src/main/java/com/ruoyi/project/monitor/mapper/SysOperLogMapper.java
View file @
bcee37b8
...
...
@@ -28,10 +28,10 @@ public interface SysOperLogMapper
/**
* 批量删除系统操作日志
*
* @param
i
ds 需要删除的
数据
* @param
operI
ds 需要删除的
操作日志ID
* @return 结果
*/
public
int
deleteOperLogByIds
(
Stri
ng
[]
i
ds
);
public
int
deleteOperLogByIds
(
Lo
ng
[]
operI
ds
);
/**
* 查询操作日志详细
...
...
Prev
1
2
3
4
5
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment