Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
guns-vip
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
chenjunxiong
guns-vip
Commits
d552b1db
Commit
d552b1db
authored
Oct 08, 2018
by
fengshuonan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改包名为cn
parent
bb2d570a
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
60 changed files
with
4869 additions
and
0 deletions
+4869
-0
src/main/java/cn/stylefeng/guns/GunsApplication.java
+38
-0
src/main/java/cn/stylefeng/guns/GunsServletInitializer.java
+33
-0
src/main/java/cn/stylefeng/guns/core/aop/GlobalExceptionHandler.java
+138
-0
src/main/java/cn/stylefeng/guns/core/aop/LogAop.java
+121
-0
src/main/java/cn/stylefeng/guns/core/aop/PermissionAop.java
+72
-0
src/main/java/cn/stylefeng/guns/core/beetl/BeetlConfiguration.java
+74
-0
src/main/java/cn/stylefeng/guns/core/beetl/ShiroExt.java
+179
-0
src/main/java/cn/stylefeng/guns/core/cache/BaseCacheFactory.java
+49
-0
src/main/java/cn/stylefeng/guns/core/cache/CacheKit.java
+59
-0
src/main/java/cn/stylefeng/guns/core/cache/EhcacheFactory.java
+86
-0
src/main/java/cn/stylefeng/guns/core/cache/ICache.java
+40
-0
src/main/java/cn/stylefeng/guns/core/cache/ILoader.java
+23
-0
src/main/java/cn/stylefeng/guns/core/common/annotion/BussinessLog.java
+48
-0
src/main/java/cn/stylefeng/guns/core/common/annotion/Permission.java
+37
-0
src/main/java/cn/stylefeng/guns/core/common/constant/cache/Cache.java
+30
-0
src/main/java/cn/stylefeng/guns/core/common/constant/cache/CacheKey.java
+46
-0
src/main/java/cn/stylefeng/guns/core/common/constant/dictmap/DeleteDict.java
+46
-0
src/main/java/cn/stylefeng/guns/core/common/constant/state/Order.java
+41
-0
src/main/java/cn/stylefeng/guns/core/log/LogManager.java
+48
-0
src/main/java/cn/stylefeng/guns/core/log/LogObjectHolder.java
+48
-0
src/main/java/cn/stylefeng/guns/core/log/factory/LogFactory.java
+62
-0
src/main/java/cn/stylefeng/guns/core/log/factory/LogTaskFactory.java
+117
-0
src/main/java/cn/stylefeng/guns/core/node/MenuNode.java
+253
-0
src/main/java/cn/stylefeng/guns/core/node/ZTreeNode.java
+93
-0
src/main/java/cn/stylefeng/guns/core/page/PageInfoBT.java
+56
-0
src/main/java/cn/stylefeng/guns/core/shiro/ShiroDbRealm.java
+93
-0
src/main/java/cn/stylefeng/guns/core/shiro/ShiroKit.java
+290
-0
src/main/java/cn/stylefeng/guns/core/shiro/ShiroUser.java
+96
-0
src/main/java/cn/stylefeng/guns/core/shiro/check/ICheck.java
+32
-0
src/main/java/cn/stylefeng/guns/core/shiro/check/PermissionCheckFactory.java
+75
-0
src/main/java/cn/stylefeng/guns/core/shiro/check/PermissionCheckManager.java
+51
-0
src/main/java/cn/stylefeng/guns/core/shiro/factory/IShiro.java
+65
-0
src/main/java/cn/stylefeng/guns/core/shiro/factory/ShiroFactroy.java
+113
-0
src/main/java/cn/stylefeng/guns/core/tag/DictSelectorTag.java
+217
-0
src/main/java/cn/stylefeng/guns/core/util/ApiMenuFilter.java
+52
-0
src/main/java/cn/stylefeng/guns/core/util/Contrast.java
+228
-0
src/main/java/cn/stylefeng/guns/core/util/JwtTokenUtil.java
+142
-0
src/main/java/cn/stylefeng/guns/core/util/KaptchaUtil.java
+33
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/BlackboardController.java
+50
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/KaptchaController.java
+129
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/LoginController.java
+149
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/LoginLogController.java
+85
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/MenuController.java
+256
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/NoticeController.java
+153
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/RoleController.java
+242
-0
src/main/java/cn/stylefeng/guns/modular/system/controller/UserMgrController.java
+0
-0
src/main/java/cn/stylefeng/guns/modular/system/model/Relation.java
+75
-0
src/test/java/cn/stylefeng/guns/base/BaseJunit.java
+40
-0
src/test/java/cn/stylefeng/guns/multi/entity/Test.java
+49
-0
src/test/java/cn/stylefeng/guns/multi/mapper/TestMapper.java
+16
-0
src/test/java/cn/stylefeng/guns/multi/mapper/mapping/TestMapper.xml
+19
-0
src/test/java/cn/stylefeng/guns/multi/service/TestService.java
+37
-0
src/test/java/cn/stylefeng/guns/multi/service/impl/TestServiceImpl.java
+52
-0
src/test/java/cn/stylefeng/guns/multi/test/BizTest.java
+27
-0
src/test/java/cn/stylefeng/guns/shiro/Base64Test.java
+27
-0
src/test/java/cn/stylefeng/guns/system/BlackBoardTest.java
+29
-0
src/test/java/cn/stylefeng/guns/system/DeptTest.java
+59
-0
src/test/java/cn/stylefeng/guns/system/DictTest.java
+51
-0
src/test/java/cn/stylefeng/guns/system/MenuTest.java
+0
-0
src/test/java/cn/stylefeng/guns/system/UserTest.java
+0
-0
No files found.
src/main/java/cn/stylefeng/guns/GunsApplication.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
/**
* SpringBoot方式启动类
*
* @author stylefeng
* @Date 2017/5/21 12:06
*/
@SpringBootApplication
public
class
GunsApplication
{
private
final
static
Logger
logger
=
LoggerFactory
.
getLogger
(
GunsApplication
.
class
);
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
GunsApplication
.
class
,
args
);
logger
.
info
(
"GunsApplication is success!"
);
}
}
src/main/java/cn/stylefeng/guns/GunsServletInitializer.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
;
import
org.springframework.boot.builder.SpringApplicationBuilder
;
import
org.springframework.boot.web.servlet.support.SpringBootServletInitializer
;
/**
* Guns Web程序启动类
*
* @author fengshuonan
* @date 2017-05-21 9:43
*/
public
class
GunsServletInitializer
extends
SpringBootServletInitializer
{
@Override
protected
SpringApplicationBuilder
configure
(
SpringApplicationBuilder
builder
)
{
return
builder
.
sources
(
GunsApplication
.
class
);
}
}
src/main/java/cn/stylefeng/guns/core/aop/GlobalExceptionHandler.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
aop
;
import
cn.stylefeng.guns.core.log.LogManager
;
import
cn.stylefeng.guns.core.log.factory.LogTaskFactory
;
import
cn.stylefeng.guns.core.shiro.ShiroKit
;
import
cn.stylefeng.roses.core.reqres.response.ErrorResponseData
;
import
cn.stylefeng.roses.kernel.model.exception.ServiceException
;
import
cn.stylefeng.guns.core.common.exception.BizExceptionEnum
;
import
cn.stylefeng.guns.core.common.exception.InvalidKaptchaException
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.CredentialsException
;
import
org.apache.shiro.authc.DisabledAccountException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.ui.Model
;
import
org.springframework.web.bind.annotation.ControllerAdvice
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.bind.annotation.ResponseStatus
;
import
java.lang.reflect.UndeclaredThrowableException
;
import
static
cn
.
stylefeng
.
roses
.
core
.
util
.
HttpContext
.
getIp
;
import
static
cn
.
stylefeng
.
roses
.
core
.
util
.
HttpContext
.
getRequest
;
/**
* 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
*
* @author fengshuonan
* @date 2016年11月12日 下午3:19:56
*/
@ControllerAdvice
@Order
(-
1
)
public
class
GlobalExceptionHandler
{
private
Logger
log
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
/**
* 拦截业务异常
*/
@ExceptionHandler
(
ServiceException
.
class
)
@ResponseStatus
(
HttpStatus
.
INTERNAL_SERVER_ERROR
)
@ResponseBody
public
ErrorResponseData
bussiness
(
ServiceException
e
)
{
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
exceptionLog
(
ShiroKit
.
getUser
().
getId
(),
e
));
getRequest
().
setAttribute
(
"tip"
,
e
.
getMessage
());
log
.
error
(
"业务异常:"
,
e
);
return
new
ErrorResponseData
(
e
.
getCode
(),
e
.
getMessage
());
}
/**
* 用户未登录异常
*/
@ExceptionHandler
(
AuthenticationException
.
class
)
@ResponseStatus
(
HttpStatus
.
UNAUTHORIZED
)
public
String
unAuth
(
AuthenticationException
e
)
{
log
.
error
(
"用户未登陆:"
,
e
);
return
"/login.html"
;
}
/**
* 账号被冻结异常
*/
@ExceptionHandler
(
DisabledAccountException
.
class
)
@ResponseStatus
(
HttpStatus
.
UNAUTHORIZED
)
public
String
accountLocked
(
DisabledAccountException
e
,
Model
model
)
{
String
username
=
getRequest
().
getParameter
(
"username"
);
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
loginLog
(
username
,
"账号被冻结"
,
getIp
()));
model
.
addAttribute
(
"tips"
,
"账号被冻结"
);
return
"/login.html"
;
}
/**
* 账号密码错误异常
*/
@ExceptionHandler
(
CredentialsException
.
class
)
@ResponseStatus
(
HttpStatus
.
UNAUTHORIZED
)
public
String
credentials
(
CredentialsException
e
,
Model
model
)
{
String
username
=
getRequest
().
getParameter
(
"username"
);
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
loginLog
(
username
,
"账号密码错误"
,
getIp
()));
model
.
addAttribute
(
"tips"
,
"账号密码错误"
);
return
"/login.html"
;
}
/**
* 验证码错误异常
*/
@ExceptionHandler
(
InvalidKaptchaException
.
class
)
@ResponseStatus
(
HttpStatus
.
BAD_REQUEST
)
public
String
credentials
(
InvalidKaptchaException
e
,
Model
model
)
{
String
username
=
getRequest
().
getParameter
(
"username"
);
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
loginLog
(
username
,
"验证码错误"
,
getIp
()));
model
.
addAttribute
(
"tips"
,
"验证码错误"
);
return
"/login.html"
;
}
/**
* 无权访问该资源异常
*/
@ExceptionHandler
(
UndeclaredThrowableException
.
class
)
@ResponseStatus
(
HttpStatus
.
UNAUTHORIZED
)
@ResponseBody
public
ErrorResponseData
credentials
(
UndeclaredThrowableException
e
)
{
getRequest
().
setAttribute
(
"tip"
,
"权限异常"
);
log
.
error
(
"权限异常!"
,
e
);
return
new
ErrorResponseData
(
BizExceptionEnum
.
NO_PERMITION
.
getCode
(),
BizExceptionEnum
.
NO_PERMITION
.
getMessage
());
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler
(
RuntimeException
.
class
)
@ResponseStatus
(
HttpStatus
.
INTERNAL_SERVER_ERROR
)
@ResponseBody
public
ErrorResponseData
notFount
(
RuntimeException
e
)
{
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
exceptionLog
(
ShiroKit
.
getUser
().
getId
(),
e
));
getRequest
().
setAttribute
(
"tip"
,
"服务器未知运行时异常"
);
log
.
error
(
"运行时异常:"
,
e
);
return
new
ErrorResponseData
(
BizExceptionEnum
.
SERVER_ERROR
.
getCode
(),
BizExceptionEnum
.
SERVER_ERROR
.
getMessage
());
}
}
src/main/java/cn/stylefeng/guns/core/aop/LogAop.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
aop
;
import
cn.stylefeng.guns.core.common.annotion.BussinessLog
;
import
cn.stylefeng.guns.core.log.LogManager
;
import
cn.stylefeng.guns.core.log.LogObjectHolder
;
import
cn.stylefeng.guns.core.log.factory.LogTaskFactory
;
import
cn.stylefeng.guns.core.shiro.ShiroKit
;
import
cn.stylefeng.guns.core.shiro.ShiroUser
;
import
cn.stylefeng.guns.core.util.Contrast
;
import
cn.stylefeng.roses.core.util.HttpContext
;
import
cn.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.Signature
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Component
;
import
java.lang.reflect.Method
;
import
java.util.Map
;
/**
* 日志记录
*
* @author fengshuonan
* @date 2016年12月6日 下午8:48:30
*/
@Aspect
@Component
public
class
LogAop
{
private
Logger
log
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
@Pointcut
(
value
=
"@annotation(cn.stylefeng.guns.core.common.annotion.BussinessLog)"
)
public
void
cutService
()
{
}
@Around
(
"cutService()"
)
public
Object
recordSysLog
(
ProceedingJoinPoint
point
)
throws
Throwable
{
//先执行业务
Object
result
=
point
.
proceed
();
try
{
handle
(
point
);
}
catch
(
Exception
e
)
{
log
.
error
(
"日志记录出错!"
,
e
);
}
return
result
;
}
private
void
handle
(
ProceedingJoinPoint
point
)
throws
Exception
{
//获取拦截的方法名
Signature
sig
=
point
.
getSignature
();
MethodSignature
msig
=
null
;
if
(!(
sig
instanceof
MethodSignature
))
{
throw
new
IllegalArgumentException
(
"该注解只能用于方法"
);
}
msig
=
(
MethodSignature
)
sig
;
Object
target
=
point
.
getTarget
();
Method
currentMethod
=
target
.
getClass
().
getMethod
(
msig
.
getName
(),
msig
.
getParameterTypes
());
String
methodName
=
currentMethod
.
getName
();
//如果当前用户未登录,不做日志
ShiroUser
user
=
ShiroKit
.
getUser
();
if
(
null
==
user
)
{
return
;
}
//获取拦截方法的参数
String
className
=
point
.
getTarget
().
getClass
().
getName
();
Object
[]
params
=
point
.
getArgs
();
//获取操作名称
BussinessLog
annotation
=
currentMethod
.
getAnnotation
(
BussinessLog
.
class
);
String
bussinessName
=
annotation
.
value
();
String
key
=
annotation
.
key
();
Class
dictClass
=
annotation
.
dict
();
StringBuilder
sb
=
new
StringBuilder
();
for
(
Object
param
:
params
)
{
sb
.
append
(
param
);
sb
.
append
(
" & "
);
}
//如果涉及到修改,比对变化
String
msg
;
if
(
bussinessName
.
contains
(
"修改"
)
||
bussinessName
.
contains
(
"编辑"
))
{
Object
obj1
=
LogObjectHolder
.
me
().
get
();
Map
<
String
,
String
>
obj2
=
HttpContext
.
getRequestParameters
();
msg
=
Contrast
.
contrastObj
(
dictClass
,
key
,
obj1
,
obj2
);
}
else
{
Map
<
String
,
String
>
parameters
=
HttpContext
.
getRequestParameters
();
AbstractDictMap
dictMap
=
(
AbstractDictMap
)
dictClass
.
newInstance
();
msg
=
Contrast
.
parseMutiKey
(
dictMap
,
key
,
parameters
);
}
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
bussinessLog
(
user
.
getId
(),
bussinessName
,
className
,
methodName
,
msg
));
}
}
\ No newline at end of file
src/main/java/cn/stylefeng/guns/core/aop/PermissionAop.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
aop
;
import
cn.stylefeng.guns.core.common.annotion.Permission
;
import
cn.stylefeng.guns.core.shiro.check.PermissionCheckManager
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Pointcut
;
import
org.aspectj.lang.reflect.MethodSignature
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.stereotype.Component
;
import
javax.naming.NoPermissionException
;
import
java.lang.reflect.Method
;
/**
* 权限检查的aop
*
* @author fengshuonan
* @date 2017-07-13 21:05
*/
@Aspect
@Component
@Order
(
200
)
public
class
PermissionAop
{
@Pointcut
(
value
=
"@annotation(cn.stylefeng.guns.core.common.annotion.Permission)"
)
private
void
cutPermission
()
{
}
@Around
(
"cutPermission()"
)
public
Object
doPermission
(
ProceedingJoinPoint
point
)
throws
Throwable
{
MethodSignature
ms
=
(
MethodSignature
)
point
.
getSignature
();
Method
method
=
ms
.
getMethod
();
Permission
permission
=
method
.
getAnnotation
(
Permission
.
class
);
Object
[]
permissions
=
permission
.
value
();
if
(
permissions
.
length
==
0
)
{
//检查全体角色
boolean
result
=
PermissionCheckManager
.
checkAll
();
if
(
result
)
{
return
point
.
proceed
();
}
else
{
throw
new
NoPermissionException
();
}
}
else
{
//检查指定角色
boolean
result
=
PermissionCheckManager
.
check
(
permissions
);
if
(
result
)
{
return
point
.
proceed
();
}
else
{
throw
new
NoPermissionException
();
}
}
}
}
src/main/java/cn/stylefeng/guns/core/beetl/BeetlConfiguration.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
beetl
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.guns.core.tag.DictSelectorTag
;
import
cn.stylefeng.guns.core.util.KaptchaUtil
;
import
org.beetl.core.Context
;
import
org.beetl.core.Function
;
import
org.beetl.ext.spring.BeetlGroupUtilConfiguration
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.env.Environment
;
import
java.io.UnsupportedEncodingException
;
import
java.nio.charset.StandardCharsets
;
/**
* beetl拓展配置,绑定一些工具类,方便在模板中直接调用
*
* @author stylefeng
* @Date 2018/2/22 21:03
*/
public
class
BeetlConfiguration
extends
BeetlGroupUtilConfiguration
{
@Autowired
private
Environment
env
;
@Autowired
private
DictSelectorTag
dictSelectorTag
;
@Override
public
void
initOther
()
{
groupTemplate
.
registerFunctionPackage
(
"shiro"
,
new
ShiroExt
());
groupTemplate
.
registerFunctionPackage
(
"tool"
,
new
ToolUtil
());
groupTemplate
.
registerFunctionPackage
(
"kaptcha"
,
new
KaptchaUtil
());
groupTemplate
.
registerTagFactory
(
"dictSelector"
,
()
->
dictSelectorTag
);
groupTemplate
.
registerFunction
(
"env"
,
new
Function
()
{
@Override
public
String
call
(
Object
[]
paras
,
Context
ctx
)
{
String
key
=
(
String
)
paras
[
0
];
String
value
=
env
.
getProperty
(
key
);
if
(
value
!=
null
)
{
return
getStr
(
value
);
}
if
(
paras
.
length
==
2
)
{
return
(
String
)
paras
[
1
];
}
return
null
;
}
String
getStr
(
String
str
)
{
try
{
return
new
String
(
str
.
getBytes
(
"iso8859-1"
),
StandardCharsets
.
UTF_8
);
}
catch
(
UnsupportedEncodingException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
});
}
}
src/main/java/cn/stylefeng/guns/core/beetl/ShiroExt.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
beetl
;
import
cn.stylefeng.guns.core.shiro.ShiroUser
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.subject.Subject
;
public
class
ShiroExt
{
private
static
final
String
NAMES_DELIMETER
=
","
;
/**
* 获取当前 Subject
*
* @return Subject
*/
public
static
Subject
getSubject
()
{
return
SecurityUtils
.
getSubject
();
}
/**
* 获取封装的 ShiroUser
*
* @return ShiroUser
*/
public
ShiroUser
getUser
()
{
if
(
isGuest
())
{
return
null
;
}
else
{
return
(
ShiroUser
)
getSubject
().
getPrincipals
().
getPrimaryPrincipal
();
}
}
/**
* 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用
*
* @param roleName 角色名
* @return 属于该角色:true,否则false
*/
public
boolean
hasRole
(
String
roleName
)
{
return
getSubject
()
!=
null
&&
roleName
!=
null
&&
roleName
.
length
()
>
0
&&
getSubject
().
hasRole
(
roleName
);
}
/**
* 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。
*
* @param roleName 角色名
* @return 不属于该角色:true,否则false
*/
public
boolean
lacksRole
(
String
roleName
)
{
return
!
hasRole
(
roleName
);
}
/**
* 验证当前用户是否属于以下任意一个角色。
*
* @param roleNames 角色列表
* @return 属于:true,否则false
*/
public
boolean
hasAnyRoles
(
String
roleNames
)
{
boolean
hasAnyRole
=
false
;
Subject
subject
=
getSubject
();
if
(
subject
!=
null
&&
roleNames
!=
null
&&
roleNames
.
length
()
>
0
)
{
for
(
String
role
:
roleNames
.
split
(
NAMES_DELIMETER
))
{
if
(
subject
.
hasRole
(
role
.
trim
()))
{
hasAnyRole
=
true
;
break
;
}
}
}
return
hasAnyRole
;
}
/**
* 验证当前用户是否属于以下所有角色。
*
* @param roleNames 角色列表
* @return 属于:true,否则false
*/
public
boolean
hasAllRoles
(
String
roleNames
)
{
boolean
hasAllRole
=
true
;
Subject
subject
=
getSubject
();
if
(
subject
!=
null
&&
roleNames
!=
null
&&
roleNames
.
length
()
>
0
)
{
for
(
String
role
:
roleNames
.
split
(
NAMES_DELIMETER
))
{
if
(!
subject
.
hasRole
(
role
.
trim
()))
{
hasAllRole
=
false
;
break
;
}
}
}
return
hasAllRole
;
}
/**
* 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用
*
* @param permission 权限名
* @return 拥有权限:true,否则false
*/
public
boolean
hasPermission
(
String
permission
)
{
return
getSubject
()
!=
null
&&
permission
!=
null
&&
permission
.
length
()
>
0
&&
getSubject
().
isPermitted
(
permission
);
}
/**
* 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。
*
* @param permission 权限名
* @return 拥有权限:true,否则false
*/
public
boolean
lacksPermission
(
String
permission
)
{
return
!
hasPermission
(
permission
);
}
/**
* 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用
*
* @return 通过身份验证:true,否则false
*/
public
boolean
authenticated
()
{
return
getSubject
()
!=
null
&&
getSubject
().
isAuthenticated
();
}
/**
* 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。
*
* @return 没有通过身份验证:true,否则false
*/
public
boolean
notAuthenticated
()
{
return
!
authenticated
();
}
/**
* 认证通过或已记住的用户。与guset搭配使用。
*
* @return 用户:true,否则 false
*/
public
boolean
isUser
()
{
return
getSubject
()
!=
null
&&
getSubject
().
getPrincipal
()
!=
null
;
}
/**
* 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用
*
* @return 访客:true,否则false
*/
public
boolean
isGuest
()
{
return
!
isUser
();
}
/**
* 输出当前用户信息,通常为登录帐号信息。
*
* @return 当前用户信息
*/
public
String
principal
()
{
if
(
getSubject
()
!=
null
)
{
Object
principal
=
getSubject
().
getPrincipal
();
return
principal
.
toString
();
}
return
""
;
}
}
src/main/java/cn/stylefeng/guns/core/cache/BaseCacheFactory.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
cache
;
/**
* 缓存工厂基类
*/
public
abstract
class
BaseCacheFactory
implements
ICache
{
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
get
(
String
cacheName
,
Object
key
,
ILoader
iLoader
)
{
Object
data
=
get
(
cacheName
,
key
);
if
(
data
==
null
)
{
data
=
iLoader
.
load
();
put
(
cacheName
,
key
,
data
);
}
return
(
T
)
data
;
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
get
(
String
cacheName
,
Object
key
,
Class
<?
extends
ILoader
>
iLoaderClass
)
{
Object
data
=
get
(
cacheName
,
key
);
if
(
data
==
null
)
{
try
{
ILoader
dataLoader
=
iLoaderClass
.
newInstance
();
data
=
dataLoader
.
load
();
put
(
cacheName
,
key
,
data
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
}
}
return
(
T
)
data
;
}
}
src/main/java/cn/stylefeng/guns/core/cache/CacheKit.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
cache
;
import
java.util.List
;
/**
* 缓存工具类
*/
public
class
CacheKit
{
private
static
ICache
defaultCacheFactory
=
new
EhcacheFactory
();
public
static
void
put
(
String
cacheName
,
Object
key
,
Object
value
)
{
defaultCacheFactory
.
put
(
cacheName
,
key
,
value
);
}
public
static
<
T
>
T
get
(
String
cacheName
,
Object
key
)
{
return
defaultCacheFactory
.
get
(
cacheName
,
key
);
}
@SuppressWarnings
(
"rawtypes"
)
public
static
List
getKeys
(
String
cacheName
)
{
return
defaultCacheFactory
.
getKeys
(
cacheName
);
}
public
static
void
remove
(
String
cacheName
,
Object
key
)
{
defaultCacheFactory
.
remove
(
cacheName
,
key
);
}
public
static
void
removeAll
(
String
cacheName
)
{
defaultCacheFactory
.
removeAll
(
cacheName
);
}
public
static
<
T
>
T
get
(
String
cacheName
,
Object
key
,
ILoader
iLoader
)
{
return
defaultCacheFactory
.
get
(
cacheName
,
key
,
iLoader
);
}
public
static
<
T
>
T
get
(
String
cacheName
,
Object
key
,
Class
<?
extends
ILoader
>
iLoaderClass
)
{
return
defaultCacheFactory
.
get
(
cacheName
,
key
,
iLoaderClass
);
}
}
src/main/java/cn/stylefeng/guns/core/cache/EhcacheFactory.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2011-2016, James Zhan 詹波 (jfinal@126.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
cache
;
import
net.sf.ehcache.Cache
;
import
net.sf.ehcache.CacheManager
;
import
net.sf.ehcache.Element
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.List
;
/**
* Ehcache缓存工厂
*/
public
class
EhcacheFactory
extends
BaseCacheFactory
{
private
static
CacheManager
cacheManager
;
private
static
volatile
Object
locker
=
new
Object
();
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
EhcacheFactory
.
class
);
private
static
CacheManager
getCacheManager
()
{
if
(
cacheManager
==
null
)
{
synchronized
(
EhcacheFactory
.
class
)
{
if
(
cacheManager
==
null
)
{
cacheManager
=
CacheManager
.
create
();
}
}
}
return
cacheManager
;
}
static
Cache
getOrAddCache
(
String
cacheName
)
{
CacheManager
cacheManager
=
getCacheManager
();
Cache
cache
=
cacheManager
.
getCache
(
cacheName
);
if
(
cache
==
null
)
{
synchronized
(
locker
)
{
cache
=
cacheManager
.
getCache
(
cacheName
);
if
(
cache
==
null
)
{
log
.
warn
(
"无法找到缓存 ["
+
cacheName
+
"]的配置, 使用默认配置."
);
cacheManager
.
addCacheIfAbsent
(
cacheName
);
cache
=
cacheManager
.
getCache
(
cacheName
);
log
.
debug
(
"缓存 ["
+
cacheName
+
"] 启动."
);
}
}
}
return
cache
;
}
public
void
put
(
String
cacheName
,
Object
key
,
Object
value
)
{
getOrAddCache
(
cacheName
).
put
(
new
Element
(
key
,
value
));
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
get
(
String
cacheName
,
Object
key
)
{
Element
element
=
getOrAddCache
(
cacheName
).
get
(
key
);
return
element
!=
null
?
(
T
)
element
.
getObjectValue
()
:
null
;
}
@SuppressWarnings
(
"rawtypes"
)
public
List
getKeys
(
String
cacheName
)
{
return
getOrAddCache
(
cacheName
).
getKeys
();
}
public
void
remove
(
String
cacheName
,
Object
key
)
{
getOrAddCache
(
cacheName
).
remove
(
key
);
}
public
void
removeAll
(
String
cacheName
)
{
getOrAddCache
(
cacheName
).
removeAll
();
}
}
src/main/java/cn/stylefeng/guns/core/cache/ICache.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
cache
;
import
java.util.List
;
/**
* 通用缓存接口
*/
public
interface
ICache
{
void
put
(
String
cacheName
,
Object
key
,
Object
value
);
<
T
>
T
get
(
String
cacheName
,
Object
key
);
@SuppressWarnings
(
"rawtypes"
)
List
getKeys
(
String
cacheName
);
void
remove
(
String
cacheName
,
Object
key
);
void
removeAll
(
String
cacheName
);
<
T
>
T
get
(
String
cacheName
,
Object
key
,
ILoader
iLoader
);
<
T
>
T
get
(
String
cacheName
,
Object
key
,
Class
<?
extends
ILoader
>
iLoaderClass
);
}
src/main/java/cn/stylefeng/guns/core/cache/ILoader.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
cache
;
/**
* 数据重载
*/
public
interface
ILoader
{
Object
load
();
}
src/main/java/cn/stylefeng/guns/core/common/annotion/BussinessLog.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
common
.
annotion
;
import
cn.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap
;
import
cn.stylefeng.guns.core.common.constant.dictmap.base.SystemDict
;
import
java.lang.annotation.*
;
/**
* 标记需要做业务日志的方法
*
* @author fengshuonan
* @date 2017-03-31 12:46
*/
@Inherited
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
})
public
@interface
BussinessLog
{
/**
* 业务的名称,例如:"修改菜单"
*/
String
value
()
default
""
;
/**
* 被修改的实体的唯一标识,例如:菜单实体的唯一标识为"id"
*/
String
key
()
default
"id"
;
/**
* 字典(用于查找key的中文名称和字段的中文名称)
*/
Class
<?
extends
AbstractDictMap
>
dict
()
default
SystemDict
.
class
;
}
src/main/java/cn/stylefeng/guns/core/common/annotion/Permission.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
common
.
annotion
;
import
java.lang.annotation.*
;
/**
* 权限注解 用于检查权限 规定访问权限
*
* @example @Permission({role1,role2})
* @example @Permission
*/
@Inherited
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
})
public
@interface
Permission
{
/**
* <p>角色英文名称</p>
* <p>使用注解时加上这个值表示限制只有某个角色的才可以访问对应的资源</p>
* <p>常用在某些资源限制只有超级管理员角色才可访问</p>
*/
String
[]
value
()
default
{};
}
src/main/java/cn/stylefeng/guns/core/common/constant/cache/Cache.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
common
.
constant
.
cache
;
/**
* 所有缓存名称的集合
*
* @author fengshuonan
* @date 2017-04-24 21:56
*/
public
interface
Cache
{
/**
* 常量缓存
*/
String
CONSTANT
=
"CONSTANT"
;
}
src/main/java/cn/stylefeng/guns/core/common/constant/cache/CacheKey.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
common
.
constant
.
cache
;
/**
* 缓存标识前缀集合,常用在ConstantFactory类中
*
* @author fengshuonan
* @date 2017-04-25 9:37
*/
public
interface
CacheKey
{
/**
* 角色名称(多个)
*/
String
ROLES_NAME
=
"roles_name_"
;
/**
* 角色名称(单个)
*/
String
SINGLE_ROLE_NAME
=
"single_role_name_"
;
/**
* 角色英文名称
*/
String
SINGLE_ROLE_TIP
=
"single_role_tip_"
;
/**
* 部门名称
*/
String
DEPT_NAME
=
"dept_name_"
;
}
src/main/java/cn/stylefeng/guns/core/common/constant/dictmap/DeleteDict.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
common
.
constant
.
dictmap
;
import
cn.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap
;
/**
* 用于删除业务的字典
*
* @author fengshuonan
* @date 2017-05-06 15:01
*/
public
class
DeleteDict
extends
AbstractDictMap
{
@Override
public
void
init
()
{
put
(
"roleId"
,
"角色名称"
);
put
(
"deptId"
,
"部门名称"
);
put
(
"menuId"
,
"菜单名称"
);
put
(
"dictId"
,
"字典名称"
);
put
(
"noticeId"
,
"标题"
);
}
@Override
protected
void
initBeWrapped
()
{
putFieldWrapperMethodName
(
"roleId"
,
"getCacheObject"
);
putFieldWrapperMethodName
(
"deptId"
,
"getCacheObject"
);
putFieldWrapperMethodName
(
"menuId"
,
"getCacheObject"
);
putFieldWrapperMethodName
(
"dictId"
,
"getCacheObject"
);
putFieldWrapperMethodName
(
"noticeId"
,
"getCacheObject"
);
}
}
src/main/java/cn/stylefeng/guns/core/common/constant/state/Order.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
common
.
constant
.
state
;
/**
* 数据库排序
*
* @author fengshuonan
* @Date 2017年5月31日20:48:41
*/
public
enum
Order
{
ASC
(
"asc"
),
DESC
(
"desc"
);
private
String
des
;
Order
(
String
des
)
{
this
.
des
=
des
;
}
public
String
getDes
()
{
return
des
;
}
public
void
setDes
(
String
des
)
{
this
.
des
=
des
;
}
}
src/main/java/cn/stylefeng/guns/core/log/LogManager.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
log
;
import
java.util.TimerTask
;
import
java.util.concurrent.ScheduledThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
/**
* 日志管理器
*
* @author fengshuonan
* @date 2017-03-30 16:29
*/
public
class
LogManager
{
//日志记录操作延时
private
final
int
OPERATE_DELAY_TIME
=
10
;
//异步操作记录日志的线程池
private
ScheduledThreadPoolExecutor
executor
=
new
ScheduledThreadPoolExecutor
(
10
);
private
LogManager
()
{
}
public
static
LogManager
logManager
=
new
LogManager
();
public
static
LogManager
me
()
{
return
logManager
;
}
public
void
executeLog
(
TimerTask
task
)
{
executor
.
schedule
(
task
,
OPERATE_DELAY_TIME
,
TimeUnit
.
MILLISECONDS
);
}
}
src/main/java/cn/stylefeng/guns/core/log/LogObjectHolder.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
log
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
import
org.springframework.context.annotation.Scope
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.WebApplicationContext
;
import
java.io.Serializable
;
/**
* 被修改的bean临时存放的地方
*
* @author fengshuonan
* @date 2017-03-31 11:19
*/
@Component
@Scope
(
scopeName
=
WebApplicationContext
.
SCOPE_SESSION
)
public
class
LogObjectHolder
implements
Serializable
{
private
Object
object
=
null
;
public
void
set
(
Object
obj
)
{
this
.
object
=
obj
;
}
public
Object
get
()
{
return
object
;
}
public
static
LogObjectHolder
me
(){
return
SpringContextHolder
.
getBean
(
LogObjectHolder
.
class
);
}
}
src/main/java/cn/stylefeng/guns/core/log/factory/LogFactory.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
log
.
factory
;
import
cn.stylefeng.guns.core.common.constant.state.LogSucceed
;
import
cn.stylefeng.guns.core.common.constant.state.LogType
;
import
cn.stylefeng.guns.modular.system.model.LoginLog
;
import
cn.stylefeng.guns.modular.system.model.OperationLog
;
import
java.util.Date
;
/**
* 日志对象创建工厂
*
* @author fengshuonan
* @date 2016年12月6日 下午9:18:27
*/
public
class
LogFactory
{
/**
* 创建操作日志
*/
public
static
OperationLog
createOperationLog
(
LogType
logType
,
Integer
userId
,
String
bussinessName
,
String
clazzName
,
String
methodName
,
String
msg
,
LogSucceed
succeed
)
{
OperationLog
operationLog
=
new
OperationLog
();
operationLog
.
setLogtype
(
logType
.
getMessage
());
operationLog
.
setLogname
(
bussinessName
);
operationLog
.
setUserid
(
userId
);
operationLog
.
setClassname
(
clazzName
);
operationLog
.
setMethod
(
methodName
);
operationLog
.
setCreatetime
(
new
Date
());
operationLog
.
setSucceed
(
succeed
.
getMessage
());
operationLog
.
setMessage
(
msg
);
return
operationLog
;
}
/**
* 创建登录日志
*/
public
static
LoginLog
createLoginLog
(
LogType
logType
,
Integer
userId
,
String
msg
,
String
ip
)
{
LoginLog
loginLog
=
new
LoginLog
();
loginLog
.
setLogname
(
logType
.
getMessage
());
loginLog
.
setUserid
(
userId
);
loginLog
.
setCreatetime
(
new
Date
());
loginLog
.
setSucceed
(
LogSucceed
.
SUCCESS
.
getMessage
());
loginLog
.
setIp
(
ip
);
loginLog
.
setMessage
(
msg
);
return
loginLog
;
}
}
src/main/java/cn/stylefeng/guns/core/log/factory/LogTaskFactory.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
log
.
factory
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.guns.core.common.constant.state.LogSucceed
;
import
cn.stylefeng.guns.core.common.constant.state.LogType
;
import
cn.stylefeng.guns.core.log.LogManager
;
import
cn.stylefeng.guns.modular.system.dao.LoginLogMapper
;
import
cn.stylefeng.guns.modular.system.dao.OperationLogMapper
;
import
cn.stylefeng.guns.modular.system.model.LoginLog
;
import
cn.stylefeng.guns.modular.system.model.OperationLog
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.TimerTask
;
/**
* 日志操作任务创建工厂
*
* @author fengshuonan
* @date 2016年12月6日 下午9:18:27
*/
public
class
LogTaskFactory
{
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
LogManager
.
class
);
private
static
LoginLogMapper
loginLogMapper
=
SpringContextHolder
.
getBean
(
LoginLogMapper
.
class
);
private
static
OperationLogMapper
operationLogMapper
=
SpringContextHolder
.
getBean
(
OperationLogMapper
.
class
);
public
static
TimerTask
loginLog
(
final
Integer
userId
,
final
String
ip
)
{
return
new
TimerTask
()
{
@Override
public
void
run
()
{
try
{
LoginLog
loginLog
=
LogFactory
.
createLoginLog
(
LogType
.
LOGIN
,
userId
,
null
,
ip
);
loginLogMapper
.
insert
(
loginLog
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"创建登录日志异常!"
,
e
);
}
}
};
}
public
static
TimerTask
loginLog
(
final
String
username
,
final
String
msg
,
final
String
ip
)
{
return
new
TimerTask
()
{
@Override
public
void
run
()
{
LoginLog
loginLog
=
LogFactory
.
createLoginLog
(
LogType
.
LOGIN_FAIL
,
null
,
"账号:"
+
username
+
","
+
msg
,
ip
);
try
{
loginLogMapper
.
insert
(
loginLog
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"创建登录失败异常!"
,
e
);
}
}
};
}
public
static
TimerTask
exitLog
(
final
Integer
userId
,
final
String
ip
)
{
return
new
TimerTask
()
{
@Override
public
void
run
()
{
LoginLog
loginLog
=
LogFactory
.
createLoginLog
(
LogType
.
EXIT
,
userId
,
null
,
ip
);
try
{
loginLogMapper
.
insert
(
loginLog
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"创建退出日志异常!"
,
e
);
}
}
};
}
public
static
TimerTask
bussinessLog
(
final
Integer
userId
,
final
String
bussinessName
,
final
String
clazzName
,
final
String
methodName
,
final
String
msg
)
{
return
new
TimerTask
()
{
@Override
public
void
run
()
{
OperationLog
operationLog
=
LogFactory
.
createOperationLog
(
LogType
.
BUSSINESS
,
userId
,
bussinessName
,
clazzName
,
methodName
,
msg
,
LogSucceed
.
SUCCESS
);
try
{
operationLogMapper
.
insert
(
operationLog
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"创建业务日志异常!"
,
e
);
}
}
};
}
public
static
TimerTask
exceptionLog
(
final
Integer
userId
,
final
Exception
exception
)
{
return
new
TimerTask
()
{
@Override
public
void
run
()
{
String
msg
=
ToolUtil
.
getExceptionMsg
(
exception
);
OperationLog
operationLog
=
LogFactory
.
createOperationLog
(
LogType
.
EXCEPTION
,
userId
,
""
,
null
,
null
,
msg
,
LogSucceed
.
FAIL
);
try
{
operationLogMapper
.
insert
(
operationLog
);
}
catch
(
Exception
e
)
{
logger
.
error
(
"创建异常日志异常!"
,
e
);
}
}
};
}
}
src/main/java/cn/stylefeng/guns/core/node/MenuNode.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
node
;
import
cn.stylefeng.roses.kernel.model.enums.YesOrNotEnum
;
import
java.util.*
;
/**
* @author fengshuonan
* @Description 菜单的节点
* @date 2016年12月6日 上午11:34:17
*/
public
class
MenuNode
implements
Comparable
{
/**
* 节点id
*/
private
Long
id
;
/**
* 父节点
*/
private
Long
parentId
;
/**
* 节点名称
*/
private
String
name
;
/**
* 按钮级别
*/
private
Integer
levels
;
/**
* 按钮级别
*/
private
Integer
ismenu
;
/**
* 按钮的排序
*/
private
Integer
num
;
/**
* 节点的url
*/
private
String
url
;
/**
* 节点图标
*/
private
String
icon
;
/**
* 子节点的集合
*/
private
List
<
MenuNode
>
children
;
/**
* 查询子节点时候的临时集合
*/
private
List
<
MenuNode
>
linkedList
=
new
ArrayList
<
MenuNode
>();
public
MenuNode
()
{
super
();
}
public
MenuNode
(
Long
id
,
Long
parentId
)
{
super
();
this
.
id
=
id
;
this
.
parentId
=
parentId
;
}
public
Integer
getLevels
()
{
return
levels
;
}
public
void
setLevels
(
Integer
levels
)
{
this
.
levels
=
levels
;
}
public
String
getIcon
()
{
return
icon
;
}
public
void
setIcon
(
String
icon
)
{
this
.
icon
=
icon
;
}
public
static
MenuNode
createRoot
()
{
return
new
MenuNode
(
0L
,
-
1L
);
}
public
Long
getId
()
{
return
id
;
}
public
void
setId
(
Long
id
)
{
this
.
id
=
id
;
}
public
Long
getParentId
()
{
return
parentId
;
}
public
void
setParentId
(
Long
parentId
)
{
this
.
parentId
=
parentId
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
String
getUrl
()
{
return
url
;
}
public
void
setUrl
(
String
url
)
{
this
.
url
=
url
;
}
public
List
<
MenuNode
>
getChildren
()
{
return
children
;
}
public
void
setChildren
(
List
<
MenuNode
>
children
)
{
this
.
children
=
children
;
}
public
Integer
getNum
()
{
return
num
;
}
public
void
setNum
(
Integer
num
)
{
this
.
num
=
num
;
}
public
Integer
getIsmenu
()
{
return
ismenu
;
}
public
void
setIsmenu
(
Integer
ismenu
)
{
this
.
ismenu
=
ismenu
;
}
@Override
public
String
toString
()
{
return
"MenuNode{"
+
"id="
+
id
+
", parentId="
+
parentId
+
", name='"
+
name
+
'\''
+
", levels="
+
levels
+
", num="
+
num
+
", url='"
+
url
+
'\''
+
", icon='"
+
icon
+
'\''
+
", children="
+
children
+
", linkedList="
+
linkedList
+
'}'
;
}
/**
* 重写排序比较接口,首先根据等级排序,然后更具排序字段排序
*
* @param o
* @return
*/
@Override
public
int
compareTo
(
Object
o
)
{
MenuNode
menuNode
=
(
MenuNode
)
o
;
Integer
num
=
menuNode
.
getNum
();
Integer
levels
=
menuNode
.
getLevels
();
if
(
num
==
null
)
{
num
=
0
;
}
if
(
levels
==
null
)
{
levels
=
0
;
}
if
(
this
.
levels
.
compareTo
(
levels
)
==
0
)
{
return
this
.
num
.
compareTo
(
num
);
}
else
{
return
this
.
levels
.
compareTo
(
levels
);
}
}
/**
* 构建页面菜单列表
*/
public
static
List
<
MenuNode
>
buildTitle
(
List
<
MenuNode
>
nodes
)
{
if
(
nodes
.
size
()
<=
0
)
{
return
nodes
;
}
//剔除非菜单
nodes
.
removeIf
(
node
->
!
node
.
getIsmenu
().
equals
(
YesOrNotEnum
.
Y
.
getCode
()));
//对菜单排序,返回列表按菜单等级,序号的排序方式排列
Collections
.
sort
(
nodes
);
return
mergeList
(
nodes
,
nodes
.
get
(
nodes
.
size
()
-
1
).
getLevels
(),
null
);
}
/**
* 递归合并数组为子数组,最后返回第一层
*
* @param menuList
* @param listMap
* @return
*/
private
static
List
<
MenuNode
>
mergeList
(
List
<
MenuNode
>
menuList
,
int
rank
,
Map
<
Long
,
List
<
MenuNode
>>
listMap
)
{
//保存当次调用总共合并了多少元素
int
n
;
//保存当次调用总共合并出来的list
Map
<
Long
,
List
<
MenuNode
>>
currentMap
=
new
HashMap
<>();
//由于按等级从小到大排序,需要从后往前排序
//判断该节点是否属于当前循环的等级,不等于则跳出循环
for
(
n
=
menuList
.
size
()
-
1
;
n
>=
0
&&
menuList
.
get
(
n
).
getLevels
()
==
rank
;
n
--)
{
//判断之前的调用是否有返回以该节点的id为key的map,有则设置为children列表。
if
(
listMap
!=
null
&&
listMap
.
get
(
menuList
.
get
(
n
).
getId
())
!=
null
)
{
menuList
.
get
(
n
).
setChildren
(
listMap
.
get
(
menuList
.
get
(
n
).
getId
()));
}
if
(
menuList
.
get
(
n
).
getParentId
()!=
null
&&
menuList
.
get
(
n
).
getParentId
()!=
0
)
{
//判断当前节点所属的pid是否已经创建了以该pid为key的键值对,没有则创建新的链表
currentMap
.
computeIfAbsent
(
menuList
.
get
(
n
).
getParentId
(),
k
->
new
LinkedList
<>());
//将该节点插入到对应的list的头部
currentMap
.
get
(
menuList
.
get
(
n
).
getParentId
()).
add
(
0
,
menuList
.
get
(
n
));
}
}
if
(
n
<
0
)
{
return
menuList
;
}
else
{
return
mergeList
(
menuList
.
subList
(
0
,
n
+
1
),
menuList
.
get
(
n
).
getLevels
(),
currentMap
);
}
}
}
src/main/java/cn/stylefeng/guns/core/node/ZTreeNode.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
node
;
/**
* jquery ztree 插件的节点
*
* @author fengshuonan
* @date 2017年2月17日 下午8:25:14
*/
public
class
ZTreeNode
{
private
Long
id
;
//节点id
private
Long
pId
;
//父节点id
private
String
name
;
//节点名称
private
Boolean
open
;
//是否打开节点
private
Boolean
checked
;
//是否被选中
public
Long
getId
()
{
return
id
;
}
public
void
setId
(
Long
id
)
{
this
.
id
=
id
;
}
public
Long
getpId
()
{
return
pId
;
}
public
void
setpId
(
Long
pId
)
{
this
.
pId
=
pId
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
Boolean
getOpen
()
{
return
open
;
}
public
void
setOpen
(
Boolean
open
)
{
this
.
open
=
open
;
}
public
Boolean
getIsOpen
()
{
return
open
;
}
public
void
setIsOpen
(
Boolean
open
)
{
this
.
open
=
open
;
}
public
Boolean
getChecked
()
{
return
checked
;
}
public
void
setChecked
(
Boolean
checked
)
{
this
.
checked
=
checked
;
}
public
static
ZTreeNode
createParent
()
{
ZTreeNode
zTreeNode
=
new
ZTreeNode
();
zTreeNode
.
setChecked
(
true
);
zTreeNode
.
setId
(
0L
);
zTreeNode
.
setName
(
"顶级"
);
zTreeNode
.
setOpen
(
true
);
zTreeNode
.
setpId
(
0L
);
return
zTreeNode
;
}
}
src/main/java/cn/stylefeng/guns/core/page/PageInfoBT.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
page
;
import
com.baomidou.mybatisplus.plugins.Page
;
import
java.util.List
;
/**
* 分页结果的封装(for Bootstrap Table)
*
* @author fengshuonan
* @Date 2017年1月22日 下午11:06:41
*/
public
class
PageInfoBT
<
T
>
{
// 结果集
private
List
<
T
>
rows
;
// 总数
private
long
total
;
public
PageInfoBT
(
Page
<
T
>
page
)
{
this
.
rows
=
page
.
getRecords
();
this
.
total
=
page
.
getTotal
();
}
public
List
<
T
>
getRows
()
{
return
rows
;
}
public
void
setRows
(
List
<
T
>
rows
)
{
this
.
rows
=
rows
;
}
public
long
getTotal
()
{
return
total
;
}
public
void
setTotal
(
long
total
)
{
this
.
total
=
total
;
}
}
src/main/java/cn/stylefeng/guns/core/shiro/ShiroDbRealm.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.guns.core.shiro.factory.IShiro
;
import
cn.stylefeng.guns.core.shiro.factory.ShiroFactroy
;
import
cn.stylefeng.guns.modular.system.model.User
;
import
org.apache.shiro.authc.AuthenticationException
;
import
org.apache.shiro.authc.AuthenticationInfo
;
import
org.apache.shiro.authc.AuthenticationToken
;
import
org.apache.shiro.authc.UsernamePasswordToken
;
import
org.apache.shiro.authc.credential.CredentialsMatcher
;
import
org.apache.shiro.authc.credential.HashedCredentialsMatcher
;
import
org.apache.shiro.authz.AuthorizationInfo
;
import
org.apache.shiro.authz.SimpleAuthorizationInfo
;
import
org.apache.shiro.realm.AuthorizingRealm
;
import
org.apache.shiro.subject.PrincipalCollection
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
public
class
ShiroDbRealm
extends
AuthorizingRealm
{
/**
* 登录认证
*/
@Override
protected
AuthenticationInfo
doGetAuthenticationInfo
(
AuthenticationToken
authcToken
)
throws
AuthenticationException
{
IShiro
shiroFactory
=
ShiroFactroy
.
me
();
UsernamePasswordToken
token
=
(
UsernamePasswordToken
)
authcToken
;
User
user
=
shiroFactory
.
user
(
token
.
getUsername
());
ShiroUser
shiroUser
=
shiroFactory
.
shiroUser
(
user
);
return
shiroFactory
.
info
(
shiroUser
,
user
,
super
.
getName
());
}
/**
* 权限认证
*/
@Override
protected
AuthorizationInfo
doGetAuthorizationInfo
(
PrincipalCollection
principals
)
{
IShiro
shiroFactory
=
ShiroFactroy
.
me
();
ShiroUser
shiroUser
=
(
ShiroUser
)
principals
.
getPrimaryPrincipal
();
List
<
Integer
>
roleList
=
shiroUser
.
getRoleList
();
Set
<
String
>
permissionSet
=
new
HashSet
<>();
Set
<
String
>
roleNameSet
=
new
HashSet
<>();
for
(
Integer
roleId
:
roleList
)
{
List
<
String
>
permissions
=
shiroFactory
.
findPermissionsByRoleId
(
roleId
);
if
(
permissions
!=
null
)
{
for
(
String
permission
:
permissions
)
{
if
(
ToolUtil
.
isNotEmpty
(
permission
))
{
permissionSet
.
add
(
permission
);
}
}
}
String
roleName
=
shiroFactory
.
findRoleNameByRoleId
(
roleId
);
roleNameSet
.
add
(
roleName
);
}
SimpleAuthorizationInfo
info
=
new
SimpleAuthorizationInfo
();
info
.
addStringPermissions
(
permissionSet
);
info
.
addRoles
(
roleNameSet
);
return
info
;
}
/**
* 设置认证加密方式
*/
@Override
public
void
setCredentialsMatcher
(
CredentialsMatcher
credentialsMatcher
)
{
HashedCredentialsMatcher
md5CredentialsMatcher
=
new
HashedCredentialsMatcher
();
md5CredentialsMatcher
.
setHashAlgorithmName
(
ShiroKit
.
hashAlgorithmName
);
md5CredentialsMatcher
.
setHashIterations
(
ShiroKit
.
hashIterations
);
super
.
setCredentialsMatcher
(
md5CredentialsMatcher
);
}
}
src/main/java/cn/stylefeng/guns/core/shiro/ShiroKit.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.guns.core.common.constant.Const
;
import
cn.stylefeng.guns.core.common.constant.factory.ConstantFactory
;
import
org.apache.shiro.SecurityUtils
;
import
org.apache.shiro.crypto.hash.Md5Hash
;
import
org.apache.shiro.crypto.hash.SimpleHash
;
import
org.apache.shiro.session.Session
;
import
org.apache.shiro.subject.Subject
;
import
org.apache.shiro.util.ByteSource
;
import
java.util.List
;
/**
* shiro工具类
*
* @author dafei, Chill Zhuang
*/
public
class
ShiroKit
{
private
static
final
String
NAMES_DELIMETER
=
","
;
/**
* 加盐参数
*/
public
final
static
String
hashAlgorithmName
=
"MD5"
;
/**
* 循环次数
*/
public
final
static
int
hashIterations
=
1024
;
/**
* shiro密码加密工具类
*
* @param credentials 密码
* @param saltSource 密码盐
* @return
*/
public
static
String
md5
(
String
credentials
,
String
saltSource
)
{
ByteSource
salt
=
new
Md5Hash
(
saltSource
);
return
new
SimpleHash
(
hashAlgorithmName
,
credentials
,
salt
,
hashIterations
).
toString
();
}
/**
* 获取随机盐值
* @param length
* @return
*/
public
static
String
getRandomSalt
(
int
length
)
{
return
ToolUtil
.
getRandomString
(
length
);
}
/**
* 获取当前 Subject
*
* @return Subject
*/
public
static
Subject
getSubject
()
{
return
SecurityUtils
.
getSubject
();
}
/**
* 获取封装的 ShiroUser
*
* @return ShiroUser
*/
public
static
ShiroUser
getUser
()
{
if
(
isGuest
())
{
return
null
;
}
else
{
return
(
ShiroUser
)
getSubject
().
getPrincipals
().
getPrimaryPrincipal
();
}
}
/**
* 从shiro获取session
*
*/
public
static
Session
getSession
()
{
return
getSubject
().
getSession
();
}
/**
* 获取shiro指定的sessionKey
*
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
getSessionAttr
(
String
key
)
{
Session
session
=
getSession
();
return
session
!=
null
?
(
T
)
session
.
getAttribute
(
key
)
:
null
;
}
/**
* 设置shiro指定的sessionKey
*
*/
public
static
void
setSessionAttr
(
String
key
,
Object
value
)
{
Session
session
=
getSession
();
session
.
setAttribute
(
key
,
value
);
}
/**
* 移除shiro指定的sessionKey
*/
public
static
void
removeSessionAttr
(
String
key
)
{
Session
session
=
getSession
();
if
(
session
!=
null
)
session
.
removeAttribute
(
key
);
}
/**
* 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用
*
* @param roleName
* 角色名
* @return 属于该角色:true,否则false
*/
public
static
boolean
hasRole
(
String
roleName
)
{
return
getSubject
()
!=
null
&&
roleName
!=
null
&&
roleName
.
length
()
>
0
&&
getSubject
().
hasRole
(
roleName
);
}
/**
* 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。
*
* @param roleName
* 角色名
* @return 不属于该角色:true,否则false
*/
public
static
boolean
lacksRole
(
String
roleName
)
{
return
!
hasRole
(
roleName
);
}
/**
* 验证当前用户是否属于以下任意一个角色。
*
* @param roleNames
* 角色列表
* @return 属于:true,否则false
*/
public
static
boolean
hasAnyRoles
(
String
roleNames
)
{
boolean
hasAnyRole
=
false
;
Subject
subject
=
getSubject
();
if
(
subject
!=
null
&&
roleNames
!=
null
&&
roleNames
.
length
()
>
0
)
{
for
(
String
role
:
roleNames
.
split
(
NAMES_DELIMETER
))
{
if
(
subject
.
hasRole
(
role
.
trim
()))
{
hasAnyRole
=
true
;
break
;
}
}
}
return
hasAnyRole
;
}
/**
* 验证当前用户是否属于以下所有角色。
*
* @param roleNames
* 角色列表
* @return 属于:true,否则false
*/
public
static
boolean
hasAllRoles
(
String
roleNames
)
{
boolean
hasAllRole
=
true
;
Subject
subject
=
getSubject
();
if
(
subject
!=
null
&&
roleNames
!=
null
&&
roleNames
.
length
()
>
0
)
{
for
(
String
role
:
roleNames
.
split
(
NAMES_DELIMETER
))
{
if
(!
subject
.
hasRole
(
role
.
trim
()))
{
hasAllRole
=
false
;
break
;
}
}
}
return
hasAllRole
;
}
/**
* 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用
*
* @param permission
* 权限名
* @return 拥有权限:true,否则false
*/
public
static
boolean
hasPermission
(
String
permission
)
{
return
getSubject
()
!=
null
&&
permission
!=
null
&&
permission
.
length
()
>
0
&&
getSubject
().
isPermitted
(
permission
);
}
/**
* 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。
*
* @param permission
* 权限名
* @return 拥有权限:true,否则false
*/
public
static
boolean
lacksPermission
(
String
permission
)
{
return
!
hasPermission
(
permission
);
}
/**
* 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用
*
* @return 通过身份验证:true,否则false
*/
public
static
boolean
isAuthenticated
()
{
return
getSubject
()
!=
null
&&
getSubject
().
isAuthenticated
();
}
/**
* 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。
*
* @return 没有通过身份验证:true,否则false
*/
public
static
boolean
notAuthenticated
()
{
return
!
isAuthenticated
();
}
/**
* 认证通过或已记住的用户。与guset搭配使用。
*
* @return 用户:true,否则 false
*/
public
static
boolean
isUser
()
{
return
getSubject
()
!=
null
&&
getSubject
().
getPrincipal
()
!=
null
;
}
/**
* 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用
*
* @return 访客:true,否则false
*/
public
static
boolean
isGuest
()
{
return
!
isUser
();
}
/**
* 输出当前用户信息,通常为登录帐号信息。
*
* @return 当前用户信息
*/
public
static
String
principal
()
{
if
(
getSubject
()
!=
null
)
{
Object
principal
=
getSubject
().
getPrincipal
();
return
principal
.
toString
();
}
return
""
;
}
/**
* 获取当前用户的部门数据范围的集合
*/
public
static
List
<
Integer
>
getDeptDataScope
()
{
Integer
deptId
=
getUser
().
getDeptId
();
List
<
Integer
>
subDeptIds
=
ConstantFactory
.
me
().
getSubDeptId
(
deptId
);
subDeptIds
.
add
(
deptId
);
return
subDeptIds
;
}
/**
* 判断当前用户是否是超级管理员
*/
public
static
boolean
isAdmin
()
{
List
<
Integer
>
roleList
=
ShiroKit
.
getUser
().
getRoleList
();
for
(
Integer
integer
:
roleList
)
{
String
singleRoleTip
=
ConstantFactory
.
me
().
getSingleRoleTip
(
integer
);
if
(
singleRoleTip
.
equals
(
Const
.
ADMIN_NAME
))
{
return
true
;
}
}
return
false
;
}
}
src/main/java/cn/stylefeng/guns/core/shiro/ShiroUser.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
;
import
java.io.Serializable
;
import
java.util.List
;
/**
* 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息
*
* @author fengshuonan
* @date 2016年12月5日 上午10:26:43
*/
public
class
ShiroUser
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
public
Integer
id
;
// 主键ID
public
String
account
;
// 账号
public
String
name
;
// 姓名
public
Integer
deptId
;
// 部门id
public
List
<
Integer
>
roleList
;
// 角色集
public
String
deptName
;
// 部门名称
public
List
<
String
>
roleNames
;
// 角色名称集
public
Integer
getId
()
{
return
id
;
}
public
void
setId
(
Integer
id
)
{
this
.
id
=
id
;
}
public
String
getAccount
()
{
return
account
;
}
public
void
setAccount
(
String
account
)
{
this
.
account
=
account
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
Integer
getDeptId
()
{
return
deptId
;
}
public
void
setDeptId
(
Integer
deptId
)
{
this
.
deptId
=
deptId
;
}
public
List
<
Integer
>
getRoleList
()
{
return
roleList
;
}
public
void
setRoleList
(
List
<
Integer
>
roleList
)
{
this
.
roleList
=
roleList
;
}
public
String
getDeptName
()
{
return
deptName
;
}
public
void
setDeptName
(
String
deptName
)
{
this
.
deptName
=
deptName
;
}
public
List
<
String
>
getRoleNames
()
{
return
roleNames
;
}
public
void
setRoleNames
(
List
<
String
>
roleNames
)
{
this
.
roleNames
=
roleNames
;
}
}
src/main/java/cn/stylefeng/guns/core/shiro/check/ICheck.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
.
check
;
/**
* 检查用接口
*/
public
interface
ICheck
{
/**
* 检查当前登录用户是否拥有指定的角色访问当
*/
boolean
check
(
Object
[]
permissions
);
/**
* 检查当前登录用户是否拥有当前请求的servlet的权限
*/
boolean
checkAll
();
}
src/main/java/cn/stylefeng/guns/core/shiro/check/PermissionCheckFactory.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
.
check
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.stylefeng.guns.core.shiro.ShiroKit
;
import
cn.stylefeng.guns.core.shiro.ShiroUser
;
import
cn.stylefeng.roses.core.util.HttpContext
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
import
cn.stylefeng.guns.core.listener.ConfigListener
;
import
org.springframework.context.annotation.DependsOn
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.ArrayList
;
/**
* 权限自定义检查
*/
@Service
@DependsOn
(
"springContextHolder"
)
@Transactional
(
readOnly
=
true
)
public
class
PermissionCheckFactory
implements
ICheck
{
public
static
ICheck
me
()
{
return
SpringContextHolder
.
getBean
(
ICheck
.
class
);
}
@Override
public
boolean
check
(
Object
[]
permissions
)
{
ShiroUser
user
=
ShiroKit
.
getUser
();
if
(
null
==
user
)
{
return
false
;
}
ArrayList
<
Object
>
objects
=
CollectionUtil
.
newArrayList
(
permissions
);
String
join
=
CollectionUtil
.
join
(
objects
,
","
);
if
(
ShiroKit
.
hasAnyRoles
(
join
))
{
return
true
;
}
return
false
;
}
@Override
public
boolean
checkAll
()
{
HttpServletRequest
request
=
HttpContext
.
getRequest
();
ShiroUser
user
=
ShiroKit
.
getUser
();
if
(
null
==
user
)
{
return
false
;
}
String
requestURI
=
request
.
getRequestURI
().
replaceFirst
(
ConfigListener
.
getConf
().
get
(
"contextPath"
),
""
);
String
[]
str
=
requestURI
.
split
(
"/"
);
if
(
str
.
length
>
3
)
{
requestURI
=
"/"
+
str
[
1
]
+
"/"
+
str
[
2
];
}
if
(
ShiroKit
.
hasPermission
(
requestURI
))
{
return
true
;
}
return
false
;
}
}
src/main/java/cn/stylefeng/guns/core/shiro/check/PermissionCheckManager.java
0 → 100644
View file @
d552b1db
/**
* Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
.
check
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
/**
* 权限检查管理器(入口)
*/
public
class
PermissionCheckManager
{
private
final
static
PermissionCheckManager
me
=
new
PermissionCheckManager
();
private
ICheck
defaultCheckFactory
=
SpringContextHolder
.
getBean
(
ICheck
.
class
);
public
static
PermissionCheckManager
me
()
{
return
me
;
}
private
PermissionCheckManager
()
{
}
public
PermissionCheckManager
(
ICheck
checkFactory
)
{
this
.
defaultCheckFactory
=
checkFactory
;
}
public
void
setDefaultCheckFactory
(
ICheck
defaultCheckFactory
)
{
this
.
defaultCheckFactory
=
defaultCheckFactory
;
}
public
static
boolean
check
(
Object
[]
permissions
)
{
return
me
.
defaultCheckFactory
.
check
(
permissions
);
}
public
static
boolean
checkAll
()
{
return
me
.
defaultCheckFactory
.
checkAll
();
}
}
src/main/java/cn/stylefeng/guns/core/shiro/factory/IShiro.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
.
factory
;
import
cn.stylefeng.guns.core.shiro.ShiroUser
;
import
cn.stylefeng.guns.modular.system.model.User
;
import
org.apache.shiro.authc.SimpleAuthenticationInfo
;
import
java.util.List
;
/**
* 定义shirorealm所需数据的接口
*
* @author fengshuonan
* @date 2016年12月5日 上午10:23:34
*/
public
interface
IShiro
{
/**
* 根据账号获取登录用户
*
* @param account 账号
*/
User
user
(
String
account
);
/**
* 根据系统用户获取Shiro的用户
*
* @param user 系统用户
*/
ShiroUser
shiroUser
(
User
user
);
/**
* 获取权限列表通过角色id
*
* @param roleId 角色id
*/
List
<
String
>
findPermissionsByRoleId
(
Integer
roleId
);
/**
* 根据角色id获取角色名称
*
* @param roleId 角色id
*/
String
findRoleNameByRoleId
(
Integer
roleId
);
/**
* 获取shiro的认证信息
*/
SimpleAuthenticationInfo
info
(
ShiroUser
shiroUser
,
User
user
,
String
realmName
);
}
src/main/java/cn/stylefeng/guns/core/shiro/factory/ShiroFactroy.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
shiro
.
factory
;
import
cn.hutool.core.convert.Convert
;
import
cn.stylefeng.guns.core.shiro.ShiroUser
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
import
cn.stylefeng.guns.core.common.constant.factory.ConstantFactory
;
import
cn.stylefeng.guns.core.common.constant.state.ManagerStatus
;
import
cn.stylefeng.guns.modular.system.dao.MenuMapper
;
import
cn.stylefeng.guns.modular.system.dao.UserMapper
;
import
cn.stylefeng.guns.modular.system.model.User
;
import
org.apache.shiro.authc.CredentialsException
;
import
org.apache.shiro.authc.LockedAccountException
;
import
org.apache.shiro.authc.SimpleAuthenticationInfo
;
import
org.apache.shiro.crypto.hash.Md5Hash
;
import
org.apache.shiro.util.ByteSource
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.DependsOn
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.ArrayList
;
import
java.util.List
;
@Service
@DependsOn
(
"springContextHolder"
)
@Transactional
(
readOnly
=
true
)
public
class
ShiroFactroy
implements
IShiro
{
@Autowired
private
UserMapper
userMapper
;
@Autowired
private
MenuMapper
menuMapper
;
public
static
IShiro
me
()
{
return
SpringContextHolder
.
getBean
(
IShiro
.
class
);
}
@Override
public
User
user
(
String
account
)
{
User
user
=
userMapper
.
getByAccount
(
account
);
// 账号不存在
if
(
null
==
user
)
{
throw
new
CredentialsException
();
}
// 账号被冻结
if
(
user
.
getStatus
()
!=
ManagerStatus
.
OK
.
getCode
())
{
throw
new
LockedAccountException
();
}
return
user
;
}
@Override
public
ShiroUser
shiroUser
(
User
user
)
{
ShiroUser
shiroUser
=
new
ShiroUser
();
shiroUser
.
setId
(
user
.
getId
());
shiroUser
.
setAccount
(
user
.
getAccount
());
shiroUser
.
setDeptId
(
user
.
getDeptid
());
shiroUser
.
setDeptName
(
ConstantFactory
.
me
().
getDeptName
(
user
.
getDeptid
()));
shiroUser
.
setName
(
user
.
getName
());
Integer
[]
roleArray
=
Convert
.
toIntArray
(
user
.
getRoleid
());
List
<
Integer
>
roleList
=
new
ArrayList
<
Integer
>();
List
<
String
>
roleNameList
=
new
ArrayList
<
String
>();
for
(
int
roleId
:
roleArray
)
{
roleList
.
add
(
roleId
);
roleNameList
.
add
(
ConstantFactory
.
me
().
getSingleRoleName
(
roleId
));
}
shiroUser
.
setRoleList
(
roleList
);
shiroUser
.
setRoleNames
(
roleNameList
);
return
shiroUser
;
}
@Override
public
List
<
String
>
findPermissionsByRoleId
(
Integer
roleId
)
{
return
menuMapper
.
getResUrlsByRoleId
(
roleId
);
}
@Override
public
String
findRoleNameByRoleId
(
Integer
roleId
)
{
return
ConstantFactory
.
me
().
getSingleRoleTip
(
roleId
);
}
@Override
public
SimpleAuthenticationInfo
info
(
ShiroUser
shiroUser
,
User
user
,
String
realmName
)
{
String
credentials
=
user
.
getPassword
();
// 密码加盐处理
String
source
=
user
.
getSalt
();
ByteSource
credentialsSalt
=
new
Md5Hash
(
source
);
return
new
SimpleAuthenticationInfo
(
shiroUser
,
credentials
,
credentialsSalt
,
realmName
);
}
}
src/main/java/cn/stylefeng/guns/core/tag/DictSelectorTag.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
tag
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.roses.kernel.model.exception.ServiceException
;
import
cn.stylefeng.guns.core.common.exception.BizExceptionEnum
;
import
cn.stylefeng.guns.modular.system.model.Dict
;
import
cn.stylefeng.guns.modular.system.service.IDictService
;
import
org.beetl.core.Tag
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Scope
;
import
org.springframework.stereotype.Component
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Map
;
/**
* 字典标签渲染
*
* @author zhangjiajia
* @Date 2018年6月4日17:33:32
*/
@Component
@Scope
(
"prototype"
)
public
class
DictSelectorTag
extends
Tag
{
@Autowired
IDictService
iDictService
;
@Override
public
void
render
(){
//String tagName = (String) this.args[0];
Map
attrs
=
(
Map
)
args
[
1
];
if
(
ToolUtil
.
isEmpty
(
attrs
.
get
(
"code"
))){
throw
new
ServiceException
(
BizExceptionEnum
.
ERROR_CODE_EMPTY
);
}
//字典类型编码
String
code
=
attrs
.
get
(
"code"
).
toString
();
//控件显示类型select 选择框,radio 单选按钮,checkbox 多选按钮
String
type
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"type"
))?
attrs
.
get
(
"type"
).
toString
():
"select"
;
//开启多选
String
multiple
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"multiple"
))?
attrs
.
get
(
"multiple"
).
toString
():
""
;
//字典名称
String
label
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"label"
))?
attrs
.
get
(
"label"
).
toString
():
""
;
//提示
String
placeholder
=
(
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"placeholder"
))?
attrs
.
get
(
"placeholder"
).
toString
():
""
);
//宽度
String
width
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"width"
))?
attrs
.
get
(
"width"
).
toString
():
"248"
;
//默认值
String
value
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"value"
))?
attrs
.
get
(
"value"
).
toString
():
""
;
//id
String
id
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"id"
))?
attrs
.
get
(
"id"
).
toString
():
""
;
//name
String
name
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"name"
))?
attrs
.
get
(
"name"
).
toString
():
""
;
//分割线
String
underline
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"underline"
))?
attrs
.
get
(
"underline"
).
toString
():
""
;
//onchange事件
String
onchange
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"onchange"
))?
attrs
.
get
(
"onchange"
).
toString
():
""
;
//readonly属性
String
readonly
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"readonly"
))?
attrs
.
get
(
"readonly"
).
toString
():
""
;
//disabled属性
String
disabled
=
ToolUtil
.
isNotEmpty
(
attrs
.
get
(
"disabled"
))?
attrs
.
get
(
"disabled"
).
toString
():
""
;
//searchnum 下拉选项数量达到多少启用搜索,默认10
int
searchnum
=
ToolUtil
.
isNum
(
attrs
.
get
(
"searchnum"
))?
Integer
.
parseInt
(
attrs
.
get
(
"searchnum"
).
toString
()):
10
;
//根据code查询字典数据
List
<
Dict
>
list
=
iDictService
.
selectByParentCode
(
code
);
StringBuffer
html
=
new
StringBuffer
();
html
.
append
(
"<div class=\"form-group\">\r\n"
);
html
.
append
(
"<label class=\"col-sm-3 control-label\">"
+
label
+
"</label>\r\n"
);
html
.
append
(
"<div class=\"col-sm-9\">\r\n"
);
//单选按钮
if
(
"radio"
.
equals
(
type
))
{
list
.
forEach
(
obj
->{
html
.
append
(
"<label class=\"radio-inline i-checks\">\r\n<input type=\"radio\" "
);
//判断控件是否禁用
if
(
"true"
.
equals
(
disabled
)||
"disabled"
.
equals
(
disabled
))
{
html
.
append
(
"disabled "
);
}
else
{
if
(
ToolUtil
.
isNotEmpty
(
name
)){
html
.
append
(
"name=\""
+
name
+
"\" "
);
}
}
if
(
"true"
.
equals
(
readonly
)||
"disabled"
.
equals
(
readonly
))
{
html
.
append
(
"disabled "
);
}
if
(
ToolUtil
.
isNotEmpty
(
value
)&&
value
.
equals
(
obj
.
getCode
())){
html
.
append
(
"checked "
);
}
html
.
append
(
"value=\""
+
obj
.
getCode
()+
"\" >"
+
obj
.
getName
()+
"</label>\r\n"
);
});
//多选按钮
}
else
if
(
"checkbox"
.
equals
(
type
)){
list
.
forEach
(
obj
->{
html
.
append
(
"<label class=\"checkbox-inline i-checks\">\r\n<input type=\"checkbox\" "
);
//判断控件是否禁用
if
(
"true"
.
equals
(
disabled
)||
"disabled"
.
equals
(
disabled
))
{
html
.
append
(
"disabled "
);
}
else
{
if
(
ToolUtil
.
isNotEmpty
(
name
)){
html
.
append
(
"name=\""
+
name
+
"\" "
);
}
}
if
(
"true"
.
equals
(
readonly
)||
"disabled"
.
equals
(
readonly
))
{
html
.
append
(
"disabled "
);
}
if
(
ToolUtil
.
isNotEmpty
(
value
)&&
value
.
equals
(
obj
.
getCode
())){
html
.
append
(
"checked "
);
}
html
.
append
(
"value=\""
+
obj
.
getCode
()+
"\" >"
+
obj
.
getName
()+
"</label>\r\n"
);
});
//默认select
}
else
{
//开启多选
if
(
"true"
.
equals
(
multiple
)){
if
(
list
.
size
()>=
searchnum
)
{
html
.
append
(
"<select multiple "
);
}
else
{
html
.
append
(
"<select multiple=\"multiple\" size=\"10\" "
);
}
}
else
{
html
.
append
(
"<select "
);
}
//判断控件是否启用提示
if
(
ToolUtil
.
isNotEmpty
(
placeholder
)){
html
.
append
(
" data-placeholder=\""
+
placeholder
+
"\" "
);
}
//判断控件是否禁用
if
(
"true"
.
equals
(
disabled
)||
"disabled"
.
equals
(
disabled
))
{
html
.
append
(
"disabled=\"disabled\" "
);
}
else
{
//启用
if
(
ToolUtil
.
isNotEmpty
(
id
)){
html
.
append
(
"id=\""
+
id
+
"\" "
);
}
if
(
ToolUtil
.
isNotEmpty
(
name
)){
html
.
append
(
"name=\""
+
name
+
"\" "
);
}
}
//判断是否启用搜索框
//判断下拉数据,如果查询出来的条数达到启用搜索的数量就启用
if
(
list
.
size
()>=
searchnum
){
html
.
append
(
"class=\"form-control chosen-select\" style=\"width:"
+
width
+
"px\" tabindex=\"1\" \r\n"
);
}
else
{
html
.
append
(
"class=\"form-control\" style=\"width:"
+
width
+
"px\" \r\n"
);
}
//判断控件是否只读
if
(
"true"
.
equals
(
readonly
)||
"readonly"
.
equals
(
readonly
))
{
if
(
list
.
size
()>=
searchnum
)
{
html
.
append
(
"disabled=\"disabled\" "
);
}
else
{
html
.
append
(
"onfocus=\"this.defaultIndex=this.selectedIndex;\" onchange=\"this.selectedIndex=this.defaultIndex;\" "
);
}
}
//判断是否绑定onchange事件
if
(
ToolUtil
.
isNotEmpty
(
onchange
)){
html
.
append
(
"onchange=\""
+
onchange
+
"($(this).children('option:selected').val())\" "
);
}
html
.
append
(
">"
);
if
(
ToolUtil
.
isNotEmpty
(
placeholder
)){
html
.
append
(
"<option value=\"\">"
+
placeholder
+
"</option>\r\n"
);
}
//将查询出来的数据添加到select中
list
.
forEach
(
obj
->{
if
(
ToolUtil
.
isNotEmpty
(
value
)&&
value
.
equals
(
obj
.
getCode
())){
html
.
append
(
"<option selected value=\""
+
obj
.
getCode
()+
"\">"
+
obj
.
getName
()+
"</option>\r\n"
);
}
else
{
html
.
append
(
"<option value=\""
+
obj
.
getCode
()+
"\">"
+
obj
.
getName
()+
"</option>\r\n"
);
}
});
html
.
append
(
"</select>\r\n"
);
}
html
.
append
(
"</div>\r\n</div>\r\n"
);
//判断是否添加分割线
if
(
ToolUtil
.
isNotEmpty
(
underline
)
&&
"true"
.
equals
(
underline
))
{
html
.
append
(
"<div class=\"hr-line-dashed\" ></div >\r\n"
);
}
try
{
this
.
ctx
.
byteWriter
.
writeString
(
html
.
toString
());
}
catch
(
IOException
e
){
throw
new
RuntimeException
(
"输出字典标签错误"
);
}
}
}
src/main/java/cn/stylefeng/guns/core/util/ApiMenuFilter.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
util
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
import
cn.stylefeng.guns.config.properties.GunsProperties
;
import
cn.stylefeng.guns.core.common.constant.Const
;
import
cn.stylefeng.guns.core.node.MenuNode
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* api接口文档显示过滤
*
* @author fengshuonan
* @date 2017-08-17 16:55
*/
public
class
ApiMenuFilter
extends
MenuNode
{
public
static
List
<
MenuNode
>
build
(
List
<
MenuNode
>
nodes
)
{
//如果关闭了接口文档,则不显示接口文档菜单
GunsProperties
gunsProperties
=
SpringContextHolder
.
getBean
(
GunsProperties
.
class
);
if
(!
gunsProperties
.
getSwaggerOpen
())
{
List
<
MenuNode
>
menuNodesCopy
=
new
ArrayList
<>();
for
(
MenuNode
menuNode
:
nodes
)
{
if
(
Const
.
API_MENU_NAME
.
equals
(
menuNode
.
getName
()))
{
continue
;
}
else
{
menuNodesCopy
.
add
(
menuNode
);
}
}
nodes
=
menuNodesCopy
;
}
return
nodes
;
}
}
src/main/java/cn/stylefeng/guns/core/util/Contrast.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
util
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap
;
import
cn.stylefeng.guns.core.common.constant.dictmap.factory.DictFieldWarpperFactory
;
import
java.beans.PropertyDescriptor
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.util.Date
;
import
java.util.Map
;
/**
* 对比两个对象的变化的工具类
*
* @author fengshuonan
* @Date 2017/3/31 10:36
*/
public
class
Contrast
{
//记录每个修改字段的分隔符
public
static
final
String
separator
=
";;;"
;
/**
* 比较两个对象,并返回不一致的信息
*
* @author stylefeng
* @Date 2017/5/9 19:34
*/
public
static
String
contrastObj
(
Object
pojo1
,
Object
pojo2
)
{
String
str
=
""
;
try
{
Class
clazz
=
pojo1
.
getClass
();
Field
[]
fields
=
pojo1
.
getClass
().
getDeclaredFields
();
int
i
=
1
;
for
(
Field
field
:
fields
)
{
if
(
"serialVersionUID"
.
equals
(
field
.
getName
()))
{
continue
;
}
PropertyDescriptor
pd
=
new
PropertyDescriptor
(
field
.
getName
(),
clazz
);
Method
getMethod
=
pd
.
getReadMethod
();
Object
o1
=
getMethod
.
invoke
(
pojo1
);
Object
o2
=
getMethod
.
invoke
(
pojo2
);
if
(
o1
==
null
||
o2
==
null
)
{
continue
;
}
if
(
o1
instanceof
Date
)
{
o1
=
DateUtil
.
formatDate
((
Date
)
o1
);
}
if
(!
o1
.
toString
().
equals
(
o2
.
toString
()))
{
if
(
i
!=
1
)
{
str
+=
separator
;
}
str
+=
"字段名称"
+
field
.
getName
()
+
",旧值:"
+
o1
+
",新值:"
+
o2
;
i
++;
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
str
;
}
/**
* 比较两个对象pojo1和pojo2,并输出不一致信息
*
* @author stylefeng
* @Date 2017/5/9 19:34
*/
public
static
String
contrastObj
(
Class
dictClass
,
String
key
,
Object
pojo1
,
Map
<
String
,
String
>
pojo2
)
throws
IllegalAccessException
,
InstantiationException
{
AbstractDictMap
dictMap
=
(
AbstractDictMap
)
dictClass
.
newInstance
();
String
str
=
parseMutiKey
(
dictMap
,
key
,
pojo2
)
+
separator
;
try
{
Class
clazz
=
pojo1
.
getClass
();
Field
[]
fields
=
pojo1
.
getClass
().
getDeclaredFields
();
int
i
=
1
;
for
(
Field
field
:
fields
)
{
if
(
"serialVersionUID"
.
equals
(
field
.
getName
()))
{
continue
;
}
PropertyDescriptor
pd
=
new
PropertyDescriptor
(
field
.
getName
(),
clazz
);
Method
getMethod
=
pd
.
getReadMethod
();
Object
o1
=
getMethod
.
invoke
(
pojo1
);
Object
o2
=
pojo2
.
get
(
StrUtil
.
lowerFirst
(
getMethod
.
getName
().
substring
(
3
)));
if
(
o1
==
null
||
o2
==
null
)
{
continue
;
}
if
(
o1
instanceof
Date
)
{
o1
=
DateUtil
.
formatDate
((
Date
)
o1
);
}
else
if
(
o1
instanceof
Integer
)
{
o2
=
Integer
.
parseInt
(
o2
.
toString
());
}
if
(!
o1
.
toString
().
equals
(
o2
.
toString
()))
{
if
(
i
!=
1
)
{
str
+=
separator
;
}
String
fieldName
=
dictMap
.
get
(
field
.
getName
());
String
fieldWarpperMethodName
=
dictMap
.
getFieldWarpperMethodName
(
field
.
getName
());
if
(
fieldWarpperMethodName
!=
null
)
{
Object
o1Warpper
=
DictFieldWarpperFactory
.
createFieldWarpper
(
o1
,
fieldWarpperMethodName
);
Object
o2Warpper
=
DictFieldWarpperFactory
.
createFieldWarpper
(
o2
,
fieldWarpperMethodName
);
str
+=
"字段名称:"
+
fieldName
+
",旧值:"
+
o1Warpper
+
",新值:"
+
o2Warpper
;
}
else
{
str
+=
"字段名称:"
+
fieldName
+
",旧值:"
+
o1
+
",新值:"
+
o2
;
}
i
++;
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
str
;
}
/**
* 比较两个对象pojo1和pojo2,并输出不一致信息
*
* @author stylefeng
* @Date 2017/5/9 19:34
*/
public
static
String
contrastObjByName
(
Class
dictClass
,
String
key
,
Object
pojo1
,
Map
<
String
,
String
>
pojo2
)
throws
IllegalAccessException
,
InstantiationException
{
AbstractDictMap
dictMap
=
(
AbstractDictMap
)
dictClass
.
newInstance
();
String
str
=
parseMutiKey
(
dictMap
,
key
,
pojo2
)
+
separator
;
try
{
Class
clazz
=
pojo1
.
getClass
();
Field
[]
fields
=
pojo1
.
getClass
().
getDeclaredFields
();
int
i
=
1
;
for
(
Field
field
:
fields
)
{
if
(
"serialVersionUID"
.
equals
(
field
.
getName
()))
{
continue
;
}
String
prefix
=
"get"
;
int
prefixLength
=
3
;
if
(
field
.
getType
().
getName
().
equals
(
"java.lang.Boolean"
))
{
prefix
=
"is"
;
prefixLength
=
2
;
}
Method
getMethod
=
null
;
try
{
getMethod
=
clazz
.
getDeclaredMethod
(
prefix
+
StrUtil
.
upperFirst
(
field
.
getName
()));
}
catch
(
java
.
lang
.
NoSuchMethodException
e
)
{
System
.
err
.
println
(
"this className:"
+
clazz
.
getName
()
+
" is not methodName: "
+
e
.
getMessage
());
continue
;
}
Object
o1
=
getMethod
.
invoke
(
pojo1
);
Object
o2
=
pojo2
.
get
(
StrUtil
.
lowerFirst
(
getMethod
.
getName
().
substring
(
prefixLength
)));
if
(
o1
==
null
||
o2
==
null
)
{
continue
;
}
if
(
o1
instanceof
Date
)
{
o1
=
DateUtil
.
formatDate
((
Date
)
o1
);
}
else
if
(
o1
instanceof
Integer
)
{
o2
=
Integer
.
parseInt
(
o2
.
toString
());
}
if
(!
o1
.
toString
().
equals
(
o2
.
toString
()))
{
if
(
i
!=
1
)
{
str
+=
separator
;
}
String
fieldName
=
dictMap
.
get
(
field
.
getName
());
String
fieldWarpperMethodName
=
dictMap
.
getFieldWarpperMethodName
(
field
.
getName
());
if
(
fieldWarpperMethodName
!=
null
)
{
Object
o1Warpper
=
DictFieldWarpperFactory
.
createFieldWarpper
(
o1
,
fieldWarpperMethodName
);
Object
o2Warpper
=
DictFieldWarpperFactory
.
createFieldWarpper
(
o2
,
fieldWarpperMethodName
);
str
+=
"字段名称:"
+
fieldName
+
",旧值:"
+
o1Warpper
+
",新值:"
+
o2Warpper
;
}
else
{
str
+=
"字段名称:"
+
fieldName
+
",旧值:"
+
o1
+
",新值:"
+
o2
;
}
i
++;
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
str
;
}
/**
* 解析多个key(逗号隔开的)
*
* @author stylefeng
* @Date 2017/5/16 22:19
*/
public
static
String
parseMutiKey
(
AbstractDictMap
dictMap
,
String
key
,
Map
<
String
,
String
>
requests
)
{
StringBuilder
sb
=
new
StringBuilder
();
if
(
key
.
contains
(
","
))
{
String
[]
keys
=
key
.
split
(
","
);
for
(
String
item
:
keys
)
{
String
fieldWarpperMethodName
=
dictMap
.
getFieldWarpperMethodName
(
item
);
String
value
=
requests
.
get
(
item
);
if
(
fieldWarpperMethodName
!=
null
)
{
Object
valueWarpper
=
DictFieldWarpperFactory
.
createFieldWarpper
(
value
,
fieldWarpperMethodName
);
sb
.
append
(
dictMap
.
get
(
item
)
+
"="
+
valueWarpper
+
","
);
}
else
{
sb
.
append
(
dictMap
.
get
(
item
)
+
"="
+
value
+
","
);
}
}
return
StrUtil
.
removeSuffix
(
sb
.
toString
(),
","
);
}
else
{
String
fieldWarpperMethodName
=
dictMap
.
getFieldWarpperMethodName
(
key
);
String
value
=
requests
.
get
(
key
);
if
(
fieldWarpperMethodName
!=
null
)
{
Object
valueWarpper
=
DictFieldWarpperFactory
.
createFieldWarpper
(
value
,
fieldWarpperMethodName
);
sb
.
append
(
dictMap
.
get
(
key
)
+
"="
+
valueWarpper
);
}
else
{
sb
.
append
(
dictMap
.
get
(
key
)
+
"="
+
value
);
}
return
sb
.
toString
();
}
}
}
\ No newline at end of file
src/main/java/cn/stylefeng/guns/core/util/JwtTokenUtil.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
util
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.guns.core.common.constant.JwtConstants
;
import
io.jsonwebtoken.*
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* <p>jwt token工具类</p>
* <pre>
* jwt的claim里一般包含以下几种数据:
* 1. iss -- token的发行者
* 2. sub -- 该JWT所面向的用户
* 3. aud -- 接收该JWT的一方
* 4. exp -- token的失效时间
* 5. nbf -- 在此时间段之前,不会被处理
* 6. iat -- jwt发布时间
* 7. jti -- jwt唯一标识,防止重复使用
* </pre>
*
* @author fengshuonan
* @Date 2017/8/25 10:59
*/
public
class
JwtTokenUtil
{
/**
* 获取用户名从token中
*/
public
static
String
getUsernameFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getSubject
();
}
/**
* 获取jwt发布时间
*/
public
static
Date
getIssuedAtDateFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getIssuedAt
();
}
/**
* 获取jwt失效时间
*/
public
static
Date
getExpirationDateFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getExpiration
();
}
/**
* 获取jwt接收者
*/
public
static
String
getAudienceFromToken
(
String
token
)
{
return
getClaimFromToken
(
token
).
getAudience
();
}
/**
* 获取私有的jwt claim
*/
public
static
String
getPrivateClaimFromToken
(
String
token
,
String
key
)
{
return
getClaimFromToken
(
token
).
get
(
key
).
toString
();
}
/**
* 获取jwt的payload部分
*/
public
static
Claims
getClaimFromToken
(
String
token
)
{
return
Jwts
.
parser
()
.
setSigningKey
(
JwtConstants
.
SECRET
)
.
parseClaimsJws
(
token
)
.
getBody
();
}
/**
* 解析token是否正确,不正确会报异常<br>
*/
public
static
void
parseToken
(
String
token
)
throws
JwtException
{
Jwts
.
parser
().
setSigningKey
(
JwtConstants
.
SECRET
).
parseClaimsJws
(
token
).
getBody
();
}
/**
* <pre>
* 验证token是否失效
* true:过期 false:没过期
* </pre>
*/
public
static
Boolean
isTokenExpired
(
String
token
)
{
try
{
final
Date
expiration
=
getExpirationDateFromToken
(
token
);
return
expiration
.
before
(
new
Date
());
}
catch
(
ExpiredJwtException
expiredJwtException
)
{
return
true
;
}
}
/**
* 生成token(通过用户名和签名时候用的随机数)
*/
public
static
String
generateToken
(
String
userId
)
{
Map
<
String
,
Object
>
claims
=
new
HashMap
<>();
return
doGenerateToken
(
claims
,
userId
);
}
/**
* 生成token
*/
private
static
String
doGenerateToken
(
Map
<
String
,
Object
>
claims
,
String
subject
)
{
final
Date
createdDate
=
new
Date
();
final
Date
expirationDate
=
new
Date
(
createdDate
.
getTime
()
+
JwtConstants
.
EXPIRATION
*
1000
);
return
Jwts
.
builder
()
.
setClaims
(
claims
)
.
setSubject
(
subject
)
.
setIssuedAt
(
createdDate
)
.
setExpiration
(
expirationDate
)
.
signWith
(
SignatureAlgorithm
.
HS512
,
JwtConstants
.
SECRET
)
.
compact
();
}
/**
* 获取混淆MD5签名用的随机字符串
*/
public
static
String
getRandomKey
()
{
return
ToolUtil
.
getRandomString
(
6
);
}
}
\ No newline at end of file
src/main/java/cn/stylefeng/guns/core/util/KaptchaUtil.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
core
.
util
;
import
cn.stylefeng.roses.core.util.SpringContextHolder
;
import
cn.stylefeng.guns.config.properties.GunsProperties
;
/**
* 验证码工具类
*/
public
class
KaptchaUtil
{
/**
* 获取验证码开关
*/
public
static
Boolean
getKaptchaOnOff
()
{
return
SpringContextHolder
.
getBean
(
GunsProperties
.
class
).
getKaptchaOpen
();
}
}
\ No newline at end of file
src/main/java/cn/stylefeng/guns/modular/system/controller/BlackboardController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.stylefeng.roses.core.base.controller.BaseController
;
import
cn.stylefeng.guns.modular.system.service.INoticeService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
java.util.List
;
import
java.util.Map
;
/**
* 总览信息
*
* @author fengshuonan
* @Date 2017年3月4日23:05:54
*/
@Controller
@RequestMapping
(
"/blackboard"
)
public
class
BlackboardController
extends
BaseController
{
@Autowired
private
INoticeService
noticeService
;
/**
* 跳转到黑板
*/
@RequestMapping
(
""
)
public
String
blackboard
(
Model
model
)
{
List
<
Map
<
String
,
Object
>>
notices
=
noticeService
.
list
(
null
);
model
.
addAttribute
(
"noticeList"
,
notices
);
return
"/blackboard.html"
;
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/KaptchaController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.stylefeng.roses.core.util.FileUtil
;
import
com.google.code.kaptcha.Constants
;
import
com.google.code.kaptcha.Producer
;
import
cn.stylefeng.guns.config.properties.GunsProperties
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
javax.imageio.ImageIO
;
import
javax.servlet.ServletOutputStream
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpSession
;
import
java.awt.image.BufferedImage
;
import
java.io.IOException
;
/**
* 验证码生成
*
* @author fengshuonan
* @date 2017-05-05 23:10
*/
@Controller
@RequestMapping
(
"/kaptcha"
)
public
class
KaptchaController
{
@Autowired
private
GunsProperties
gunsProperties
;
@Autowired
private
Producer
producer
;
/**
* 生成验证码
*/
@RequestMapping
(
""
)
public
void
index
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
HttpSession
session
=
request
.
getSession
();
response
.
setDateHeader
(
"Expires"
,
0
);
// Set standard HTTP/1.1 no-cache headers.
response
.
setHeader
(
"Cache-Control"
,
"no-store, no-cache, must-revalidate"
);
// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
response
.
addHeader
(
"Cache-Control"
,
"post-check=0, pre-check=0"
);
// Set standard HTTP/1.0 no-cache header.
response
.
setHeader
(
"Pragma"
,
"no-cache"
);
// return a jpeg
response
.
setContentType
(
"image/jpeg"
);
// create the text for the image
String
capText
=
producer
.
createText
();
// store the text in the session
session
.
setAttribute
(
Constants
.
KAPTCHA_SESSION_KEY
,
capText
);
// create the image with the text
BufferedImage
bi
=
producer
.
createImage
(
capText
);
ServletOutputStream
out
=
null
;
try
{
out
=
response
.
getOutputStream
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
// write the data out
try
{
ImageIO
.
write
(
bi
,
"jpg"
,
out
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
try
{
try
{
out
.
flush
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
finally
{
try
{
out
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
/**
* 返回图片
*
* @author stylefeng
* @Date 2017/5/24 23:00
*/
@RequestMapping
(
"/{pictureId}"
)
public
void
renderPicture
(
@PathVariable
(
"pictureId"
)
String
pictureId
,
HttpServletResponse
response
)
{
String
path
=
gunsProperties
.
getFileUploadPath
()
+
pictureId
;
try
{
byte
[]
bytes
=
FileUtil
.
toByteArray
(
path
);
response
.
getOutputStream
().
write
(
bytes
);
}
catch
(
Exception
e
)
{
//如果找不到图片就返回一个默认图片
try
{
response
.
sendRedirect
(
"/static/img/girl.gif"
);
}
catch
(
IOException
e1
)
{
e1
.
printStackTrace
();
}
}
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/LoginController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.stylefeng.guns.core.log.LogManager
;
import
cn.stylefeng.guns.core.log.factory.LogTaskFactory
;
import
cn.stylefeng.guns.core.node.MenuNode
;
import
cn.stylefeng.guns.core.shiro.ShiroKit
;
import
cn.stylefeng.guns.core.shiro.ShiroUser
;
import
cn.stylefeng.guns.core.util.ApiMenuFilter
;
import
cn.stylefeng.guns.core.util.KaptchaUtil
;
import
cn.stylefeng.roses.core.base.controller.BaseController
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
com.google.code.kaptcha.Constants
;
import
cn.stylefeng.guns.core.common.exception.InvalidKaptchaException
;
import
cn.stylefeng.guns.modular.system.model.User
;
import
cn.stylefeng.guns.modular.system.service.IMenuService
;
import
cn.stylefeng.guns.modular.system.service.IUserService
;
import
org.apache.shiro.authc.UsernamePasswordToken
;
import
org.apache.shiro.subject.Subject
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
java.util.List
;
import
static
cn
.
stylefeng
.
roses
.
core
.
util
.
HttpContext
.
getIp
;
/**
* 登录控制器
*
* @author fengshuonan
* @Date 2017年1月10日 下午8:25:24
*/
@Controller
public
class
LoginController
extends
BaseController
{
@Autowired
private
IMenuService
menuService
;
@Autowired
private
IUserService
userService
;
/**
* 跳转到主页
*/
@RequestMapping
(
value
=
"/"
,
method
=
RequestMethod
.
GET
)
public
String
index
(
Model
model
)
{
//获取菜单列表
List
<
Integer
>
roleList
=
ShiroKit
.
getUser
().
getRoleList
();
if
(
roleList
==
null
||
roleList
.
size
()
==
0
)
{
ShiroKit
.
getSubject
().
logout
();
model
.
addAttribute
(
"tips"
,
"该用户没有角色,无法登陆"
);
return
"/login.html"
;
}
List
<
MenuNode
>
menus
=
menuService
.
getMenusByRoleIds
(
roleList
);
List
<
MenuNode
>
titles
=
MenuNode
.
buildTitle
(
menus
);
titles
=
ApiMenuFilter
.
build
(
titles
);
model
.
addAttribute
(
"titles"
,
titles
);
//获取用户头像
Integer
id
=
ShiroKit
.
getUser
().
getId
();
User
user
=
userService
.
selectById
(
id
);
String
avatar
=
user
.
getAvatar
();
model
.
addAttribute
(
"avatar"
,
avatar
);
return
"/index.html"
;
}
/**
* 跳转到登录页面
*/
@RequestMapping
(
value
=
"/login"
,
method
=
RequestMethod
.
GET
)
public
String
login
()
{
if
(
ShiroKit
.
isAuthenticated
()
||
ShiroKit
.
getUser
()
!=
null
)
{
return
REDIRECT
+
"/"
;
}
else
{
return
"/login.html"
;
}
}
/**
* 点击登录执行的动作
*/
@RequestMapping
(
value
=
"/login"
,
method
=
RequestMethod
.
POST
)
public
String
loginVali
()
{
String
username
=
super
.
getPara
(
"username"
).
trim
();
String
password
=
super
.
getPara
(
"password"
).
trim
();
String
remember
=
super
.
getPara
(
"remember"
);
//验证验证码是否正确
if
(
KaptchaUtil
.
getKaptchaOnOff
())
{
String
kaptcha
=
super
.
getPara
(
"kaptcha"
).
trim
();
String
code
=
(
String
)
super
.
getSession
().
getAttribute
(
Constants
.
KAPTCHA_SESSION_KEY
);
if
(
ToolUtil
.
isEmpty
(
kaptcha
)
||
!
kaptcha
.
equalsIgnoreCase
(
code
))
{
throw
new
InvalidKaptchaException
();
}
}
Subject
currentUser
=
ShiroKit
.
getSubject
();
UsernamePasswordToken
token
=
new
UsernamePasswordToken
(
username
,
password
.
toCharArray
());
if
(
"on"
.
equals
(
remember
))
{
token
.
setRememberMe
(
true
);
}
else
{
token
.
setRememberMe
(
false
);
}
currentUser
.
login
(
token
);
ShiroUser
shiroUser
=
ShiroKit
.
getUser
();
super
.
getSession
().
setAttribute
(
"shiroUser"
,
shiroUser
);
super
.
getSession
().
setAttribute
(
"username"
,
shiroUser
.
getAccount
());
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
loginLog
(
shiroUser
.
getId
(),
getIp
()));
ShiroKit
.
getSession
().
setAttribute
(
"sessionFlag"
,
true
);
return
REDIRECT
+
"/"
;
}
/**
* 退出登录
*/
@RequestMapping
(
value
=
"/logout"
,
method
=
RequestMethod
.
GET
)
public
String
logOut
()
{
LogManager
.
me
().
executeLog
(
LogTaskFactory
.
exitLog
(
ShiroKit
.
getUser
().
getId
(),
getIp
()));
ShiroKit
.
getSubject
().
logout
();
deleteAllCookie
();
return
REDIRECT
+
"/login"
;
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/LoginLogController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.stylefeng.guns.core.common.annotion.BussinessLog
;
import
cn.stylefeng.guns.core.common.annotion.Permission
;
import
cn.stylefeng.guns.core.page.PageInfoBT
;
import
cn.stylefeng.roses.core.base.controller.BaseController
;
import
com.baomidou.mybatisplus.mapper.SqlRunner
;
import
com.baomidou.mybatisplus.plugins.Page
;
import
cn.stylefeng.guns.core.common.constant.Const
;
import
cn.stylefeng.guns.core.common.constant.factory.PageFactory
;
import
cn.stylefeng.guns.modular.system.model.LoginLog
;
import
cn.stylefeng.guns.modular.system.service.ILoginLogService
;
import
cn.stylefeng.guns.modular.system.warpper.LogWarpper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
java.util.List
;
import
java.util.Map
;
/**
* 日志管理的控制器
*
* @author fengshuonan
* @Date 2017年4月5日 19:45:36
*/
@Controller
@RequestMapping
(
"/loginLog"
)
public
class
LoginLogController
extends
BaseController
{
private
static
String
PREFIX
=
"/system/log/"
;
@Autowired
private
ILoginLogService
loginLogService
;
/**
* 跳转到日志管理的首页
*/
@RequestMapping
(
""
)
public
String
index
()
{
return
PREFIX
+
"login_log.html"
;
}
/**
* 查询登录日志列表
*/
@RequestMapping
(
"/list"
)
@Permission
(
Const
.
ADMIN_NAME
)
@ResponseBody
public
Object
list
(
@RequestParam
(
required
=
false
)
String
beginTime
,
@RequestParam
(
required
=
false
)
String
endTime
,
@RequestParam
(
required
=
false
)
String
logName
)
{
Page
<
LoginLog
>
page
=
new
PageFactory
<
LoginLog
>().
defaultPage
();
List
<
Map
<
String
,
Object
>>
result
=
loginLogService
.
getLoginLogs
(
page
,
beginTime
,
endTime
,
logName
,
page
.
getOrderByField
(),
page
.
isAsc
());
page
.
setRecords
(
new
LogWarpper
(
result
).
wrap
());
return
new
PageInfoBT
<>(
page
);
}
/**
* 清空日志
*/
@BussinessLog
(
"清空登录日志"
)
@RequestMapping
(
"/delLoginLog"
)
@Permission
(
Const
.
ADMIN_NAME
)
@ResponseBody
public
Object
delLog
()
{
SqlRunner
.
db
().
delete
(
"delete from sys_login_log"
);
return
SUCCESS_TIP
;
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/MenuController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.stylefeng.guns.core.common.annotion.BussinessLog
;
import
cn.stylefeng.guns.core.common.annotion.Permission
;
import
cn.stylefeng.guns.core.log.LogObjectHolder
;
import
cn.stylefeng.guns.core.node.ZTreeNode
;
import
cn.stylefeng.roses.core.base.controller.BaseController
;
import
cn.stylefeng.roses.core.reqres.response.ResponseData
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.roses.kernel.model.exception.ServiceException
;
import
com.baomidou.mybatisplus.mapper.EntityWrapper
;
import
cn.stylefeng.guns.core.common.constant.Const
;
import
cn.stylefeng.guns.core.common.constant.dictmap.MenuDict
;
import
cn.stylefeng.guns.core.common.constant.factory.ConstantFactory
;
import
cn.stylefeng.guns.core.common.constant.state.MenuStatus
;
import
cn.stylefeng.guns.core.common.exception.BizExceptionEnum
;
import
cn.stylefeng.guns.modular.system.model.Menu
;
import
cn.stylefeng.guns.modular.system.service.IMenuService
;
import
cn.stylefeng.guns.modular.system.warpper.MenuWarpper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
javax.validation.Valid
;
import
java.util.List
;
import
java.util.Map
;
/**
* 菜单控制器
*
* @author fengshuonan
* @Date 2017年2月12日21:59:14
*/
@Controller
@RequestMapping
(
"/menu"
)
public
class
MenuController
extends
BaseController
{
private
static
String
PREFIX
=
"/system/menu/"
;
@Autowired
private
IMenuService
menuService
;
/**
* 跳转到菜单列表列表页面
*/
@RequestMapping
(
""
)
public
String
index
()
{
return
PREFIX
+
"menu.html"
;
}
/**
* 跳转到菜单列表列表页面
*/
@RequestMapping
(
value
=
"/menu_add"
)
public
String
menuAdd
()
{
return
PREFIX
+
"menu_add.html"
;
}
/**
* 跳转到菜单详情列表页面
*/
@Permission
(
Const
.
ADMIN_NAME
)
@RequestMapping
(
value
=
"/menu_edit/{menuId}"
)
public
String
menuEdit
(
@PathVariable
Long
menuId
,
Model
model
)
{
if
(
ToolUtil
.
isEmpty
(
menuId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
Menu
menu
=
this
.
menuService
.
selectById
(
menuId
);
//获取父级菜单的id
Menu
temp
=
new
Menu
();
temp
.
setCode
(
menu
.
getPcode
());
Menu
pMenu
=
this
.
menuService
.
selectOne
(
new
EntityWrapper
<>(
temp
));
//如果父级是顶级菜单
if
(
pMenu
==
null
)
{
menu
.
setPcode
(
"0"
);
}
else
{
//设置父级菜单的code为父级菜单的id
menu
.
setPcode
(
String
.
valueOf
(
pMenu
.
getId
()));
}
Map
<
String
,
Object
>
menuMap
=
BeanUtil
.
beanToMap
(
menu
);
menuMap
.
put
(
"pcodeName"
,
ConstantFactory
.
me
().
getMenuNameByCode
(
temp
.
getCode
()));
model
.
addAttribute
(
"menu"
,
menuMap
);
LogObjectHolder
.
me
().
set
(
menu
);
return
PREFIX
+
"menu_edit.html"
;
}
/**
* 修该菜单
*/
@Permission
(
Const
.
ADMIN_NAME
)
@RequestMapping
(
value
=
"/edit"
)
@BussinessLog
(
value
=
"修改菜单"
,
key
=
"name"
,
dict
=
MenuDict
.
class
)
@ResponseBody
public
ResponseData
edit
(
@Valid
Menu
menu
,
BindingResult
result
)
{
if
(
result
.
hasErrors
())
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
//设置父级菜单编号
menuSetPcode
(
menu
);
this
.
menuService
.
updateById
(
menu
);
return
SUCCESS_TIP
;
}
/**
* 获取菜单列表
*/
@Permission
(
Const
.
ADMIN_NAME
)
@RequestMapping
(
value
=
"/list"
)
@ResponseBody
public
Object
list
(
@RequestParam
(
required
=
false
)
String
menuName
,
@RequestParam
(
required
=
false
)
String
level
)
{
List
<
Map
<
String
,
Object
>>
menus
=
this
.
menuService
.
selectMenus
(
menuName
,
level
);
return
super
.
warpObject
(
new
MenuWarpper
(
menus
));
}
/**
* 新增菜单
*/
@Permission
(
Const
.
ADMIN_NAME
)
@RequestMapping
(
value
=
"/add"
)
@BussinessLog
(
value
=
"菜单新增"
,
key
=
"name"
,
dict
=
MenuDict
.
class
)
@ResponseBody
public
ResponseData
add
(
@Valid
Menu
menu
,
BindingResult
result
)
{
if
(
result
.
hasErrors
())
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
//判断是否存在该编号
String
existedMenuName
=
ConstantFactory
.
me
().
getMenuNameByCode
(
menu
.
getCode
());
if
(
ToolUtil
.
isNotEmpty
(
existedMenuName
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
EXISTED_THE_MENU
);
}
//设置父级菜单编号
menuSetPcode
(
menu
);
menu
.
setStatus
(
MenuStatus
.
ENABLE
.
getCode
());
this
.
menuService
.
insert
(
menu
);
return
SUCCESS_TIP
;
}
/**
* 删除菜单
*/
@Permission
(
Const
.
ADMIN_NAME
)
@RequestMapping
(
value
=
"/remove"
)
@BussinessLog
(
value
=
"删除菜单"
,
key
=
"menuId"
,
dict
=
MenuDict
.
class
)
@ResponseBody
public
ResponseData
remove
(
@RequestParam
Long
menuId
)
{
if
(
ToolUtil
.
isEmpty
(
menuId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
//缓存菜单的名称
LogObjectHolder
.
me
().
set
(
ConstantFactory
.
me
().
getMenuName
(
menuId
));
this
.
menuService
.
delMenuContainSubMenus
(
menuId
);
return
SUCCESS_TIP
;
}
/**
* 查看菜单
*/
@RequestMapping
(
value
=
"/view/{menuId}"
)
@ResponseBody
public
ResponseData
view
(
@PathVariable
Long
menuId
)
{
if
(
ToolUtil
.
isEmpty
(
menuId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
this
.
menuService
.
selectById
(
menuId
);
return
SUCCESS_TIP
;
}
/**
* 获取菜单列表(首页用)
*/
@RequestMapping
(
value
=
"/menuTreeList"
)
@ResponseBody
public
List
<
ZTreeNode
>
menuTreeList
()
{
return
this
.
menuService
.
menuTreeList
();
}
/**
* 获取菜单列表(选择父级菜单用)
*/
@RequestMapping
(
value
=
"/selectMenuTreeList"
)
@ResponseBody
public
List
<
ZTreeNode
>
selectMenuTreeList
()
{
List
<
ZTreeNode
>
roleTreeList
=
this
.
menuService
.
menuTreeList
();
roleTreeList
.
add
(
ZTreeNode
.
createParent
());
return
roleTreeList
;
}
/**
* 获取角色列表
*/
@RequestMapping
(
value
=
"/menuTreeListByRoleId/{roleId}"
)
@ResponseBody
public
List
<
ZTreeNode
>
menuTreeListByRoleId
(
@PathVariable
Integer
roleId
)
{
List
<
Long
>
menuIds
=
this
.
menuService
.
getMenuIdsByRoleId
(
roleId
);
if
(
ToolUtil
.
isEmpty
(
menuIds
))
{
return
this
.
menuService
.
menuTreeList
();
}
else
{
return
this
.
menuService
.
menuTreeListByMenuIds
(
menuIds
);
}
}
/**
* 根据请求的父级菜单编号设置pcode和层级
*/
private
void
menuSetPcode
(
@Valid
Menu
menu
)
{
if
(
ToolUtil
.
isEmpty
(
menu
.
getPcode
())
||
menu
.
getPcode
().
equals
(
"0"
))
{
menu
.
setPcode
(
"0"
);
menu
.
setPcodes
(
"[0],"
);
menu
.
setLevels
(
1
);
}
else
{
long
code
=
Long
.
parseLong
(
menu
.
getPcode
());
Menu
pMenu
=
menuService
.
selectById
(
code
);
Integer
pLevels
=
pMenu
.
getLevels
();
menu
.
setPcode
(
pMenu
.
getCode
());
//如果编号和父编号一致会导致无限递归
if
(
menu
.
getCode
().
equals
(
menu
.
getPcode
()))
{
throw
new
ServiceException
(
BizExceptionEnum
.
MENU_PCODE_COINCIDENCE
);
}
menu
.
setLevels
(
pLevels
+
1
);
menu
.
setPcodes
(
pMenu
.
getPcodes
()
+
"["
+
pMenu
.
getCode
()
+
"],"
);
}
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/NoticeController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.stylefeng.guns.core.common.annotion.BussinessLog
;
import
cn.stylefeng.guns.core.log.LogObjectHolder
;
import
cn.stylefeng.guns.core.shiro.ShiroKit
;
import
cn.stylefeng.roses.core.base.controller.BaseController
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.roses.kernel.model.exception.ServiceException
;
import
cn.stylefeng.guns.core.common.constant.dictmap.NoticeMap
;
import
cn.stylefeng.guns.core.common.constant.factory.ConstantFactory
;
import
cn.stylefeng.guns.core.common.exception.BizExceptionEnum
;
import
cn.stylefeng.guns.modular.system.model.Notice
;
import
cn.stylefeng.guns.modular.system.service.INoticeService
;
import
cn.stylefeng.guns.modular.system.warpper.NoticeWrapper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
/**
* 通知控制器
*
* @author fengshuonan
* @Date 2017-05-09 23:02:21
*/
@Controller
@RequestMapping
(
"/notice"
)
public
class
NoticeController
extends
BaseController
{
private
String
PREFIX
=
"/system/notice/"
;
@Autowired
private
INoticeService
noticeService
;
/**
* 跳转到通知列表首页
*/
@RequestMapping
(
""
)
public
String
index
()
{
return
PREFIX
+
"notice.html"
;
}
/**
* 跳转到添加通知
*/
@RequestMapping
(
"/notice_add"
)
public
String
noticeAdd
()
{
return
PREFIX
+
"notice_add.html"
;
}
/**
* 跳转到修改通知
*/
@RequestMapping
(
"/notice_update/{noticeId}"
)
public
String
noticeUpdate
(
@PathVariable
Integer
noticeId
,
Model
model
)
{
Notice
notice
=
this
.
noticeService
.
selectById
(
noticeId
);
model
.
addAttribute
(
"notice"
,
notice
);
LogObjectHolder
.
me
().
set
(
notice
);
return
PREFIX
+
"notice_edit.html"
;
}
/**
* 跳转到首页通知
*/
@RequestMapping
(
"/hello"
)
public
String
hello
()
{
List
<
Map
<
String
,
Object
>>
notices
=
noticeService
.
list
(
null
);
super
.
setAttr
(
"noticeList"
,
notices
);
return
"/blackboard.html"
;
}
/**
* 获取通知列表
*/
@RequestMapping
(
value
=
"/list"
)
@ResponseBody
public
Object
list
(
String
condition
)
{
List
<
Map
<
String
,
Object
>>
list
=
this
.
noticeService
.
list
(
condition
);
return
super
.
warpObject
(
new
NoticeWrapper
(
list
));
}
/**
* 新增通知
*/
@RequestMapping
(
value
=
"/add"
)
@ResponseBody
@BussinessLog
(
value
=
"新增通知"
,
key
=
"title"
,
dict
=
NoticeMap
.
class
)
public
Object
add
(
Notice
notice
)
{
if
(
ToolUtil
.
isOneEmpty
(
notice
,
notice
.
getTitle
(),
notice
.
getContent
()))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
notice
.
setCreater
(
ShiroKit
.
getUser
().
getId
());
notice
.
setCreatetime
(
new
Date
());
notice
.
insert
();
return
SUCCESS_TIP
;
}
/**
* 删除通知
*/
@RequestMapping
(
value
=
"/delete"
)
@ResponseBody
@BussinessLog
(
value
=
"删除通知"
,
key
=
"noticeId"
,
dict
=
NoticeMap
.
class
)
public
Object
delete
(
@RequestParam
Integer
noticeId
)
{
//缓存通知名称
LogObjectHolder
.
me
().
set
(
ConstantFactory
.
me
().
getNoticeTitle
(
noticeId
));
this
.
noticeService
.
deleteById
(
noticeId
);
return
SUCCESS_TIP
;
}
/**
* 修改通知
*/
@RequestMapping
(
value
=
"/update"
)
@ResponseBody
@BussinessLog
(
value
=
"修改通知"
,
key
=
"title"
,
dict
=
NoticeMap
.
class
)
public
Object
update
(
Notice
notice
)
{
if
(
ToolUtil
.
isOneEmpty
(
notice
,
notice
.
getId
(),
notice
.
getTitle
(),
notice
.
getContent
()))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
Notice
old
=
this
.
noticeService
.
selectById
(
notice
.
getId
());
old
.
setTitle
(
notice
.
getTitle
());
old
.
setContent
(
notice
.
getContent
());
old
.
updateById
();
return
SUCCESS_TIP
;
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/RoleController.java
0 → 100644
View file @
d552b1db
/**
* Copyright 2018-2020 stylefeng & fengshuonan (https://gitee.com/stylefeng)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
controller
;
import
cn.stylefeng.guns.core.cache.CacheKit
;
import
cn.stylefeng.guns.core.common.annotion.BussinessLog
;
import
cn.stylefeng.guns.core.common.annotion.Permission
;
import
cn.stylefeng.guns.core.common.constant.cache.Cache
;
import
cn.stylefeng.guns.core.log.LogObjectHolder
;
import
cn.stylefeng.guns.core.node.ZTreeNode
;
import
cn.stylefeng.roses.core.base.controller.BaseController
;
import
cn.stylefeng.roses.core.reqres.response.ResponseData
;
import
cn.stylefeng.roses.core.util.ToolUtil
;
import
cn.stylefeng.roses.kernel.model.exception.ServiceException
;
import
cn.stylefeng.guns.core.common.constant.Const
;
import
cn.stylefeng.guns.core.common.constant.dictmap.RoleDict
;
import
cn.stylefeng.guns.core.common.constant.factory.ConstantFactory
;
import
cn.stylefeng.guns.core.common.exception.BizExceptionEnum
;
import
cn.stylefeng.guns.modular.system.model.Role
;
import
cn.stylefeng.guns.modular.system.model.User
;
import
cn.stylefeng.guns.modular.system.service.IRoleService
;
import
cn.stylefeng.guns.modular.system.service.IUserService
;
import
cn.stylefeng.guns.modular.system.warpper.RoleWarpper
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
javax.validation.Valid
;
import
java.util.List
;
import
java.util.Map
;
/**
* 角色控制器
*
* @author fengshuonan
* @Date 2017年2月12日21:59:14
*/
@Controller
@RequestMapping
(
"/role"
)
public
class
RoleController
extends
BaseController
{
private
static
String
PREFIX
=
"/system/role"
;
@Autowired
private
IUserService
userService
;
@Autowired
private
IRoleService
roleService
;
/**
* 跳转到角色列表页面
*/
@RequestMapping
(
""
)
public
String
index
()
{
return
PREFIX
+
"/role.html"
;
}
/**
* 跳转到添加角色
*/
@RequestMapping
(
value
=
"/role_add"
)
public
String
roleAdd
()
{
return
PREFIX
+
"/role_add.html"
;
}
/**
* 跳转到修改角色
*/
@Permission
@RequestMapping
(
value
=
"/role_edit/{roleId}"
)
public
String
roleEdit
(
@PathVariable
Integer
roleId
,
Model
model
)
{
if
(
ToolUtil
.
isEmpty
(
roleId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
Role
role
=
this
.
roleService
.
selectById
(
roleId
);
model
.
addAttribute
(
role
);
model
.
addAttribute
(
"pName"
,
ConstantFactory
.
me
().
getSingleRoleName
(
role
.
getPid
()));
model
.
addAttribute
(
"deptName"
,
ConstantFactory
.
me
().
getDeptName
(
role
.
getDeptid
()));
LogObjectHolder
.
me
().
set
(
role
);
return
PREFIX
+
"/role_edit.html"
;
}
/**
* 跳转到角色分配
*/
@Permission
@RequestMapping
(
value
=
"/role_assign/{roleId}"
)
public
String
roleAssign
(
@PathVariable
(
"roleId"
)
Integer
roleId
,
Model
model
)
{
if
(
ToolUtil
.
isEmpty
(
roleId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
model
.
addAttribute
(
"roleId"
,
roleId
);
model
.
addAttribute
(
"roleName"
,
ConstantFactory
.
me
().
getSingleRoleName
(
roleId
));
return
PREFIX
+
"/role_assign.html"
;
}
/**
* 获取角色列表
*/
@Permission
@RequestMapping
(
value
=
"/list"
)
@ResponseBody
public
Object
list
(
@RequestParam
(
required
=
false
)
String
roleName
)
{
List
<
Map
<
String
,
Object
>>
roles
=
this
.
roleService
.
selectRoles
(
super
.
getPara
(
"roleName"
));
return
super
.
warpObject
(
new
RoleWarpper
(
roles
));
}
/**
* 角色新增
*/
@RequestMapping
(
value
=
"/add"
)
@BussinessLog
(
value
=
"添加角色"
,
key
=
"name"
,
dict
=
RoleDict
.
class
)
@Permission
(
Const
.
ADMIN_NAME
)
@ResponseBody
public
ResponseData
add
(
@Valid
Role
role
,
BindingResult
result
)
{
if
(
result
.
hasErrors
())
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
role
.
setId
(
null
);
this
.
roleService
.
insert
(
role
);
return
SUCCESS_TIP
;
}
/**
* 角色修改
*/
@RequestMapping
(
value
=
"/edit"
)
@BussinessLog
(
value
=
"修改角色"
,
key
=
"name"
,
dict
=
RoleDict
.
class
)
@Permission
(
Const
.
ADMIN_NAME
)
@ResponseBody
public
ResponseData
edit
(
@Valid
Role
role
,
BindingResult
result
)
{
if
(
result
.
hasErrors
())
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
this
.
roleService
.
updateById
(
role
);
//删除缓存
CacheKit
.
removeAll
(
Cache
.
CONSTANT
);
return
SUCCESS_TIP
;
}
/**
* 删除角色
*/
@RequestMapping
(
value
=
"/remove"
)
@BussinessLog
(
value
=
"删除角色"
,
key
=
"roleId"
,
dict
=
RoleDict
.
class
)
@Permission
(
Const
.
ADMIN_NAME
)
@ResponseBody
public
ResponseData
remove
(
@RequestParam
Integer
roleId
)
{
if
(
ToolUtil
.
isEmpty
(
roleId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
//不能删除超级管理员角色
if
(
roleId
.
equals
(
Const
.
ADMIN_ROLE_ID
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
CANT_DELETE_ADMIN
);
}
//缓存被删除的角色名称
LogObjectHolder
.
me
().
set
(
ConstantFactory
.
me
().
getSingleRoleName
(
roleId
));
this
.
roleService
.
delRoleById
(
roleId
);
//删除缓存
CacheKit
.
removeAll
(
Cache
.
CONSTANT
);
return
SUCCESS_TIP
;
}
/**
* 查看角色
*/
@RequestMapping
(
value
=
"/view/{roleId}"
)
@ResponseBody
public
ResponseData
view
(
@PathVariable
Integer
roleId
)
{
if
(
ToolUtil
.
isEmpty
(
roleId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
this
.
roleService
.
selectById
(
roleId
);
return
SUCCESS_TIP
;
}
/**
* 配置权限
*/
@RequestMapping
(
"/setAuthority"
)
@BussinessLog
(
value
=
"配置权限"
,
key
=
"roleId,ids"
,
dict
=
RoleDict
.
class
)
@Permission
(
Const
.
ADMIN_NAME
)
@ResponseBody
public
ResponseData
setAuthority
(
@RequestParam
(
"roleId"
)
Integer
roleId
,
@RequestParam
(
"ids"
)
String
ids
)
{
if
(
ToolUtil
.
isOneEmpty
(
roleId
))
{
throw
new
ServiceException
(
BizExceptionEnum
.
REQUEST_NULL
);
}
this
.
roleService
.
setAuthority
(
roleId
,
ids
);
return
SUCCESS_TIP
;
}
/**
* 获取角色列表
*/
@RequestMapping
(
value
=
"/roleTreeList"
)
@ResponseBody
public
List
<
ZTreeNode
>
roleTreeList
()
{
List
<
ZTreeNode
>
roleTreeList
=
this
.
roleService
.
roleTreeList
();
roleTreeList
.
add
(
ZTreeNode
.
createParent
());
return
roleTreeList
;
}
/**
* 获取角色列表
*/
@RequestMapping
(
value
=
"/roleTreeListByUserId/{userId}"
)
@ResponseBody
public
List
<
ZTreeNode
>
roleTreeListByUserId
(
@PathVariable
Integer
userId
)
{
User
theUser
=
this
.
userService
.
selectById
(
userId
);
String
roleid
=
theUser
.
getRoleid
();
if
(
ToolUtil
.
isEmpty
(
roleid
))
{
return
this
.
roleService
.
roleTreeList
();
}
else
{
String
[]
strArray
=
roleid
.
split
(
","
);
return
this
.
roleService
.
roleTreeListByRoleId
(
strArray
);
}
}
}
src/main/java/cn/stylefeng/guns/modular/system/controller/UserMgrController.java
0 → 100644
View file @
d552b1db
This diff is collapsed.
Click to expand it.
src/main/java/cn/stylefeng/guns/modular/system/model/Relation.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
modular
.
system
.
model
;
import
com.baomidou.mybatisplus.activerecord.Model
;
import
com.baomidou.mybatisplus.annotations.TableId
;
import
com.baomidou.mybatisplus.annotations.TableName
;
import
com.baomidou.mybatisplus.enums.IdType
;
import
java.io.Serializable
;
/**
* <p>
* 角色和菜单关联表
* </p>
*
* @author stylefeng
* @since 2017-07-11
*/
@TableName
(
"sys_relation"
)
public
class
Relation
extends
Model
<
Relation
>
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 主键
*/
@TableId
(
value
=
"id"
,
type
=
IdType
.
AUTO
)
private
Integer
id
;
/**
* 菜单id
*/
private
Long
menuid
;
/**
* 角色id
*/
private
Integer
roleid
;
public
Integer
getId
()
{
return
id
;
}
public
void
setId
(
Integer
id
)
{
this
.
id
=
id
;
}
public
Long
getMenuid
()
{
return
menuid
;
}
public
void
setMenuid
(
Long
menuid
)
{
this
.
menuid
=
menuid
;
}
public
Integer
getRoleid
()
{
return
roleid
;
}
public
void
setRoleid
(
Integer
roleid
)
{
this
.
roleid
=
roleid
;
}
@Override
protected
Serializable
pkVal
()
{
return
this
.
id
;
}
@Override
public
String
toString
()
{
return
"Relation{"
+
"id="
+
id
+
", menuid="
+
menuid
+
", roleid="
+
roleid
+
"}"
;
}
}
src/test/java/cn/stylefeng/guns/base/BaseJunit.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
base
;
import
cn.stylefeng.guns.GunsApplication
;
import
org.junit.Before
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
org.springframework.test.context.web.WebAppConfiguration
;
import
org.springframework.test.web.servlet.MockMvc
;
import
org.springframework.test.web.servlet.setup.MockMvcBuilders
;
import
org.springframework.web.context.WebApplicationContext
;
/**
* 基础测试类
*
* @author stylefeng
* @Date 2017/5/21 16:10
*/
@RunWith
(
SpringRunner
.
class
)
@SpringBootTest
(
classes
=
GunsApplication
.
class
)
@WebAppConfiguration
//@Transactional //打开的话测试之后数据可自动回滚
public
class
BaseJunit
{
@Autowired
WebApplicationContext
webApplicationContext
;
protected
MockMvc
mockMvc
;
@Before
public
void
setupMockMvc
(){
mockMvc
=
MockMvcBuilders
.
webAppContextSetup
(
webApplicationContext
).
build
();
}
@Before
public
void
initDatabase
(){
}
}
src/test/java/cn/stylefeng/guns/multi/entity/Test.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
multi
.
entity
;
import
com.baomidou.mybatisplus.annotations.TableId
;
import
com.baomidou.mybatisplus.enums.IdType
;
import
java.io.Serializable
;
/**
* <p>
*
* </p>
*
* @author fengshuonan
* @since 2018-07-10
*/
public
class
Test
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
@TableId
(
value
=
"aaa"
,
type
=
IdType
.
AUTO
)
private
Integer
aaa
;
private
String
bbb
;
public
Integer
getAaa
()
{
return
aaa
;
}
public
void
setAaa
(
Integer
aaa
)
{
this
.
aaa
=
aaa
;
}
public
String
getBbb
()
{
return
bbb
;
}
public
void
setBbb
(
String
bbb
)
{
this
.
bbb
=
bbb
;
}
@Override
public
String
toString
()
{
return
"Test{"
+
"aaa="
+
aaa
+
", bbb="
+
bbb
+
"}"
;
}
}
src/test/java/cn/stylefeng/guns/multi/mapper/TestMapper.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
multi
.
mapper
;
import
com.baomidou.mybatisplus.mapper.BaseMapper
;
import
cn.stylefeng.guns.multi.entity.Test
;
/**
* <p>
* Mapper 接口
* </p>
*
* @author fengshuonan
* @since 2018-07-10
*/
public
interface
TestMapper
extends
BaseMapper
<
Test
>
{
}
src/test/java/cn/stylefeng/guns/multi/mapper/mapping/TestMapper.xml
0 → 100644
View file @
d552b1db
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"share.example.modular.mapper.TestMapper"
>
<!-- 开启二级缓存 -->
<cache
type=
"org.mybatis.caches.ehcache.LoggingEhcache"
/>
<!-- 通用查询映射结果 -->
<resultMap
id=
"BaseResultMap"
type=
"cn.stylefeng.guns.multi.entity.Test"
>
<id
column=
"aaa"
property=
"aaa"
/>
<result
column=
"bbb"
property=
"bbb"
/>
</resultMap>
<!-- 通用查询结果列 -->
<sql
id=
"Base_Column_List"
>
aaa, bbb
</sql>
</mapper>
src/test/java/cn/stylefeng/guns/multi/service/TestService.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
multi
.
service
;
/**
* <p>
* 服务类
* </p>
*
* @author fengshuonan
* @since 2018-07-10
*/
public
interface
TestService
{
/**
* 测试多数据源的业务
*
* @author stylefeng
* @Date 2017/6/23 23:02
*/
void
testBiz
();
/**
* 测试多数据源的业务
*
* @author stylefeng
* @Date 2017/6/23 23:02
*/
void
testGuns
();
/**
* 测试多数据源的业务
*
* @author stylefeng
* @Date 2017/6/23 23:02
*/
void
testAll
();
}
src/test/java/cn/stylefeng/guns/multi/service/impl/TestServiceImpl.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
multi
.
service
.
impl
;
import
cn.stylefeng.roses.core.mutidatasource.annotion.DataSource
;
import
cn.stylefeng.guns.core.common.constant.DatasourceEnum
;
import
cn.stylefeng.guns.multi.entity.Test
;
import
cn.stylefeng.guns.multi.mapper.TestMapper
;
import
cn.stylefeng.guns.multi.service.TestService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
/**
* <p>
* 服务实现类
* </p>
*
* @author fengshuonan
* @since 2018-07-10
*/
@Service
public
class
TestServiceImpl
implements
TestService
{
@Autowired
private
TestMapper
testMapper
;
@Override
@DataSource
(
name
=
DatasourceEnum
.
DATA_SOURCE_BIZ
)
@Transactional
public
void
testBiz
()
{
Test
test
=
new
Test
();
test
.
setBbb
(
"bizTest"
);
testMapper
.
insert
(
test
);
}
@Override
@DataSource
(
name
=
DatasourceEnum
.
DATA_SOURCE_GUNS
)
@Transactional
public
void
testGuns
()
{
Test
test
=
new
Test
();
test
.
setBbb
(
"gunsTest"
);
testMapper
.
insert
(
test
);
}
@Override
@Transactional
public
void
testAll
()
{
testBiz
();
testGuns
();
//int i = 1 / 0;
}
}
src/test/java/cn/stylefeng/guns/multi/test/BizTest.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
multi
.
test
;
import
cn.stylefeng.guns.multi.service.TestService
;
import
cn.stylefeng.guns.base.BaseJunit
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
/**
* 业务测试
*
* @author fengshuonan
* @date 2017-06-23 23:12
*/
public
class
BizTest
extends
BaseJunit
{
@Autowired
TestService
testService
;
@Test
public
void
test
()
{
testService
.
testGuns
();
testService
.
testBiz
();
//testService.testAll();
}
}
src/test/java/cn/stylefeng/guns/shiro/Base64Test.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
shiro
;
import
org.springframework.util.Base64Utils
;
import
java.io.UnsupportedEncodingException
;
import
java.util.Arrays
;
public
class
Base64Test
{
/**
* Shiro 记住密码采用的是AES加密,AES key length 需要是16位,该方法生成16位的key
*/
public
static
void
main
(
String
[]
args
)
{
String
keyStr
=
"guns"
;
byte
[]
keys
;
try
{
keys
=
keyStr
.
getBytes
(
"UTF-8"
);
System
.
out
.
println
(
Base64Utils
.
encodeToString
(
Arrays
.
copyOf
(
keys
,
16
)));
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
}
}
src/test/java/cn/stylefeng/guns/system/BlackBoardTest.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
system
;
import
cn.stylefeng.guns.base.BaseJunit
;
import
cn.stylefeng.guns.modular.system.dao.NoticeMapper
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
/**
* 首页通知展示测试
*
* @author fengshuonan
* @date 2017-05-21 15:02
*/
public
class
BlackBoardTest
extends
BaseJunit
{
@Autowired
NoticeMapper
noticeMapper
;
@Test
public
void
blackBoardTest
()
{
List
<
Map
<
String
,
Object
>>
notices
=
noticeMapper
.
list
(
null
);
assertTrue
(
notices
.
size
()
>
0
);
}
}
src/test/java/cn/stylefeng/guns/system/DeptTest.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
system
;
import
cn.stylefeng.guns.base.BaseJunit
;
import
cn.stylefeng.guns.modular.system.dao.DeptMapper
;
import
cn.stylefeng.guns.modular.system.model.Dept
;
import
org.junit.Test
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.Map
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
/**
* 字典服务测试
*
* @author fengshuonan
* @date 2017-04-27 17:05
*/
public
class
DeptTest
extends
BaseJunit
{
@Resource
DeptMapper
deptMapper
;
@Test
public
void
addDeptTest
()
{
Dept
dept
=
new
Dept
();
dept
.
setFullname
(
"测试fullname"
);
dept
.
setNum
(
5
);
dept
.
setPid
(
1
);
dept
.
setSimplename
(
"测试"
);
dept
.
setTips
(
"测试tips"
);
dept
.
setVersion
(
1
);
Integer
insert
=
deptMapper
.
insert
(
dept
);
assertEquals
(
insert
,
new
Integer
(
1
));
}
@Test
public
void
updateTest
()
{
Dept
dept
=
this
.
deptMapper
.
selectById
(
24
);
dept
.
setTips
(
"哈哈"
);
boolean
flag
=
dept
.
updateById
();
assertTrue
(
flag
);
}
@Test
public
void
deleteTest
()
{
Dept
dept
=
this
.
deptMapper
.
selectById
(
24
);
Integer
integer
=
deptMapper
.
deleteById
(
dept
);
assertTrue
(
integer
>
0
);
}
@Test
public
void
listTest
()
{
List
<
Map
<
String
,
Object
>>
list
=
this
.
deptMapper
.
list
(
"总公司"
);
assertTrue
(
list
.
size
()
>
0
);
}
}
src/test/java/cn/stylefeng/guns/system/DictTest.java
0 → 100644
View file @
d552b1db
package
cn
.
stylefeng
.
guns
.
system
;
import
cn.stylefeng.guns.base.BaseJunit
;
import
cn.stylefeng.guns.modular.system.dao.DictMapper
;
import
cn.stylefeng.guns.modular.system.service.IDictService
;
import
org.junit.Assert
;
import
org.junit.Test
;
import
javax.annotation.Resource
;
import
java.util.List
;
import
java.util.Map
;
/**
* 字典服务测试
*
* @author fengshuonan
* @date 2017-04-27 17:05
*/
public
class
DictTest
extends
BaseJunit
{
@Resource
IDictService
dictService
;
@Resource
DictMapper
dictMapper
;
@Test
public
void
addTest
()
{
String
dictCode
=
"test"
;
String
dictName
=
"字典测试"
;
String
dictTips
=
"这是一个字典测试"
;
String
dictValues
=
"1:测试1:1;2:测试2:2"
;
dictService
.
addDict
(
dictCode
,
dictName
,
dictTips
,
dictValues
);
}
@Test
public
void
editTest
()
{
dictService
.
editDict
(
16
,
"tes"
,
"测试"
,
"备注"
,
"1:测试1;2:测试2"
);
}
@Test
public
void
deleteTest
()
{
this
.
dictService
.
delteDict
(
16
);
}
@Test
public
void
listTest
()
{
List
<
Map
<
String
,
Object
>>
list
=
this
.
dictMapper
.
list
(
"性别"
);
Assert
.
assertTrue
(
list
.
size
()
>
0
);
}
}
src/test/java/cn/stylefeng/guns/system/MenuTest.java
0 → 100644
View file @
d552b1db
This diff is collapsed.
Click to expand it.
src/test/java/cn/stylefeng/guns/system/UserTest.java
0 → 100644
View file @
d552b1db
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
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