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
"litemall-wx-api/vscode:/vscode.git/clone" did not exist on "cc2bccf27d281b71b3bccb0441f4e9e0c9d4492d"
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