├── .gitignore ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── example │ │ └── demo │ │ ├── DemoApplication.java │ │ ├── VO │ │ └── USerAddVO.java │ │ ├── base_controller │ │ ├── AppBaseController.java │ │ └── BaseController.java │ │ ├── base_security │ │ ├── VO │ │ │ ├── RoleAddVO.java │ │ │ ├── RoleUpdateVO.java │ │ │ └── registerVO.java │ │ ├── annotation │ │ │ ├── AccessLimit.java │ │ │ ├── CurrentUser.java │ │ │ ├── Log.java │ │ │ ├── ParamXssPass.java │ │ │ ├── Pass.java │ │ │ └── ValidationParam.java │ │ ├── captha │ │ │ ├── CaptchaClient.java │ │ │ ├── bean │ │ │ │ └── CaptchaBean.java │ │ │ ├── service │ │ │ │ ├── AbstractCaptchaService.java │ │ │ │ ├── ICaptchaService.java │ │ │ │ └── SimpleCaptchaService.java │ │ │ └── strategy │ │ │ │ ├── CalculateCaptchaStrategy.java │ │ │ │ ├── ChineseCaptchaStrategy.java │ │ │ │ ├── ICaptchaStrategy.java │ │ │ │ └── SimpleCaptchaStrategy.java │ │ ├── commons │ │ │ ├── Constant.java │ │ │ └── PublicResultConstant.java │ │ ├── config │ │ │ ├── CurrentUserMethodArgumentResolver.java │ │ │ ├── JWTFilter.java │ │ │ ├── JWTToken.java │ │ │ ├── MyRealm.java │ │ │ ├── ResponseHelper.java │ │ │ ├── ShiroConfig.java │ │ │ └── SpringContextBeanService.java │ │ ├── controller │ │ │ └── LoginController.java │ │ └── util │ │ │ ├── ComUtil.java │ │ │ ├── DateTimeUtil.java │ │ │ ├── FileUtil.java │ │ │ ├── JWTUtil.java │ │ │ ├── ResponseModel.java │ │ │ └── StringUtil.java │ │ ├── commons │ │ ├── Constants.java │ │ └── HttpStatus.java │ │ ├── config │ │ ├── LiquibaseConfig.java │ │ ├── MybatisPlusConfiguration.java │ │ └── SwaggerConfiguration.java │ │ ├── controller │ │ ├── SysLogController.java │ │ ├── SysResController.java │ │ ├── SysRoleController.java │ │ ├── SysRoleResController.java │ │ ├── SysUserController.java │ │ └── SysUserRoleController.java │ │ ├── entity │ │ ├── SysLog.java │ │ ├── SysRes.java │ │ ├── SysRole.java │ │ ├── SysRoleRes.java │ │ ├── SysUser.java │ │ └── SysUserRole.java │ │ ├── mapper │ │ ├── SysLogMapper.java │ │ ├── SysResMapper.java │ │ ├── SysRoleMapper.java │ │ ├── SysRoleResMapper.java │ │ ├── SysUserMapper.java │ │ └── SysUserRoleMapper.java │ │ ├── service │ │ ├── SysLogService.java │ │ ├── SysResService.java │ │ ├── SysRoleResService.java │ │ ├── SysRoleService.java │ │ ├── SysUserRoleService.java │ │ ├── SysUserService.java │ │ └── impl │ │ │ ├── SysLogServiceImpl.java │ │ │ ├── SysResServiceImpl.java │ │ │ ├── SysRoleResServiceImpl.java │ │ │ ├── SysRoleServiceImpl.java │ │ │ ├── SysUserRoleServiceImpl.java │ │ │ └── SysUserServiceImpl.java │ │ └── utils │ │ ├── CurrentUserUtils.java │ │ ├── DateUtils.java │ │ └── JpushClientUtil.java └── resources │ ├── application-dev.yml │ ├── application-local.yml │ ├── application.yml │ ├── mapper │ ├── SysLogMapper.xml │ ├── SysResMapper.xml │ ├── SysRoleMapper.xml │ ├── SysRoleResMapper.xml │ ├── SysUserMapper.xml │ └── SysUserRoleMapper.xml │ └── migrates │ ├── init │ ├── db.changelog.xml │ └── db.data.initlog.xml │ └── master.xml └── test └── java └── com └── example └── demo └── DemoApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | .mvn 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | 28 | ### VS Code ### 29 | .vscode/ 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##项目架构简介: 2 | 完全是采用Springboot为基础框架实现的单体工程架构,集成了各种当前主流插件,使得框架更加的健壮和简洁,具体集成的插件如下. 3 | 4 | ##集成插件:(可以根据需要再添加) 5 | (springboot+redis+mybatis+mybatis-plus+lombok+liquibase+shiro+jwt+swagger) 6 | 7 | 1.mybatis-plus: 8 | 几乎实现涵盖了所有的单表操作和分页操作 9 | 10 | 2.liquibase: 11 | 数据库迁移工具:初始化表和初始化数据,修改表字段和修改数据的管理工具 12 | 13 | 3.shiro+jwt: 14 | 权限认证系统:基于方法级别的权限校验,实现token代替session进行鉴权 15 | 16 | 4.swagger-ui: 17 | 实现前后端动态可视化数据交互及接口对接 18 | 19 | 5.lombok: 20 | 简化bean对象的生成 21 | 22 | 6.逆向工程: 23 | 实现表结构到实体,service,mapper,xml等文件的生成。 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.4.RELEASE 9 | 10 | 11 | com.example 12 | springboot-demo 13 | 0.1 14 | demo 15 | springboot案例 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-jdbc 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | org.mybatis.spring.boot 32 | mybatis-spring-boot-starter 33 | 2.0.1 34 | 35 | 36 | org.projectlombok 37 | lombok 38 | true 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-test 43 | test 44 | 45 | 46 | com.alibaba 47 | druid 48 | 1.1.12 49 | 50 | 51 | mysql 52 | mysql-connector-java 53 | 5.1.46 54 | 55 | 56 | com.baomidou 57 | mybatis-plus-boot-starter 58 | 3.1.1 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-data-redis 63 | 2.1.4.RELEASE 64 | 65 | 66 | 67 | org.liquibase 68 | liquibase-core 69 | 3.5.3 70 | 71 | 72 | 73 | io.springfox 74 | springfox-swagger2 75 | 2.8.0 76 | 77 | 78 | io.springfox 79 | springfox-swagger-ui 80 | 2.8.0 81 | 82 | 83 | org.apache.commons 84 | commons-collections4 85 | 4.1 86 | 87 | 88 | com.google.guava 89 | guava 90 | 23.0 91 | 92 | 93 | org.apache.commons 94 | commons-lang3 95 | 3.8.1 96 | 97 | 98 | 99 | org.apache.shiro 100 | shiro-spring 101 | 1.4.0 102 | 103 | 104 | com.auth0 105 | java-jwt 106 | 3.3.0 107 | 108 | 109 | 110 | org.springframework.boot 111 | spring-boot-devtools 112 | 2.0.4.RELEASE 113 | provided 114 | true 115 | 116 | 117 | 118 | com.alibaba 119 | fastjson 120 | 1.2.54 121 | 122 | 123 | 124 | org.apache.ant 125 | ant 126 | 1.10.1 127 | 128 | 129 | com.belerweb 130 | pinyin4j 131 | 2.5.0 132 | 133 | 134 | 135 | net.coobird 136 | thumbnailator 137 | 0.4.8 138 | 139 | 140 | com.github.t3hnar 141 | scala-bcrypt_2.10 142 | 3.1 143 | 144 | 145 | joda-time 146 | joda-time 147 | 2.9.9 148 | 149 | 150 | 151 | 152 | 153 | 154 | org.springframework.boot 155 | spring-boot-maven-plugin 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | import org.mybatis.spring.annotation.MapperScan; 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.web.servlet.ServletComponentScan; 6 | import org.springframework.data.redis.core.StringRedisTemplate; 7 | 8 | @ServletComponentScan 9 | @SpringBootApplication 10 | @MapperScan("com.example.demo.mapper") 11 | public class DemoApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(DemoApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/VO/USerAddVO.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.VO; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import io.swagger.annotations.ApiModel; 5 | import io.swagger.annotations.ApiModelProperty; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotNull; 11 | import java.io.Serializable; 12 | import java.util.Date; 13 | 14 | /** 15 | * @author liuxinghong 16 | * @Description: 17 | * @date 2019/5/7 000710:53 18 | */ 19 | @Data 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | @ApiModel("添加用户") 23 | public class USerAddVO implements Serializable { 24 | 25 | @ApiModelProperty("用户编号") 26 | @NotNull(message = "编号不能为空!") 27 | private String userNo; 28 | @ApiModelProperty("手机号码") 29 | private String mobileNo; 30 | /** 31 | * 登录用户名 32 | */ 33 | @ApiModelProperty("用户名") 34 | private String loginName; 35 | 36 | @ApiModelProperty("姓名") 37 | private String name; 38 | /** 39 | * 登录密码 40 | */ 41 | @ApiModelProperty("密码") 42 | private String pwd; 43 | /** 44 | * 微信号 45 | */ 46 | @ApiModelProperty("微信号") 47 | private String weixinId; 48 | /** 49 | * 注册时间 50 | */ 51 | @ApiModelProperty("注册时间") 52 | private Date regTime; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_controller/AppBaseController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_controller; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 4 | import com.example.demo.commons.HttpStatus; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.google.common.base.Joiner; 7 | import com.google.common.collect.Lists; 8 | import com.google.common.collect.Maps; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.http.MediaType; 13 | import org.springframework.http.ResponseEntity; 14 | import org.springframework.validation.BindingResult; 15 | import org.springframework.validation.FieldError; 16 | import org.springframework.web.bind.MethodArgumentNotValidException; 17 | import org.springframework.web.bind.ServletRequestBindingException; 18 | import org.springframework.web.bind.annotation.ExceptionHandler; 19 | 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | /** 26 | * 基础Controller 27 | * @author lxh 28 | */ 29 | public class AppBaseController { 30 | 31 | private static final Logger LOGGER = LoggerFactory.getLogger(AppBaseController.class); 32 | 33 | 34 | private static final String TOKEN_NON_EXISTENT = "Missing cookie 'token'"; 35 | 36 | /** 设置成功响应 */ 37 | protected ResponseEntity success(Object data) { 38 | return responseEntity(HttpStatus.OK,data,HttpStatus.OK.msg()); 39 | } 40 | 41 | protected ResponseEntity success(String msg) { 42 | return responseEntity(HttpStatus.OK,null,msg); 43 | } 44 | 45 | protected ResponseEntity success() { 46 | return responseEntity(HttpStatus.OK,null,HttpStatus.OK.msg()); 47 | } 48 | 49 | protected ResponseEntity success(Object data, String msg) { 50 | return responseEntity(HttpStatus.OK,data,msg); 51 | } 52 | 53 | /** 设置失败响应 */ 54 | protected ResponseEntity error(Object data) { 55 | return responseEntity(HttpStatus.BAD_REQUEST,data,HttpStatus.BAD_REQUEST.msg()); 56 | } 57 | 58 | protected ResponseEntity error(String msg) { 59 | return responseEntity(HttpStatus.BAD_REQUEST,null,msg); 60 | } 61 | 62 | protected ResponseEntity error(HttpStatus code ){ 63 | return responseEntity(code,null,code.msg()); 64 | } 65 | 66 | protected ResponseEntity error() { 67 | return responseEntity(HttpStatus.BAD_REQUEST,null,HttpStatus.BAD_REQUEST.msg()); 68 | } 69 | 70 | protected ResponseEntity error(Object data, String msg) { 71 | return responseEntity(HttpStatus.BAD_REQUEST,data,msg); 72 | } 73 | 74 | /** 设置响应代码 */ 75 | protected ResponseEntity responseEntity(HttpStatus code, Object data, String msg) { 76 | Map map = Maps.newHashMap(); 77 | if (data != null) { 78 | if (data instanceof Page) { 79 | Page page = (Page) data; 80 | map.put("data", page.getRecords()); 81 | map.put("current", page.getCurrent()); 82 | map.put("size", page.getSize()); 83 | map.put("pages", page.getPages()); 84 | map.put("total", page.getTotal()); 85 | } else if (data instanceof List) { 86 | map.put("data", data); 87 | } else { 88 | map.put("data", data); 89 | } 90 | } 91 | map.put("code", code.value()); 92 | map.put("msg", msg); 93 | map.put("timestamp", System.currentTimeMillis()); 94 | return ResponseEntity.ok() 95 | .header("Access-Control-Allow-Origin","*") 96 | .contentType(MediaType.APPLICATION_JSON) 97 | .body(map); 98 | } 99 | 100 | /** 异常处理 */ 101 | @ExceptionHandler(Exception.class) 102 | public void exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) 103 | throws Exception { 104 | Map map = Maps.newHashMap(); 105 | /*if (ex instanceof AuthorizationException){ 106 | status = HttpStatus.FORBIDDEN.value(); 107 | map.put("code", HttpStatus.FORBIDDEN.value()); 108 | map.put("msg", HttpStatus.FORBIDDEN.msg()); 109 | } else if (ex instanceof UnauthorizedException) { 110 | status = HttpStatus.FORBIDDEN.value(); 111 | map.put("code", HttpStatus.FORBIDDEN.value()); 112 | map.put("msg", HttpStatus.FORBIDDEN.msg()); 113 | } else if(ex instanceof LoginException){ 114 | status = HttpStatus.FORBIDDEN.value(); 115 | map.put("code", HttpStatus.LOGIN_FAIL.value()); 116 | map.put("msg", ex.getMessage()); 117 | } else if(ex instanceof UploadException){ 118 | status = HttpStatus.INTERNAL_SERVER_ERROR.value(); 119 | map.put("code", HttpStatus.V5_UPLOAD_FAIL.value()); 120 | map.put("msg", ex.getMessage()); 121 | } else if(ex instanceof TokenParserException) { 122 | status = HttpStatus.FORBIDDEN.value(); 123 | map.put("code", HttpStatus.TOKEN_PARSER_FAIL.value()); 124 | map.put("msg", ex.getMessage());*/ 125 | if(ex instanceof MethodArgumentNotValidException){ 126 | map.put("code", HttpStatus.VALIDATED_FAIL.value()); 127 | MethodArgumentNotValidException mane = (MethodArgumentNotValidException)ex; 128 | BindingResult bindingResult = mane.getBindingResult(); 129 | List errorMessage = Lists.newArrayList(); 130 | List fes = bindingResult.getFieldErrors(); 131 | for (FieldError fe : fes) { 132 | errorMessage.add(fe.getDefaultMessage()); 133 | } 134 | map.put("msg", Joiner.on(",").join(errorMessage)); 135 | } else if(ex instanceof ServletRequestBindingException) { 136 | if(StringUtils.contains(ex.getMessage(),TOKEN_NON_EXISTENT)) { 137 | map.put("code", HttpStatus.UNAUTHORIZED.value()); 138 | map.put("msg",ex.getMessage()); 139 | } 140 | } else if(ex instanceof RuntimeException) { 141 | map.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); 142 | map.put("msg",ex.getMessage()); 143 | } else { 144 | map.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); 145 | map.put("msg", HttpStatus.INTERNAL_SERVER_ERROR.msg()); 146 | } 147 | 148 | ex.printStackTrace(); 149 | LOGGER.error(ex.getMessage(),ex); 150 | response.setContentType("application/json;charset=UTF-8"); 151 | response.setHeader("Access-Control-Allow-Origin","*"); 152 | response.setStatus(200); 153 | map.put("timestamp", System.currentTimeMillis()); 154 | response.getOutputStream().write(new ObjectMapper().writeValueAsString(map).getBytes()); 155 | } 156 | 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_controller/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_controller; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 4 | import com.example.demo.commons.HttpStatus; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.google.common.base.Joiner; 7 | import com.google.common.collect.Lists; 8 | import com.google.common.collect.Maps; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.apache.shiro.authz.UnauthorizedException; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.http.MediaType; 14 | import org.springframework.http.ResponseEntity; 15 | import org.springframework.validation.BindingResult; 16 | import org.springframework.validation.FieldError; 17 | import org.springframework.web.bind.MethodArgumentNotValidException; 18 | import org.springframework.web.bind.ServletRequestBindingException; 19 | import org.springframework.web.bind.annotation.ExceptionHandler; 20 | 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpServletResponse; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | /** 27 | * 基础Controller 28 | * @author lxh 29 | */ 30 | public class BaseController { 31 | 32 | 33 | private static final Logger LOGGER = LoggerFactory.getLogger(BaseController.class); 34 | 35 | private static final String TOKEN_NON_EXISTENT = "Missing cookie 'token'"; 36 | 37 | /** 设置成功响应 */ 38 | protected ResponseEntity success(Object data) { 39 | return responseEntity(HttpStatus.OK,data,HttpStatus.OK.msg()); 40 | } 41 | 42 | protected ResponseEntity success(String msg) { 43 | return responseEntity(HttpStatus.OK,null,msg); 44 | } 45 | 46 | protected ResponseEntity success() { 47 | return responseEntity(HttpStatus.OK,null,HttpStatus.OK.msg()); 48 | } 49 | 50 | protected ResponseEntity success(Object data, String msg) { 51 | return responseEntity(HttpStatus.OK,data,msg); 52 | } 53 | 54 | /** 设置失败响应 */ 55 | protected ResponseEntity error(Object data) { 56 | return responseEntity(HttpStatus.BAD_REQUEST,data,HttpStatus.BAD_REQUEST.msg()); 57 | } 58 | 59 | protected ResponseEntity error(String msg) { 60 | return responseEntity(HttpStatus.BAD_REQUEST,null,msg); 61 | } 62 | 63 | protected ResponseEntity error(HttpStatus code ){ 64 | return responseEntity(code,null,code.msg()); 65 | } 66 | 67 | protected ResponseEntity error() { 68 | return responseEntity(HttpStatus.BAD_REQUEST,null,HttpStatus.BAD_REQUEST.msg()); 69 | } 70 | 71 | protected ResponseEntity error(Object data, String msg) { 72 | return responseEntity(HttpStatus.BAD_REQUEST,data,msg); 73 | } 74 | 75 | /** 设置响应代码 */ 76 | protected ResponseEntity responseEntity(HttpStatus code, Object data, String msg) { 77 | Map map = Maps.newHashMap(); 78 | if (data != null) { 79 | if (data instanceof Page) { 80 | Page page = (Page) data; 81 | map.put("data", page.getRecords()); 82 | map.put("current", page.getCurrent()); 83 | map.put("size", page.getSize()); 84 | map.put("pages", page.getPages()); 85 | map.put("total", page.getTotal()); 86 | } else if (data instanceof List) { 87 | map.put("data", data); 88 | } else { 89 | map.put("data", data); 90 | } 91 | } 92 | map.put("code", code.value()); 93 | map.put("msg", msg); 94 | map.put("timestamp", System.currentTimeMillis()); 95 | return ResponseEntity.ok() 96 | .header("Access-Control-Allow-Origin","*") 97 | .contentType(MediaType.APPLICATION_JSON) 98 | .body(map); 99 | } 100 | 101 | /** 异常处理 */ 102 | @ExceptionHandler(Exception.class) 103 | public void exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) 104 | throws Exception { 105 | Map map = Maps.newHashMap(); 106 | int status = 0; 107 | // 方法级别shiro权限校验失败时异常信息处理 108 | if(ex instanceof MethodArgumentNotValidException){ 109 | status = HttpStatus.INTERNAL_SERVER_ERROR.value(); 110 | map.put("code", HttpStatus.VALIDATED_FAIL.value()); 111 | MethodArgumentNotValidException mane = (MethodArgumentNotValidException)ex; 112 | BindingResult bindingResult = mane.getBindingResult(); 113 | List errorMessage = Lists.newArrayList(); 114 | List fes = bindingResult.getFieldErrors(); 115 | for (FieldError fe : fes) { 116 | errorMessage.add(fe.getDefaultMessage()); 117 | } 118 | map.put("msg", Joiner.on(",").join(errorMessage)); 119 | } else if(ex instanceof ServletRequestBindingException) { 120 | status = HttpStatus.INTERNAL_SERVER_ERROR.value(); 121 | if(StringUtils.contains(ex.getMessage(),TOKEN_NON_EXISTENT)) { 122 | status = HttpStatus.UNAUTHORIZED.value(); 123 | map.put("code", HttpStatus.UNAUTHORIZED.value()); 124 | String message = StringUtils.isEmpty(ex.getMessage()) ? ex.getCause().getMessage() : ex.getMessage(); 125 | map.put("msg",message); 126 | } 127 | }else if(ex instanceof UnauthorizedException) {//登录权限异常 128 | status = HttpStatus.UNAUTHORIZED.value(); 129 | map.put("code", HttpStatus.UNAUTHORIZED.value()); 130 | String message = StringUtils.isEmpty(ex.getMessage()) ? ex.getCause().getMessage() : ex.getMessage(); 131 | map.put("msg",message); 132 | }else if(ex instanceof RuntimeException) { 133 | status = HttpStatus.INTERNAL_SERVER_ERROR.value(); 134 | map.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); 135 | String message = StringUtils.isEmpty(ex.getMessage()) ? ex.getCause().getMessage() : ex.getMessage(); 136 | map.put("msg",message); 137 | } 138 | 139 | 140 | if(status == 0) { 141 | status = HttpStatus.INTERNAL_SERVER_ERROR.value(); 142 | map.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); 143 | map.put("msg", HttpStatus.INTERNAL_SERVER_ERROR.msg()); 144 | } 145 | ex.printStackTrace(); 146 | LOGGER.error(ex.getMessage(),ex); 147 | response.setContentType("application/json;charset=UTF-8"); 148 | response.setHeader("Access-Control-Allow-Origin","*"); 149 | response.setStatus(status); 150 | map.put("timestamp", System.currentTimeMillis()); 151 | response.getOutputStream().write(new ObjectMapper().writeValueAsString(map).getBytes()); 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/VO/RoleAddVO.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.VO; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * Mapper 接口 13 | *

14 | * 15 | * @author liugh 16 | * @since 2018-06-30 17 | */ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | public class RoleAddVO implements Serializable { 22 | private String roleName; 23 | private String roleCode; 24 | private List menuIds; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/VO/RoleUpdateVO.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.VO; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotNull; 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | /** 10 | * @author liuxinghong 11 | * @Description: 12 | * @date 2019/5/15 001518:25 13 | */ 14 | @Data 15 | public class RoleUpdateVO implements Serializable { 16 | @NotNull() 17 | private String id; 18 | private String name; 19 | private String code; 20 | private Integer sortNum; 21 | private String des; 22 | private List menuIds; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/VO/registerVO.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.VO; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import lombok.Data; 5 | 6 | import javax.validation.constraints.NotNull; 7 | import javax.validation.constraints.Pattern; 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @author liuxinghong 12 | * @Description: 注册接口 13 | * @date 2019/5/15 001517:09 14 | */ 15 | @Data 16 | public class registerVO implements Serializable { 17 | 18 | /** 19 | * 用户名 20 | */ 21 | @NotNull(message = "用户名不能为空") 22 | private String loginName; 23 | /** 24 | * 用户编号 25 | */ 26 | private String userNo; 27 | /** 28 | * 用户密码 29 | */ 30 | @NotNull(message = "密码不能为空") 31 | private String pwd; 32 | 33 | private String salt; 34 | /** 35 | * 姓名 36 | */ 37 | @NotNull(message = "名称不能为空") 38 | private String name; 39 | /** 40 | * 邮箱 41 | */ 42 | private String email; 43 | /** 44 | * 1:男,0:女 45 | */ 46 | private Integer sex; 47 | /** 48 | * 手机号 49 | */ 50 | @NotNull(message = "手机号不能为空") 51 | @Pattern(regexp = "^1[345789]\\d{9}$",message = "手机号格式不正确!") 52 | private String mobileNo; 53 | /** 54 | * 微信号 55 | */ 56 | private String weixinId; 57 | /** 58 | * 头像 59 | */ 60 | private String avatar; 61 | 62 | /** 63 | * 验证码 64 | */ 65 | private String captcha; 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/annotation/AccessLimit.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.annotation; 2 | 3 | import java.lang.annotation.*; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | /** 7 | * Created by liugh on 2018/10/12. 8 | */ 9 | @Target( { ElementType.METHOD } ) 10 | @Retention( RetentionPolicy.RUNTIME ) 11 | @Documented 12 | public @interface AccessLimit { 13 | /** 14 | * 每秒向桶中放入令牌的数量 默认最大即不做限流 15 | * @return 16 | */ 17 | double perSecond() default Double.MAX_VALUE; 18 | 19 | /** 20 | * 获取令牌的等待时间 默认0 21 | * @return 22 | */ 23 | int timeOut() default 0; 24 | 25 | /** 26 | * 超时时间单位 27 | * @return 28 | */ 29 | TimeUnit timeOutUnit() default TimeUnit.MILLISECONDS; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/annotation/CurrentUser.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.annotation; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * 在Controller的方法参数中使用此注解,该方法在映射时会注入当前登录的User对象 11 | * @author : liugh 12 | * @date : 2018/05/08 13 | */ 14 | @Target(ElementType.PARAMETER) // 可用在方法的参数上 15 | @Retention(RetentionPolicy.RUNTIME) // 运行时有效 16 | public @interface CurrentUser { 17 | } -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/annotation/Log.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.annotation; 2 | 3 | 4 | import java.lang.annotation.*; 5 | 6 | /** 7 | * 在Controller方法上加入改注解会自动记录日志 8 | * @author : liugh 9 | * @date : 2018/05/08 10 | */ 11 | @Target( { ElementType.METHOD } ) 12 | @Retention( RetentionPolicy.RUNTIME ) 13 | @Documented 14 | public @interface Log { 15 | 16 | /** 17 | * 模块名称 18 | */ 19 | String modelName() default ""; 20 | 21 | /** 22 | * 操作 23 | */ 24 | String action()default ""; 25 | /** 26 | * 描述. 27 | */ 28 | String description() default ""; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/annotation/ParamXssPass.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.annotation; 2 | 3 | 4 | import java.lang.annotation.*; 5 | 6 | /** 7 | * 在Controller方法上加入该注解不会转义参数, 8 | * 如果不加该注解则会: --> <script>alert(1)<script> 9 | * @author liugh 10 | * @since on 2018/6/27. 11 | */ 12 | @Target( { ElementType.METHOD } ) 13 | @Retention( RetentionPolicy.RUNTIME ) 14 | @Documented 15 | public @interface ParamXssPass { 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/annotation/Pass.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.annotation; 2 | 3 | 4 | import java.lang.annotation.*; 5 | 6 | /** 7 | * 在Controller方法上加入该注解不会验证身份 8 | * @author : liugh 9 | * @date : 2018/05/08 10 | */ 11 | @Target( { ElementType.METHOD } ) 12 | @Retention( RetentionPolicy.RUNTIME ) 13 | @Documented 14 | public @interface Pass { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/annotation/ValidationParam.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author liugh 7 | * @since on 2018/5/9. 8 | */ 9 | @Target(ElementType.PARAMETER) // 可用在方法的参数上 10 | @Retention(RetentionPolicy.RUNTIME) // 运行时有效 11 | @Documented 12 | public @interface ValidationParam { 13 | /** 14 | * 必填参数 15 | */ 16 | String value() default ""; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/CaptchaClient.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | import com.example.demo.base_security.captha.service.SimpleCaptchaService; 6 | import com.example.demo.base_security.captha.strategy.ICaptchaStrategy; 7 | import com.example.demo.base_security.captha.strategy.SimpleCaptchaStrategy; 8 | 9 | import java.awt.*; 10 | 11 | /** 12 | * Nothing seek, Nothing find. 13 | * author: shuzhilong 14 | * Date: 2017/9/26 下午2:52 15 | * desc: (The role of this class is to ...) 16 | * To change this template use preferences | editor | File and code Templates 17 | */ 18 | public class CaptchaClient { 19 | private SimpleCaptchaService simpleCaptchaService; 20 | 21 | private CaptchaClient(int width, int height, int lineNum, float yawp, Color color 22 | , ICaptchaStrategy captchaStrategy, boolean transform) { 23 | this.simpleCaptchaService = new SimpleCaptchaService(width,height, 24 | lineNum,yawp,color,captchaStrategy,transform); 25 | } 26 | 27 | public CaptchaBean generate() { 28 | return simpleCaptchaService.generateCaptcha(); 29 | } 30 | 31 | public static Builder create() { 32 | return new Builder(); 33 | } 34 | 35 | public static final class Builder { 36 | private int width = 90; 37 | private int height = 30; 38 | private int lineNum = 2; 39 | private float yawp = 0.01f; 40 | Color color = new Color(253, 251, 255); 41 | ICaptchaStrategy captchaStrategy = new SimpleCaptchaStrategy(); 42 | private boolean transform=false; 43 | 44 | public Builder width(int width) { 45 | this.width = width; 46 | return this; 47 | } 48 | 49 | public Builder height(int height) { 50 | this.height = height; 51 | return this; 52 | } 53 | 54 | public Builder lineNum(int lineNum) { 55 | this.lineNum = lineNum; 56 | return this; 57 | } 58 | 59 | public Builder yawp(float yawp) { 60 | this.yawp = yawp; 61 | return this; 62 | } 63 | 64 | public Builder color(Color color) { 65 | this.color = color; 66 | return this; 67 | } 68 | 69 | public Builder transform(boolean transform) { 70 | this.transform = transform; 71 | return this; 72 | } 73 | 74 | public Builder captchaStrategy(ICaptchaStrategy captchaStrategy) { 75 | this.captchaStrategy = captchaStrategy; 76 | return this; 77 | } 78 | 79 | public CaptchaClient build() { 80 | return new CaptchaClient(width,height,lineNum,yawp,color,captchaStrategy,transform); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/bean/CaptchaBean.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.bean; 2 | 3 | import java.awt.image.BufferedImage; 4 | 5 | /** 6 | * Nothing seek, Nothing find. 7 | * author: shuzhilong 8 | * Date: 2017/9/26 下午3:34 9 | * desc: (The role of this class is to ...) 10 | * To change this template use preferences | editor | File and code Templates 11 | */ 12 | public class CaptchaBean { 13 | 14 | private String result; 15 | private String[] codeArray; 16 | private BufferedImage bufferedImage; 17 | 18 | public String getResult() { 19 | return result; 20 | } 21 | 22 | public void setResult(String result) { 23 | this.result = result; 24 | } 25 | 26 | public String[] getCodeArray() { 27 | return codeArray; 28 | } 29 | 30 | public void setCodeArray(String[] codeArray) { 31 | this.codeArray = codeArray; 32 | } 33 | 34 | public BufferedImage getBufferedImage() { 35 | return bufferedImage; 36 | } 37 | 38 | public void setBufferedImage(BufferedImage bufferedImage) { 39 | this.bufferedImage = bufferedImage; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/service/AbstractCaptchaService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.service; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | import com.example.demo.base_security.captha.strategy.ICaptchaStrategy; 6 | 7 | import java.awt.*; 8 | import java.awt.geom.AffineTransform; 9 | import java.awt.image.BufferedImage; 10 | import java.util.Random; 11 | 12 | /** 13 | * Nothing seek, Nothing find. 14 | * author: shuzhilong 15 | * Date: 2017/9/26 下午3:17 16 | * desc: (The role of this class is to ...) 17 | * To change this template use preferences | editor | File and code Templates 18 | */ 19 | public abstract class AbstractCaptchaService implements ICaptchaService { 20 | 21 | Random random = new Random(); 22 | ICaptchaStrategy captchaStrategy; 23 | 24 | int width = 90; 25 | int height = 30; 26 | int lineNum = 2; 27 | float yawp = 0.01f; 28 | Color color = new Color(253, 251, 255); 29 | boolean transform=false; 30 | 31 | public CaptchaBean generateCaptcha() { 32 | // 1.build image 33 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 34 | Graphics graphics = image.getGraphics(); 35 | graphics.setColor(color); 36 | // graphics.setColor(getRandColor(200, 250)); 37 | graphics.fillRect(0, 0, width, height); 38 | 39 | //2.mixSource 40 | mixSource(image); 41 | 42 | //3.drawCode 43 | CaptchaBean result = drawCode(graphics); 44 | result.setBufferedImage(image); 45 | return result; 46 | } 47 | 48 | public void mixSource(BufferedImage image) { 49 | drawPoint(image); 50 | drawLine(image); 51 | drawOther(image); 52 | } 53 | 54 | public void drawLine(BufferedImage image) { 55 | Graphics graphics = image.getGraphics(); 56 | for (int i = 0; i < lineNum; i++) { 57 | int xs = random.nextInt(width); 58 | int ys = random.nextInt(height); 59 | int xe = xs + random.nextInt(width); 60 | int ye = ys + random.nextInt(height); 61 | graphics.setColor(getRandColor(1, 255)); 62 | graphics.drawLine(xs, ys, xe, ye); 63 | } 64 | } 65 | 66 | public void drawPoint(BufferedImage image) { 67 | // 添加噪点 68 | float yawpRate = 0.05f;// 噪声率 69 | int area = (int) (yawpRate * width * height); 70 | for (int i = 0; i < area; i++) { 71 | int x = random.nextInt(width); 72 | int y = random.nextInt(height); 73 | image.setRGB(x, y, random.nextInt(255)); 74 | } 75 | } 76 | 77 | public abstract void drawOther(BufferedImage image); 78 | 79 | public CaptchaBean drawCode(Graphics graphics) { 80 | //1.genarate code 81 | CaptchaBean captcha = captchaStrategy.generateCode(); 82 | 83 | //2.drapCode 84 | Font font = getFont(16); 85 | graphics.setFont(font); 86 | if(captcha!=null&&captcha.getCodeArray()!=null 87 | &&captcha.getResult()!=null&&captcha.getCodeArray().length>0) { 88 | for(int i=0;i 255) 119 | fc = 255; 120 | if (bc > 255) 121 | bc = 255; 122 | int r = fc + random.nextInt(bc - fc); 123 | int g = fc + random.nextInt(bc - fc); 124 | int b = fc + random.nextInt(bc - fc); 125 | return new Color(r, g, b); 126 | } 127 | 128 | private Font getFont(int size) { 129 | Random random = new Random(); 130 | Font font[] = new Font[5]; 131 | font[0] = new Font("Ravie", Font.BOLD, size); 132 | font[1] = new Font("Antique Olive Compact", Font.BOLD, size); 133 | font[2] = new Font("Fixedsys", Font.BOLD, size); 134 | font[3] = new Font("Wide Latin", Font.BOLD, size); 135 | font[4] = new Font("Gill Sans Ultra Bold", Font.BOLD, size); 136 | return font[random.nextInt(5)]; 137 | } 138 | 139 | public void setCaptchaStrategy(ICaptchaStrategy captchaStrategy) { 140 | this.captchaStrategy = captchaStrategy; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/service/ICaptchaService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.service; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | 6 | /** 7 | * Nothing seek, Nothing find. 8 | * author: shuzhilong 9 | * Date: 2017/9/26 下午3:09 10 | * desc: (The role of this class is to ...) 11 | * To change this template use preferences | editor | File and code Templates 12 | */ 13 | public interface ICaptchaService { 14 | 15 | CaptchaBean generateCaptcha(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/service/SimpleCaptchaService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.service; 2 | 3 | 4 | import com.example.demo.base_security.captha.strategy.ICaptchaStrategy; 5 | 6 | import java.awt.*; 7 | import java.awt.image.BufferedImage; 8 | 9 | /** 10 | * Nothing seek, Nothing find. 11 | * author: shuzhilong 12 | * Date: 2017/9/26 下午4:33 13 | * desc: (The role of this class is to ...) 14 | * To change this template use preferences | editor | File and code Templates 15 | */ 16 | public class SimpleCaptchaService extends AbstractCaptchaService { 17 | 18 | public SimpleCaptchaService(int width, int height, int linNum, float yawp, 19 | Color color, ICaptchaStrategy captchaStrategy, boolean transform) { 20 | this.width = width; 21 | this.height = height; 22 | this.lineNum = linNum; 23 | this.yawp = yawp; 24 | this.color = color; 25 | this.transform = transform; 26 | this.captchaStrategy = captchaStrategy; 27 | } 28 | 29 | @Override 30 | public void drawOther(BufferedImage image) { 31 | //do something 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/strategy/CalculateCaptchaStrategy.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.strategy; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | 6 | import java.util.Random; 7 | 8 | /** 9 | * Nothing seek, Nothing find. 10 | * author: shuzhilong 11 | * Date: 2017/9/26 下午3:03 12 | * desc: (The role of this class is to ...) 13 | * To change this template use preferences | editor | File and code Templates 14 | */ 15 | public class CalculateCaptchaStrategy implements ICaptchaStrategy { 16 | 17 | private int codecnt=4; 18 | 19 | public CalculateCaptchaStrategy() { 20 | } 21 | 22 | public CaptchaBean generateCode() { 23 | CaptchaBean captchaBean = new CaptchaBean(); 24 | String[] codeArray = new String[codecnt]; 25 | int result=0; 26 | 27 | char[] op = "+-".toCharArray(); 28 | Random r = new Random(); 29 | 30 | int firstNum = r.nextInt(100); 31 | codeArray[0] = String.valueOf(firstNum); 32 | 33 | int index = r.nextInt(2); 34 | char operation = op[index]; 35 | codeArray[1] = String.valueOf(operation); 36 | 37 | int secondNum = r.nextInt(100); 38 | codeArray[2] = String.valueOf(secondNum); 39 | 40 | codeArray[3] = String.valueOf("="); 41 | 42 | if (operation == '+') { 43 | result = firstNum+secondNum; 44 | } else if (operation == '-') { 45 | result = firstNum-secondNum; 46 | } 47 | // else if (operation == '*') { 48 | // result = firstNum*secondNum; 49 | // } 50 | captchaBean.setCodeArray(codeArray); 51 | captchaBean.setResult(String.valueOf(result)); 52 | return captchaBean; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/strategy/ChineseCaptchaStrategy.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.strategy; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | 6 | import java.util.Random; 7 | 8 | /** 9 | * Nothing seek, Nothing find. 10 | * author: shuzhilong 11 | * Date: 2017/9/26 下午3:02 12 | * desc: (The role of this class is to ...) 13 | * To change this template use preferences | editor | File and code Templates 14 | */ 15 | public class ChineseCaptchaStrategy implements ICaptchaStrategy { 16 | private int codecnt=4; 17 | 18 | //常用汉字集 19 | static String base = "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9" + 20 | "\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c" + 21 | "\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a" + 22 | "\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837" + 23 | "\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83" + 24 | "\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de" + 25 | "\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1" + 26 | "\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b" + 27 | "\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403" + 28 | "\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240" + 29 | "\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d" + 30 | "\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199" + 31 | "\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b" + 32 | "\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f" + 33 | "\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7" + 34 | "\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd" + 35 | "\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3" + 36 | "\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb" + 37 | "\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176" + 38 | "\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e" + 39 | "\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27" + 40 | "\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d" + 41 | "\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138" + 42 | "\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a" + 43 | "\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b" + 44 | "\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c" + 45 | "\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020" + 46 | "\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc" + 47 | "\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834" + 48 | "\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf" + 49 | "\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f" + 50 | "\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3" + 51 | "\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e" + 52 | "\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c" + 53 | "\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"; 54 | 55 | public ChineseCaptchaStrategy() { 56 | 57 | } 58 | 59 | public ChineseCaptchaStrategy(int codecnt) { 60 | this.codecnt = codecnt; 61 | } 62 | 63 | public CaptchaBean generateCode() { 64 | CaptchaBean captchaBean = new CaptchaBean(); 65 | String[] codeArray = new String[codecnt]; 66 | Random r = new Random(); 67 | StringBuffer builder = new StringBuffer(); 68 | for (int i = 0; i < codecnt; i++) { 69 | String ch = String.valueOf(base.charAt(r.nextInt(base.length()))); 70 | codeArray[i] = ch; 71 | builder.append(ch); 72 | } 73 | captchaBean.setCodeArray(codeArray); 74 | captchaBean.setResult(builder.toString()); 75 | return captchaBean; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/strategy/ICaptchaStrategy.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.strategy; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | 6 | /** 7 | * Nothing seek, Nothing find. 8 | * author: shuzhilong 9 | * Date: 2017/9/26 下午2:54 10 | * desc: (The role of this class is to ...) 11 | * To change this template use preferences | editor | File and code Templates 12 | */ 13 | public interface ICaptchaStrategy { 14 | CaptchaBean generateCode(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/captha/strategy/SimpleCaptchaStrategy.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.captha.strategy; 2 | 3 | 4 | import com.example.demo.base_security.captha.bean.CaptchaBean; 5 | 6 | import java.util.Random; 7 | 8 | /** 9 | * Nothing seek, Nothing find. 10 | * author: shuzhilong 11 | * Date: 2017/9/26 下午2:58 12 | * desc: (The role of this class is to ...) 13 | * To change this template use preferences | editor | File and code Templates 14 | */ 15 | public class SimpleCaptchaStrategy implements ICaptchaStrategy { 16 | private static char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); 17 | 18 | int codecnt=4; 19 | Random random = new Random(); 20 | 21 | public SimpleCaptchaStrategy() { 22 | } 23 | 24 | public SimpleCaptchaStrategy(int codecnt) { 25 | this.codecnt = codecnt; 26 | } 27 | 28 | public CaptchaBean generateCode() { 29 | CaptchaBean captchaBean = new CaptchaBean(); 30 | String[] codeArray = new String[codecnt]; 31 | StringBuffer builder = new StringBuffer(); 32 | for (int i = 0; i < codecnt; i++) { 33 | char c = ch[random.nextInt(ch.length)]; 34 | String ch = String.valueOf(c); 35 | codeArray[i] = ch; 36 | builder.append(ch); 37 | } 38 | captchaBean.setCodeArray(codeArray); 39 | captchaBean.setResult(builder.toString()); 40 | return captchaBean; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/commons/Constant.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.commons; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * @author liugh 8 | * @since 2018-05-03 9 | */ 10 | public class Constant { 11 | 12 | public static final int BYTE_BUFFER = 1024; 13 | 14 | public static Set METHOD_URL_SET = new HashSet<>(); 15 | 16 | /** 17 | * 用户注册默认角色 18 | */ 19 | public static final int DEFAULT_REGISTER_ROLE = 5; 20 | 21 | public static final int BUFFER_MULTIPLE = 10; 22 | 23 | //验证码过期时间 24 | public static final Long PASS_TIME = 50000 * 60 *1000L; 25 | 26 | //根菜单节点 27 | public static final String ROOT_MENU = "0"; 28 | 29 | //菜单类型,1:菜单 2:按钮操作 30 | public static final int TYPE_MENU = 1; 31 | 32 | //菜单类型,1:菜单 2:按钮操作 33 | public static final int TYPE_BUTTON = 2; 34 | 35 | public static Boolean isPass = false; 36 | 37 | //启用 38 | public static final int ENABLE = 1; 39 | //禁用 40 | public static final int DISABLE = 0; 41 | 42 | public static class FilePostFix{ 43 | public static final String ZIP_FILE =".zip"; 44 | 45 | public static final String [] IMAGES ={"jpg", "jpeg", "JPG", "JPEG", "gif", "GIF", "bmp", "BMP", "png"}; 46 | public static final String [] ZIP ={"ZIP","zip","rar","RAR"}; 47 | public static final String [] VIDEO ={"mp4","MP4","mpg","mpe","mpa","m15","m1v", "mp2","rmvb"}; 48 | public static final String [] APK ={"apk","exe"}; 49 | public static final String [] OFFICE ={"xls","xlsx","docx","doc","ppt","pptx"}; 50 | 51 | } 52 | public class FileType{ 53 | public static final int FILE_IMG = 1; 54 | public static final int FILE_ZIP = 2; 55 | public static final int FILE_VEDIO= 3; 56 | public static final int FILE_APK = 4; 57 | public static final int FIVE_OFFICE = 5; 58 | public static final String FILE_IMG_DIR= "/img/"; 59 | public static final String FILE_ZIP_DIR= "/zip/"; 60 | public static final String FILE_VEDIO_DIR= "/video/"; 61 | public static final String FILE_APK_DIR= "/apk/"; 62 | public static final String FIVE_OFFICE_DIR= "/office/"; 63 | } 64 | 65 | /** 66 | * 角色类型 67 | */ 68 | public static final Integer ROLE_TYPE_ADMIN =0; 69 | public static final Integer ROLE_TYPE_NORMAL =1; 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/commons/PublicResultConstant.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.commons; 2 | 3 | /** 4 | * @author liugh 5 | * @since 2018-05-03 6 | */ 7 | public class PublicResultConstant { 8 | 9 | public static final String FAILED = "系统错误"; 10 | 11 | public static final String SUCCEED = "操作成功"; 12 | 13 | public static final String UNAUTHORIZED = "登录验证失败,请重新登录"; 14 | 15 | public static final String ERROR = "操作失败"; 16 | 17 | public static final String DATA_ERROR = "数据操作错误"; 18 | 19 | public static final String PARAM_ERROR = "参数错误"; 20 | 21 | public static final String INVALID_USERNAME_PASSWORD = "用户名或密码错误"; 22 | 23 | public static final String INVALID_RE_PASSWORD = "两次输入密码不一致"; 24 | 25 | public static final String INVALID_USER = "用户不存在"; 26 | 27 | public static final String INVALID_ROLE = "角色不存在"; 28 | 29 | public static final String ROLE_USER_USED = "角色使用中,不可删除"; 30 | 31 | public static final String USER_NO_PERMITION = "当前用户无该接口权限"; 32 | 33 | public static final String VERIFY_PARAM_ERROR = "校验码错误"; 34 | 35 | public static final String VERIFY_PARAM_PASS = "校验码过期"; 36 | 37 | public static final String MOBILE_ERROR = "手机号格式错误"; 38 | 39 | public static final String UPDATE_ROLEINFO_ERROR = "更新角色信息失败"; 40 | 41 | public static final String UPDATE_SYSADMIN_INFO_ERROR = "不能修改管理员信息!"; 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/CurrentUserMethodArgumentResolver.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | 3 | import com.example.demo.entity.SysUser; 4 | import com.example.demo.base_security.annotation.CurrentUser; 5 | import org.apache.shiro.authz.UnauthorizedException; 6 | import org.springframework.core.MethodParameter; 7 | import org.springframework.web.bind.support.WebDataBinderFactory; 8 | import org.springframework.web.context.request.NativeWebRequest; 9 | import org.springframework.web.context.request.RequestAttributes; 10 | import org.springframework.web.method.support.HandlerMethodArgumentResolver; 11 | import org.springframework.web.method.support.ModelAndViewContainer; 12 | 13 | /** 14 | * 增加方法注入,将含有 @CurrentUser 注解的方法参数注入当前登录用户 15 | * @author liugh 16 | * @since 2018-05-03 17 | */ 18 | public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver { 19 | @Override 20 | public boolean supportsParameter(MethodParameter parameter) { 21 | return parameter.getParameterType().isAssignableFrom(SysUser.class) 22 | && parameter.hasParameterAnnotation(CurrentUser.class); 23 | } 24 | 25 | @Override 26 | public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { 27 | SysUser user = (SysUser) webRequest.getAttribute("currentUser", RequestAttributes.SCOPE_REQUEST); 28 | if (user == null) { 29 | throw new UnauthorizedException("获取用户信息失败"); 30 | } 31 | return user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/JWTFilter.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.example.demo.base_security.commons.Constant; 5 | import com.example.demo.entity.SysUser; 6 | import com.example.demo.base_security.commons.PublicResultConstant; 7 | import com.example.demo.service.SysUserService; 8 | import com.example.demo.base_security.util.ComUtil; 9 | import com.example.demo.base_security.util.JWTUtil; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.apache.shiro.authz.UnauthorizedException; 12 | import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; 13 | import org.springframework.http.HttpStatus; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | import javax.servlet.ServletRequest; 16 | import javax.servlet.ServletResponse; 17 | import javax.servlet.http.HttpServletRequest; 18 | import javax.servlet.http.HttpServletResponse; 19 | import java.io.PrintWriter; 20 | 21 | /** 22 | * @author grm 23 | * 24 | * 代码的执行流程preHandle->isAccessAllowed->isLoginAttempt->executeLogin 25 | */ 26 | public class JWTFilter extends BasicHttpAuthenticationFilter{ 27 | 28 | private SysUserService userService; 29 | /** 30 | * 判断用户是否想要登入。 31 | * 检测header里面是否包含Authorization字段即可 32 | */ 33 | @Override 34 | protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) { 35 | HttpServletRequest req = (HttpServletRequest) request; 36 | String authorization = req.getHeader("Authorization"); 37 | return authorization != null; 38 | } 39 | 40 | /** 41 | * 42 | */ 43 | @Override 44 | protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { 45 | HttpServletRequest httpServletRequest = (HttpServletRequest) request; 46 | String authorization = httpServletRequest.getHeader("Authorization"); 47 | JWTToken token = new JWTToken(authorization); 48 | // 提交给realm进行登入,如果错误他会抛出异常并被捕获 49 | getSubject(request, response).login(token); 50 | // 如果没有抛出异常则代表登入成功,返回true 51 | setUserBean(request, response, token); 52 | return true; 53 | } 54 | 55 | /** 56 | * 这里我们详细说明下为什么最终返回的都是true,即允许访问 57 | * 例如我们提供一个地址 GET /article 58 | * 登入用户和游客看到的内容是不同的 59 | * 如果在这里返回了false,请求会被直接拦截,用户看不到任何东西 60 | * 所以我们在这里返回true,Controller中可以通过 subject.isAuthenticated() 来判断用户是否登入 61 | * 如果有些资源只有登入用户才能访问,我们只需要在方法上面加上 @RequiresAuthentication 注解即可 62 | * 但是这样做有一个缺点,就是不能够对GET,POST等请求进行分别过滤鉴权(因为我们重写了官方的方法),但实际上对应用影响不大 63 | */ 64 | @Override 65 | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { 66 | if (isLoginAttempt(request, response)) { 67 | try { 68 | executeLogin(request, response); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | responseError(request, response); 72 | } 73 | } 74 | return true; 75 | } 76 | 77 | private void setUserBean(ServletRequest request, ServletResponse response, JWTToken token) { 78 | if (this.userService == null) { 79 | this.userService = SpringContextBeanService.getBean(SysUserService.class); 80 | } 81 | String userId = JWTUtil.getUserNo(token.getPrincipal().toString()); 82 | SysUser userBean = userService.getById(userId); 83 | request.setAttribute("currentUser", userBean); 84 | } 85 | 86 | /** 87 | * 对跨域提供支持 88 | */ 89 | @Override 90 | protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { 91 | HttpServletRequest httpServletRequest = (HttpServletRequest) request; 92 | HttpServletResponse httpServletResponse = (HttpServletResponse) response; 93 | httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin")); 94 | httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS"); 95 | httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); 96 | // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态 97 | if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) { 98 | httpServletResponse.setStatus(HttpStatus.OK.value()); 99 | return false; 100 | } 101 | String authorization = httpServletRequest.getHeader("Authorization"); 102 | if (verificationPassAnnotation(request, response, httpServletRequest, authorization)){ 103 | return true; 104 | } 105 | if(ComUtil.isEmpty(authorization)){ 106 | responseError(request, response); 107 | return false; 108 | } 109 | return super.preHandle(request, response); 110 | } 111 | 112 | /** 113 | * 验证请求方法是否有@Pass注解,有则直接放行 114 | * @param request 115 | * @param response 116 | * @param httpServletRequest 117 | * @param authorization 118 | * @return 119 | * @throws Exception 120 | */ 121 | private boolean verificationPassAnnotation(ServletRequest request, ServletResponse response, HttpServletRequest httpServletRequest, String authorization) throws Exception { 122 | for (String urlMethod: Constant.METHOD_URL_SET) { 123 | String[] split = urlMethod.split(":--:"); 124 | if(split[0].equals(httpServletRequest.getRequestURI()) 125 | && (split[1].equals(httpServletRequest.getMethod()) || split[1].equals("RequestMapping"))){ 126 | Constant.isPass=true; 127 | if(ComUtil.isEmpty(authorization)){ 128 | //如果当前url不需要认证,则注入当前登录用户时,给一个空的 129 | httpServletRequest.setAttribute("currentUser",new SysUser()); 130 | return true; 131 | }else { 132 | super.preHandle(request, response); 133 | } 134 | } 135 | if(StringUtils.countMatches(urlMethod, "{")>0 && 136 | StringUtils.countMatches(urlMethod, "/") == StringUtils.countMatches(split[0], "/") 137 | && (split[1].equals(httpServletRequest.getMethod()) || split[1].equals("RequestMapping"))){ 138 | if(isSameUrl(split[0],httpServletRequest.getRequestURI())){ 139 | Constant.isPass=true; 140 | if(ComUtil.isEmpty(authorization)){ 141 | httpServletRequest.setAttribute("currentUser",new SysUser()); 142 | return true; 143 | }else { 144 | super.preHandle(request, response); 145 | } 146 | } 147 | } 148 | } 149 | return false; 150 | } 151 | 152 | /** 153 | * 判断路径参数的url是否和controller方法url一致 154 | * @param localUrl 155 | * @param requestUrl 156 | * @return 157 | */ 158 | private boolean isSameUrl(String localUrl,String requestUrl){ 159 | String[] tempLocalUrls = localUrl.split("/"); 160 | String[] tempRequestUrls = requestUrl.split("/"); 161 | if(tempLocalUrls.length != tempRequestUrls.length){ 162 | return false; 163 | } 164 | StringBuilder sbLocalUrl =new StringBuilder(); 165 | StringBuilder sbRequestUrl =new StringBuilder(); 166 | for (int i = 0; i < tempLocalUrls.length; i++) { 167 | if(StringUtils.countMatches(tempLocalUrls[i], "{") > 0){ 168 | tempLocalUrls[i]="*"; 169 | tempRequestUrls[i]="*"; 170 | } 171 | sbLocalUrl.append(tempLocalUrls[i]+"/"); 172 | sbRequestUrl.append(tempRequestUrls[i]+"/"); 173 | } 174 | return sbLocalUrl.toString().trim().equals(sbRequestUrl.toString().trim()); 175 | } 176 | 177 | /** 178 | * 非法url返回身份错误信息 179 | */ 180 | private void responseError(ServletRequest request, ServletResponse response) { 181 | PrintWriter out = null; 182 | try { 183 | response.setCharacterEncoding("utf-8"); 184 | out = response.getWriter(); 185 | response.setContentType("application/json; charset=utf-8"); 186 | out.print(JSONObject.toJSONString(ResponseHelper.unauthorized(PublicResultConstant.UNAUTHORIZED)));//401 187 | out.flush(); 188 | } catch (Exception e) { 189 | e.printStackTrace(); 190 | }finally { 191 | if (out != null) { 192 | out.close(); 193 | } 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/JWTToken.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | 3 | import org.apache.shiro.authc.AuthenticationToken; 4 | 5 | /** 6 | * @author liugh 7 | * @since 2018-05-03 8 | */ 9 | public class JWTToken implements AuthenticationToken { 10 | 11 | // 密钥 12 | private String token; 13 | 14 | public JWTToken(String token) { 15 | this.token = token; 16 | } 17 | 18 | @Override 19 | public Object getPrincipal() { 20 | return token; 21 | } 22 | 23 | @Override 24 | public Object getCredentials() { 25 | return token; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/MyRealm.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | 3 | import com.example.demo.base_security.commons.Constant; 4 | import com.example.demo.entity.SysUser; 5 | import com.example.demo.service.*; 6 | import com.example.demo.base_security.util.JWTUtil; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.apache.shiro.authc.AuthenticationInfo; 9 | import org.apache.shiro.authc.AuthenticationToken; 10 | import org.apache.shiro.authc.SimpleAuthenticationInfo; 11 | import org.apache.shiro.authz.AuthorizationInfo; 12 | import org.apache.shiro.authz.UnauthorizedException; 13 | import org.apache.shiro.realm.AuthorizingRealm; 14 | import org.apache.shiro.subject.PrincipalCollection; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.context.annotation.Configuration; 17 | import org.springframework.data.redis.core.RedisTemplate; 18 | import org.springframework.data.redis.core.StringRedisTemplate; 19 | import org.springframework.stereotype.Component; 20 | 21 | import javax.annotation.Resource; 22 | 23 | /** 24 | * @author liugh 25 | * @since 2018-05-03 26 | */ 27 | @Configuration 28 | public class MyRealm extends AuthorizingRealm { 29 | private SysUserService sysUserService; 30 | private SysUserRoleService userToRoleService; 31 | private SysResService menuService; 32 | private SysRoleService roleService; 33 | 34 | private static RedisTemplate redisTemplate; 35 | @Autowired 36 | public void setRedisTemplate(RedisTemplate redisTemplate) { 37 | MyRealm.redisTemplate = redisTemplate; 38 | } 39 | 40 | /** 41 | * 大坑!,必须重写此方法,不然Shiro会报错 42 | */ 43 | @Override 44 | public boolean supports(AuthenticationToken token) { 45 | return token instanceof JWTToken; 46 | } 47 | 48 | /** 49 | * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的 50 | */ 51 | // @Override 52 | // protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 53 | // if (userToRoleService == null) { 54 | // this.userToRoleService = SpringContextBeanService.getBean(SysUserRoleService.class); 55 | // } 56 | // if (menuService == null) { 57 | // this.menuService = SpringContextBeanService.getBean(SysResService.class); 58 | // } 59 | // if (roleService == null) { 60 | // this.roleService = SpringContextBeanService.getBean(SysRoleService.class); 61 | // } 62 | // 63 | // String userNo = JWTUtil.getUserNo(principals.toString()); 64 | // SysUser user = SysUserService.getById(userNo); 65 | // SysUserRole userToRole = userToRoleService.selectByUserNo(user.getUserNo()); 66 | // 67 | // SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); 68 | // /* 69 | // Role role = roleService.selectOne(new EntityWrapper().eq("role_code", userToRole.getRoleCode())); 70 | // //添加控制角色级别的权限 71 | // Set roleNameSet = new HashSet<>(); 72 | // roleNameSet.add(role.getRoleName()); 73 | // simpleAuthorizationInfo.addRoles(roleNameSet); 74 | // */ 75 | // //控制菜单级别按钮 类中用@RequiresPermissions("user:list") 对应数据库中code字段来控制controller 76 | // ArrayList pers = new ArrayList<>(); 77 | // List menuList = menuService.findMenuByRoleCode(userToRole.getRoleCode()); 78 | // for (SysRes per : menuList) { 79 | // if (!ComUtil.isEmpty(per.getCode())) { 80 | // pers.add(String.valueOf(per.getCode())); 81 | // } 82 | // } 83 | // Set permission = new HashSet<>(pers); 84 | // simpleAuthorizationInfo.addStringPermissions(permission); 85 | // return simpleAuthorizationInfo; 86 | //} 87 | 88 | /** 89 | * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。 90 | */ 91 | @Override 92 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws UnauthorizedException { 93 | if (sysUserService == null) { 94 | this.sysUserService = SpringContextBeanService.getBean(SysUserService.class); 95 | } 96 | String token = (String) auth.getCredentials(); 97 | if(Constant.isPass){ 98 | return new SimpleAuthenticationInfo(token, token, this.getName()); 99 | } 100 | // 解密获得username,用于和redis和数据库进行对比 101 | String userNo = JWTUtil.getUserNo(token); 102 | if (userNo == null) { 103 | throw new UnauthorizedException("token invalid"); 104 | } 105 | //实现单点登录 106 | Object token1 = redisTemplate.opsForHash().get("token", userNo); 107 | if (null !=token1 && StringUtils.isNotBlank(String.valueOf(token1))){ 108 | if (!token.equals(token1)){ 109 | throw new UnauthorizedException("登录重复,请重新登录"); 110 | } 111 | } 112 | SysUser userBean = sysUserService.getById(userNo); 113 | if (userBean == null) { 114 | throw new UnauthorizedException("User didn't existed!"); 115 | } 116 | if (! JWTUtil.verify(token, userNo,userBean.getLoginName(), userBean.getPwd())) { 117 | throw new UnauthorizedException("Username or password error"); 118 | } 119 | return new SimpleAuthenticationInfo(token, token, this.getName()); 120 | } 121 | 122 | @Override 123 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { 124 | return null; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/ResponseHelper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | 3 | import com.example.demo.base_security.util.ResponseModel; 4 | import org.springframework.http.HttpStatus; 5 | 6 | /** 7 | * 统一返回相应参数 8 | * @author liugh 53182347@qq.com 9 | */ 10 | public class ResponseHelper { 11 | 12 | public ResponseHelper() { 13 | } 14 | 15 | public static ResponseModel notFound(String message) { 16 | ResponseModel response = new ResponseModel(); 17 | response.setStatus(HttpStatus.NOT_FOUND.value()); 18 | response.setCode(HttpStatus.NOT_FOUND.getReasonPhrase()); 19 | response.setMessage(message); 20 | return response; 21 | } 22 | 23 | public static ResponseModel internalServerError(String message) { 24 | ResponseModel response = new ResponseModel(); 25 | response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); 26 | response.setCode(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); 27 | response.setMessage(message); 28 | return response; 29 | } 30 | 31 | public static ResponseModel validationFailure(String message) { 32 | ResponseModel response = new ResponseModel(); 33 | response.setStatus(HttpStatus.BAD_REQUEST.value()); 34 | response.setCode(HttpStatus.BAD_REQUEST.getReasonPhrase()); 35 | response.setMessage(message); 36 | return response; 37 | } 38 | //权限验证失败 39 | public static ResponseModel unauthorized(String message) { 40 | ResponseModel response = new ResponseModel(); 41 | response.setStatus(HttpStatus.UNAUTHORIZED.value()); 42 | response.setCode(HttpStatus.UNAUTHORIZED.getReasonPhrase()); 43 | response.setMessage(message); 44 | return response; 45 | } 46 | 47 | public static ResponseModel buildResponseModel(T result) { 48 | ResponseModel response = new ResponseModel(); 49 | response.setStatus(HttpStatus.OK.value()); 50 | response.setCode(HttpStatus.OK.getReasonPhrase()); 51 | response.setMessage(HttpStatus.OK.getReasonPhrase()); 52 | response.setResult(result); 53 | return response; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; 3 | import org.apache.shiro.mgt.DefaultSubjectDAO; 4 | import org.apache.shiro.spring.LifecycleBeanPostProcessor; 5 | import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 6 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 7 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 8 | import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.servlet.Filter; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author liugh 18 | * @since 2018-05-03 19 | */ 20 | @Configuration 21 | public class ShiroConfig { 22 | 23 | @Bean 24 | public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { 25 | return new LifecycleBeanPostProcessor(); 26 | } 27 | 28 | @Bean 29 | public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){ 30 | DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator(); 31 | defaultAdvisorAutoProxyCreator.setUsePrefix(true); 32 | 33 | return defaultAdvisorAutoProxyCreator; 34 | } 35 | 36 | @Bean("securityManager") 37 | public DefaultWebSecurityManager getManager() { 38 | DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); 39 | // 使用自己的realm 40 | manager.setRealm(new MyRealm()); 41 | /* 42 | * 关闭shiro自带的session,详情见文档 43 | * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29 44 | */ 45 | DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); 46 | DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); 47 | defaultSessionStorageEvaluator.setSessionStorageEnabled(false); 48 | subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); 49 | manager.setSubjectDAO(subjectDAO); 50 | return manager; 51 | } 52 | 53 | @Bean("shiroFilter") 54 | public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager) { 55 | ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); 56 | // 添加自己的过滤器并且取名为jwt 57 | Map filterMap = new HashMap<>(); 58 | filterMap.put("jwt", new JWTFilter()); 59 | factoryBean.setFilters(filterMap); 60 | factoryBean.setSecurityManager(securityManager); 61 | /* 62 | * 自定义url规则 63 | * http://shiro.apache.org/web.html#urls- 64 | */ 65 | Map filterRuleMap = new HashMap<>(2); 66 | // 访问401和404页面不通过我们的Filter 67 | //通过http://127.0.0.1:9527/druid/index.html 访问 liugh/liugh 68 | filterRuleMap.put("/druid/**", "anon"); 69 | //放行webSocket 70 | filterRuleMap.put("/websocket/*", "anon"); 71 | //放行swagger 72 | filterRuleMap.put("/swagger-ui.html", "anon"); 73 | filterRuleMap.put("/swagger-resources", "anon"); 74 | filterRuleMap.put("/v2/api-docs", "anon"); 75 | filterRuleMap.put("/webjars/springfox-swagger-ui/**", "anon"); 76 | // 所有请求通过我们自己的JWT Filter 77 | filterRuleMap.put("/**", "jwt"); 78 | //放行文件下载 79 | filterRuleMap.put("/file/download/**", "anon"); 80 | //放行登出 81 | filterRuleMap.put("/logout/**", "anon"); 82 | //登录注册放行 83 | filterRuleMap.put("/login/**", "anon"); 84 | factoryBean.setFilterChainDefinitionMap(filterRuleMap); 85 | return factoryBean; 86 | } 87 | 88 | @Bean 89 | public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { 90 | AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); 91 | advisor.setSecurityManager(securityManager); 92 | return advisor; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/config/SpringContextBeanService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.config; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * 获取spring上下文 10 | * @author liugh 11 | * @since 2018-03-21 12 | */ 13 | @Component 14 | public class SpringContextBeanService implements ApplicationContextAware { 15 | private static ApplicationContext context = null; 16 | 17 | @Override 18 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 19 | context = applicationContext; 20 | } 21 | 22 | public static T getBean(String name) 23 | { 24 | return (T)context.getBean(name); 25 | } 26 | 27 | public static T getBean(Class beanClass){ 28 | return context.getBean(beanClass); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.controller; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.example.demo.base_controller.BaseController; 5 | import com.example.demo.base_security.VO.registerVO; 6 | import com.example.demo.base_security.captha.CaptchaClient; 7 | import com.example.demo.base_security.captha.bean.CaptchaBean; 8 | import com.example.demo.entity.SysUser; 9 | import com.example.demo.base_security.annotation.Log; 10 | import com.example.demo.base_security.annotation.Pass; 11 | import com.example.demo.base_security.annotation.ValidationParam; 12 | import com.example.demo.base_security.util.ComUtil; 13 | import com.example.demo.service.SysUserService; 14 | import com.google.common.collect.ImmutableMap; 15 | import io.swagger.annotations.Api; 16 | import io.swagger.annotations.ApiImplicitParam; 17 | import io.swagger.annotations.ApiImplicitParams; 18 | import io.swagger.annotations.ApiOperation; 19 | import org.apache.commons.codec.binary.Base64; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.data.redis.core.StringRedisTemplate; 22 | import org.springframework.http.MediaType; 23 | import org.springframework.http.ResponseEntity; 24 | import org.springframework.validation.annotation.Validated; 25 | import org.springframework.web.bind.annotation.*; 26 | import springfox.documentation.annotations.ApiIgnore; 27 | 28 | import javax.imageio.ImageIO; 29 | import javax.servlet.http.HttpServletRequest; 30 | import java.awt.image.BufferedImage; 31 | import java.io.ByteArrayOutputStream; 32 | import java.io.IOException; 33 | import java.util.UUID; 34 | import java.util.concurrent.TimeUnit; 35 | 36 | /** 37 | * 登录接口 38 | * @author liugh 39 | * @since 2018-05-03 40 | */ 41 | @RestController 42 | @Api(description="身份认证模块") 43 | @RequestMapping("/login") 44 | public class LoginController extends BaseController { 45 | @Autowired 46 | private SysUserService userService; 47 | @Autowired 48 | private StringRedisTemplate stringRedisTemplate; 49 | 50 | @Autowired 51 | private CaptchaClient captchaClient; 52 | 53 | 54 | @ApiOperation(value="手机密码登录", notes="body体参数,不需要Authorization",produces = "application/json") 55 | @PostMapping("/login") 56 | @Log(action="SignIn",modelName= "Login",description="前台密码登录接口") 57 | public Object login( 58 | @ValidationParam("mobileNo,pwd")@RequestBody JSONObject requestJson) throws Exception{ 59 | return success(userService.checkMobileAndPasswd(requestJson)); 60 | } 61 | 62 | @ApiOperation(value="短信验证码登录", notes="body体参数,不需要Authorization",produces = "application/json") 63 | @PostMapping("/login/captcha") 64 | @Log(action="SignInByCaptcha",modelName= "Login",description="前台短信验证码登录接口") 65 | public Object loginBycaptcha( 66 | @ValidationParam("mobile,captcha")@RequestBody JSONObject requestJson) throws Exception{ 67 | return success( userService.checkMobileAndCatcha(requestJson)); 68 | } 69 | 70 | @ApiOperation(value="手机验证码注册", notes="body体参数,不需要Authorization",produces = "application/json") 71 | @PostMapping("/register") 72 | @Log(action="register",modelName= "Login",description="注册接口") 73 | public Object register(@Validated @RequestBody registerVO vo)throws Exception { 74 | return success( userService.checkAndRegisterUser(vo)); 75 | } 76 | 77 | 78 | @ApiOperation(value="忘记密码", notes="body体参数,不需要Authorization",produces = "application/json") 79 | @PostMapping("/forget/password") 80 | public Object resetPassWord (@RequestBody JSONObject requestJson ) throws Exception{ 81 | return success(userService.updateForgetPasswd(requestJson)); 82 | } 83 | /** 84 | * 检查用户是否注册过 85 | * @param mobile 86 | * @return 87 | * @throws Exception 88 | */ 89 | @GetMapping("/check/mobile") 90 | @ApiIgnore 91 | public Object loginBycaptcha(@RequestParam("mobile") String mobile) throws Exception{ 92 | SysUser user = userService.getUserByMobile(mobile); 93 | return success(!ComUtil.isEmpty(user)); 94 | } 95 | 96 | /** 97 | * 退出登录 98 | * @return 99 | */ 100 | @GetMapping("/loginOut") 101 | public Object loginOut(@RequestParam("userId") String userId, HttpServletRequest request){ 102 | //将将当前请求头设置为null 103 | request.setAttribute("currentUser",null); 104 | return success(userService.loginOut(userId)); 105 | } 106 | 107 | 108 | @GetMapping("/captcha") 109 | @ApiOperation(value="获取验证码图片", notes="") 110 | public Object captcha() { 111 | try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) { 112 | CaptchaBean captchaBean = captchaClient.generate(); 113 | String capText = captchaBean.getResult(); 114 | String uuid = UUID.randomUUID().toString(); 115 | stringRedisTemplate.boundValueOps(uuid).set(capText,60, TimeUnit.SECONDS);//验证码过期时间60秒 116 | BufferedImage bi = captchaBean.getBufferedImage(); 117 | ImageIO.write(bi, "jpg", baos); 118 | String imgBase64 = Base64.encodeBase64String(baos.toByteArray()); 119 | 120 | return ResponseEntity.ok() 121 | .header("Access-Control-Allow-Origin","*") 122 | .contentType(MediaType.APPLICATION_JSON) 123 | .body( 124 | ImmutableMap.of("data", ImmutableMap.of(uuid,"data:image/jpeg;base64,"+imgBase64) 125 | ,"code", 200 126 | ,"msg", "成功!" 127 | ,"timestamp", System.currentTimeMillis()) 128 | ); 129 | } catch (IOException e) { 130 | throw new RuntimeException(e.getMessage(),e); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/util/ComUtil.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.util; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * @author liugh 7 | * @since 2018-05-07 8 | */ 9 | public class ComUtil { 10 | 11 | public static boolean isEmpty(Object aObj) { 12 | if (aObj instanceof String) { 13 | return isEmpty((String) aObj); 14 | } else if (aObj instanceof Long) { 15 | return isEmpty((Long) aObj); 16 | } else if (aObj instanceof Date) { 17 | return isEmpty((Date) aObj); 18 | } else if (aObj instanceof Collection) { 19 | return isEmpty((Collection) aObj); 20 | } else if (aObj instanceof Map) { 21 | return isEmpty((Map) aObj); 22 | } else if (aObj != null && aObj.getClass().isArray()) { 23 | return isEmptyArray(aObj); 24 | } else { 25 | return isNull(aObj); 26 | } 27 | } 28 | 29 | private static boolean isEmptyArray(Object array) { 30 | int length = 0; 31 | if (array instanceof int[]) { 32 | length = ((int[]) array).length; 33 | } else if (array instanceof byte[]) { 34 | length = ((byte[]) array).length; 35 | } else if (array instanceof short[]) { 36 | length = ((short[]) array).length; 37 | } else if (array instanceof char[]) { 38 | length = ((char[]) array).length; 39 | } else if (array instanceof float[]) { 40 | length = ((float[]) array).length; 41 | } else if (array instanceof double[]) { 42 | length = ((double[]) array).length; 43 | } else if (array instanceof long[]) { 44 | length = ((long[]) array).length; 45 | } else if (array instanceof boolean[]) { 46 | length = ((boolean[]) array).length; 47 | } else { 48 | length = ((Object[]) array).length; 49 | } 50 | if (length == 0) { 51 | return true; 52 | } 53 | return false; 54 | } 55 | 56 | 57 | public static boolean isEmpty(Date aDate) { 58 | if (aDate == null) { 59 | return true; 60 | } else { 61 | return false; 62 | } 63 | } 64 | 65 | public static boolean isEmpty(Long aLong) { 66 | if (aLong == null) { 67 | return true; 68 | } else { 69 | return false; 70 | } 71 | } 72 | 73 | 74 | public static boolean isEmpty(Map m) { 75 | if (m == null || m.size() == 0) { 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | public static boolean isEmpty(Collection c) { 82 | if (c == null || c.size() == 0) { 83 | return true; 84 | } 85 | return false; 86 | } 87 | 88 | public static boolean isEmpty(String aStr) { 89 | if (aStr == null || aStr.trim().isEmpty()) { 90 | return true; 91 | } else { 92 | return false; 93 | } 94 | } 95 | 96 | 97 | 98 | public static String trim(String aStr) { 99 | if (aStr == null) { 100 | return ""; 101 | } else { 102 | return aStr.trim(); 103 | } 104 | } 105 | 106 | public static boolean isNull(Object oStr) { 107 | if (oStr == null) { 108 | return true; 109 | } else { 110 | return false; 111 | } 112 | } 113 | 114 | 115 | public static boolean equals(String str1, String str2) { 116 | return str1 != null ? str1.equals(str2) : str2 == null; 117 | } 118 | 119 | public static boolean equals(Long L1, Long L2) { 120 | return L1 != null ? L1.equals(L2) : L2 == null; 121 | } 122 | 123 | public static boolean equals(Object obj1, Object obj2) { 124 | boolean result; 125 | if (obj1 != null) { 126 | result = obj1.equals(obj2); 127 | } else { 128 | result = (obj2 == null); 129 | } 130 | return result; 131 | } 132 | 133 | public static boolean equalsIgnoreCase(String str1, String str2) { 134 | return str1 != null ? str1.equalsIgnoreCase(str2) : str2 == null; 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.util; 2 | 3 | import com.example.demo.base_security.commons.Constant; 4 | import org.apache.tools.zip.ZipFile; 5 | import org.apache.tools.zip.ZipOutputStream; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import sun.misc.BASE64Decoder; 9 | import sun.misc.BASE64Encoder; 10 | import javax.imageio.ImageIO; 11 | import javax.imageio.stream.ImageInputStream; 12 | import java.io.*; 13 | import java.nio.channels.FileChannel; 14 | import java.nio.charset.Charset; 15 | import java.util.*; 16 | import org.apache.tools.zip.ZipEntry; 17 | import net.coobird.thumbnailator.Thumbnails; 18 | 19 | 20 | /** 21 | * @author liugh 22 | * @since on 2018/5/8. 23 | */ 24 | public class FileUtil { 25 | 26 | //2M 27 | public static final int FILE_SIZE = 1000000; 28 | 29 | private static final Logger logger = LoggerFactory.getLogger(FileUtil.class); 30 | 31 | 32 | private static ResourceBundle bundle = ResourceBundle.getBundle("config/constant"); 33 | 34 | public static String fileUploadPath =bundle.getString("file-upload.dir"); 35 | 36 | /** 37 | * 判断当前文件是否是zip文件 38 | * 39 | * @param fileName 40 | * 文件名 41 | * @return true 是 42 | */ 43 | public static boolean isZip(String fileName) { 44 | return fileName.toLowerCase().endsWith(Constant.FilePostFix.ZIP_FILE); 45 | } 46 | 47 | 48 | public static void removeDocument(String fileName){ 49 | File file=new File(fileName); 50 | if(file.exists() && file.isFile()) { 51 | file.delete(); 52 | } 53 | if(file.isDirectory()){ 54 | delDir(fileName); 55 | } 56 | if (fileName.lastIndexOf(Constant.FilePostFix.ZIP_FILE) > 0) { 57 | delDir(fileName.substring(0,fileName.lastIndexOf(Constant.FilePostFix.ZIP_FILE))+"/"); 58 | } 59 | 60 | } 61 | 62 | 63 | 64 | 65 | public static boolean checkZipFile(String sourcePath){ 66 | System.setProperty("sun.zip.encoding", System.getProperty("sun.jnu.encoding")); 67 | ZipFile zipFile =null; 68 | try { 69 | File sourceFile = new File(sourcePath); 70 | zipFile = new ZipFile(sourcePath, "gbk"); 71 | if ((!sourceFile.exists()) && (sourceFile.length() <= 0)) { 72 | throw new Exception("要解压的文件不存在!"); 73 | } 74 | Enumeration e = zipFile.getEntries(); 75 | while (e.hasMoreElements()) { 76 | ZipEntry zipEnt = (ZipEntry) e.nextElement(); 77 | if (zipEnt.isDirectory()) { 78 | return false; 79 | } 80 | if(zipEnt.getName().endsWith(".shp")){ 81 | return true; 82 | } 83 | } 84 | 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | return false; 88 | }finally { 89 | try { 90 | if(null!=zipFile){ 91 | zipFile.close(); 92 | } 93 | } catch (IOException e) { 94 | e.printStackTrace(); 95 | } 96 | } 97 | return false; 98 | } 99 | 100 | private static List listFile = new ArrayList<>(); 101 | 102 | /** 103 | * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下 104 | * (把指定文件夹下的所有文件目录和文件都压缩到指定文件夹下) 105 | * @param sourceFilePath 106 | * :待压缩的文件路径 107 | * @param zipFilePath 108 | * :压缩后存放路径 109 | * @param fileName 110 | * :压缩后文件的名称 111 | * @return 112 | */ 113 | public static boolean fileToZip(String sourceFilePath,String zipFilePath,String fileName)throws Exception{ 114 | boolean flag = false; 115 | FileOutputStream fos =null; 116 | ZipOutputStream zos =null; 117 | BufferedInputStream bis =null; 118 | FileInputStream fis =null; 119 | BufferedOutputStream bufferedOutputStream =null; 120 | File sourceFile = new File(sourceFilePath); 121 | if(sourceFile.exists() == false){ 122 | throw new Exception("待压缩的文件目录:"+sourceFilePath+"不存在."); 123 | }else{ 124 | try { 125 | File zipFile = new File(zipFilePath +fileName ); 126 | if(zipFile.exists()){ 127 | throw new Exception(zipFilePath + "目录下存在名字为:" + fileName +Constant.FilePostFix.ZIP_FILE +"打包文件."); 128 | }else{ 129 | File[] sourceFiles = sourceFile.listFiles(); 130 | if(null == sourceFiles || sourceFiles.length<1){ 131 | throw new Exception("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩."); 132 | }else{ 133 | fos = new FileOutputStream(zipFile); 134 | bufferedOutputStream = new BufferedOutputStream(fos); 135 | zos = new ZipOutputStream(bufferedOutputStream); 136 | byte[] bufs = new byte[1024*10]; 137 | for(int i=0;i e = zipFile.getEntries(); 401 | while (e.hasMoreElements()) { 402 | ZipEntry zipEnt = (ZipEntry) e.nextElement(); 403 | gbkPath = zipEnt.getName(); 404 | if (zipEnt.isDirectory()) { 405 | strtemp = strPath + File.separator + gbkPath; 406 | File dir = new File(strtemp); 407 | dir.mkdirs(); 408 | continue; 409 | } else { 410 | // 读写文件 411 | is = zipFile.getInputStream((ZipEntry) zipEnt); 412 | bis = new BufferedInputStream(is); 413 | gbkPath = zipEnt.getName(); 414 | strtemp = strPath + File.separator + gbkPath; 415 | // 建目录 416 | String strsubdir = gbkPath; 417 | for (int i = 0; i < strsubdir.length(); i++) { 418 | if ("/".equalsIgnoreCase(strsubdir.substring(i, i + 1))) { 419 | String temp = strPath + File.separator + strsubdir.substring(0, i); 420 | File subdir = new File(temp); 421 | if (!subdir.exists()) { 422 | subdir.mkdir(); 423 | } 424 | } 425 | } 426 | FileOutputStream fos = new FileOutputStream(strtemp); 427 | BufferedOutputStream bos = new BufferedOutputStream(fos); 428 | int c; 429 | while ((c = bis.read()) != -1) { 430 | bos.write((byte) c); 431 | } 432 | bos.flush(); 433 | fos.close(); 434 | bos.close(); 435 | } 436 | } 437 | zipFile.close(); 438 | return true; 439 | } catch (Exception e) { 440 | e.printStackTrace(); 441 | return false; 442 | }finally { 443 | try { 444 | if (is != null) { 445 | is.close(); 446 | } 447 | if (bis != null) { 448 | bis.close(); 449 | } 450 | } catch (IOException e) { 451 | e.printStackTrace(); 452 | } 453 | } 454 | } 455 | 456 | public static boolean deleteUploadedFile(String fileName) { 457 | String filePath = bundle.getString("file-upload.dir") + fileName; 458 | File file = new File(filePath); 459 | if(file.exists()){ 460 | if(file.isFile()) { 461 | file.delete(); 462 | }else{ 463 | removeDocument(fileName); 464 | } 465 | return true; 466 | }else{ 467 | return false; 468 | } 469 | } 470 | 471 | public static int getFileType(String originalFilename) { 472 | String postFix = originalFilename.split("//.")[originalFilename.split("//.").length-1]; 473 | if(Arrays.asList(Constant.FilePostFix.IMAGES).contains(postFix)){ 474 | return Constant.FileType.FILE_IMG; 475 | } 476 | if(Arrays.asList(Constant.FilePostFix.ZIP).contains(postFix)){ 477 | return Constant.FileType.FILE_ZIP; 478 | } 479 | if(Arrays.asList(Constant.FilePostFix.VIDEO).contains(postFix)){ 480 | return Constant.FileType.FILE_VEDIO; 481 | } 482 | if(Arrays.asList(Constant.FilePostFix.APK).contains(postFix)){ 483 | return Constant.FileType.FILE_APK; 484 | } 485 | if(Arrays.asList(Constant.FilePostFix.OFFICE).contains(postFix)){ 486 | return Constant.FileType.FIVE_OFFICE; 487 | } 488 | return Constant.FileType.FILE_IMG; 489 | } 490 | 491 | /** 492 | * 返回某目录下所有文件对象 493 | * 494 | * @param str 495 | * @return 496 | */ 497 | public static File[] getFiles(String str) { 498 | File dir = new File(StringUtil.utf8Decoding(str)); 499 | File[] result = null; 500 | if (dir.isDirectory()) { 501 | result = dir.listFiles(); 502 | } 503 | 504 | return result; 505 | } 506 | 507 | /** 508 | * 返回某个类所在包最顶层文件夹 509 | * 510 | * @param clazz 类 511 | * @return 顶层文件夹路径 512 | */ 513 | public static String getTopClassPath(Class clazz) { 514 | String path = StringUtil.utf8Decoding(clazz.getResource("/").getPath()); 515 | return path; 516 | } 517 | 518 | /** 519 | * get the jars path 520 | * 521 | * @return 522 | */ 523 | public static String getJarPath() { 524 | return FileUtil.getParent(FileUtil.getTopClassPath(FileUtil.class), 1) + File.separator + "lib"; 525 | } 526 | 527 | public static String getClassPath(String folderName) { 528 | return getJarPath().replace("lib", folderName); 529 | } 530 | 531 | /** 532 | * 获得类所在文件路径 533 | * 534 | * @param clazz 535 | * @return 536 | */ 537 | public static String getCurrPath(Class clazz) { 538 | return StringUtil.utf8Decoding(clazz.getResource("/").getPath() + clazz.getName().replace(".", File.separator)); 539 | } 540 | 541 | /** 542 | * 创建一个文件夹 543 | * 544 | * @param path 545 | * @return 546 | */ 547 | public static boolean createDir(String path) { 548 | boolean flag = false; 549 | File file = new File(StringUtil.utf8Decoding(path)); 550 | if (!file.exists()) { 551 | if (!file.isDirectory()) { 552 | flag = file.mkdir(); 553 | } 554 | } 555 | return flag; 556 | } 557 | 558 | /** 559 | * 创建一个文件 560 | * 561 | * @param path 文件路径 562 | * @return 563 | * @throws IOException 564 | */ 565 | public static boolean createFile(String path) throws IOException { 566 | return createFile(path, false); 567 | } 568 | 569 | /** 570 | * 是否强制新建文件 571 | * 572 | * @param path 文件路径 573 | * @param isDelete 文件存在后是否删除标记 574 | * @return 文件创建是否成功标记 575 | * @throws IOException 576 | * @see 1.原文件存在的情况下会删除原来的文件,重新创建一个新的同名文件,本方法返回文件创建成功标记 577 | * @see 2.原文件存在但isDelete参数设置为false,表示不删除源文件,本方法返回文件创建失败标记 578 | */ 579 | public static boolean createFile(String path, boolean isDelete) throws IOException { 580 | // 加载文件 581 | File file = new File(StringUtil.utf8Decoding(path)); 582 | // 文件是否创建成功 583 | boolean flag = true; 584 | // 判断文件是否存在 585 | if (file.exists()) { 586 | if (isDelete) { // 文件存在后删除文件 587 | // 删除原文件 588 | file.delete(); 589 | // 创建新文件 590 | file.createNewFile(); 591 | } else { 592 | flag = false; 593 | } 594 | } else { 595 | file.createNewFile(); 596 | } 597 | 598 | return flag; 599 | } 600 | 601 | /** 602 | * 将oldFile移动到指定目录 603 | * 604 | * @param oldFile 605 | * @param newDir 606 | * @return 607 | */ 608 | public static boolean moveFileTo(File oldFile, String newDir) { 609 | StringBuilder sb = new StringBuilder(newDir); 610 | sb.append(File.separator).append(oldFile.getName()); 611 | File toDir = new File(StringUtil.utf8Decoding(sb.toString())); 612 | boolean flag = false; 613 | if (!toDir.exists()) { 614 | flag = oldFile.renameTo(toDir); 615 | } 616 | return flag; 617 | } 618 | 619 | /** 620 | * 不使用renameTo,如果文件(isFile)不存在则不复制. 621 | * 622 | * @param sourceFile 623 | * @param target 624 | * @throws Exception 625 | */ 626 | public static void moveFile(File sourceFile, String target) throws Exception { 627 | if (!sourceFile.exists() || !sourceFile.isFile()) { 628 | return; 629 | } 630 | InputStream inputStream = null; 631 | File targetFile = new File(target + File.separator + sourceFile.getName()); 632 | OutputStream outputStream = null; 633 | inputStream = new FileInputStream(sourceFile); 634 | outputStream = new FileOutputStream(targetFile); 635 | int readBytes = 0; 636 | byte[] buffer = new byte[10000]; 637 | while ((readBytes = inputStream.read(buffer, 0, 10000)) != -1) { 638 | outputStream.write(buffer, 0, readBytes); 639 | } 640 | outputStream.flush(); 641 | outputStream.close(); 642 | inputStream.close(); 643 | } 644 | 645 | /** 646 | * 返回当前文件的上层文件夹路径(第几层由参数floor决定) 647 | * 648 | * @param f 649 | * @param floor 650 | * @return 651 | */ 652 | public static String getParent(File f, int floor) { 653 | String result = ""; 654 | if (f != null && f.exists()) { 655 | for (int i = 0; i < floor; ++i) { 656 | f = f.getParentFile(); 657 | } 658 | 659 | if (f != null && f.exists()) { 660 | result = f.getPath(); 661 | } 662 | } 663 | 664 | return StringUtil.utf8Decoding(result) + File.separator; 665 | } 666 | 667 | public static String getParent(String path, int floor) { 668 | return getParent(new File(path), floor); 669 | } 670 | 671 | /** 672 | * 删除文件 673 | * 674 | * @param file 675 | * @return 676 | */ 677 | public static boolean deleteFile(File file) { 678 | boolean flag = false; 679 | if (file != null && file.exists()) { 680 | if (file.isDirectory()) { 681 | for (File f : file.listFiles()) { 682 | deleteFile(f); 683 | } 684 | } 685 | flag = file.delete(); 686 | } 687 | 688 | return flag; 689 | } 690 | 691 | /** 692 | * 根据路径删除指定的目录或文件,无论存在与否 693 | * 694 | * @param sPath 要删除的目录或文件 695 | * @return 删除成功返回 true,否则返回 false。 696 | */ 697 | public static boolean DeleteFolder(String sPath) { 698 | boolean flag = false; 699 | File file = new File(sPath); 700 | // 判断目录或文件是否存在 701 | if (!file.exists()) { // 不存在返回 false 702 | return flag; 703 | } else { 704 | // 判断是否为文件 705 | if (file.isFile()) { // 为文件时调用删除文件方法 706 | return deleteFile(sPath); 707 | } else { // 为目录时调用删除目录方法 708 | return deleteDirectory(sPath); 709 | } 710 | } 711 | } 712 | 713 | /** 714 | * 删除单个文件 715 | * 716 | * @param sPath 被删除文件的文件名 717 | * @return 单个文件删除成功返回true,否则返回false 718 | */ 719 | public static boolean deleteFile(String sPath) { 720 | boolean flag = false; 721 | File file = new File(sPath); 722 | // 路径为文件且不为空则进行删除 723 | if (file.isFile() && file.exists()) { 724 | file.delete(); 725 | flag = true; 726 | } 727 | return flag; 728 | } 729 | 730 | 731 | /** 732 | * 压缩超过2m的图片 733 | * @param url 734 | * @return 735 | * @throws Exception 736 | */ 737 | public static String savePreFile(String url) throws Exception { 738 | StringBuffer str = new StringBuffer(); 739 | str.append("/img/"); 740 | str.append(DateTimeUtil.formatDatetoString(new Date())); 741 | str.append("/pre/"); 742 | str.append(url.substring(url.lastIndexOf("/")+1)); 743 | String preUrl = fileUploadPath + str.toString(); 744 | File filePath = new File(StringUtil.utf8Decoding(preUrl.substring(0,preUrl.lastIndexOf("/")))); 745 | if(!filePath.exists()){ 746 | filePath.mkdirs(); 747 | } 748 | createFile(preUrl); 749 | //其中的scale是可以指定图片的大小,值在0到1之间,1f就是原图大小,0.5就是原图的一半大小,这里的大小是指图片的长宽。 750 | //而outputQuality是图片的质量,值也是在0到1,越接近于1质量越好,越接近于0质量越差。 751 | Thumbnails.of(fileUploadPath+url) 752 | .scale(1f) 753 | .outputQuality(0.5f) 754 | .toFile(preUrl); 755 | return str.toString(); 756 | } 757 | 758 | /** 759 | * 删除目录(文件夹)以及目录下的文件 760 | * 761 | * @param sPath 被删除目录的文件路径 762 | * @return 目录删除成功返回true,否则返回false 763 | */ 764 | public static boolean deleteDirectory(String sPath) { 765 | // 如果sPath不以文件分隔符结尾,自动添加文件分隔符 766 | if (!sPath.endsWith(File.separator)) { 767 | sPath = sPath + File.separator; 768 | } 769 | File dirFile = new File(sPath); 770 | // 如果dir对应的文件不存在,或者不是一个目录,则退出 771 | if (!dirFile.exists() || !dirFile.isDirectory()) { 772 | return false; 773 | } 774 | boolean flag = true; 775 | // 删除文件夹下的所有文件(包括子目录) 776 | File[] files = dirFile.listFiles(); 777 | for (int i = 0; i < files.length; i++) { 778 | // 删除子文件 779 | if (files[i].isFile()) { 780 | flag = deleteFile(files[i].getAbsolutePath()); 781 | if (!flag) { 782 | break; 783 | } 784 | } // 删除子目录 785 | else { 786 | flag = deleteDirectory(files[i].getAbsolutePath()); 787 | if (!flag) { 788 | break; 789 | } 790 | } 791 | } 792 | if (!flag) { 793 | return false; 794 | } 795 | // 删除当前目录 796 | if (dirFile.delete()) { 797 | return true; 798 | } else { 799 | return false; 800 | } 801 | } 802 | 803 | /** 804 | * 检查文件名是否合法 805 | * 806 | * @param fileName 807 | * @return 808 | */ 809 | public static boolean isValidFileName(String fileName) { 810 | if (fileName == null || fileName.length() > 255) 811 | return false; 812 | else { 813 | return fileName.matches( 814 | "[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$"); 815 | } 816 | } 817 | 818 | /** 819 | * 复制文件 820 | * 821 | * @param src 822 | * @param dst 823 | */ 824 | public static void copy(File src, File dst) { 825 | InputStream in = null; 826 | OutputStream out = null; 827 | try { 828 | in = new FileInputStream(src); 829 | out = new FileOutputStream(dst); 830 | 831 | // Transfer bytes from in to out 832 | byte[] buf = new byte[1024]; 833 | int len = -1; 834 | while ((len = in.read(buf)) > 0) { 835 | out.write(buf, 0, len); 836 | } 837 | } catch (Exception e) { 838 | e.printStackTrace(); 839 | } finally { 840 | try { 841 | if (in != null) { 842 | in.close(); 843 | } 844 | } catch (Exception e) { 845 | e.printStackTrace(); 846 | } finally { 847 | try { 848 | if (out != null) { 849 | out.close(); 850 | } 851 | } catch (Exception e2) { 852 | e2.printStackTrace(); 853 | } 854 | } 855 | } 856 | return; 857 | } 858 | 859 | /** 860 | * 取指定文件的扩展名 861 | * 862 | * @param filePathName 文件路径 863 | * @return 扩展名 864 | */ 865 | public static String getFileExt(String filePathName) { 866 | int pos = 0; 867 | pos = filePathName.lastIndexOf('.'); 868 | if (pos != -1) { 869 | return filePathName.substring(pos + 1, filePathName.length()); 870 | } 871 | else { 872 | return ""; 873 | } 874 | } 875 | 876 | /** 877 | * 去掉文件扩展名 878 | * 879 | * @param filename 880 | * @return 881 | */ 882 | public static String trimExtension(String filename) { 883 | if ((filename != null) && (filename.length() > 0)) { 884 | int i = filename.lastIndexOf('.'); 885 | if ((i > -1) && (i < (filename.length()))) { 886 | return filename.substring(0, i); 887 | } 888 | } 889 | return filename; 890 | } 891 | 892 | /** 893 | * 读取文件大小 894 | * 895 | * @param filename 指定文件路径 896 | * @return 文件大小 897 | */ 898 | public static int getFileSize(String filename) { 899 | try { 900 | File fl = new File(filename); 901 | int length = (int) fl.length(); 902 | return length; 903 | } catch (Exception e) { 904 | return 0; 905 | } 906 | 907 | } 908 | 909 | /** 910 | * 判断是否是图片 911 | * 912 | * @param file 913 | * @return 914 | */ 915 | public static boolean isImage(File file) { 916 | boolean flag = false; 917 | try { 918 | ImageInputStream is = ImageIO.createImageInputStream(file); 919 | if (null == is) { 920 | return flag; 921 | } 922 | is.close(); 923 | flag = true; 924 | } catch (Exception e) { 925 | e.printStackTrace(); 926 | } 927 | return flag; 928 | } 929 | 930 | /** 931 | * TODO. 读取文件内容 932 | * 933 | * @param file 934 | * @param fullFilePath 935 | * @return 936 | * @throws IOException 937 | */ 938 | @SuppressWarnings("unused") 939 | public static String readFileContent(File file, String fullFilePath) throws IOException { 940 | String returnStr = ""; 941 | if (ComUtil.isEmpty(file) && ComUtil.isEmpty(fullFilePath)) { 942 | return ""; 943 | } 944 | if (ComUtil.isEmpty(file)) { 945 | file = new File(fullFilePath); 946 | } 947 | FileInputStream in = null; 948 | 949 | try { 950 | in = new FileInputStream(file); 951 | byte[] buf = new byte[1024]; 952 | int len = -1; 953 | while ((len = in.read(buf)) > 0) { 954 | returnStr += new String(buf, "utf-8"); 955 | buf = new byte[1024]; 956 | } 957 | } catch (FileNotFoundException e) { 958 | logger.error(e.getMessage() + ";" + file.getPath(), e); 959 | throw e; 960 | } catch (IOException e) { 961 | logger.error(e.getMessage() + ";" + file.getPath(), e); 962 | throw e; 963 | } finally { 964 | try { 965 | if (in != null) { 966 | in.close(); 967 | } 968 | } catch (Exception e) { 969 | e.printStackTrace(); 970 | } 971 | 972 | } 973 | return returnStr; 974 | } 975 | 976 | public static boolean writeToFile(String content, File file, String fullFilePath) throws IOException { 977 | if ((ComUtil.isEmpty(file) && ComUtil.isEmpty(fullFilePath)) || ComUtil.isEmpty(content)) { 978 | return false; 979 | } 980 | if (ComUtil.isEmpty(file)) { 981 | file = new File(fullFilePath); 982 | } 983 | FileOutputStream out = null; 984 | 985 | try { 986 | 987 | out = new FileOutputStream(file); 988 | 989 | out.write(content.getBytes("utf-8")); 990 | } catch (FileNotFoundException e) { 991 | logger.error(e.getMessage() + ";" + file.getPath(), e); 992 | throw e; 993 | } catch (IOException e) { 994 | logger.error(e.getMessage() + ";" + file.getPath(), e); 995 | throw e; 996 | } finally { 997 | try { 998 | if (out != null) { 999 | out.close(); 1000 | } 1001 | } catch (Exception e) { 1002 | e.printStackTrace(); 1003 | } 1004 | 1005 | } 1006 | return false; 1007 | } 1008 | 1009 | /** 1010 | * 在指定的目录下创建文件 1011 | * 1012 | * @param directory 1013 | * @param fileName 1014 | * @param content 1015 | * @throws Exception 1016 | */ 1017 | public static String createFile(String directory, String fileName, InputStream content) throws Exception { 1018 | File currentDir = new File(directory); 1019 | if (!currentDir.exists()) { 1020 | currentDir.mkdirs(); 1021 | } 1022 | FileOutputStream fileOut = null; 1023 | String fullFilePath = directory + File.separator + fileName; 1024 | try { 1025 | fileOut = new FileOutputStream(fullFilePath); 1026 | int len = 0; 1027 | byte[] buffer = new byte[1024]; 1028 | while ((len = content.read(buffer)) > 0) { 1029 | fileOut.write(buffer); 1030 | } 1031 | } finally { 1032 | if (content != null) { 1033 | content.close(); 1034 | } 1035 | if (fileOut != null) { 1036 | fileOut.close(); 1037 | } 1038 | } 1039 | return fullFilePath; 1040 | } 1041 | 1042 | public static File mkdir(String directory) { 1043 | File dir = new File(directory); 1044 | if (!dir.exists()) { 1045 | dir.mkdirs(); 1046 | } 1047 | return dir; 1048 | } 1049 | 1050 | public static String readFileContent(File file, Charset charset) throws Exception { 1051 | if (!file.exists() || file.isDirectory()) throw new Exception("file is not exists or is a directory"); 1052 | StringWriter out = new StringWriter(); 1053 | FileInputStream in = new FileInputStream(file); 1054 | try { 1055 | byte[] buffer = new byte[1024]; 1056 | int length = 0; 1057 | while ((length = in.read(buffer)) > 0) { 1058 | out.write(new String(buffer, 0, length, charset)); 1059 | } 1060 | } finally { 1061 | if (in != null) in.close(); 1062 | if (out != null) out.close(); 1063 | } 1064 | return out.toString(); 1065 | } 1066 | 1067 | public static String image2Base64String(InputStream content) throws Exception { 1068 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 1069 | try { 1070 | int length = 0; 1071 | byte[] buffer = new byte[1024]; 1072 | while((length = content.read(buffer)) > 0){ 1073 | out.write(buffer,0,length); 1074 | } 1075 | } finally { 1076 | if (content != null) content.close(); 1077 | if(out != null) out.close(); 1078 | } 1079 | BASE64Encoder encoder = new BASE64Encoder(); 1080 | return encoder.encode(out.toByteArray()); 1081 | } 1082 | 1083 | public static byte[] base64String2Image(String base64String) throws Exception{ 1084 | if(ComUtil.isEmpty(base64String)) return null; 1085 | base64String = base64String.replaceAll("data:image/(jpg|png|jpeg);base64,",""); 1086 | BASE64Decoder decoder = new BASE64Decoder(); 1087 | return decoder.decodeBuffer(base64String); 1088 | } 1089 | 1090 | // public static void main(String[] args) throws Exception { 1091 | // //System.out.println(Jsoup.parse(new File("D:\\result.htm"),"GBK").outerHtml()); 1092 | // //System.out.println(readFileContent(new File("D:\\result.htm"),Charset.forName("GBK"))); 1093 | // //System.out.println(image2Base64String(new FileInputStream(new File("D://123.png")))); 1094 | // System.out.println("data:image/png;base64,".replaceAll("data:image/(jpg|png|jpeg);base64,","")); 1095 | // } 1096 | /** 1097 | * 创建文件路径(文件夹) 1098 | * @param fileName 1099 | */ 1100 | public static void fileMkdir(String fileName) { 1101 | File fileTotal=new File(fileName); 1102 | if (!fileTotal.exists()) { 1103 | fileTotal.mkdirs(); 1104 | } 1105 | } 1106 | } 1107 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/util/JWTUtil.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.util; 2 | 3 | import com.auth0.jwt.JWT; 4 | import com.auth0.jwt.JWTVerifier; 5 | import com.auth0.jwt.algorithms.Algorithm; 6 | import com.auth0.jwt.exceptions.JWTDecodeException; 7 | import com.auth0.jwt.interfaces.DecodedJWT; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.data.redis.connection.RedisConnectionFactory; 14 | import org.springframework.data.redis.core.RedisTemplate; 15 | import org.springframework.data.redis.core.StringRedisTemplate; 16 | import org.springframework.stereotype.Component; 17 | 18 | import javax.annotation.Resource; 19 | import java.io.UnsupportedEncodingException; 20 | import java.sql.Savepoint; 21 | import java.util.Date; 22 | 23 | /** 24 | * @author liugh 25 | * @since 2018-05-07 26 | */ 27 | @Component 28 | public class JWTUtil { 29 | private static RedisTemplate redisTemplate; 30 | @Autowired 31 | public void setRedisTemplate(RedisTemplate redisTemplate) { 32 | JWTUtil.redisTemplate = redisTemplate; 33 | } 34 | 35 | // 过期时间(秒) 36 | private static Long expireTime; 37 | @Value("${expireTime}") 38 | private void getTime(Long expireTime){ 39 | JWTUtil.expireTime =expireTime; 40 | } 41 | // private static final long EXPIRE_TIME = 15*24*60*60*1000; 42 | 43 | /** 44 | * 校验token是否正确 45 | * @param token 密钥 46 | * @param secret 用户的密码 47 | * @return 是否正确 48 | */ 49 | public static boolean verify(String token, String userNo,String loginName, String secret) { 50 | try { 51 | if (StringUtils.startsWith(token,"Bearer") || StringUtils.startsWith(token,"bearer")){ 52 | String resultToken; 53 | if (StringUtils.startsWith(token,"B")){ 54 | resultToken = token.split("Bearer")[1].trim(); 55 | }else { 56 | resultToken = token.split("bearer")[1].trim(); 57 | } 58 | Algorithm algorithm = Algorithm.HMAC256(secret); 59 | JWTVerifier verifier = JWT.require(algorithm) 60 | .withClaim("id", userNo) 61 | .withClaim("loginName",loginName) 62 | .build(); 63 | verifier.verify(resultToken); 64 | return true; 65 | }else { 66 | return false; 67 | } 68 | } catch (Exception exception) { 69 | return false; 70 | } 71 | } 72 | 73 | /** 74 | * 获得token中的信息无需secret解密也能获得 75 | * @return token中包含的用户id 76 | */ 77 | public static String getUserNo(String token) { 78 | try { 79 | String resultToken; 80 | if (StringUtils.startsWith(token,"B")){ 81 | resultToken = token.split("Bearer")[1].trim(); 82 | }else { 83 | resultToken = token.split("bearer")[1].trim(); 84 | } 85 | DecodedJWT jwt = JWT.decode(resultToken); 86 | return jwt.getClaim("id").asString(); 87 | } catch (JWTDecodeException e) { 88 | return null; 89 | } 90 | } 91 | 92 | /** 93 | * 生成签名,指定时间后过期,一经生成不可修改,令牌在指定时间内一直有效 94 | * @param id 用户主键 95 | * @param secret 用户的密码 96 | * @return 加密的token 97 | */ 98 | public static String sign(String id,String loginName, String secret) { 99 | try { 100 | Date date = new Date(System.currentTimeMillis()+expireTime); 101 | Algorithm algorithm = Algorithm.HMAC256(secret); 102 | // 附带用户id信息 103 | String token = "Bearer "+JWT.create() 104 | .withClaim("id", id) 105 | .withClaim("loginName",loginName) 106 | .withExpiresAt(date) 107 | .sign(algorithm); 108 | //存放在redis里面(实现单端登录) 109 | saveRedis(id,token); 110 | return token; 111 | } catch (UnsupportedEncodingException e) { 112 | return null; 113 | } 114 | } 115 | 116 | private static void saveRedis(String id, String token) { 117 | Object token1 = redisTemplate.opsForHash().get("token", id); 118 | if (null != token1 && StringUtils.isNotBlank(String.valueOf(token1))){ 119 | redisTemplate.opsForHash().delete("token",id); 120 | } 121 | redisTemplate.opsForHash().put("token",id,token); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/util/ResponseModel.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.util; 2 | 3 | /** 4 | * 统一返回相应参数实体类 5 | * @author liugh 53182347@qq.com 6 | */ 7 | 8 | import org.springframework.web.context.request.RequestContextHolder; 9 | import org.springframework.web.context.request.ServletRequestAttributes; 10 | 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.Serializable; 13 | 14 | public class ResponseModel implements Serializable { 15 | private static final long serialVersionUID = -1241360949457314497L; 16 | private int status; 17 | private T result; 18 | private String message; 19 | private String code; 20 | 21 | public ResponseModel() { 22 | HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) 23 | .getResponse(); 24 | response.setCharacterEncoding("UTF-8"); 25 | } 26 | 27 | public String getMessage() { 28 | return this.message; 29 | } 30 | 31 | public String getCode() { 32 | return this.code; 33 | } 34 | 35 | public void setCode(String code) { 36 | this.code = code; 37 | } 38 | 39 | public void setMessage(String message) { 40 | this.message = message; 41 | } 42 | 43 | 44 | public int getStatus() { 45 | return this.status; 46 | } 47 | 48 | public void setStatus(int status) { 49 | this.status = status; 50 | } 51 | 52 | public T getResult() { 53 | return this.result; 54 | } 55 | 56 | public void setResult(T result) { 57 | this.result = result; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "ResponseModel [status=" + this.status + ", result=" + this.result + ", message=" + this.message + ", code=" + this.code + "]"; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/base_security/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.base_security.util; 2 | 3 | 4 | import net.sourceforge.pinyin4j.PinyinHelper; 5 | import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; 6 | import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; 7 | import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; 8 | import java.io.UnsupportedEncodingException; 9 | import java.lang.annotation.Annotation; 10 | import java.lang.reflect.Method; 11 | import java.net.URLDecoder; 12 | import java.util.regex.Matcher; 13 | import java.util.regex.Pattern; 14 | 15 | /** 16 | * @author liugh 17 | * @since on 2018/5/8. 18 | */ 19 | public class StringUtil { 20 | 21 | public static String pin(String chinese) throws Exception { 22 | String pinyin = ""; 23 | HanyuPinyinOutputFormat pinyinOutputFormat = new HanyuPinyinOutputFormat(); 24 | pinyinOutputFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE); 25 | pinyinOutputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); 26 | String[] pinyinArray = null; 27 | for(char ch : chinese.toCharArray()){ 28 | pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch,pinyinOutputFormat); 29 | pinyin += ComUtil.isEmpty(pinyinArray) ? ch : pinyinArray[0]; 30 | } 31 | return pinyin; 32 | } 33 | 34 | /** 35 | * 获取方法中指定注解的value值返回 36 | * @param method 方法名 37 | * @param validationParamValue 注解的类名 38 | * @return 39 | */ 40 | public static String getMethodAnnotationOne(Method method, String validationParamValue) { 41 | String retParam =null; 42 | Annotation[][] parameterAnnotations = method.getParameterAnnotations(); 43 | for (int i = 0; i < parameterAnnotations.length; i++) { 44 | for (int j = 0; j < parameterAnnotations[i].length; j++) { 45 | String str = parameterAnnotations[i][j].toString(); 46 | if(str.indexOf(validationParamValue) >0){ 47 | retParam = str.substring(str.indexOf("=")+1,str.indexOf(")")); 48 | } 49 | } 50 | } 51 | return retParam; 52 | } 53 | 54 | public static boolean isValidURLAddress(String url) { 55 | String pattern = "([h]|[H])([t]|[T])([t]|[T])([p]|[P])([s]|[S]){0,1}://([^:/]+)(:([0-9]+))?(/\\S*)*"; 56 | return url.matches(pattern); 57 | } 58 | /** 59 | * 将utf-8编码的汉字转为中文 60 | * @author zhaoqiang 61 | * @param str 62 | * @return 63 | */ 64 | public static String utf8Decoding(String str){ 65 | String result = str; 66 | try 67 | { 68 | result = URLDecoder.decode(str, "UTF-8"); 69 | } 70 | catch (UnsupportedEncodingException e) 71 | { 72 | e.printStackTrace(); 73 | } 74 | return result; 75 | } 76 | 77 | public static boolean checkEmail(String email) { 78 | if (ComUtil.isEmpty(email)) { 79 | return false; 80 | } 81 | boolean flag = false; 82 | try { 83 | String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; 84 | Pattern regex = Pattern.compile(check); 85 | Matcher matcher = regex.matcher(email); 86 | flag = matcher.matches(); 87 | } catch (Exception e) { 88 | flag = false; 89 | } 90 | return flag; 91 | } 92 | /** 93 | * 验证手机号码,11位数字,1开通,第二位数必须是3456789这些数字之一 * 94 | * @param mobileNumber 95 | * @return 96 | */ 97 | public static boolean checkMobileNumber(String mobileNumber) { 98 | boolean flag = false; 99 | try { 100 | // Pattern regex = Pattern.compile("^(((13[0-9])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8})|(0\\d{2}-\\d{8})|(0\\d{3}-\\d{7})$"); 101 | Pattern regex = Pattern.compile("^1[345789]\\d{9}$"); 102 | Matcher matcher = regex.matcher(mobileNumber); 103 | flag = matcher.matches(); 104 | } catch (Exception e) { 105 | e.printStackTrace(); 106 | flag = false; 107 | } 108 | return flag; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/commons/Constants.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.commons; 2 | 3 | 4 | /** 5 | * 常量配置清单(按需添加) 6 | * @author liuxinghong 7 | */ 8 | public class Constants { 9 | /** 10 | * 没有分隔符的年月日 11 | */ 12 | public static final String YYYYMMdd = "YYYYMMdd"; 13 | /** 14 | * 没有分隔符的年月日时分秒毫秒 15 | */ 16 | public static final String YYYYMMddHHmmssSSS = "YYYYMMddHHmmssSSS"; 17 | public static final String YYYY_MM_DD_HH_MM_SS = "YYYY-MM-dd HH:mm:ss"; 18 | public static final String YYYY_MM_DD = "YYYY-MM-dd"; 19 | public static final String SPLIT = ","; 20 | /** 21 | * 文件路径分隔符,windows 22 | */ 23 | public static final String PATH_SEPARATOR_WIN = "\\"; 24 | /** 25 | * 文件路径分隔符 linux 26 | */ 27 | public static final String PATH_SEPARATOR_LINUX = "/"; 28 | /** 29 | * 状态正常 30 | */ 31 | public static final Integer STATUE_NORMAL = 1; 32 | /** 33 | * 状态删除 34 | */ 35 | public static final Integer STATUE_DEL = 0; 36 | 37 | 38 | /** 39 | * 顶级父节点 40 | */ 41 | public static final Integer TOP_PARENT = 0; 42 | /** 43 | * 顶级父节点 44 | */ 45 | public static final String STRING_TOP_PARENT = "0"; 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/commons/HttpStatus.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.commons; 2 | 3 | /** 4 | * @author lxh 5 | */ 6 | 7 | public enum HttpStatus { 8 | 9 | OK(200, "请求成功"), 10 | BAD_REQUEST(400, "请求出错"), 11 | UNAUTHORIZED(401, "登录异常,重新登录"), 12 | FORBIDDEN(403, "没有权限"), 13 | NOT_FOUND(404, "找不到页面"), 14 | INTERNAL_SERVER_ERROR(500, "服务器出错"), 15 | LOGIN_FAIL(1001,"登录异常!"), 16 | TOKEN_PARSER_FAIL(1002,"令牌解析异常!"), 17 | VALIDATED_FAIL(1004,"数据验证失败!"), 18 | 19 | NSOP_DATA_NULL(501, "没有查询到数据"), 20 | NSOP_SAVE_FAIL(502, "保存数据失败"), 21 | NSOP_DEL_FAIL(503, "删除数据失败"), 22 | 23 | //用户已签约 24 | NSOP_CONTRACT(2008,"用户已签约!"), 25 | NSOP_NO_QUERY_CONTRACT(2009,"没有查询到签约信息!"), 26 | 27 | NSOP_CAPTCHA_NULL(601,"请输入验证码!"), 28 | NSOP_CAPTCHA_ERROR(602,"验证码输入错误!"), 29 | NSOP_CAPTCHA_INVALID(603,"验证码已失效!"), 30 | NSOP_UPLOAD_FAIL(1003,"上传失败"); 31 | 32 | 33 | private final int value; 34 | 35 | private final String msg; 36 | 37 | HttpStatus(int value, String msg) { 38 | this.value = value; 39 | this.msg = msg; 40 | } 41 | 42 | public int value() { 43 | return value; 44 | } 45 | 46 | public String msg() { 47 | return msg; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/config/LiquibaseConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.config; 2 | 3 | import liquibase.integration.spring.SpringLiquibase; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | import javax.sql.DataSource; 10 | 11 | /** 12 | * @author liuxinghong 13 | * @Description: 14 | * @date 2019/5/6 000618:43 15 | */ 16 | @Configuration 17 | public class LiquibaseConfig { 18 | 19 | @Value("${liquibase.path}") 20 | private String path; 21 | @Bean 22 | public SpringLiquibase liquibase(DataSource dataSource) { 23 | SpringLiquibase liquibase = new SpringLiquibase(); 24 | liquibase.setDataSource(dataSource); 25 | liquibase.setChangeLog(path); 26 | // liquibase.setContexts("dev,test,production"); 27 | liquibase.setShouldRun(true); 28 | return liquibase; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/config/MybatisPlusConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 5 | import org.mybatis.spring.annotation.MapperScan; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.context.annotation.Profile; 9 | 10 | /** 11 | * @author lxh 12 | * @date 2018/4/27 13 | */ 14 | @Configuration 15 | @MapperScan("com.example.demo.mapper*") 16 | public class MybatisPlusConfiguration { 17 | /** 18 | * mybatis-plus SQL执行效率插件【生产环境可以关闭】 19 | */ 20 | @Bean 21 | @Profile({"local","dev","test"})// 设置 dev test 环境开启 22 | public PerformanceInterceptor performanceInterceptor() { 23 | PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); 24 | performanceInterceptor.setFormat(true); 25 | performanceInterceptor.setMaxTime(20 * 1000); 26 | return performanceInterceptor; 27 | } 28 | 29 | 30 | /** 31 | * mybatis-plus分页插件 32 | * 文档:http://mp.baomidou.com
33 | */ 34 | @Bean 35 | public PaginationInterceptor paginationInterceptor() { 36 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 37 | paginationInterceptor.setDialectType("mysql"); 38 | // paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持 39 | /* 40 | * 【测试多租户】 SQL 解析处理拦截器
41 | * 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )
42 | */ 43 | /*List sqlParserList = new ArrayList<>(); 44 | TenantSqlParser tenantSqlParser = new TenantSqlParser(); 45 | tenantSqlParser.setTenantHandler(new TenantHandler() { 46 | @Override 47 | public Expression getTenantId() { 48 | return new LongValue(1L); 49 | } 50 | 51 | @Override 52 | public String getTenantIdColumn() { 53 | return "tenant_id"; 54 | } 55 | 56 | @Override 57 | public boolean doTableFilter(String tableName) { 58 | // 这里可以判断是否过滤表 59 | *//* 60 | if ("user".equals(tableName)) { 61 | return true; 62 | }*//* 63 | return false; 64 | } 65 | }); 66 | 67 | 68 | sqlParserList.add(tenantSqlParser); 69 | paginationInterceptor.setSqlParserList(sqlParserList); 70 | paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() { 71 | @Override 72 | public boolean doFilter(MetaObject metaObject) { 73 | MappedStatement ms = PluginUtils.getMappedStatement(metaObject); 74 | // 过滤自定义查询此时无租户信息约束【 麻花藤 】出现 75 | if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) { 76 | return true; 77 | } 78 | return false; 79 | } 80 | });*/ 81 | return paginationInterceptor; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.config; 2 | 3 | import com.google.common.collect.Sets; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.ParameterBuilder; 8 | import springfox.documentation.builders.PathSelectors; 9 | import springfox.documentation.builders.RequestHandlerSelectors; 10 | import springfox.documentation.schema.ModelRef; 11 | import springfox.documentation.service.ApiInfo; 12 | import springfox.documentation.service.Contact; 13 | import springfox.documentation.service.Parameter; 14 | import springfox.documentation.spi.DocumentationType; 15 | import springfox.documentation.spring.web.plugins.Docket; 16 | import springfox.documentation.swagger.web.SwaggerResource; 17 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | /** 23 | * @author liuxinghong 24 | * @Description: 25 | * @date 2019/5/7 000709:19 26 | */ 27 | @Configuration 28 | @EnableSwagger2 29 | public class SwaggerConfiguration { 30 | 31 | @Bean 32 | public Docket configSpringfoxDocketForAll() { 33 | ParameterBuilder tokenPar = new ParameterBuilder(); 34 | List pars = new ArrayList<>(); 35 | tokenPar.name("Authorization").description("权限验证令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); 36 | pars.add(tokenPar.build()); 37 | return new Docket(DocumentationType.SWAGGER_2) 38 | .produces(Sets.newHashSet("application/json","application/x-www-form-urlencoded","*/*")) 39 | .consumes(Sets.newHashSet("application/json","application/x-www-form-urlencoded","*/*")) 40 | .protocols(Sets.newHashSet("http")) 41 | .forCodeGeneration(true) 42 | .select() 43 | .paths(PathSelectors.any()) 44 | .apis(RequestHandlerSelectors.basePackage("com.example.demo")) 45 | .build() 46 | .globalOperationParameters(pars) 47 | .apiInfo(apiInfo()); 48 | } 49 | private ApiInfo apiInfo(){ 50 | return new ApiInfoBuilder() 51 | .title("接口调用文档") 52 | .description("前后端调试对接文档") 53 | .contact(new Contact("liuxinghong","","349695133@qq.com")) 54 | .version("2.0") 55 | .build(); 56 | } 57 | private SwaggerResource swaggerResource(String name, String location) { 58 | SwaggerResource swaggerResource = new SwaggerResource(); 59 | swaggerResource.setName(name); 60 | swaggerResource.setLocation(location); 61 | swaggerResource.setSwaggerVersion("2.0"); 62 | return swaggerResource; 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/main/java/com/example/demo/controller/SysLogController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import org.springframework.stereotype.Controller; 7 | 8 | /** 9 | *

10 | * 日志信息表 前端控制器 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Controller 17 | @RequestMapping("/sysLog") 18 | public class SysLogController { 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/controller/SysResController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import org.springframework.stereotype.Controller; 7 | 8 | /** 9 | *

10 | * 资源表 前端控制器 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Controller 17 | @RequestMapping("/entity/sysRes") 18 | public class SysResController { 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/controller/SysRoleController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import org.springframework.stereotype.Controller; 7 | 8 | /** 9 | *

10 | * 角色表 前端控制器 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Controller 17 | @RequestMapping("/entity/sysRole") 18 | public class SysRoleController { 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/controller/SysRoleResController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import org.springframework.stereotype.Controller; 7 | 8 | /** 9 | *

10 | * 角色资源表 前端控制器 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Controller 17 | @RequestMapping("/entity/sysRoleRes") 18 | public class SysRoleResController { 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/controller/SysUserController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.core.toolkit.IdWorker; 6 | import com.example.demo.VO.USerAddVO; 7 | import com.example.demo.base_controller.BaseController; 8 | import com.example.demo.entity.SysUser; 9 | import com.example.demo.service.SysUserService; 10 | import io.swagger.annotations.Api; 11 | import io.swagger.annotations.ApiImplicitParam; 12 | import io.swagger.annotations.ApiImplicitParams; 13 | import io.swagger.annotations.ApiOperation; 14 | import org.mindrot.jbcrypt.BCrypt; 15 | import org.springframework.beans.BeanUtils; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | import org.springframework.validation.annotation.Validated; 18 | import org.springframework.web.bind.annotation.*; 19 | 20 | import org.springframework.stereotype.Controller; 21 | 22 | /** 23 | *

24 | * 用户表 前端控制器 25 | *

26 | * 27 | * @author LXH 28 | * @since 2019-05-06 29 | */ 30 | @Controller 31 | @RequestMapping("/sysUser") 32 | @Api("用户管理") 33 | public class SysUserController extends BaseController { 34 | @Autowired 35 | private SysUserService userService; 36 | 37 | @PostMapping("/add") 38 | @ApiOperation(value="添加用户", notes="添加用户") 39 | public Object add(@RequestBody @Validated USerAddVO vo){ 40 | SysUser user = new SysUser(); 41 | user.setId(IdWorker.getIdStr()); 42 | user.setPwd(BCrypt.hashpw(vo.getPwd(), BCrypt.gensalt())); 43 | BeanUtils.copyProperties(vo,user); 44 | QueryWrapper wrapper = new QueryWrapper<>(); 45 | wrapper.setEntity(new SysUser()); 46 | return success(userService.save(user)); 47 | } 48 | 49 | @GetMapping("/list") 50 | @ApiOperation(value="用户列表", notes="") 51 | @ApiImplicitParams({ 52 | @ApiImplicitParam(name = "pageNO", value = "页数", dataType = "Integer"), 53 | @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "Integer") 54 | }) 55 | public Object list(@RequestParam("pageNO") Integer pageNO, @RequestParam("pageSize") Integer pageSize){ 56 | return success(userService.pageList(pageNO,pageSize)); 57 | } 58 | 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/controller/SysUserRoleController.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import org.springframework.stereotype.Controller; 7 | 8 | /** 9 | *

10 | * 用户角色表 前端控制器 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Controller 17 | @RequestMapping("/entity/sysUserRole") 18 | public class SysUserRoleController { 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/entity/SysLog.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.entity; 2 | 3 | import java.util.Date; 4 | 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.Data; 8 | import scala.util.parsing.combinator.testing.Str; 9 | 10 | import java.io.Serializable; 11 | 12 | /** 13 | *

14 | * 日志信息表 15 | *

16 | * 17 | * @author LXH 18 | * @since 2019-05-06 19 | */ 20 | @TableName("sys_log") 21 | @Data 22 | public class SysLog implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | /** 27 | * 日志信息表主键 28 | */ 29 | private String id; 30 | /** 31 | * 日志类型(1:增,2:删,3:改,4:查) 32 | */ 33 | private Integer type; 34 | /** 35 | * 日志说明(日志数据) 36 | */ 37 | private String desc; 38 | /** 39 | * 操作详情 40 | */ 41 | private String remark; 42 | /** 43 | * 操作人IP地址 44 | */ 45 | private String adr; 46 | /** 47 | * 删除标识(1:未删除,2:已删除) 48 | */ 49 | private Integer status; 50 | /** 51 | * 创建时间 52 | */ 53 | @TableField("create_time") 54 | private Date createTime; 55 | /** 56 | * 创建用户 57 | */ 58 | @TableField("create_user") 59 | private String createUser; 60 | 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/entity/SysRes.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import lombok.Data; 6 | 7 | import java.util.Date; 8 | import java.io.Serializable; 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 资源表 14 | *

15 | * 16 | * @author LXH 17 | * @since 2019-05-06 18 | */ 19 | @TableName("sys_res") 20 | @Data 21 | public class SysRes implements Serializable { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private String id; 26 | private String pid; 27 | /** 28 | * 在vue中name表示路由名称,非vue是资源名称 29 | */ 30 | private String name; 31 | private String permission; 32 | /** 33 | * vue中表示路由的path 34 | */ 35 | private String url; 36 | /** 37 | * 排序 38 | */ 39 | @TableField("sort_num") 40 | private Integer sortNum; 41 | /** 42 | * PC菜单图片 43 | */ 44 | private String icon1; 45 | /** 46 | * APP菜单图片 47 | */ 48 | private String icon2; 49 | /** 50 | * TreeTable排序 51 | */ 52 | private String pids; 53 | /** 54 | * 1 菜单 2 按钮 55 | */ 56 | private Integer type; 57 | private String des; 58 | /** 59 | * 1 可用 0 不可用 -1: 删除 60 | */ 61 | private Integer status; 62 | /** 63 | * 创建时间 64 | */ 65 | @TableField("create_time") 66 | private Date createTime; 67 | /** 68 | * 修改时间 69 | */ 70 | @TableField("update_time") 71 | private Date updateTime; 72 | 73 | @TableField(exist = false) 74 | private List ChildRes; 75 | 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import lombok.Data; 6 | 7 | import java.util.Date; 8 | import java.io.Serializable; 9 | 10 | /** 11 | *

12 | * 角色表 13 | *

14 | * 15 | * @author LXH 16 | * @since 2019-05-06 17 | */ 18 | @TableName("sys_role") 19 | @Data 20 | public class SysRole implements Serializable { 21 | 22 | private static final long serialVersionUID = 1L; 23 | 24 | private String id; 25 | private String name; 26 | private String code; 27 | @TableField("sort_num") 28 | private Integer sortNum; 29 | private String des; 30 | /** 31 | * 角色类型 0,超管 1.普通用户 32 | */ 33 | private Integer type; 34 | /** 35 | * 1 可用 0 不可用 -1: 删除 36 | */ 37 | private Integer status; 38 | /** 39 | * 创建时间 40 | */ 41 | @TableField("create_time") 42 | private Date createTime; 43 | /** 44 | * 修改时间 45 | */ 46 | @TableField("update_time") 47 | private Date updateTime; 48 | 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/entity/SysRoleRes.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | *

12 | * 角色资源表 13 | *

14 | * 15 | * @author LXH 16 | * @since 2019-05-06 17 | */ 18 | @TableName("sys_role_res") 19 | @Data 20 | @Builder 21 | public class SysRoleRes implements Serializable { 22 | 23 | private static final long serialVersionUID = 1L; 24 | 25 | private String id; 26 | @TableField("res_id") 27 | private String resId; 28 | @TableField("role_id") 29 | private String roleId; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/entity/SysUser.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.entity; 2 | 3 | import java.util.Date; 4 | 5 | import com.baomidou.mybatisplus.annotation.TableField; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.*; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | *

13 | * 用户表 14 | *

15 | * 16 | * @author LXH 17 | * @since 2019-05-06 18 | */ 19 | @TableName("sys_user") 20 | @Data 21 | @Builder 22 | @ToString 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | public class SysUser implements Serializable { 26 | 27 | private static final long serialVersionUID = 1L; 28 | 29 | private String id; 30 | @TableField("login_name") 31 | private String loginName; 32 | @TableField("user_no") 33 | private String userNo; 34 | private String pwd; 35 | private String salt; 36 | private String name; 37 | private String email; 38 | /** 39 | * 1:男,0:女 40 | */ 41 | private Integer sex; 42 | /** 43 | * 手机号 44 | */ 45 | @TableField("mobile_no") 46 | private String mobileNo; 47 | /** 48 | * 微信号 49 | */ 50 | @TableField("weixin_id") 51 | private String weixinId; 52 | /** 53 | * 注册时间 54 | */ 55 | @TableField("reg_time") 56 | private Date regTime; 57 | /** 58 | * 头像 59 | */ 60 | private String avatar; 61 | /** 62 | * 1 可用 0 不可用 -1: 删除 63 | */ 64 | private Integer status; 65 | /** 66 | * 创建时间 67 | */ 68 | @TableField("create_time") 69 | private Date createTime; 70 | /** 71 | * 修改时间 72 | */ 73 | @TableField("update_time") 74 | private Date updateTime; 75 | /** 76 | * 客户id 77 | */ 78 | @TableField("client_id") 79 | private String clientId; 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/entity/SysUserRole.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableName; 5 | import lombok.Data; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 用户角色表 12 | *

13 | * 14 | * @author LXH 15 | * @since 2019-05-06 16 | */ 17 | @TableName("sys_user_role") 18 | @Data 19 | public class SysUserRole implements Serializable { 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | private String id; 24 | @TableField("user_id") 25 | private String userId; 26 | @TableField("role_id") 27 | private String roleId; 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/mapper/SysLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.example.demo.entity.SysLog; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 日志信息表 Mapper 接口 10 | *

11 | * 12 | * @author LXH 13 | * @since 2019-05-06 14 | */ 15 | @Mapper 16 | public interface SysLogMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/mapper/SysResMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.example.demo.entity.SysRes; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Param; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 资源表 Mapper 接口 14 | *

15 | * 16 | * @author LXH 17 | * @since 2019-05-06 18 | */ 19 | @Mapper 20 | public interface SysResMapper extends BaseMapper { 21 | 22 | List findMenuByRoleCode(@Param("roleCode") List roleCode); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.example.demo.entity.SysRole; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | /** 9 | *

10 | * 角色表 Mapper 接口 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Mapper 17 | public interface SysRoleMapper extends BaseMapper { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/mapper/SysRoleResMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.example.demo.entity.SysRoleRes; 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | /** 9 | *

10 | * 角色资源表 Mapper 接口 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | @Mapper 17 | public interface SysRoleResMapper extends BaseMapper { 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/mapper/SysUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import com.example.demo.entity.SysUser; 7 | import org.apache.ibatis.annotations.Mapper; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 用户表 Mapper 接口 14 | *

15 | * 16 | * @author LXH 17 | * @since 2019-05-06 18 | */ 19 | @Mapper 20 | public interface SysUserMapper extends BaseMapper { 21 | List selectByParam(Page pageInfo); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/mapper/SysUserRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.example.demo.entity.SysUserRole; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | /** 8 | *

9 | * 用户角色表 Mapper 接口 10 | *

11 | * 12 | * @author LXH 13 | * @since 2019-05-06 14 | */ 15 | @Mapper 16 | public interface SysUserRoleMapper extends BaseMapper { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/SysLogService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.example.demo.entity.SysLog; 5 | 6 | /** 7 | *

8 | * 日志信息表 服务类 9 | *

10 | * 11 | * @author LXH 12 | * @since 2019-05-06 13 | */ 14 | public interface SysLogService extends IService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/SysResService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.example.demo.entity.SysRes; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 资源表 服务类 12 | *

13 | * 14 | * @author LXH 15 | * @since 2019-05-06 16 | */ 17 | public interface SysResService extends IService { 18 | 19 | 20 | /** 21 | * 根据 Ids 查询 22 | * @param permissionIds ids 23 | * @return 权限List 24 | */ 25 | List selectByIds(List permissionIds); 26 | 27 | /** 28 | * 根据角色查询菜单 29 | * @param roleIds 角色主键S 30 | * @return 31 | */ 32 | List findMenuByRoleCode(List roleIds); 33 | 34 | /** 35 | * 获取菜单树形结构 36 | * @param pId 37 | * @param list 38 | * @return 39 | */ 40 | List treeMenuList(String pId, List list); 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/SysRoleResService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.example.demo.entity.SysRoleRes; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

11 | * 角色资源表 服务类 12 | *

13 | * 14 | * @author LXH 15 | * @since 2019-05-06 16 | */ 17 | public interface SysRoleResService extends IService { 18 | /** 19 | * 根据角色ID查询 20 | * @param roleId 角色ID 21 | * @return 结果集 22 | */ 23 | List selectByRoleCode(String roleId); 24 | 25 | /** 26 | * 根据角色、权限集合录入数据 27 | * @param roleCode 角色ID 28 | * @param menuCodes 权限集合 29 | * @return 结果 true/false 30 | */ 31 | boolean saveAll(String roleCode, List menuCodes); 32 | 33 | boolean deleteAllByRoleCode(String roleCode); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/SysRoleService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.example.demo.base_security.VO.RoleAddVO; 6 | import com.example.demo.base_security.VO.RoleUpdateVO; 7 | import com.example.demo.entity.SysRole; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | *

13 | * 角色表 服务类 14 | *

15 | * 16 | * @author LXH 17 | * @since 2019-05-06 18 | */ 19 | public interface SysRoleService extends IService { 20 | 21 | /** 22 | * 新增角色以及角色权限信息 23 | * @param roleModel 角色以及角色权限信息 24 | * @return 新增结果 true/false 25 | */ 26 | boolean addRoleAndPermission(RoleAddVO roleModel)throws Exception; 27 | 28 | /** 29 | * 更新色以及角色权限信息 30 | * @param roleModel 31 | * @return 32 | * @throws Exception 33 | */ 34 | boolean updateRoleInfo(RoleUpdateVO roleModel)throws Exception; 35 | 36 | /** 37 | * 通过角色ID获取菜单列表 38 | * @param roleId 39 | * @return 40 | */ 41 | Map getMenuByRoleCode(String roleId); 42 | 43 | /** 44 | * 判断当前是否是超级管理员,如果是,不能修改信息 抛出异常 45 | * @param userNo 46 | * @throws Exception 47 | */ 48 | void getRoleIsAdminByUserNo(String userNo) throws Exception; 49 | 50 | Map selectByRoleCode(String roleCode)throws Exception; 51 | 52 | void deleteByRoleCode(String roleCode)throws Exception; 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/SysUserRoleService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.example.demo.entity.SysUserRole; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 用户角色表 服务类 11 | *

12 | * 13 | * @author LXH 14 | * @since 2019-05-06 15 | */ 16 | public interface SysUserRoleService extends IService { 17 | 18 | /** 19 | * 根据用户ID查询人员角色 20 | * @param id 用户ID 21 | * @return 结果 22 | */ 23 | List selectByUserNo(String id); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/SysUserService.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service; 2 | 3 | 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import com.baomidou.mybatisplus.extension.service.IService; 7 | import com.example.demo.base_security.VO.registerVO; 8 | import com.example.demo.entity.SysUser; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import java.util.Map; 12 | 13 | /** 14 | *

15 | * 用户表 服务类 16 | *

17 | * 18 | * @author LXH 19 | * @since 2019-05-06 20 | */ 21 | public interface SysUserService extends IService { 22 | 23 | 24 | Page pageList(Integer pageNO, Integer pageSize); 25 | /** 26 | * 根据用户名查询用户 27 | * @param username 用户名 28 | * @return 用户 29 | */ 30 | SysUser getUserByUserName(String username); 31 | 32 | SysUser getUserByMobile(String mobile); 33 | 34 | /** 35 | * 注册用户 36 | * @param user 37 | * @return 38 | */ 39 | SysUser register(SysUser user); 40 | 41 | Map getLoginUserAndMenuInfo(SysUser user); 42 | 43 | void deleteByUserNo(String userId)throws Exception; 44 | 45 | Page selectPageByConditionUser(Page userPage, String info, Integer[] status, String startTime, String endTime); 46 | 47 | Map checkMobileAndPasswd(JSONObject requestJson)throws Exception; 48 | 49 | Map checkMobileAndCatcha(JSONObject requestJson)throws Exception; 50 | 51 | SysUser checkAndRegisterUser(registerVO vo)throws Exception; 52 | 53 | SysUser updateForgetPasswd(JSONObject requestJson)throws Exception; 54 | 55 | void resetMobile(SysUser currentUser, JSONObject requestJson)throws Exception; 56 | 57 | void resetPassWord(SysUser currentUser, JSONObject requestJson)throws Exception; 58 | 59 | boolean loginOut(String userId); 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/impl/SysLogServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.example.demo.entity.SysLog; 5 | import com.example.demo.mapper.SysLogMapper; 6 | import com.example.demo.service.SysLogService; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | *

11 | * 日志信息表 服务实现类 12 | *

13 | * 14 | * @author LXH 15 | * @since 2019-05-06 16 | */ 17 | @Service 18 | public class SysLogServiceImpl extends ServiceImpl implements SysLogService { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/impl/SysResServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.example.demo.commons.Constant; 6 | import com.example.demo.entity.SysRes; 7 | import com.example.demo.mapper.SysResMapper; 8 | import com.example.demo.service.SysResService; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.cache.annotation.Cacheable; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | import javax.management.Query; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | /** 19 | *

20 | * 资源表 服务实现类 21 | *

22 | * 23 | * @author LXH 24 | * @since 2019-05-06 25 | */ 26 | @Service 27 | @Transactional 28 | public class SysResServiceImpl extends ServiceImpl implements SysResService { 29 | 30 | @Autowired 31 | private SysResMapper menuMapper; 32 | 33 | @Override 34 | //redis方法级别的缓存,需要做缓存打开改注解即可 35 | //@Cacheable(value = "UserToRole",keyGenerator="wiselyKeyGenerator") 36 | public List selectByIds(List permissionIds) { 37 | QueryWrapper ew = new QueryWrapper<>(); 38 | ew.in("id", permissionIds); 39 | return this.list(ew); 40 | } 41 | 42 | @Override 43 | // @Cacheable(value = "UserToRole",keyGenerator="wiselyKeyGenerator") 44 | public List findMenuByRoleCode(List roleIds) { 45 | return menuMapper.findMenuByRoleCode(roleIds); 46 | } 47 | 48 | @Override 49 | public List treeMenuList(String pId, List list) { 50 | List IteratorMenuList = new ArrayList<>(); 51 | for (SysRes m : list) { 52 | if (String.valueOf(m.getPid()).equals(pId)) { 53 | List childMenuList = treeMenuList(String.valueOf(m.getId()), list); 54 | m.setChildRes(childMenuList); 55 | if(m.getType() == Constant.TYPE_MENU){ 56 | IteratorMenuList.add(m); 57 | } 58 | } 59 | } 60 | return IteratorMenuList; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/impl/SysRoleResServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.toolkit.IdWorker; 5 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 6 | import com.example.demo.entity.SysRoleRes; 7 | import com.example.demo.mapper.SysRoleResMapper; 8 | import com.example.demo.base_security.util.ComUtil; 9 | import com.example.demo.service.SysRoleResService; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | *

17 | * 角色资源表 服务实现类 18 | *

19 | * 20 | * @author LXH 21 | * @since 2019-05-06 22 | */ 23 | @Service 24 | public class SysRoleResServiceImpl extends ServiceImpl implements SysRoleResService { 25 | 26 | @Override 27 | //redis生成key注解,以类名方法名和参数组成key 28 | // @Cacheable(value = "UserToRole",keyGenerator="wiselyKeyGenerator") 29 | public List selectByRoleCode(String roleCode) { 30 | QueryWrapper ew = new QueryWrapper<>(); 31 | ew.eq("role_id", roleCode); 32 | return this.list(ew); 33 | } 34 | 35 | @Override 36 | public boolean saveAll(String roleCode, List menuCodes) { 37 | boolean result = true; 38 | if (!ComUtil.isEmpty(menuCodes)) { 39 | List modelList = new ArrayList<>(); 40 | for (String menuCode : menuCodes) { 41 | modelList.add(SysRoleRes.builder().id(IdWorker.getIdStr()).roleId(roleCode).resId(menuCode).build()); 42 | } 43 | result = this.saveBatch(modelList); 44 | } 45 | return result; 46 | } 47 | 48 | @Override 49 | public boolean deleteAllByRoleCode(String roleCode) { 50 | QueryWrapper ew = new QueryWrapper<>(); 51 | ew.eq("role_id", roleCode); 52 | return this.remove(ew); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/impl/SysRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.example.demo.base_security.VO.RoleAddVO; 6 | import com.example.demo.base_security.VO.RoleUpdateVO; 7 | import com.example.demo.base_security.commons.Constant; 8 | import com.example.demo.entity.SysRes; 9 | import com.example.demo.entity.SysRole; 10 | import com.example.demo.entity.SysRoleRes; 11 | import com.example.demo.entity.SysUserRole; 12 | import com.example.demo.mapper.SysRoleMapper; 13 | import com.example.demo.base_security.commons.PublicResultConstant; 14 | import com.example.demo.base_security.util.ComUtil; 15 | import com.example.demo.service.SysResService; 16 | import com.example.demo.service.SysRoleResService; 17 | import com.example.demo.service.SysRoleService; 18 | import com.example.demo.service.SysUserRoleService; 19 | import com.google.common.collect.Lists; 20 | import org.apache.commons.collections4.CollectionUtils; 21 | import org.joda.time.DateTime; 22 | import org.springframework.beans.BeanUtils; 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.stereotype.Service; 25 | 26 | import java.util.*; 27 | import java.util.stream.Collectors; 28 | 29 | /** 30 | *

31 | * 角色表 服务实现类 32 | *

33 | * 34 | * @author LXH 35 | * @since 2019-05-06 36 | */ 37 | @Service 38 | public class SysRoleServiceImpl extends ServiceImpl implements SysRoleService { 39 | 40 | @Autowired 41 | private SysRoleResService roleToMenuService; 42 | 43 | @Autowired 44 | private SysUserRoleService userToRoleService; 45 | 46 | @Autowired 47 | private SysResService menuService; 48 | 49 | @Override 50 | public boolean addRoleAndPermission(RoleAddVO roleModel) throws Exception{ 51 | SysRole role = new SysRole(); 52 | BeanUtils.copyProperties(roleModel,role); 53 | boolean result = this.save(role); 54 | if (! result) { 55 | throw new RuntimeException(PublicResultConstant.UPDATE_ROLEINFO_ERROR); 56 | } 57 | result = roleToMenuService.saveAll(role.getId(), roleModel.getMenuIds()); 58 | return result; 59 | } 60 | 61 | @Override 62 | public boolean updateRoleInfo(RoleUpdateVO roleModel) throws Exception{ 63 | SysRole role1 = this.getById(roleModel.getId()); 64 | if (Constant.ROLE_TYPE_ADMIN.equals(role1.getType())){ 65 | throw new RuntimeException(PublicResultConstant.UPDATE_SYSADMIN_INFO_ERROR); 66 | } 67 | if (ComUtil.isEmpty(role1)) { 68 | return false; 69 | } 70 | BeanUtils.copyProperties(roleModel,role1); 71 | role1.setUpdateTime(DateTime.now().toDate()); 72 | boolean result = this.updateById(role1); 73 | if (! result) { 74 | throw new RuntimeException(PublicResultConstant.UPDATE_ROLEINFO_ERROR); 75 | } 76 | result = roleToMenuService.remove(new QueryWrapper().eq("role_id",roleModel.getId())); 77 | if (! result) { 78 | throw new RuntimeException("删除权限信息失败"); 79 | } 80 | result = roleToMenuService.saveAll(role1.getId(), roleModel.getMenuIds()); 81 | if (! result) { 82 | throw new RuntimeException("更新权限信息失败"); 83 | } 84 | return result; 85 | 86 | } 87 | 88 | @Override 89 | public void getRoleIsAdminByUserNo(String userNo) throws Exception { 90 | List userToRole = userToRoleService.selectByUserNo(userNo); 91 | if (CollectionUtils.isNotEmpty(userToRole)){ 92 | List ids = userToRole.stream().map(item -> item.getRoleId()).collect(Collectors.toList()); 93 | List role = this.listByIds(ids).stream().collect(Collectors.toList()); 94 | role.forEach(item->{ 95 | if(item.getType().equals(Constant.ROLE_TYPE_ADMIN)){ 96 | throw new RuntimeException(PublicResultConstant.UPDATE_SYSADMIN_INFO_ERROR); 97 | } 98 | 99 | }); 100 | 101 | } 102 | } 103 | 104 | @Override 105 | public Map selectByRoleCode(String roleCode) throws Exception { 106 | SysRole role = this.getById(roleCode); 107 | if(ComUtil.isEmpty(role)){ 108 | throw new RuntimeException(PublicResultConstant.INVALID_ROLE); 109 | } 110 | Map result = new HashMap<>(); 111 | result.put("role", role); 112 | //权限信息 113 | result.put("nodes", this.getMenuByRoleCode(role.getId())); 114 | return result; 115 | } 116 | 117 | @Override 118 | public void deleteByRoleCode(String roleCode) throws Exception { 119 | if (ComUtil.isEmpty(this.getById(roleCode))) { 120 | throw new RuntimeException("角色不存在"); 121 | } 122 | if(!ComUtil.isEmpty(userToRoleService.list(new QueryWrapper().eq("role_id",roleCode)))){ 123 | throw new RuntimeException("角色存在相关用户,请先删除相关角色的用户"); 124 | } 125 | this.remove(new QueryWrapper().eq("role_code",roleCode)); 126 | } 127 | 128 | 129 | @Override 130 | public Map getMenuByRoleCode(String roleCode) { 131 | Map retMap =new HashMap<>(); 132 | LinkedList ids = Lists.newLinkedList(); 133 | ids.add(roleCode); 134 | List menuList = menuService.findMenuByRoleCode(ids); 135 | List buttonList = new ArrayList(); 136 | List retMenuList = menuService.treeMenuList(Constant.ROOT_MENU, menuList); 137 | for (SysRes buttonMenu : menuList) { 138 | if(buttonMenu.getType() == Constant.TYPE_BUTTON){ 139 | buttonList.add(buttonMenu); 140 | } 141 | } 142 | retMap.put("menuList",retMenuList); 143 | retMap.put("buttonList",buttonList); 144 | return retMap; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/impl/SysUserRoleServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.example.demo.entity.SysUserRole; 6 | import com.example.demo.mapper.SysUserRoleMapper; 7 | import com.example.demo.base_security.util.ComUtil; 8 | import com.example.demo.service.SysUserRoleService; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | *

15 | * 用户角色表 服务实现类 16 | *

17 | * 18 | * @author LXH 19 | * @since 2019-05-06 20 | */ 21 | @Service 22 | public class SysUserRoleServiceImpl extends ServiceImpl implements SysUserRoleService { 23 | 24 | @Override 25 | // @Cacheable(value = "UserToRole",keyGenerator="wiselyKeyGenerator") 26 | public List selectByUserNo(String userId) { 27 | QueryWrapper ew = new QueryWrapper<>(); 28 | ew.eq("user_id", userId); 29 | List userToRoleList = this.list(ew); 30 | return ComUtil.isEmpty(userToRoleList)? null: userToRoleList; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/service/impl/SysUserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.service.impl; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 5 | import com.baomidou.mybatisplus.core.toolkit.IdWorker; 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 7 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 8 | import com.example.demo.base_security.VO.registerVO; 9 | import com.example.demo.base_security.commons.Constant; 10 | import com.example.demo.entity.SysRes; 11 | import com.example.demo.entity.SysUser; 12 | import com.example.demo.entity.SysUserRole; 13 | import com.example.demo.mapper.SysUserMapper; 14 | import com.example.demo.base_security.commons.PublicResultConstant; 15 | import com.example.demo.base_security.util.ComUtil; 16 | import com.example.demo.base_security.util.JWTUtil; 17 | import com.example.demo.base_security.util.StringUtil; 18 | import com.example.demo.service.SysResService; 19 | import com.example.demo.service.SysRoleService; 20 | import com.example.demo.service.SysUserRoleService; 21 | import com.example.demo.service.SysUserService; 22 | import com.example.demo.utils.CurrentUserUtils; 23 | import com.google.common.collect.Sets; 24 | import org.apache.commons.collections4.CollectionUtils; 25 | import org.joda.time.DateTime; 26 | import org.mindrot.jbcrypt.BCrypt; 27 | import lombok.extern.slf4j.Slf4j; 28 | import org.apache.commons.lang3.StringUtils; 29 | import org.springframework.beans.BeanUtils; 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.beans.factory.annotation.Value; 32 | import org.springframework.data.redis.core.StringRedisTemplate; 33 | import org.springframework.stereotype.Service; 34 | import org.springframework.transaction.annotation.Transactional; 35 | 36 | import javax.servlet.http.HttpServletRequest; 37 | import java.util.*; 38 | import java.util.stream.Collectors; 39 | 40 | /** 41 | *

42 | * 用户表 服务实现类 43 | *

44 | * 45 | * @author LXH 46 | * @since 2019-05-06 47 | */ 48 | @Service 49 | @Slf4j 50 | @Transactional 51 | public class SysUserServiceImpl extends ServiceImpl implements SysUserService { 52 | 53 | @Value("${defaultPwd}") 54 | private String defaultPwd; 55 | @Autowired 56 | private SysUserMapper userMapper; 57 | 58 | @Autowired 59 | private StringRedisTemplate stringRedisTemplate; 60 | 61 | @Autowired 62 | private SysUserRoleService userToRoleService; 63 | @Autowired 64 | private SysResService menuService; 65 | @Autowired 66 | private SysUserRoleService sysUserRoleService; 67 | 68 | @Autowired 69 | private SysRoleService roleService; 70 | 71 | @Override 72 | public Page pageList(Integer pageNO, Integer pageSize) { 73 | Page pageInfo = new Page<>(pageNO, pageSize);//创建分页 74 | List list = userMapper.selectByParam(pageInfo); 75 | pageInfo.setRecords(list); 76 | SysUser user = CurrentUserUtils.getUser(); 77 | 78 | return pageInfo; 79 | 80 | } 81 | 82 | @Override 83 | public SysUser getUserByUserName(String username) { 84 | return null; 85 | } 86 | 87 | @Override 88 | public SysUser getUserByMobile(String mobile) { 89 | QueryWrapper ew = new QueryWrapper<>(); 90 | ew.eq("mobile", mobile); 91 | ew.eq("status", Constant.ENABLE); 92 | return this.getOne(ew); 93 | } 94 | 95 | @Override 96 | public SysUser register(SysUser user) { 97 | user.setId(IdWorker.getIdStr()); 98 | user.setUserNo(user.getId()); 99 | user.setCreateTime(DateTime.now().toDate()); 100 | user.setStatus(Constant.ENABLE); 101 | user.setCreateTime(DateTime.now().toDate()); 102 | user.setUpdateTime(DateTime.now().toDate()); 103 | boolean result = this.save(user); 104 | // if (result) { 105 | // UserToRole userToRole = UserToRole.builder().userNo(user.getUserNo()).roleCode(roleCode).build(); 106 | // userToRoleService.insert(userToRole); 107 | // } 108 | return user; 109 | } 110 | 111 | @Override 112 | public Map getLoginUserAndMenuInfo(SysUser user) { 113 | Map result = new HashMap<>(); 114 | List userToRoleList = sysUserRoleService.selectByUserNo(user.getId()); 115 | String token = JWTUtil.sign(user.getId(),user.getLoginName(), user.getPwd()); 116 | result.put("token", token); 117 | result.put("user", user); 118 | List buttonList = new ArrayList<>(); 119 | //根据角色主键查询启用的菜单权限 120 | if (CollectionUtils.isNotEmpty(userToRoleList)) { 121 | List roleIds = userToRoleList.stream().map(item -> item.getRoleId()).collect(Collectors.toList()); 122 | List menuList = menuService.findMenuByRoleCode(roleIds); 123 | //去重 124 | if (CollectionUtils.isNotEmpty(menuList)) { 125 | HashSet ids = Sets.newHashSet(); 126 | menuList.forEach(item -> { 127 | ids.add(item.getId()); 128 | }); 129 | List sysRes = menuService.listByIds(ids).stream().collect(Collectors.toList()); 130 | List retMenuList = menuService.treeMenuList(Constant.ROOT_MENU, sysRes); 131 | for (SysRes buttonMenu : menuList) { 132 | if (buttonMenu.getType() == Constant.TYPE_BUTTON) { 133 | buttonList.add(buttonMenu); 134 | } 135 | } 136 | result.put("menuList", retMenuList); 137 | result.put("buttonList", buttonList); 138 | } 139 | } 140 | return result; 141 | } 142 | 143 | @Override 144 | public void deleteByUserNo(String userId) throws Exception { 145 | SysUser user = this.getById(userId); 146 | if (ComUtil.isEmpty(user)) { 147 | throw new RuntimeException(PublicResultConstant.INVALID_USER); 148 | } 149 | //todo: 暂未实现 150 | } 151 | 152 | @Override 153 | public Page selectPageByConditionUser(Page userPage, String info, Integer[] status, String startTime, String endTime) { 154 | return null; 155 | } 156 | 157 | @Override 158 | public Map checkMobileAndPasswd(JSONObject requestJson) throws Exception { 159 | String mobileNo = String.valueOf(requestJson.get("mobileNo")); 160 | String pwd = String.valueOf(requestJson.get("pwd")); 161 | if (StringUtils.isBlank(mobileNo) || StringUtils.isBlank(pwd)) { 162 | throw new RuntimeException("入参不能为空!"); 163 | } 164 | if (!StringUtil.checkMobileNumber(mobileNo)) { 165 | throw new RuntimeException(PublicResultConstant.MOBILE_ERROR); 166 | } 167 | SysUser user = this.getOne(new QueryWrapper().eq("mobile_no", mobileNo).eq("status", 1)); 168 | if (ComUtil.isEmpty(user) || !BCrypt.checkpw(requestJson.getString("pwd"), user.getPwd())) { 169 | throw new RuntimeException(PublicResultConstant.INVALID_USERNAME_PASSWORD); 170 | } 171 | return this.getLoginUserAndMenuInfo(user); 172 | } 173 | 174 | @Override 175 | public Map checkMobileAndCatcha(JSONObject requestJson) throws Exception { 176 | String mobile = requestJson.getString("mobile"); 177 | if (!StringUtil.checkMobileNumber(mobile)) { 178 | throw new RuntimeException(PublicResultConstant.MOBILE_ERROR); 179 | } 180 | SysUser user = this.getUserByMobile(mobile); 181 | //如果不是启用的状态 182 | if (!ComUtil.isEmpty(user) && user.getStatus() != Constant.ENABLE) { 183 | throw new RuntimeException("该用户状态不是启用的!"); 184 | } 185 | //todo:验证码校验 暂未处理 186 | // List smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(mobile, 187 | // requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.AUTH.name())); 188 | // if(ComUtil.isEmpty(smsVerifies)){ 189 | // throw new RuntimeException(PublicResultConstant.VERIFY_PARAM_ERROR); 190 | // } 191 | // if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){ 192 | // throw new RuntimeException(PublicResultConstant.VERIFY_PARAM_PASS); 193 | // } 194 | if (ComUtil.isEmpty(user)) { 195 | //设置默认密码 196 | SysUser userRegister = SysUser.builder().pwd(BCrypt.hashpw(defaultPwd, BCrypt.gensalt())) 197 | .mobileNo(mobile).loginName(mobile).build(); 198 | user = this.register(userRegister); 199 | } 200 | return this.getLoginUserAndMenuInfo(user); 201 | } 202 | 203 | @Override 204 | public SysUser checkAndRegisterUser(registerVO vo) throws Exception { 205 | //可直接转为java对象,简化操作,不用再set一个个属性 206 | SysUser userRegister = new SysUser(); 207 | BeanUtils.copyProperties(vo, userRegister); 208 | //todo:验证码相关逻辑暂未处理 209 | 210 | // List smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(userRegister.getMobile(), 211 | // requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.REG.name())); 212 | // if(ComUtil.isEmpty(smsVerifies)){ 213 | // throw new BusinessException(PublicResultConstant.VERIFY_PARAM_ERROR); 214 | // } 215 | //验证码是否过期 216 | // if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){ 217 | // throw new BusinessException(PublicResultConstant.VERIFY_PARAM_PASS); 218 | // } 219 | userRegister.setPwd(BCrypt.hashpw(vo.getPwd(), BCrypt.gensalt())); 220 | //默认注册普通用户 221 | return this.register(userRegister); 222 | } 223 | 224 | @Override 225 | public SysUser updateForgetPasswd(JSONObject requestJson) throws Exception { 226 | String mobile = requestJson.getString("mobile"); 227 | if (!StringUtil.checkMobileNumber(mobile)) { 228 | throw new RuntimeException(PublicResultConstant.MOBILE_ERROR); 229 | } 230 | if (!requestJson.getString("password").equals(requestJson.getString("rePassword"))) { 231 | throw new RuntimeException(PublicResultConstant.INVALID_RE_PASSWORD); 232 | } 233 | SysUser user = this.getUserByMobile(mobile); 234 | roleService.getRoleIsAdminByUserNo(user.getUserNo()); 235 | if (ComUtil.isEmpty(user)) { 236 | throw new RuntimeException(PublicResultConstant.INVALID_USER); 237 | } 238 | //todo:短信验证码校验暂未设置 239 | // List smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(mobile, 240 | // requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.FINDPASSWORD.name())); 241 | // if(ComUtil.isEmpty(smsVerifies)){ 242 | // throw new BusinessException(PublicResultConstant.VERIFY_PARAM_ERROR); 243 | // } 244 | // if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){ 245 | // throw new BusinessException(PublicResultConstant.VERIFY_PARAM_PASS); 246 | // } 247 | user.setPwd(BCrypt.hashpw(requestJson.getString("password"), BCrypt.gensalt())); 248 | this.updateById(user); 249 | return user; 250 | } 251 | 252 | @Override 253 | public void resetMobile(SysUser currentUser, JSONObject requestJson) throws Exception { 254 | String newMobile = requestJson.getString("newMobile"); 255 | if (!StringUtil.checkMobileNumber(newMobile)) { 256 | throw new RuntimeException(PublicResultConstant.MOBILE_ERROR); 257 | } 258 | /**todo: 短信验证码 暂未处置 259 | List smsVerifies = smsVerifyService.getByMobileAndCaptchaAndType(newMobile, 260 | requestJson.getString("captcha"), SmsSendUtil.SMSType.getType(SmsSendUtil.SMSType.MODIFYINFO.name())); 261 | if(ComUtil.isEmpty(smsVerifies)){ 262 | throw new RuntimeException(PublicResultConstant.VERIFY_PARAM_ERROR); 263 | } 264 | if(SmsSendUtil.isCaptchaPassTime(smsVerifies.get(0).getCreateTime())){ 265 | throw new RuntimeException(PublicResultConstant.VERIFY_PARAM_PASS); 266 | } 267 | **/ 268 | currentUser.setMobileNo(newMobile); 269 | this.updateById(currentUser); 270 | } 271 | 272 | @Override 273 | public void resetPassWord(SysUser currentUser, JSONObject requestJson) throws Exception { 274 | if (!requestJson.getString("password").equals(requestJson.getString("rePassword"))) { 275 | throw new RuntimeException(PublicResultConstant.INVALID_RE_PASSWORD); 276 | } 277 | if (!BCrypt.checkpw(requestJson.getString("oldPassword"), currentUser.getPwd())) { 278 | throw new RuntimeException(PublicResultConstant.INVALID_USERNAME_PASSWORD); 279 | } 280 | currentUser.setPwd(BCrypt.hashpw(requestJson.getString("password"), BCrypt.gensalt())); 281 | this.updateById(currentUser); 282 | } 283 | 284 | @Override 285 | public boolean loginOut(String userId) { 286 | stringRedisTemplate.opsForHash().delete("token", userId); 287 | return true; 288 | } 289 | } 290 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/utils/CurrentUserUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.utils; 2 | 3 | import com.baomidou.mybatisplus.extension.api.R; 4 | import com.example.demo.entity.SysUser; 5 | import org.apache.shiro.SecurityUtils; 6 | import org.springframework.web.context.request.RequestContextHolder; 7 | import org.springframework.web.context.request.ServletRequestAttributes; 8 | import springfox.documentation.RequestHandler; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | 12 | /** 13 | * @author liuxinghong 14 | * @Description: 获取当前用用信息 15 | * @date 2019/5/16 001617:40 16 | */ 17 | public class CurrentUserUtils { 18 | 19 | public static SysUser getUser(){ 20 | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); 21 | 22 | HttpServletRequest request = servletRequestAttributes.getRequest(); 23 | SysUser user = (SysUser)request.getAttribute("currentUser"); 24 | if (null != user){ 25 | return user; 26 | } 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/example/demo/utils/DateUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.demo.utils; 2 | 3 | 4 | import com.baomidou.mybatisplus.core.toolkit.StringUtils; 5 | 6 | import java.text.ParseException; 7 | import java.text.SimpleDateFormat; 8 | import java.util.Date; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * Description: 13 | * 14 | * @author : lxh 15 | * Date: 2018-01-29 16 | * Time: 17:30 17 | */ 18 | public class DateUtils { 19 | public static SimpleDateFormat matter1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 20 | /** 21 | * 将字符串转date 22 | * @param str 23 | * @param pattern "yyyy-MM-dd HH:mm:ss" "yyyy-MM-dd" "yyyy-MM-dd HH:mm" 24 | * @return 25 | */ 26 | public static Date stringToDate(String str , String pattern){ 27 | SimpleDateFormat sdf = new SimpleDateFormat(pattern); 28 | try { 29 | if(StringUtils.isNotEmpty(str)&&StringUtils.isNotEmpty(pattern)){ 30 | return sdf.parse(str); 31 | }else{ 32 | return null; 33 | } 34 | } catch (ParseException e) { 35 | e.printStackTrace(); 36 | return null; 37 | } 38 | } 39 | 40 | public static String dateToString(Date date,String format){ 41 | if(date!=null){ 42 | SimpleDateFormat sdf = new SimpleDateFormat(format); 43 | return sdf.format(date); 44 | }else{ 45 | return ""; 46 | } 47 | } 48 | /** 49 | * long类型转为String 50 | * @return 格式yyyy-MM-dd ,精确到日 51 | */ 52 | public static Date longToDate(long l) { 53 | try { 54 | Date dt = new Date(l); 55 | return dt; 56 | } catch (Exception e) { 57 | return null; 58 | } 59 | } 60 | 61 | // public static void main(String[] args){ 62 | // System.out.println(stringToDate("2017-01-01","yyyy-MM-dd")); 63 | // } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | datasource: 4 | name: test 5 | url: jdbc:mysql://18.136.204.238:3306/springboot_demo?useUnicode=true&characterEncoding=UTF-8&useSSL=false 6 | username: 7 | password: 8 | type: com.alibaba.druid.pool.DruidDataSource 9 | driver-class-name: com.mysql.jdbc.Driver 10 | 11 | redis: 12 | database: 2 13 | host: 18.136.204.238 14 | port: 6379 15 | password: 16 | cache: 17 | type: redis 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/resources/application-local.yml: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | datasource: 4 | name: test 5 | url: jdbc:mysql://192.168.60.182:3306/springboot_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai 6 | username: root 7 | password: root 8 | type: com.alibaba.druid.pool.DruidDataSource 9 | driver-class-name: com.mysql.jdbc.Driver 10 | 11 | redis: 12 | database: 3 13 | host: 192.168.60.182 14 | port: 6379 15 | password: root 16 | cache: 17 | type: redis 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8090 3 | # servlet: 4 | # context-path: /sb 5 | 6 | spring: 7 | profiles: 8 | active: local 9 | application: 10 | name: spring-demo 11 | 12 | logging: 13 | level: 14 | org.springframework: info 15 | 16 | 17 | 18 | liquibase: 19 | path: classpath:migrates/master.xml 20 | #配置文件上传支持文件大小 21 | servlet: 22 | multipart: 23 | max-file-size: 200MB 24 | max-request-size: 200MB 25 | 26 | #文件上传支持文件类型 27 | file: 28 | upload: 29 | acceptTypes: txt,jpg,jpeg,png,gif,svg,ico,doc,docx,xls,xlsx,ppt,pptx,pdf,flv,mp4,avi,rmvb 30 | 31 | mybatis-plus: 32 | mapper-locations: classpath*:mapper/*.xml 33 | #实体扫描,多个package用逗号或者分号分隔 34 | typeAliasesPackage: com.example.demo.entity 35 | #typeEnumsPackage: com.baomidou.springboot.entity.enums 36 | global-config: 37 | #主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID"; 38 | id-type: 1 39 | #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" 40 | field-strategy: 2 41 | #驼峰下划线转换 42 | db-column-underline: true 43 | #刷新mapper 调试神器 44 | refresh-mapper: true 45 | #数据库大写下划线转换 46 | #capital-mode: true 47 | #序列接口实现类配置 48 | #key-generator: com.baomidou.springboot.xxx 49 | #逻辑删除配置 50 | logic-delete-value: 0 51 | logic-not-delete-value: 1 52 | #自定义填充策略接口实现 53 | #meta-object-handler: com.baomidou.springboot.xxx 54 | #自定义SQL注入器 55 | #sql-injector: com.baomidou.springboot.xxx 56 | configuration: 57 | map-underscore-to-camel-case: true 58 | cache-enabled: false 59 | 60 | #用户默认登录密码 61 | defaultPwd: 123456 62 | #token过期时间:单位毫秒 63 | expireTime: 15000 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/main/resources/mapper/SysLogMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | id, type, desc, remark, adr, status, create_time AS createTime, create_user AS createUser 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/mapper/SysResMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | id, pid, name, permission, url, sort_num AS sortNum, icon1, icon2, pids, type, des, status, create_time AS createTime, update_time AS updateTime 26 | 27 | 28 | 29 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/main/resources/mapper/SysRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | id, name, code, sort_num AS sortNum, des, status, create_time AS createTime, update_time AS updateTime 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/resources/mapper/SysRoleResMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | id, res_id AS resId, role_id AS roleId 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/resources/mapper/SysUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | id, login_name AS loginName, pwd, salt, name, email, sex, telephone, avatar, status, create_time AS createTime, update_time AS updateTime 28 | 29 | 30 | 31 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/main/resources/mapper/SysUserRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | id, user_id AS userId, role_id AS roleId 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/resources/migrates/init/db.changelog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/main/resources/migrates/init/db.data.initlog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 超级管理员 11 | 12 | 13 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/resources/migrates/master.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/test/java/com/example/demo/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.demo; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------