优化首页
This commit is contained in:
parent
4516c36b1d
commit
f371c83579
|
|
@ -12,7 +12,7 @@ public class AliyunOSSRest {
|
||||||
// @Autowired
|
// @Autowired
|
||||||
// private AliyunOSSClient aliyunOSSClient ;
|
// private AliyunOSSClient aliyunOSSClient ;
|
||||||
@GetMapping("policy.json")
|
@GetMapping("policy.json")
|
||||||
public JSONObject getPolicy() {
|
public JSONObject getPolicy(String id) {
|
||||||
String dir = String.valueOf(System.currentTimeMillis());
|
String dir = String.valueOf(System.currentTimeMillis());
|
||||||
// return aliyunOSSClient .getPostObjectPolicy(dir);
|
// return aliyunOSSClient .getPostObjectPolicy(dir);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ import io.swagger.annotations.ApiOperation;
|
||||||
@Api("用户信息管理")
|
@Api("用户信息管理")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/test/*")
|
@RequestMapping("/test/*")
|
||||||
public class TestController extends BaseController
|
public class TestController extends BaseController {
|
||||||
{
|
|
||||||
private final static List<Test> testList = new ArrayList<>();
|
private final static List<Test> testList = new ArrayList<>();
|
||||||
|
|
||||||
{
|
{
|
||||||
testList.add(new Test("1", "admin", "admin123"));
|
testList.add(new Test("1", "admin", "admin123"));
|
||||||
testList.add(new Test("2", "ry", "admin123"));
|
testList.add(new Test("2", "ry", "admin123"));
|
||||||
|
|
@ -35,62 +35,52 @@ public class TestController extends BaseController
|
||||||
|
|
||||||
@ApiOperation("获取列表")
|
@ApiOperation("获取列表")
|
||||||
@GetMapping("list")
|
@GetMapping("list")
|
||||||
public List<Test> testList()
|
public List<Test> testList() {
|
||||||
{
|
|
||||||
return testList;
|
return testList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("新增用户")
|
@ApiOperation("新增用户")
|
||||||
@PostMapping("save")
|
@PostMapping("save")
|
||||||
public AjaxResult save(Test test)
|
public AjaxResult save(Test test) {
|
||||||
{
|
|
||||||
return testList.add(test) ? success() : error();
|
return testList.add(test) ? success() : error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("更新用户")
|
@ApiOperation("更新用户")
|
||||||
@ApiImplicitParam(name = "Test", value = "单个用户信息", dataType = "Test")
|
@ApiImplicitParam(name = "Test", value = "单个用户信息", dataType = "Test")
|
||||||
@PutMapping("update")
|
@PutMapping("update")
|
||||||
public AjaxResult update(Test test)
|
public AjaxResult update(Test test) {
|
||||||
{
|
|
||||||
return testList.remove(test) && testList.add(test) ? success() : error();
|
return testList.remove(test) && testList.add(test) ? success() : error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("删除用户")
|
@ApiOperation("删除用户")
|
||||||
@ApiImplicitParam(name = "Tests", value = "单个用户信息", dataType = "Test")
|
@ApiImplicitParam(name = "Tests", value = "单个用户信息", dataType = "Test")
|
||||||
@DeleteMapping("delete")
|
@DeleteMapping("delete")
|
||||||
public AjaxResult delete(Test test)
|
public AjaxResult delete(Test test) {
|
||||||
{
|
|
||||||
return testList.remove(test) ? success() : error();
|
return testList.remove(test) ? success() : error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Test
|
class Test {
|
||||||
{
|
|
||||||
private String userId;
|
private String userId;
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
public Test()
|
public Test() {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Test(String userId, String username, String password)
|
public Test(String userId, String username, String password) {
|
||||||
{
|
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o)
|
public boolean equals(Object o) {
|
||||||
{
|
if (this == o) {
|
||||||
if (this == o)
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (o == null || getClass() != o.getClass())
|
if (o == null || getClass() != o.getClass()) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,41 +90,34 @@ class Test
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode() {
|
||||||
{
|
|
||||||
int result = userId != null ? userId.hashCode() : 0;
|
int result = userId != null ? userId.hashCode() : 0;
|
||||||
result = 31 * result + (username != null ? username.hashCode() : 0);
|
result = 31 * result + (username != null ? username.hashCode() : 0);
|
||||||
result = 31 * result + (password != null ? password.hashCode() : 0);
|
result = 31 * result + (password != null ? password.hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserId()
|
public String getUserId() {
|
||||||
{
|
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserId(String userId)
|
public void setUserId(String userId) {
|
||||||
{
|
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername()
|
public String getUsername() {
|
||||||
{
|
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username)
|
public void setUsername(String username) {
|
||||||
{
|
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPassword()
|
public String getPassword() {
|
||||||
{
|
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(String password)
|
public void setPassword(String password) {
|
||||||
{
|
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class SwaggerConfig
|
||||||
.apiInfo(apiInfo())
|
.apiInfo(apiInfo())
|
||||||
.select()
|
.select()
|
||||||
// 指定当前包路径
|
// 指定当前包路径
|
||||||
.apis(RequestHandlerSelectors.basePackage("com.ruoyi.web.controller.tool"))
|
.apis(RequestHandlerSelectors.basePackage("com.ruoyi"))
|
||||||
// 扫描所有 .apis(RequestHandlerSelectors.any())
|
// 扫描所有 .apis(RequestHandlerSelectors.any())
|
||||||
.paths(PathSelectors.any())
|
.paths(PathSelectors.any())
|
||||||
.build();
|
.build();
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,10 @@
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.step-content{
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
.step-list{
|
.step-list{
|
||||||
display: none;
|
display: none;
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +30,8 @@ function login() {
|
||||||
"rememberMe": rememberMe
|
"rememberMe": rememberMe
|
||||||
},
|
},
|
||||||
success: function(r) {
|
success: function(r) {
|
||||||
if (r.code == 0) {
|
debugger
|
||||||
|
if (r.code == 200) {
|
||||||
location.href = ctx + 'index';
|
location.href = ctx + 'index';
|
||||||
} else {
|
} else {
|
||||||
$.modal.closeLoading();
|
$.modal.closeLoading();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.ruoyi.common.base;
|
package com.ruoyi.common.base;
|
||||||
|
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,7 +66,7 @@ public class AjaxResult extends HashMap<String, Object>
|
||||||
{
|
{
|
||||||
AjaxResult json = new AjaxResult();
|
AjaxResult json = new AjaxResult();
|
||||||
json.put("msg", msg);
|
json.put("msg", msg);
|
||||||
json.put("code", 0);
|
json.put("code", Constants.SUCCESS);
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@ public class Constants
|
||||||
/**
|
/**
|
||||||
* 通用成功标识
|
* 通用成功标识
|
||||||
*/
|
*/
|
||||||
public static final String SUCCESS = "0";
|
public static final String SUCCESS = "200";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用失败标识
|
* 通用失败标识
|
||||||
*/
|
*/
|
||||||
public static final String FAIL = "1";
|
public static final String FAIL = "500";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录成功
|
* 登录成功
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,12 @@
|
||||||
<version>3.3.0</version>
|
<version>3.3.0</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--前后端分离验证-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跨域设置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class CorsConfig {
|
||||||
|
private CorsConfiguration buildConfig() {
|
||||||
|
CorsConfiguration corsConfiguration = new CorsConfiguration();
|
||||||
|
// 1允许任何域名使用
|
||||||
|
corsConfiguration.addAllowedOrigin("*");
|
||||||
|
// 2允许任何头
|
||||||
|
corsConfiguration.addAllowedHeader("*");
|
||||||
|
// 3允许任何方法(post、get等)
|
||||||
|
corsConfiguration.addAllowedMethod("*");
|
||||||
|
return corsConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsFilter corsFilter() {
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", buildConfig());
|
||||||
|
return new CorsFilter(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -246,6 +246,7 @@ public class ShiroConfig
|
||||||
filterChainDefinitionMap.put("/js/**", "anon");
|
filterChainDefinitionMap.put("/js/**", "anon");
|
||||||
filterChainDefinitionMap.put("/ruoyi/**", "anon");
|
filterChainDefinitionMap.put("/ruoyi/**", "anon");
|
||||||
filterChainDefinitionMap.put("/druid/**", "anon");
|
filterChainDefinitionMap.put("/druid/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/api/**", "anon");
|
||||||
filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
|
filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
|
||||||
// 退出 logout地址,shiro去清除session
|
// 退出 logout地址,shiro去清除session
|
||||||
filterChainDefinitionMap.put("/logout", "logout");
|
filterChainDefinitionMap.put("/logout", "logout");
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.ruoyi.framework.jwt;
|
||||||
|
|
||||||
|
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mr.Li
|
||||||
|
* @create 2018-07-12 15:56
|
||||||
|
* @desc
|
||||||
|
**/
|
||||||
|
public class JwtFilter extends BasicHttpAuthenticationFilter {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行登录认证
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @param mappedValue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
|
||||||
|
try {
|
||||||
|
executeLogin(request, response);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
|
||||||
|
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||||
|
String token = httpServletRequest.getHeader("Authorization");
|
||||||
|
|
||||||
|
JwtToken jwtToken = new JwtToken(token);
|
||||||
|
// 提交给realm进行登入,如果错误他会抛出异常并被捕获
|
||||||
|
getSubject(request, response).login(jwtToken);
|
||||||
|
// 如果没有抛出异常则代表登入成功,返回true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对跨域提供支持
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
|
||||||
|
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
||||||
|
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
||||||
|
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
|
||||||
|
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
|
||||||
|
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
|
||||||
|
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
|
||||||
|
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
|
||||||
|
httpServletResponse.setStatus(HttpStatus.OK.value());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.preHandle(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.ruoyi.framework.jwt;
|
||||||
|
|
||||||
|
import org.apache.shiro.authc.AuthenticationToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mr.Li
|
||||||
|
* @create 2018-07-12 15:19
|
||||||
|
* @desc
|
||||||
|
**/
|
||||||
|
public class JwtToken implements AuthenticationToken {
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public JwtToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getPrincipal() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getCredentials() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.ruoyi.framework.jwt;
|
||||||
|
|
||||||
|
import com.auth0.jwt.JWT;
|
||||||
|
import com.auth0.jwt.JWTVerifier;
|
||||||
|
import com.auth0.jwt.algorithms.Algorithm;
|
||||||
|
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||||
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
|
import com.ruoyi.framework.web.util.ServletUtils;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Mr.Li
|
||||||
|
* @create 2018-07-12 14:23
|
||||||
|
* @desc JWT工具类
|
||||||
|
**/
|
||||||
|
public class JwtUtil {
|
||||||
|
|
||||||
|
private static final long EXPIRE_TIME = 5 * 60 * 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验token是否正确
|
||||||
|
*
|
||||||
|
* @param token 密钥
|
||||||
|
* @param secret 用户的密码
|
||||||
|
* @return 是否正确
|
||||||
|
*/
|
||||||
|
public static boolean verify(String token, String username, String secret) {
|
||||||
|
try {
|
||||||
|
//根据密码生成JWT效验器
|
||||||
|
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||||
|
JWTVerifier verifier = JWT.require(algorithm)
|
||||||
|
.withClaim("username", username)
|
||||||
|
.build();
|
||||||
|
//效验TOKEN
|
||||||
|
DecodedJWT jwt = verifier.verify(token);
|
||||||
|
return true;
|
||||||
|
} catch (Exception exception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得token中的信息无需secret解密也能获得
|
||||||
|
*
|
||||||
|
* @return token中包含的用户名
|
||||||
|
*/
|
||||||
|
public static String getLoginName() {
|
||||||
|
try {
|
||||||
|
String token = ServletUtils.getRequest().getHeader("token");
|
||||||
|
DecodedJWT jwt = JWT.decode(token);
|
||||||
|
return jwt.getClaim("loginName").asString();
|
||||||
|
} catch (JWTDecodeException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成签名,5min后过期
|
||||||
|
*
|
||||||
|
* @param loginName 用户名
|
||||||
|
* @param secret 用户的密码
|
||||||
|
* @return 加密的token
|
||||||
|
*/
|
||||||
|
public static String sign(String loginName, String secret) {
|
||||||
|
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
|
||||||
|
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||||
|
// 附带username信息
|
||||||
|
return JWT.create()
|
||||||
|
.withClaim("loginName", loginName)
|
||||||
|
.withExpiresAt(date)
|
||||||
|
.sign(algorithm);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package com.ruoyi.framework.shiro.realm;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.ruoyi.framework.jwt.JwtToken;
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.AuthenticationException;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
import org.apache.shiro.authc.AuthenticationInfo;
|
import org.apache.shiro.authc.AuthenticationInfo;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="status != null and status != ''">
|
<if test="status != null and status != ''">
|
||||||
AND u.status = #{status}
|
AND u.status = #{status}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="userType != null and userType != ''">
|
||||||
|
AND u.user_type = #{userType}
|
||||||
|
</if>
|
||||||
<if test="phonenumber != null and phonenumber != ''">
|
<if test="phonenumber != null and phonenumber != ''">
|
||||||
AND u.phonenumber like concat('%', #{phonenumber}, '%')
|
AND u.phonenumber like concat('%', #{phonenumber}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,14 @@ import com.ruoyi.common.utils.ExcelUtil;
|
||||||
* @author zhujj
|
* @author zhujj
|
||||||
* @date 2018-11-29
|
* @date 2018-11-29
|
||||||
*/
|
*/
|
||||||
@Controller
|
@RestController
|
||||||
@RequestMapping("/agile/genTable")
|
@RequestMapping("/genTable")
|
||||||
public class GenTableController extends BaseController {
|
public class GenTableController extends BaseController {
|
||||||
private String prefix = "agile/genTable";
|
private String prefix = "agile/genTable";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IGenTableService genTableService;
|
private IGenTableService genTableService;
|
||||||
|
|
||||||
@RequiresPermissions("agile:genTable:view")
|
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public String genTable() {
|
public String genTable() {
|
||||||
return prefix + "/genTable";
|
return prefix + "/genTable";
|
||||||
|
|
@ -39,7 +38,6 @@ public class GenTableController extends BaseController {
|
||||||
/**
|
/**
|
||||||
* 查询代码生成列表
|
* 查询代码生成列表
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("agile:genTable:list")
|
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public TableDataInfo list(GenTable genTable) {
|
public TableDataInfo list(GenTable genTable) {
|
||||||
|
|
@ -51,7 +49,6 @@ public class GenTableController extends BaseController {
|
||||||
/**
|
/**
|
||||||
* 导出代码生成列表
|
* 导出代码生成列表
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("agile:genTable:export")
|
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AjaxResult export(GenTable genTable) {
|
public AjaxResult export(GenTable genTable) {
|
||||||
|
|
@ -71,7 +68,6 @@ public class GenTableController extends BaseController {
|
||||||
/**
|
/**
|
||||||
* 新增保存代码生成
|
* 新增保存代码生成
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("agile:genTable:add")
|
|
||||||
@Log(title = "代码生成", businessType = BusinessType.INSERT)
|
@Log(title = "代码生成", businessType = BusinessType.INSERT)
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
@ -93,7 +89,6 @@ public class GenTableController extends BaseController {
|
||||||
/**
|
/**
|
||||||
* 修改保存代码生成
|
* 修改保存代码生成
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("agile:genTable:edit")
|
|
||||||
@Log(title = "代码生成", businessType = BusinessType.UPDATE)
|
@Log(title = "代码生成", businessType = BusinessType.UPDATE)
|
||||||
@PostMapping("/edit")
|
@PostMapping("/edit")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
@ -104,7 +99,6 @@ public class GenTableController extends BaseController {
|
||||||
/**
|
/**
|
||||||
* 删除代码生成
|
* 删除代码生成
|
||||||
*/
|
*/
|
||||||
@RequiresPermissions("agile:genTable:remove")
|
|
||||||
@Log(title = "代码生成", businessType = BusinessType.DELETE)
|
@Log(title = "代码生成", businessType = BusinessType.DELETE)
|
||||||
@PostMapping("/remove")
|
@PostMapping("/remove")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
|
|
||||||
|
|
@ -2,46 +2,58 @@
|
||||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<head th:include="include :: header"></head>
|
<head th:include="include :: header"></head>
|
||||||
<link th:href="@{/ajax/libs/layui/extend/steps/steps.css}" rel="stylesheet"/>
|
<link th:href="@{/ajax/libs/layui/css/layui.css}" rel="stylesheet"/>
|
||||||
<body class="white-bg">
|
<body class="white-bg">
|
||||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||||
<form class="form-horizontal m" id="form-genTable-add">
|
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;">
|
||||||
<div id="step_demo" class="step-body">
|
<legend>基本信息</legend>
|
||||||
<div class="step-header" style="width:80%;overflow: hidden;">
|
</fieldset>
|
||||||
<ul>
|
<form class="form-horizontal m">
|
||||||
<li>
|
<div class="layui-inline">
|
||||||
<span class="step-name">选择表</span>
|
<label class="layui-form-label">搜索选择框</label>
|
||||||
</li>
|
<div class="layui-input-inline">
|
||||||
<li>
|
<select name="modules" lay-verify="required" lay-search="">
|
||||||
<span class="step-name">基本信息</span>
|
<option value="">直接选择或搜索选择</option>
|
||||||
</li>
|
<option value="1">layer</option>
|
||||||
<li>
|
<option value="2">form</option>
|
||||||
<span class="step-name">字段信息</span>
|
<option value="3">layim</option>
|
||||||
</li>
|
<option value="4">element</option>
|
||||||
<li>
|
<option value="5">laytpl</option>
|
||||||
<span class="step-name">生成信息</span>
|
<option value="6">upload</option>
|
||||||
</li>
|
<option value="7">laydate</option>
|
||||||
<li>
|
<option value="8">laypage</option>
|
||||||
<span class="step-name">完成</span>
|
<option value="9">flow</option>
|
||||||
</li>
|
<option value="10">util</option>
|
||||||
|
<option value="11">code</option>
|
||||||
|
<option value="12">tree</option>
|
||||||
|
<option value="13">layedit</option>
|
||||||
|
<option value="14">nav</option>
|
||||||
|
<option value="15">tab</option>
|
||||||
|
<option value="16">table</option>
|
||||||
|
<option value="17">select</option>
|
||||||
|
<option value="18">checkbox</option>
|
||||||
|
<option value="19">switch</option>
|
||||||
|
<option value="20">radio</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight ibox-content hide">
|
||||||
|
|
||||||
|
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||||
|
<ul class="layui-tab-title">
|
||||||
|
<li class="layui-this">基本信息</li>
|
||||||
|
<li>字段信息</li>
|
||||||
|
<li>生成信息</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
<div class="layui-tab-content" style="height: 100px;">
|
||||||
<div class="step-content">
|
<form class="form-horizontal m" id="form-genTable-add">
|
||||||
<div class="step-list">
|
<div class="layui-tab-item layui-show">
|
||||||
<div class="form-group">
|
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;">
|
||||||
<label class="col-sm-3 control-label">数据源名称:</label>
|
<legend>基本信息</legend>
|
||||||
<div class="col-sm-8">
|
</fieldset>
|
||||||
<input id="dataSourceName" name="dataSourceName" class="form-control" type="text">
|
<div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-sm-3 control-label">选择表:</label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input id="tableName" name="tableName" class="form-control" type="text">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="step-list">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-3 control-label">实体类名称:</label>
|
<label class="col-sm-3 control-label">实体类名称:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
|
|
@ -73,8 +85,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="step-list">待确认</div>
|
</div>
|
||||||
<div class="step-list">
|
<div class="layui-tab-item">
|
||||||
|
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;">
|
||||||
|
<legend>字段信息</legend>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;">
|
||||||
|
<legend>生成信息</legend>
|
||||||
|
</fieldset>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-3 control-label">使用的模板:</label>
|
<label class="col-sm-3 control-label">使用的模板:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
|
|
@ -130,14 +150,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
<button id="preBtn">上一步</button>
|
</div>
|
||||||
<button id="nextBtn">下一步</button>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div th:include="include::footer"></div>
|
<div th:include="include::footer"></div>
|
||||||
|
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var prefix = ctx + "agile/genTable"
|
var prefix = ctx + "agile/genTable"
|
||||||
$("#form-genTable-add").validate({
|
$("#form-genTable-add").validate({
|
||||||
|
|
@ -153,33 +173,48 @@
|
||||||
$.operate.save(prefix + "/add", $('#form-genTable-add').serialize());
|
$.operate.save(prefix + "/add", $('#form-genTable-add').serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layui.config({
|
layui.use(['element','form', 'layedit', 'laydate'], function(){
|
||||||
debug: true
|
var $ = layui.jquery
|
||||||
,base: '/ajax/libs/layui/extend/'
|
,element = layui.element; //Tab的切换功能,切换事件监听等,需要依赖element模块
|
||||||
}).extend({
|
|
||||||
steps:"steps/steps"
|
//触发事件
|
||||||
|
var active = {
|
||||||
|
tabAdd: function(){
|
||||||
|
//新增一个Tab项
|
||||||
|
element.tabAdd('demo', {
|
||||||
|
title: '新选项'+ (Math.random()*1000|0) //用于演示
|
||||||
|
,content: '内容'+ (Math.random()*1000|0)
|
||||||
|
,id: new Date().getTime() //实际使用一般是规定好的id,这里以时间戳模拟下
|
||||||
|
})
|
||||||
|
}
|
||||||
|
,tabDelete: function(othis){
|
||||||
|
//删除指定Tab项
|
||||||
|
element.tabDelete('demo', '44'); //删除:“商品管理”
|
||||||
|
|
||||||
|
|
||||||
|
othis.addClass('layui-btn-disabled');
|
||||||
|
}
|
||||||
|
,tabChange: function(){
|
||||||
|
//切换到指定Tab项
|
||||||
|
element.tabChange('demo', '22'); //切换到:用户管理
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$('.site-demo-active').on('click', function(){
|
||||||
|
var othis = $(this), type = othis.data('type');
|
||||||
|
active[type] ? active[type].call(this, othis) : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Hash地址的定位
|
||||||
|
var layid = location.hash.replace(/^#test=/, '');
|
||||||
|
element.tabChange('test', layid);
|
||||||
|
|
||||||
|
element.on('tab(test)', function(elem){
|
||||||
layui.use(['jquery', 'steps'],function(){
|
location.hash = 'test='+ $(this).attr('lay-id');
|
||||||
|
|
||||||
var $ = layui.$;
|
|
||||||
|
|
||||||
var $step= $("#step_demo").step();
|
|
||||||
|
|
||||||
$("#preBtn").click(function(event) {
|
|
||||||
console.log("上一步");
|
|
||||||
$step.preStep();//上一步
|
|
||||||
});
|
|
||||||
$("#nextBtn").click(function(event) {
|
|
||||||
console.log("下一步");
|
|
||||||
$step.nextStep();//下一步
|
|
||||||
});
|
|
||||||
$("#goBtn").click(function(event) {
|
|
||||||
$step.goStep(3);//到指定步
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
<head th:include="include :: header"></head>
|
<head th:include="include :: header"></head>
|
||||||
<body class="gray-bg">
|
<body class="gray-bg">
|
||||||
<div class="container-div">
|
<div class="container-div">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 search-collapse">
|
<div class="col-sm-12 search-collapse">
|
||||||
<form id="formId">
|
<form id="formId">
|
||||||
|
|
@ -26,7 +27,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group-sm hidden-xs" id="toolbar" role="group">
|
<div class="btn-group-sm hidden-xs" id="toolbar" role="group">
|
||||||
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="agile:genTable:add">
|
<a class="btn btn-success" onclick="$.operate.addFull()" shiro:hasPermission="agile:genTable:add">
|
||||||
<i class="fa fa-plus"></i> 添加
|
<i class="fa fa-plus"></i> 添加
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="agile:genTable:edit">
|
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="agile:genTable:edit">
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@
|
||||||
<artifactId>ruoyi-framework</artifactId>
|
<artifactId>ruoyi-framework</artifactId>
|
||||||
<version>${ruoyi.version}</version>
|
<version>${ruoyi.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
<version>1.5.19</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
package com.ruoyi.vip.controller;
|
||||||
|
|
||||||
|
import com.auth0.jwt.JWTVerifier;
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.base.AjaxResult;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.json.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.ExcelUtil;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.framework.jwt.JwtUtil;
|
||||||
|
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||||
|
import com.ruoyi.framework.web.base.BaseController;
|
||||||
|
import com.ruoyi.framework.web.page.TableDataInfo;
|
||||||
|
import com.ruoyi.framework.web.util.ServletUtils;
|
||||||
|
import com.ruoyi.framework.web.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysUser;
|
||||||
|
import com.ruoyi.vip.domain.VipUser;
|
||||||
|
import com.ruoyi.vip.service.IVipUserService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Api("用户信息管理")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/v1/vip/user")
|
||||||
|
public class ApiVipUserController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVipUserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysPasswordService passwordService;
|
||||||
|
|
||||||
|
@ApiOperation("用户登陆")
|
||||||
|
@Log(title = "用户登陆", businessType = BusinessType.EXPORT)
|
||||||
|
@RequestMapping(value = "/login", method = RequestMethod.POST,produces= "application/json;charset=UTF-8")
|
||||||
|
public AjaxResult login(@RequestBody SysUser user) {
|
||||||
|
AjaxResult success = success("登陆成功");
|
||||||
|
boolean rememberMe=false;
|
||||||
|
UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword(), rememberMe);
|
||||||
|
Subject subject = SecurityUtils.getSubject();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
subject.login(token);
|
||||||
|
String tokenSign=JwtUtil.sign(user.getUserName(),user.getUserName());
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
|
json.put("token",tokenSign);
|
||||||
|
success.put("data",json);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
String msg = "用户或密码错误";
|
||||||
|
if (StringUtils.isNotEmpty(e.getMessage()))
|
||||||
|
{
|
||||||
|
msg = e.getMessage();
|
||||||
|
}
|
||||||
|
return error(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@GetMapping("/info")
|
||||||
|
public AjaxResult get() {
|
||||||
|
AjaxResult success = success("登陆成功");
|
||||||
|
VipUser vipUser = userService.selectUserByLoginName(JwtUtil.getLoginName());
|
||||||
|
success.put("user", vipUser);
|
||||||
|
SysUser vipUser2 =ShiroUtils.getSysUser();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
@PostMapping("/list")
|
||||||
|
@ResponseBody
|
||||||
|
public TableDataInfo list(VipUser user) {
|
||||||
|
|
||||||
|
List<VipUser> list = userService.selectUserList( user );
|
||||||
|
return getDataTable( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult export(VipUser user) {
|
||||||
|
List<VipUser> list = userService.selectUserList( user );
|
||||||
|
ExcelUtil<VipUser> util = new ExcelUtil<VipUser>( VipUser.class );
|
||||||
|
return util.exportExcel( list, "user" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增保存用户
|
||||||
|
*/
|
||||||
|
@Log(title = "用户管理", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/add")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult addSave(VipUser user) {
|
||||||
|
user.setSalt( ShiroUtils.randomSalt() );
|
||||||
|
user.setPassword( passwordService.encryptPassword( user.getLoginName(), user.getPassword(), user.getSalt() ) );
|
||||||
|
user.setCreateBy( ShiroUtils.getLoginName() );
|
||||||
|
return toAjax( userService.insertUser( user ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改保存用户
|
||||||
|
*/
|
||||||
|
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/edit")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult editSave(VipUser user) {
|
||||||
|
|
||||||
|
user.setUpdateBy( ShiroUtils.getLoginName() );
|
||||||
|
return toAjax( userService.updateUser( user ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/resetPwd")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult resetPwdSave(VipUser user) {
|
||||||
|
user.setSalt( ShiroUtils.randomSalt() );
|
||||||
|
user.setPassword( passwordService.encryptPassword( user.getLoginName(), user.getPassword(), user.getSalt() ) );
|
||||||
|
return toAjax( userService.resetUserPwd( user ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresPermissions("vip:user:remove")
|
||||||
|
@Log(title = "用户管理", businessType = BusinessType.DELETE)
|
||||||
|
@PostMapping("/remove")
|
||||||
|
@ResponseBody
|
||||||
|
public AjaxResult remove(String ids) {
|
||||||
|
try {
|
||||||
|
return toAjax( userService.deleteUserByIds( ids ) );
|
||||||
|
} catch (Exception e) {
|
||||||
|
return error( e.getMessage() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验用户名
|
||||||
|
*/
|
||||||
|
@PostMapping("/checkLoginNameUnique")
|
||||||
|
@ResponseBody
|
||||||
|
public String checkLoginNameUnique(VipUser user) {
|
||||||
|
return userService.checkLoginNameUnique( user.getLoginName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验手机号码
|
||||||
|
*/
|
||||||
|
@PostMapping("/checkPhoneUnique")
|
||||||
|
@ResponseBody
|
||||||
|
public String checkPhoneUnique(VipUser user) {
|
||||||
|
return userService.checkPhoneUnique( user );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验email邮箱
|
||||||
|
*/
|
||||||
|
@PostMapping("/checkEmailUnique")
|
||||||
|
@ResponseBody
|
||||||
|
public String checkEmailUnique(VipUser user) {
|
||||||
|
return userService.checkEmailUnique( user );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户对象 sys_user
|
* 用户对象 vip_user
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.ruoyi.vip.framework;
|
||||||
|
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义带用户类型token
|
||||||
|
* @author Sunny
|
||||||
|
*/
|
||||||
|
public class UsernamePasswordByUserTypeToken extends UsernamePasswordToken {
|
||||||
|
private static final long serialVersionUID = -7638434498222500528L;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 用户类型
|
||||||
|
* 1:积分后台用户(后台管理员)
|
||||||
|
* 2:积分兑换端用户(店长店员)
|
||||||
|
* 3:积分验证端用户(第三方合作店铺)
|
||||||
|
*/
|
||||||
|
private String userType;
|
||||||
|
|
||||||
|
public String getUserType() {
|
||||||
|
return userType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserType(String userType) {
|
||||||
|
this.userType = userType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UsernamePasswordByUserTypeToken(String username, String password, String userType) {
|
||||||
|
super(username, password);
|
||||||
|
this.userType = userType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
package com.ruoyi.vip.framework;
|
||||||
|
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
import com.ruoyi.common.constant.ShiroConstants;
|
||||||
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
|
import com.ruoyi.common.enums.UserStatus;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
import com.ruoyi.framework.manager.AsyncManager;
|
||||||
|
import com.ruoyi.framework.manager.factory.AsyncFactory;
|
||||||
|
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||||
|
import com.ruoyi.framework.web.exception.user.*;
|
||||||
|
import com.ruoyi.framework.web.util.MessageUtils;
|
||||||
|
import com.ruoyi.framework.web.util.ServletUtils;
|
||||||
|
import com.ruoyi.framework.web.util.ShiroUtils;
|
||||||
|
import com.ruoyi.vip.domain.VipUser;
|
||||||
|
import com.ruoyi.vip.service.IVipUserService;
|
||||||
|
import org.apache.shiro.authc.credential.PasswordService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录校验方法
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class VipLoginService
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private VipPasswordService vipPasswordService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IVipUserService vipUserService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
*/
|
||||||
|
public VipUser login(String username, String password)
|
||||||
|
{
|
||||||
|
// 验证码校验
|
||||||
|
if (!StringUtils.isEmpty(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
||||||
|
throw new CaptchaException();
|
||||||
|
}
|
||||||
|
// 用户名或密码为空 错误
|
||||||
|
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
|
||||||
|
throw new UserNotExistsException();
|
||||||
|
}
|
||||||
|
// 密码如果不在指定范围内 错误
|
||||||
|
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||||
|
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||||
|
throw new UserPasswordNotMatchException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户名不在指定范围内 错误
|
||||||
|
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|
||||||
|
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||||
|
throw new UserPasswordNotMatchException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户信息
|
||||||
|
VipUser user = vipUserService.selectUserByLoginName(username);
|
||||||
|
|
||||||
|
if (user == null && maybeMobilePhoneNumber(username))
|
||||||
|
{
|
||||||
|
user = vipUserService.selectUserByPhoneNumber(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user == null && maybeEmail(username))
|
||||||
|
{
|
||||||
|
user = vipUserService.selectUserByEmail(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
|
||||||
|
throw new UserNotExistsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
|
||||||
|
throw new UserDeleteException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
|
||||||
|
throw new UserBlockedException(user.getRemark());
|
||||||
|
}
|
||||||
|
|
||||||
|
vipPasswordService.validate(user, password);
|
||||||
|
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
|
||||||
|
recordLoginInfo(user);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean maybeEmail(String username)
|
||||||
|
{
|
||||||
|
if (!username.matches(UserConstants.EMAIL_PATTERN))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean maybeMobilePhoneNumber(String username)
|
||||||
|
{
|
||||||
|
if (!username.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录登录信息
|
||||||
|
*/
|
||||||
|
public void recordLoginInfo(VipUser user)
|
||||||
|
{
|
||||||
|
user.setLoginIp(ShiroUtils.getIp());
|
||||||
|
user.setLoginDate(DateUtils.getNowDate());
|
||||||
|
vipUserService.updateUserInfo(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.ruoyi.vip.framework;
|
||||||
|
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
import com.ruoyi.framework.manager.AsyncManager;
|
||||||
|
import com.ruoyi.framework.manager.factory.AsyncFactory;
|
||||||
|
import com.ruoyi.framework.web.exception.user.UserPasswordNotMatchException;
|
||||||
|
import com.ruoyi.framework.web.exception.user.UserPasswordRetryLimitExceedException;
|
||||||
|
import com.ruoyi.framework.web.util.MessageUtils;
|
||||||
|
import com.ruoyi.system.domain.SysUser;
|
||||||
|
import com.ruoyi.vip.domain.VipUser;
|
||||||
|
import org.apache.shiro.cache.Cache;
|
||||||
|
import org.apache.shiro.cache.CacheManager;
|
||||||
|
import org.apache.shiro.crypto.hash.Md5Hash;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录密码方法
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class VipPasswordService
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private CacheManager cacheManager;
|
||||||
|
|
||||||
|
private Cache<String, AtomicInteger> loginRecordCache;
|
||||||
|
|
||||||
|
@Value(value = "${user.password.maxRetryCount}")
|
||||||
|
private String maxRetryCount;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
loginRecordCache = cacheManager.getCache("loginRecordCache");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(VipUser user, String password)
|
||||||
|
{
|
||||||
|
String loginName = user.getLoginName();
|
||||||
|
|
||||||
|
AtomicInteger retryCount = loginRecordCache.get(loginName);
|
||||||
|
|
||||||
|
if (retryCount == null)
|
||||||
|
{
|
||||||
|
retryCount = new AtomicInteger(0);
|
||||||
|
loginRecordCache.put(loginName, retryCount);
|
||||||
|
}
|
||||||
|
if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue())
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount)));
|
||||||
|
throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matches(user, password))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", retryCount)));
|
||||||
|
loginRecordCache.put(loginName, retryCount);
|
||||||
|
throw new UserPasswordNotMatchException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clearLoginRecordCache(loginName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(VipUser user, String newPassword)
|
||||||
|
{
|
||||||
|
return user.getPassword().equals(encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearLoginRecordCache(String username)
|
||||||
|
{
|
||||||
|
loginRecordCache.remove(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String encryptPassword(String username, String password, String salt)
|
||||||
|
{
|
||||||
|
return new Md5Hash(username + password + salt).toHex().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
package com.ruoyi.vip.framework;
|
||||||
|
|
||||||
|
import com.ruoyi.framework.shiro.service.SysLoginService;
|
||||||
|
import com.ruoyi.framework.web.exception.user.*;
|
||||||
|
import com.ruoyi.framework.web.util.ShiroUtils;
|
||||||
|
import com.ruoyi.system.domain.SysUser;
|
||||||
|
import com.ruoyi.system.service.ISysMenuService;
|
||||||
|
import com.ruoyi.system.service.ISysRoleService;
|
||||||
|
import com.ruoyi.vip.domain.VipUser;
|
||||||
|
import com.ruoyi.vip.utils.VipUserUtils;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.authc.*;
|
||||||
|
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 org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义Realm 处理登录 权限
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class VipUserRealm extends AuthorizingRealm
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(VipUserRealm.class);
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VipLoginService vipLoginService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
|
||||||
|
{
|
||||||
|
VipUser user = VipUserUtils.getVipUser();
|
||||||
|
// 角色列表
|
||||||
|
Set<String> roles = new HashSet<String>();
|
||||||
|
// 功能列表
|
||||||
|
Set<String> menus = new HashSet<String>();
|
||||||
|
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录认证
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
|
||||||
|
{
|
||||||
|
UsernamePasswordByUserTypeToken upToken = (UsernamePasswordByUserTypeToken) token;
|
||||||
|
String username = upToken.getUsername();
|
||||||
|
String password = "";
|
||||||
|
if (upToken.getPassword() != null)
|
||||||
|
{
|
||||||
|
password = new String(upToken.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
VipUser user = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
user = vipLoginService.login(username, password);
|
||||||
|
}
|
||||||
|
catch (CaptchaException e)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (UserNotExistsException e)
|
||||||
|
{
|
||||||
|
throw new UnknownAccountException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (UserPasswordNotMatchException e)
|
||||||
|
{
|
||||||
|
throw new IncorrectCredentialsException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (UserPasswordRetryLimitExceedException e)
|
||||||
|
{
|
||||||
|
throw new ExcessiveAttemptsException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (UserBlockedException e)
|
||||||
|
{
|
||||||
|
throw new LockedAccountException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (RoleBlockedException e)
|
||||||
|
{
|
||||||
|
throw new LockedAccountException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
|
||||||
|
throw new AuthenticationException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理缓存权限
|
||||||
|
*/
|
||||||
|
public void clearCachedAuthorizationInfo()
|
||||||
|
{
|
||||||
|
this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.ruoyi.vip.utils;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.utils.bean.BeanUtils;
|
||||||
|
import com.ruoyi.framework.shiro.realm.UserRealm;
|
||||||
|
import com.ruoyi.vip.domain.VipUser;
|
||||||
|
import org.apache.shiro.SecurityUtils;
|
||||||
|
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
|
||||||
|
import org.apache.shiro.mgt.RealmSecurityManager;
|
||||||
|
import org.apache.shiro.session.Session;
|
||||||
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
|
import org.apache.shiro.subject.SimplePrincipalCollection;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shiro 工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class VipUserUtils
|
||||||
|
{
|
||||||
|
public static Subject getSubjct()
|
||||||
|
{
|
||||||
|
return SecurityUtils.getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Session getSession()
|
||||||
|
{
|
||||||
|
return SecurityUtils.getSubject().getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void logout()
|
||||||
|
{
|
||||||
|
getSubjct().logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VipUser getVipUser()
|
||||||
|
{
|
||||||
|
VipUser user = null;
|
||||||
|
Object obj = getSubjct().getPrincipal();
|
||||||
|
if (StringUtils.isNotNull(obj))
|
||||||
|
{
|
||||||
|
user = new VipUser();
|
||||||
|
BeanUtils.copyBeanProp(user, obj);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVipUser(VipUser user)
|
||||||
|
{
|
||||||
|
Subject subject = getSubjct();
|
||||||
|
PrincipalCollection principalCollection = subject.getPrincipals();
|
||||||
|
String realmName = principalCollection.getRealmNames().iterator().next();
|
||||||
|
PrincipalCollection newPrincipalCollection = new SimplePrincipalCollection(user, realmName);
|
||||||
|
// 重新加载Principal
|
||||||
|
subject.runAs(newPrincipalCollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearCachedAuthorizationInfo()
|
||||||
|
{
|
||||||
|
RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
|
||||||
|
UserRealm realm = (UserRealm) rsm.getRealms().iterator().next();
|
||||||
|
realm.clearCachedAuthorizationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Long getUserId()
|
||||||
|
{
|
||||||
|
return getVipUser().getId().longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLoginName()
|
||||||
|
{
|
||||||
|
return getVipUser().getLoginName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getIp()
|
||||||
|
{
|
||||||
|
return getSubjct().getSession().getHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSessionId()
|
||||||
|
{
|
||||||
|
return String.valueOf(getSubjct().getSession().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机盐
|
||||||
|
*/
|
||||||
|
public static String randomSalt()
|
||||||
|
{
|
||||||
|
// 一个Byte占两个字节,此处生成的3字节,字符串长度为6
|
||||||
|
SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();
|
||||||
|
String hex = secureRandom.nextBytes(3).toHex();
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue