Browse Source

2021/6/10 16:23 系统管理部分功能完善

yinhao 4 years ago
parent
commit
e22f058c81
96 changed files with 3671 additions and 239 deletions
  1. 21 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/HuimvSmartApiServiceApplication.java
  2. 2 2
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/HuimvSmartApiserviceApplication.java
  3. 40 0
      huimv-smart-gateway/src/main/java/com/huimv/gateway/config/CorsResponseHeaderFilter.java
  4. 64 9
      huimv-smart-gateway/src/main/java/com/huimv/gateway/config/GatewayCrosConfig.java
  5. 80 0
      huimv-smart-management/src/main/java/com/huimv/management/controller/SensitiveWordController.java
  6. 9 1
      huimv-smart-management/src/main/java/com/huimv/management/dao/PastureDao.java
  7. 7 1
      huimv-smart-management/src/main/java/com/huimv/management/dao/PigstyDao.java
  8. 17 0
      huimv-smart-management/src/main/java/com/huimv/management/dao/SensitiveWordDao.java
  9. 11 1
      huimv-smart-management/src/main/java/com/huimv/management/entity/IndoorEnvironmentEntity.java
  10. 46 0
      huimv-smart-management/src/main/java/com/huimv/management/entity/SensitiveWordEntity.java
  11. 20 0
      huimv-smart-management/src/main/java/com/huimv/management/service/SensitiveWordService.java
  12. 58 13
      huimv-smart-management/src/main/java/com/huimv/management/service/impl/IndoorEnvironmentServiceImpl.java
  13. 29 0
      huimv-smart-management/src/main/java/com/huimv/management/service/impl/SensitiveWordServiceImpl.java
  14. 16 0
      huimv-smart-management/src/main/resources/mapper/management/SensitiveWordDao.xml
  15. 15 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/Oauth2AuthApplication.java
  16. 124 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/api/CommonResult.java
  17. 11 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/api/IErrorCode.java
  18. 28 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/api/ResultCode.java
  19. 28 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/component/JwtTokenEnhancer.java
  20. 82 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/config/Oauth2ServerConfig.java
  21. 33 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/config/RedisRepositoryConfig.java
  22. 40 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/config/WebSecurityConfig.java
  23. 23 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/constant/MessageConstant.java
  24. 11 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/constant/RedisConstant.java
  25. 42 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/controller/AuthController.java
  26. 30 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/controller/KeyPairController.java
  27. 31 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/domain/Oauth2TokenDto.java
  28. 89 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/domain/SecurityUser.java
  29. 22 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/domain/UserDTO.java
  30. 20 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/exception/Oauth2ExceptionHandler.java
  31. 32 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/service/ResourceServiceImpl.java
  32. 61 0
      huimv-smart-oauth2/src/main/java/com/huimv/oauth2/service/UserServiceImpl.java
  33. 0 0
      huimv-smart-oauth2/src/main/resources/application.yml
  34. 21 0
      micro-oauth2/micro-oauth2-api/pom.xml
  35. 15 0
      micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/Oauth2ApiApplication.java
  36. 18 0
      micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/controller/HelloController.java
  37. 26 0
      micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/controller/UserController.java
  38. 18 0
      micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/domain/UserDTO.java
  39. 31 0
      micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/holder/LoginUserHolder.java
  40. 16 0
      micro-oauth2/micro-oauth2-api/src/main/resources/application.yml
  41. 39 0
      micro-oauth2/micro-oauth2-auth/pom.xml
  42. 15 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/Oauth2AuthApplication.java
  43. 124 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/api/CommonResult.java
  44. 11 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/api/IErrorCode.java
  45. 28 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/api/ResultCode.java
  46. 28 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/component/JwtTokenEnhancer.java
  47. 82 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/config/Oauth2ServerConfig.java
  48. 33 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/config/RedisRepositoryConfig.java
  49. 40 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/config/WebSecurityConfig.java
  50. 23 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/constant/MessageConstant.java
  51. 11 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/constant/RedisConstant.java
  52. 42 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/controller/AuthController.java
  53. 30 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/controller/KeyPairController.java
  54. 31 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/domain/Oauth2TokenDto.java
  55. 89 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/domain/SecurityUser.java
  56. 22 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/domain/UserDTO.java
  57. 20 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/exception/Oauth2ExceptionHandler.java
  58. 32 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/service/ResourceServiceImpl.java
  59. 61 0
      micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/service/UserServiceImpl.java
  60. 23 0
      micro-oauth2/micro-oauth2-auth/src/main/resources/application.yml
  61. BIN
      micro-oauth2/micro-oauth2-auth/src/main/resources/jwt.jks
  62. 57 0
      micro-oauth2/micro-oauth2-gateway/pom.xml
  63. 15 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/Oauth2GatewayApplication.java
  64. 124 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/api/CommonResult.java
  65. 11 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/api/IErrorCode.java
  66. 28 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/api/ResultCode.java
  67. 46 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/authorization/AuthorizationManager.java
  68. 33 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/component/RestAuthenticationEntryPoint.java
  69. 34 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/component/RestfulAccessDeniedHandler.java
  70. 20 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/config/IgnoreUrlsConfig.java
  71. 33 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/config/RedisRepositoryConfig.java
  72. 66 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/config/ResourceServerConfig.java
  73. 12 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/constant/AuthConstant.java
  74. 10 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/constant/RedisConstant.java
  75. 50 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/filter/AuthGlobalFilter.java
  76. 42 0
      micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/filter/IgnoreUrlsRemoveJwtFilter.java
  77. 44 0
      micro-oauth2/micro-oauth2-gateway/src/main/resources/application.yml
  78. 103 0
      micro-oauth2/pom.xml
  79. 26 26
      renren-fast/src/main/java/io/renren/config/CorsConfig.java
  80. 101 0
      renren-fast/src/main/java/io/renren/modules/sys/controller/SysDepartmentController.java
  81. 99 0
      renren-fast/src/main/java/io/renren/modules/sys/controller/SysJobController.java
  82. 4 4
      renren-fast/src/main/java/io/renren/modules/sys/controller/SysLoginController.java
  83. 1 1
      renren-fast/src/main/java/io/renren/modules/sys/controller/SysUserController.java
  84. 19 0
      renren-fast/src/main/java/io/renren/modules/sys/dao/SysDepartmentDao.java
  85. 19 0
      renren-fast/src/main/java/io/renren/modules/sys/dao/SysJobDao.java
  86. 30 18
      renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserDao.java
  87. 45 0
      renren-fast/src/main/java/io/renren/modules/sys/entity/SysDepartmentEntity.java
  88. 39 0
      renren-fast/src/main/java/io/renren/modules/sys/entity/SysJobEntity.java
  89. 103 59
      renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java
  90. 94 0
      renren-fast/src/main/java/io/renren/modules/sys/entity/vo/SysUserVo.java
  91. 22 0
      renren-fast/src/main/java/io/renren/modules/sys/service/SysDepartmentService.java
  92. 20 0
      renren-fast/src/main/java/io/renren/modules/sys/service/SysJobService.java
  93. 46 0
      renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysDepartmentServiceImpl.java
  94. 45 0
      renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysJobServiceImpl.java
  95. 134 104
      renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java
  96. 25 0
      renren-fast/src/main/resources/mapper/sys/SysUserDao.xml

+ 21 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/HuimvSmartApiServiceApplication.java

@@ -0,0 +1,21 @@
+package com.huimv.apiservice;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * @author huimv
+ * @since 2021/4/26
+ */
+@MapperScan("com.huimv.apiservice.dao")
+@EnableScheduling
+@SpringBootApplication
+public class HuimvSmartApiServiceApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(HuimvSmartApiServiceApplication.class, args);
+    }
+
+}

+ 2 - 2
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/HuimvSmartApiserviceApplication.java

@@ -12,10 +12,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @MapperScan("com.huimv.apiservice.dao")
 @EnableScheduling
 @SpringBootApplication
-public class HuimvSmartApiserviceApplication {
+public class HuimvSmartApiServiceApplication {
 
     public static void main(String[] args) {
-        SpringApplication.run(HuimvSmartApiserviceApplication.class, args);
+        SpringApplication.run(HuimvSmartApiServiceApplication.class, args);
     }
 
 }

+ 40 - 0
huimv-smart-gateway/src/main/java/com/huimv/gateway/config/CorsResponseHeaderFilter.java

@@ -0,0 +1,40 @@
+package com.huimv.gateway.config;
+
+import java.util.ArrayList;
+
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * 跨域请求头处理过滤器扩展
+ */
+public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {
+    @Override
+    public int getOrder() {
+        // 指定此过滤器位于NettyWriteResponseFilter之后
+        // 即待处理完响应体后接着处理响应头
+        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;
+    }
+
+    @Override
+    @SuppressWarnings("serial")
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        return chain.filter(exchange).then(Mono.defer(() -> {
+            exchange.getResponse().getHeaders().entrySet().stream()
+                    .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))
+                    .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) 
+                            || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))
+                    .forEach(kv -> 
+            {
+                kv.setValue(new ArrayList<String>() {{add(kv.getValue().get(0));}});
+            });
+            
+            return chain.filter(exchange);
+        }));
+    }
+}

+ 64 - 9
huimv-smart-gateway/src/main/java/com/huimv/gateway/config/GatewayCrosConfig.java

@@ -2,9 +2,14 @@ package com.huimv.gateway.config;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.reactive.CorsWebFilter;
+import org.springframework.web.cors.reactive.DefaultCorsProcessor;
 import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.util.pattern.PathPatternParser;
+
 
 import java.util.Collections;
 
@@ -17,20 +22,70 @@ import java.util.Collections;
  **/
 @Configuration
 public class GatewayCrosConfig {
+//    @Bean
+//    public CorsWebFilter corsWebFilter(){
+//
+//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+//        CorsConfiguration corsConfiguration = new CorsConfiguration();
+//        //1.配置跨域
+//        corsConfiguration.addAllowedHeader("*");
+//        corsConfiguration.addAllowedMethod("*");
+////        corsConfiguration.addAllowedOrigin("*");
+//        corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
+//        corsConfiguration.setAllowCredentials(true);
+//
+//
+//        source.registerCorsConfiguration("/**",corsConfiguration);
+//        return new CorsWebFilter(source);
+//    }
+
+
     @Bean
-    public CorsWebFilter corsWebFilter(){
+    public CorsResponseHeaderFilter corsResponseHeaderFilter() {
+        return new CorsResponseHeaderFilter();
+    }
 
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+    @Bean
+    public CorsWebFilter corsFilter() {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
+        source.registerCorsConfiguration("/**", buildCorsConfiguration());
+
+        CorsWebFilter corsWebFilter = new CorsWebFilter(source, new DefaultCorsProcessor() {
+            @Override
+            protected boolean handleInternal(ServerWebExchange exchange, CorsConfiguration config,
+                                             boolean preFlightRequest)
+            {
+                // 预留扩展点
+                // if (exchange.getRequest().getMethod() == HttpMethod.OPTIONS) {
+                return super.handleInternal(exchange, config, preFlightRequest);
+                // }
+
+                // return true;
+            }
+        });
+
+        return corsWebFilter;
+    }
+
+    private CorsConfiguration buildCorsConfiguration() {
         CorsConfiguration corsConfiguration = new CorsConfiguration();
-        //1.配置跨域
-        corsConfiguration.addAllowedHeader("*");
-        corsConfiguration.addAllowedMethod("*");
-//        corsConfiguration.addAllowedOrigin("*");
         corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
-        corsConfiguration.setAllowCredentials(true);
+        //corsConfiguration.addAllowedOrigin("*");
 
+        corsConfiguration.addAllowedMethod(HttpMethod.OPTIONS);
+        corsConfiguration.addAllowedMethod(HttpMethod.POST);
+        corsConfiguration.addAllowedMethod(HttpMethod.GET);
+        corsConfiguration.addAllowedMethod(HttpMethod.PUT);
+        corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
+        corsConfiguration.addAllowedMethod(HttpMethod.PATCH);
+        // corsConfiguration.addAllowedMethod("*");
+        corsConfiguration.addAllowedHeader("*");
 
-        source.registerCorsConfiguration("/**",corsConfiguration);
-        return new CorsWebFilter(source);
+        corsConfiguration.setMaxAge(7200L);
+        corsConfiguration.setAllowCredentials(true);
+        return corsConfiguration;
     }
+
+
+
 }

+ 80 - 0
huimv-smart-management/src/main/java/com/huimv/management/controller/SensitiveWordController.java

@@ -0,0 +1,80 @@
+package com.huimv.management.controller;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import com.huimv.management.entity.SensitiveWordEntity;
+import com.huimv.management.service.SensitiveWordService;
+import com.huimv.common.utils.PageUtils;
+import com.huimv.common.utils.R;
+
+
+/**
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-06-01 13:46:33
+ */
+@RestController
+@RequestMapping("management/sensitive")
+public class SensitiveWordController {
+
+    @Autowired
+    private SensitiveWordService sensitiveWordService;
+
+    /**
+     * 列表
+     */
+    @GetMapping("/list")
+    public R list(@RequestParam Map<String, Object> params) {
+        PageUtils page = sensitiveWordService.queryPage(params);
+        return R.ok().put("page", page);
+    }
+
+
+    /**
+     * 信息
+     */
+    @GetMapping("/info/{id}")
+    public R info(@PathVariable("id") Integer id) {
+        SensitiveWordEntity sensitiveWord = sensitiveWordService.getById(id);
+        return R.ok().put("sensitiveWord", sensitiveWord);
+    }
+
+    /**
+     * 保存
+     */
+    @PostMapping("/save")
+    public R save(@RequestBody SensitiveWordEntity sensitiveWord) {
+        sensitiveWordService.save(sensitiveWord);
+        return R.ok();
+    }
+
+    /**
+     * 修改
+     */
+    @PostMapping("/update")
+    public R update(@RequestBody SensitiveWordEntity sensitiveWord) {
+        sensitiveWordService.updateById(sensitiveWord);
+
+        return R.ok();
+    }
+
+    /**
+     * 删除
+     */
+    @PostMapping("/delete")
+    public R delete(@RequestBody Integer[] ids) {
+        sensitiveWordService.removeByIds(Arrays.asList(ids));
+        return R.ok();
+    }
+
+//    @GetMapping("/check")
+//    public R check(@RequestParam("word") String word) {
+//        sensitiveWordService.check(word);
+//        return null;
+//    }
+
+}

+ 9 - 1
huimv-smart-management/src/main/java/com/huimv/management/dao/PastureDao.java

@@ -1,10 +1,16 @@
 package com.huimv.management.dao;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.huimv.management.entity.PastureEntity;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 /**
  * 牧场表
  * 
@@ -15,5 +21,7 @@ import org.springframework.stereotype.Repository;
 @Mapper
 @Repository
 public interface PastureDao extends BaseMapper<PastureEntity> {
-	
+
+    @Select("SELECT id FROM mgt_pasture ${ew.customSqlSegment} AND deleted = 0")
+    List<Integer> selectIdList(@Param(Constants.WRAPPER) LambdaQueryWrapper wrapper);
 }

+ 7 - 1
huimv-smart-management/src/main/java/com/huimv/management/dao/PigstyDao.java

@@ -3,8 +3,12 @@ package com.huimv.management.dao;
 import com.huimv.management.entity.PigstyEntity;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 /**
  * 猪舍表
  * 
@@ -15,5 +19,7 @@ import org.springframework.stereotype.Repository;
 @Mapper
 @Repository
 public interface PigstyDao extends BaseMapper<PigstyEntity> {
-	
+
+    @Select("SELECT id FROM mgt_pigsty WHERE name like CONCAT('%',#{pigstyName},'%') AND deleted = 0")
+    List<Integer> selectIdListByPigstyName(@Param("pigstyName") String pigstyName);
 }

+ 17 - 0
huimv-smart-management/src/main/java/com/huimv/management/dao/SensitiveWordDao.java

@@ -0,0 +1,17 @@
+package com.huimv.management.dao;
+
+import com.huimv.management.entity.SensitiveWordEntity;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 
+ * 
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-06-01 13:46:33
+ */
+@Mapper
+public interface SensitiveWordDao extends BaseMapper<SensitiveWordEntity> {
+	
+}

+ 11 - 1
huimv-smart-management/src/main/java/com/huimv/management/entity/IndoorEnvironmentEntity.java

@@ -24,6 +24,11 @@ public class IndoorEnvironmentEntity implements Serializable {
      */
     @TableId
     private Integer id;
+
+    /**
+     * 牧场id
+     */
+    private Integer pastureId;
     /**
      * 豬舍id
      */
@@ -49,8 +54,13 @@ public class IndoorEnvironmentEntity implements Serializable {
      * 采集时间
      */
     private Date collectTime;
+
+    /**
+     * 异常状态 0.正常 1.异常
+     */
+    private Boolean abnormalStatus;
     /**
-     * 删除状态 0正常 1已删除
+     * 删除状态 0正常 其他:已删除
      */
     @TableLogic
     private Integer deleted;

+ 46 - 0
huimv-smart-management/src/main/java/com/huimv/management/entity/SensitiveWordEntity.java

@@ -0,0 +1,46 @@
+package com.huimv.management.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 
+ * 
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-06-01 13:46:33
+ */
+@Data
+@TableName("mgt_sensitive_word")
+public class SensitiveWordEntity implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * id
+	 */
+	@TableId
+	private Integer id;
+	/**
+	 * 敏感词汇
+	 */
+	private String word;
+	/**
+	 * 删除状态 0:正常 其他:已删除
+	 */
+	@TableLogic
+	private Integer deleted;
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	private Date gmtCreate;
+	/**
+	 * 修改时间
+	 */
+	@TableField(fill = FieldFill.INSERT_UPDATE)
+	private Date gmtModified;
+
+}

+ 20 - 0
huimv-smart-management/src/main/java/com/huimv/management/service/SensitiveWordService.java

@@ -0,0 +1,20 @@
+package com.huimv.management.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huimv.common.utils.PageUtils;
+import com.huimv.management.entity.SensitiveWordEntity;
+
+import java.util.Map;
+
+/**
+ * 
+ *
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-06-01 13:46:33
+ */
+public interface SensitiveWordService extends IService<SensitiveWordEntity> {
+
+    PageUtils queryPage(Map<String, Object> params);
+}
+

+ 58 - 13
huimv-smart-management/src/main/java/com/huimv/management/service/impl/IndoorEnvironmentServiceImpl.java

@@ -2,9 +2,18 @@ package com.huimv.management.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.huimv.management.dao.PastureDao;
+import com.huimv.management.dao.PigstyDao;
 import com.huimv.management.entity.IndoorEnvironmentEntity;
+import com.huimv.management.entity.PastureEntity;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -15,31 +24,67 @@ import com.huimv.management.dao.IndoorEnvironmentDao;
 import com.huimv.management.entity.IndoorEnvironmentEntity;
 import com.huimv.management.service.IndoorEnvironmentService;
 
-
 @Service("indoorEnvironmentService")
 public class IndoorEnvironmentServiceImpl extends ServiceImpl<IndoorEnvironmentDao, IndoorEnvironmentEntity> implements IndoorEnvironmentService {
 
+    @Autowired
+    private PastureDao pastureDao;
+
+    @Autowired
+    private PigstyDao pigstyDao;
+
     @Override
     public PageUtils queryPage(Map<String, Object> params) {
 
         LambdaQueryWrapper<IndoorEnvironmentEntity> lambdaQuery = Wrappers.lambdaQuery();
-        String keywords = (String) params.get("keywords");
-        //没有参数
-        if (keywords == null || keywords.equals("")){
-            IPage<IndoorEnvironmentEntity> page = this.page(
-                    new Query<IndoorEnvironmentEntity>().getPage(params),
-                    new QueryWrapper<IndoorEnvironmentEntity>()
-            );
-            return new PageUtils(page);
+
+
+        Boolean abnormalStatus = (Boolean) params.get("abnormalStatus");
+        if (abnormalStatus != null) {
+            lambdaQuery.eq(IndoorEnvironmentEntity::getAbnormalStatus, abnormalStatus);
         }
 
-        lambdaQuery.like(IndoorEnvironmentEntity::getPigstyId,keywords);
-        IPage<IndoorEnvironmentEntity> page = page(this.page(
-                new Query<IndoorEnvironmentEntity>().getPage(params)
-        ), lambdaQuery);
+        String pastureName = String.valueOf(params.get("pastureName"));
+        if (StringUtils.isNotEmpty(pastureName)) {
+            LambdaQueryWrapper<PastureEntity> query = Wrappers.<PastureEntity>lambdaQuery().like(PastureEntity::getName, pastureName);
+            List<Integer> idList = pastureDao.selectIdList(query);
+            lambdaQuery.in(IndoorEnvironmentEntity::getPastureId, idList);
+        }
+
+        String pigstyName = String.valueOf(params.get("pigstyName"));
+        if (StringUtils.isNotEmpty(pigstyName)) {
+            lambdaQuery.in(IndoorEnvironmentEntity::getPigstyId, pigstyDao.selectIdListByPigstyName(pigstyName));
+        }
 
+        String startTime = String.valueOf(params.get("startTime"));
+        if (StringUtils.isNotEmpty(startTime)) {
+            lambdaQuery.ge(IndoorEnvironmentEntity::getCollectTime, startTime);
+        }
+
+        String endTime = String.valueOf(params.get("endTime"));
+        if (StringUtils.isNotEmpty(endTime)) {
+            lambdaQuery.le(IndoorEnvironmentEntity::getCollectTime, endTime);
+        }
 
+        IPage<IndoorEnvironmentEntity> page = this.page(new Query<IndoorEnvironmentEntity>().getPage(params),lambdaQuery);
         return new PageUtils(page);
+//        String keywords = (String) params.get("keywords");
+//        //没有参数
+//        if (keywords == null || keywords.equals("")) {
+//            IPage<IndoorEnvironmentEntity> page = this.page(
+//                    new Query<IndoorEnvironmentEntity>().getPage(params),
+//                    new QueryWrapper<IndoorEnvironmentEntity>()
+//            );
+//            return new PageUtils(page);
+//        }
+//
+//        lambdaQuery.like(IndoorEnvironmentEntity::getPigstyId, keywords);
+//        IPage<IndoorEnvironmentEntity> page = page(this.page(
+//                new Query<IndoorEnvironmentEntity>().getPage(params)
+//        ), lambdaQuery);
+//
+//
+//        return new PageUtils(page);
     }
     
     /*@Override

+ 29 - 0
huimv-smart-management/src/main/java/com/huimv/management/service/impl/SensitiveWordServiceImpl.java

@@ -0,0 +1,29 @@
+package com.huimv.management.service.impl;
+
+import org.springframework.stereotype.Service;
+import java.util.Map;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huimv.common.utils.PageUtils;
+import com.huimv.common.utils.Query;
+
+import com.huimv.management.dao.SensitiveWordDao;
+import com.huimv.management.entity.SensitiveWordEntity;
+import com.huimv.management.service.SensitiveWordService;
+
+
+@Service("sensitiveWordService")
+public class SensitiveWordServiceImpl extends ServiceImpl<SensitiveWordDao, SensitiveWordEntity> implements SensitiveWordService {
+
+    @Override
+    public PageUtils queryPage(Map<String, Object> params) {
+        IPage<SensitiveWordEntity> page = this.page(
+                new Query<SensitiveWordEntity>().getPage(params),
+                new QueryWrapper<SensitiveWordEntity>()
+        );
+
+        return new PageUtils(page);
+    }
+
+}

+ 16 - 0
huimv-smart-management/src/main/resources/mapper/management/SensitiveWordDao.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.huimv.management.dao.SensitiveWordDao">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.huimv.management.entity.SensitiveWordEntity" id="sensitiveWordMap">
+        <result property="id" column="id"/>
+        <result property="word" column="word"/>
+        <result property="deleted" column="deleted"/>
+        <result property="gmtCreate" column="gmt_create"/>
+        <result property="gmtModified" column="gmt_modified"/>
+    </resultMap>
+
+
+</mapper>

+ 15 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/Oauth2AuthApplication.java

@@ -0,0 +1,15 @@
+package com.huimv.oauth2;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@EnableDiscoveryClient
+@SpringBootApplication
+public class Oauth2AuthApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Oauth2AuthApplication.class, args);
+    }
+
+}

+ 124 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/api/CommonResult.java

@@ -0,0 +1,124 @@
+package com.huimv.oauth2.api;
+
+/**
+ * 通用返回对象
+ * Created by macro on 2019/4/19.
+ */
+public class CommonResult<T> {
+    private long code;
+    private String message;
+    private T data;
+
+    protected CommonResult() {
+    }
+
+    protected CommonResult(long code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     */
+    public static <T> CommonResult<T> success(T data) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     * @param  message 提示信息
+     */
+    public static <T> CommonResult<T> success(T data, String message) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode) {
+        return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     * @param message 错误信息
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) {
+        return new CommonResult<T>(errorCode.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> failed(String message) {
+        return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     */
+    public static <T> CommonResult<T> failed() {
+        return failed(ResultCode.FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     */
+    public static <T> CommonResult<T> validateFailed() {
+        return failed(ResultCode.VALIDATE_FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> validateFailed(String message) {
+        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 未登录返回结果
+     */
+    public static <T> CommonResult<T> unauthorized(T data) {
+        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
+    }
+
+    /**
+     * 未授权返回结果
+     */
+    public static <T> CommonResult<T> forbidden(T data) {
+        return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
+    }
+
+    public long getCode() {
+        return code;
+    }
+
+    public void setCode(long code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 11 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/api/IErrorCode.java

@@ -0,0 +1,11 @@
+package com.huimv.oauth2.api;
+
+/**
+ * 封装API的错误码
+ * Created by macro on 2019/4/19.
+ */
+public interface IErrorCode {
+    long getCode();
+
+    String getMessage();
+}

+ 28 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/api/ResultCode.java

@@ -0,0 +1,28 @@
+package com.huimv.oauth2.api;
+
+/**
+ * 枚举了一些常用API操作码
+ * Created by macro on 2019/4/19.
+ */
+public enum ResultCode implements IErrorCode {
+    SUCCESS(200, "操作成功"),
+    FAILED(500, "操作失败"),
+    VALIDATE_FAILED(404, "参数检验失败"),
+    UNAUTHORIZED(401, "暂未登录或token已经过期"),
+    FORBIDDEN(403, "没有相关权限");
+    private long code;
+    private String message;
+
+    private ResultCode(long code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public long getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}

+ 28 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/component/JwtTokenEnhancer.java

@@ -0,0 +1,28 @@
+package com.huimv.oauth2.component;
+
+import com.macro.cloud.domain.SecurityUser;
+import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.token.TokenEnhancer;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JWT内容增强器
+ * Created by macro on 2020/6/19.
+ */
+@Component
+public class JwtTokenEnhancer implements TokenEnhancer {
+    @Override
+    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
+        SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
+        Map<String, Object> info = new HashMap<>();
+        //把用户ID设置到JWT中
+        info.put("id", securityUser.getId());
+        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
+        return accessToken;
+    }
+}

+ 82 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/config/Oauth2ServerConfig.java

@@ -0,0 +1,82 @@
+package com.huimv.oauth2.config;
+
+import com.macro.cloud.component.JwtTokenEnhancer;
+import com.macro.cloud.service.UserServiceImpl;
+import lombok.AllArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.token.TokenEnhancer;
+import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
+import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
+
+import java.security.KeyPair;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 认证服务器配置
+ * Created by macro on 2020/6/19.
+ */
+@AllArgsConstructor
+@Configuration
+@EnableAuthorizationServer
+public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {
+
+    private final PasswordEncoder passwordEncoder;
+    private final UserServiceImpl userDetailsService;
+    private final AuthenticationManager authenticationManager;
+    private final JwtTokenEnhancer jwtTokenEnhancer;
+
+    @Override
+    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+        clients.inMemory()
+                .withClient("client-app")
+                .secret(passwordEncoder.encode("123456"))
+                .scopes("all")
+                .authorizedGrantTypes("password", "refresh_token")
+                .accessTokenValiditySeconds(3600)
+                .refreshTokenValiditySeconds(86400);
+    }
+
+    @Override
+    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
+        List<TokenEnhancer> delegates = new ArrayList<>();
+        delegates.add(jwtTokenEnhancer);
+        delegates.add(accessTokenConverter());
+        enhancerChain.setTokenEnhancers(delegates); //配置JWT的内容增强器
+        endpoints.authenticationManager(authenticationManager)
+                .userDetailsService(userDetailsService) //配置加载用户信息的服务
+                .accessTokenConverter(accessTokenConverter())
+                .tokenEnhancer(enhancerChain);
+    }
+
+    @Override
+    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
+        security.allowFormAuthenticationForClients();
+    }
+
+    @Bean
+    public JwtAccessTokenConverter accessTokenConverter() {
+        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
+        jwtAccessTokenConverter.setKeyPair(keyPair());
+        return jwtAccessTokenConverter;
+    }
+
+    @Bean
+    public KeyPair keyPair() {
+        //从classpath下的证书中获取秘钥对
+        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray());
+        return keyStoreKeyFactory.getKeyPair("jwt", "123456".toCharArray());
+    }
+
+}

+ 33 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/config/RedisRepositoryConfig.java

@@ -0,0 +1,33 @@
+package com.huimv.oauth2.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis相关配置
+ * Created by macro on 2020/6/19.
+ */
+@Configuration
+@EnableRedisRepositories
+public class RedisRepositoryConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(connectionFactory);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        redisTemplate.setKeySerializer(stringRedisSerializer);
+        redisTemplate.setHashKeySerializer(stringRedisSerializer);
+        Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
+}

+ 40 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/config/WebSecurityConfig.java

@@ -0,0 +1,40 @@
+package com.huimv.oauth2.config;
+
+import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+/**
+ * SpringSecurity配置
+ * Created by macro on 2020/6/19.
+ */
+@Configuration
+@EnableWebSecurity
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests()
+                .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
+                .antMatchers("/rsa/publicKey").permitAll()
+                .anyRequest().authenticated();
+    }
+
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+}

+ 23 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/constant/MessageConstant.java

@@ -0,0 +1,23 @@
+package com.huimv.oauth2.constant;
+
+/**
+ * 消息常量
+ * Created by macro on 2020/6/19.
+ */
+public class MessageConstant {
+
+    public static final String LOGIN_SUCCESS = "登录成功!";
+
+    public static final String USERNAME_PASSWORD_ERROR = "用户名或密码错误!";
+
+    public static final String CREDENTIALS_EXPIRED = "该账户的登录凭证已过期,请重新登录!";
+
+    public static final String ACCOUNT_DISABLED = "该账户已被禁用,请联系管理员!";
+
+    public static final String ACCOUNT_LOCKED = "该账号已被锁定,请联系管理员!";
+
+    public static final String ACCOUNT_EXPIRED = "该账号已过期,请联系管理员!";
+
+    public static final String PERMISSION_DENIED = "没有访问权限,请联系管理员!";
+
+}

+ 11 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/constant/RedisConstant.java

@@ -0,0 +1,11 @@
+package com.huimv.oauth2.constant;
+
+/**
+ * Redis常量
+ * Created by macro on 2020/6/19.
+ */
+public class RedisConstant {
+
+    public static final String RESOURCE_ROLES_MAP = "AUTH:RESOURCE_ROLES_MAP";
+
+}

+ 42 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/controller/AuthController.java

@@ -0,0 +1,42 @@
+package com.huimv.oauth2.controller;
+
+import com.macro.cloud.api.CommonResult;
+import com.macro.cloud.domain.Oauth2TokenDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * 自定义Oauth2获取令牌接口
+ * Created by macro on 2020/7/17.
+ */
+@RestController
+@RequestMapping("/oauth")
+public class AuthController {
+
+    @Autowired
+    private TokenEndpoint tokenEndpoint;
+
+    /**
+     * Oauth2登录认证
+     */
+    @RequestMapping(value = "/token", method = RequestMethod.POST)
+    public CommonResult<Oauth2TokenDto> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
+        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
+        Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder()
+                .token(oAuth2AccessToken.getValue())
+                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
+                .expiresIn(oAuth2AccessToken.getExpiresIn())
+                .tokenHead("Bearer ").build();
+
+        return CommonResult.success(oauth2TokenDto);
+    }
+}

+ 30 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/controller/KeyPairController.java

@@ -0,0 +1,30 @@
+package com.huimv.oauth2.controller;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.RSAKey;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.KeyPair;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Map;
+
+/**
+ * 获取RSA公钥接口
+ * Created by macro on 2020/6/19.
+ */
+@RestController
+public class KeyPairController {
+
+    @Autowired
+    private KeyPair keyPair;
+
+    @GetMapping("/rsa/publicKey")
+    public Map<String, Object> getKey() {
+        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+        RSAKey key = new RSAKey.Builder(publicKey).build();
+        return new JWKSet(key).toJSONObject();
+    }
+
+}

+ 31 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/domain/Oauth2TokenDto.java

@@ -0,0 +1,31 @@
+package com.huimv.oauth2.domain;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * Oauth2获取Token返回信息封装
+ * Created by macro on 2020/7/17.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Builder
+public class Oauth2TokenDto {
+    /**
+     * 访问令牌
+     */
+    private String token;
+    /**
+     * 刷新令牌
+     */
+    private String refreshToken;
+    /**
+     * 访问令牌头前缀
+     */
+    private String tokenHead;
+    /**
+     * 有效时间(秒)
+     */
+    private int expiresIn;
+}

+ 89 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/domain/SecurityUser.java

@@ -0,0 +1,89 @@
+package com.huimv.oauth2.domain;
+
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * 登录用户信息
+ * Created by macro on 2020/6/19.
+ */
+@Data
+public class SecurityUser implements UserDetails {
+
+    /**
+     * ID
+     */
+    private Long id;
+    /**
+     * 用户名
+     */
+    private String username;
+    /**
+     * 用户密码
+     */
+    private String password;
+    /**
+     * 用户状态
+     */
+    private Boolean enabled;
+    /**
+     * 权限数据
+     */
+    private Collection<SimpleGrantedAuthority> authorities;
+
+    public SecurityUser() {
+
+    }
+
+    public SecurityUser(UserDTO userDTO) {
+        this.setId(userDTO.getId());
+        this.setUsername(userDTO.getUsername());
+        this.setPassword(userDTO.getPassword());
+        this.setEnabled(userDTO.getStatus() == 1);
+        if (userDTO.getRoles() != null) {
+            authorities = new ArrayList<>();
+            userDTO.getRoles().forEach(item -> authorities.add(new SimpleGrantedAuthority(item)));
+        }
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return this.authorities;
+    }
+
+    @Override
+    public String getPassword() {
+        return this.password;
+    }
+
+    @Override
+    public String getUsername() {
+        return this.username;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.enabled;
+    }
+
+}

+ 22 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/domain/UserDTO.java

@@ -0,0 +1,22 @@
+package com.huimv.oauth2.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * Created by macro on 2020/6/19.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@AllArgsConstructor
+public class UserDTO{
+    private Long id;
+    private String username;
+    private String password;
+    private Integer status;
+    private List<String> roles;
+
+}

+ 20 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/exception/Oauth2ExceptionHandler.java

@@ -0,0 +1,20 @@
+package com.huimv.oauth2.exception;
+
+import com.macro.cloud.api.CommonResult;
+import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * 全局处理Oauth2抛出的异常
+ * Created by macro on 2020/7/17.
+ */
+@ControllerAdvice
+public class Oauth2ExceptionHandler {
+    @ResponseBody
+    @ExceptionHandler(value = OAuth2Exception.class)
+    public CommonResult handleOauth2(OAuth2Exception e) {
+        return CommonResult.failed(e.getMessage());
+    }
+}

+ 32 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/service/ResourceServiceImpl.java

@@ -0,0 +1,32 @@
+package com.macro.cloud.service;
+
+import cn.hutool.core.collection.CollUtil;
+import com.macro.cloud.constant.RedisConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 资源与角色匹配关系管理业务类
+ * Created by macro on 2020/6/19.
+ */
+@Service
+public class ResourceServiceImpl {
+
+    private Map<String, List<String>> resourceRolesMap;
+    @Autowired
+    private RedisTemplate<String,Object> redisTemplate;
+
+    @PostConstruct
+    public void initData() {
+        resourceRolesMap = new TreeMap<>();
+        resourceRolesMap.put("/api/hello", CollUtil.toList("ADMIN"));
+        resourceRolesMap.put("/api/user/currentUser", CollUtil.toList("ADMIN", "TEST"));
+        redisTemplate.opsForHash().putAll(RedisConstant.RESOURCE_ROLES_MAP, resourceRolesMap);
+    }
+}

+ 61 - 0
huimv-smart-oauth2/src/main/java/com/huimv/oauth2/service/UserServiceImpl.java

@@ -0,0 +1,61 @@
+package com.huimv.oauth2.service;
+
+import cn.hutool.core.collection.CollUtil;
+import com.macro.cloud.domain.SecurityUser;
+import com.macro.cloud.domain.UserDTO;
+import com.macro.cloud.constant.MessageConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AccountExpiredException;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户管理业务类
+ * Created by macro on 2020/6/19.
+ */
+@Service
+public class UserServiceImpl implements UserDetailsService {
+
+    private List<UserDTO> userList;
+    @Autowired
+    private PasswordEncoder passwordEncoder;
+
+    @PostConstruct
+    public void initData() {
+        String password = passwordEncoder.encode("123456");
+        userList = new ArrayList<>();
+        userList.add(new UserDTO(1L,"macro", password,1, CollUtil.toList("ADMIN")));
+        userList.add(new UserDTO(2L,"andy", password,1, CollUtil.toList("TEST")));
+    }
+
+    @Override
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+        List<UserDTO> findUserList = userList.stream().filter(item -> item.getUsername().equals(username)).collect(Collectors.toList());
+        if (CollUtil.isEmpty(findUserList)) {
+            throw new UsernameNotFoundException(MessageConstant.USERNAME_PASSWORD_ERROR);
+        }
+        SecurityUser securityUser = new SecurityUser(findUserList.get(0));
+        if (!securityUser.isEnabled()) {
+            throw new DisabledException(MessageConstant.ACCOUNT_DISABLED);
+        } else if (!securityUser.isAccountNonLocked()) {
+            throw new LockedException(MessageConstant.ACCOUNT_LOCKED);
+        } else if (!securityUser.isAccountNonExpired()) {
+            throw new AccountExpiredException(MessageConstant.ACCOUNT_EXPIRED);
+        } else if (!securityUser.isCredentialsNonExpired()) {
+            throw new CredentialsExpiredException(MessageConstant.CREDENTIALS_EXPIRED);
+        }
+        return securityUser;
+    }
+
+}

+ 0 - 0
huimv-smart-oauth2/src/main/resources/application.yml


+ 21 - 0
micro-oauth2/micro-oauth2-api/pom.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>micro-oauth2</artifactId>
+        <groupId>com.macro.cloud</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>micro-oauth2-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/Oauth2ApiApplication.java

@@ -0,0 +1,15 @@
+package com.macro.cloud;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@EnableDiscoveryClient
+@SpringBootApplication
+public class Oauth2ApiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Oauth2ApiApplication.class, args);
+    }
+
+}

+ 18 - 0
micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/controller/HelloController.java

@@ -0,0 +1,18 @@
+package com.macro.cloud.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 测试接口
+ * Created by macro on 2020/6/19.
+ */
+@RestController
+public class HelloController {
+
+    @GetMapping("/hello")
+    public String hello() {
+        return "Hello World.";
+    }
+
+}

+ 26 - 0
micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/controller/UserController.java

@@ -0,0 +1,26 @@
+package com.macro.cloud.controller;
+
+import com.macro.cloud.domain.UserDTO;
+import com.macro.cloud.holder.LoginUserHolder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 获取登录用户信息接口
+ * Created by macro on 2020/6/19.
+ */
+@RestController
+@RequestMapping("/user")
+public class UserController{
+
+    @Autowired
+    private LoginUserHolder loginUserHolder;
+
+    @GetMapping("/currentUser")
+    public UserDTO currentUser() {
+        return loginUserHolder.getCurrentUser();
+    }
+
+}

+ 18 - 0
micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/domain/UserDTO.java

@@ -0,0 +1,18 @@
+package com.macro.cloud.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * Created by macro on 2020/6/19.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class UserDTO {
+    private Long id;
+    private String username;
+    private String password;
+    private List<String> roles;
+}

+ 31 - 0
micro-oauth2/micro-oauth2-api/src/main/java/com/macro/cloud/holder/LoginUserHolder.java

@@ -0,0 +1,31 @@
+package com.macro.cloud.holder;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.json.JSONObject;
+import com.macro.cloud.domain.UserDTO;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 获取登录用户信息
+ * Created by macro on 2020/6/17.
+ */
+@Component
+public class LoginUserHolder {
+
+    public UserDTO getCurrentUser(){
+        //从Header中获取用户信息
+        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = servletRequestAttributes.getRequest();
+        String userStr = request.getHeader("user");
+        JSONObject userJsonObject = new JSONObject(userStr);
+        UserDTO userDTO = new UserDTO();
+        userDTO.setUsername(userJsonObject.getStr("user_name"));
+        userDTO.setId(Convert.toLong(userJsonObject.get("id")));
+        userDTO.setRoles(Convert.toList(String.class,userJsonObject.get("authorities")));
+        return userDTO;
+    }
+}

+ 16 - 0
micro-oauth2/micro-oauth2-api/src/main/resources/application.yml

@@ -0,0 +1,16 @@
+server:
+  port: 9501
+spring:
+  profiles:
+    active: dev
+  application:
+    name: micro-oauth2-api
+  cloud:
+    nacos:
+      discovery:
+        server-addr: localhost:8848
+management:
+  endpoints:
+    web:
+      exposure:
+        include: "*"

+ 39 - 0
micro-oauth2/micro-oauth2-auth/pom.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>micro-oauth2</artifactId>
+        <groupId>com.macro.cloud</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>micro-oauth2-auth</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-oauth2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+            <version>8.16</version>
+        </dependency>
+        <!-- redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/Oauth2AuthApplication.java

@@ -0,0 +1,15 @@
+package com.macro.cloud;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@EnableDiscoveryClient
+@SpringBootApplication
+public class Oauth2AuthApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Oauth2AuthApplication.class, args);
+    }
+
+}

+ 124 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/api/CommonResult.java

@@ -0,0 +1,124 @@
+package com.macro.cloud.api;
+
+/**
+ * 通用返回对象
+ * Created by macro on 2019/4/19.
+ */
+public class CommonResult<T> {
+    private long code;
+    private String message;
+    private T data;
+
+    protected CommonResult() {
+    }
+
+    protected CommonResult(long code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     */
+    public static <T> CommonResult<T> success(T data) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     * @param  message 提示信息
+     */
+    public static <T> CommonResult<T> success(T data, String message) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode) {
+        return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     * @param message 错误信息
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) {
+        return new CommonResult<T>(errorCode.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> failed(String message) {
+        return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     */
+    public static <T> CommonResult<T> failed() {
+        return failed(ResultCode.FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     */
+    public static <T> CommonResult<T> validateFailed() {
+        return failed(ResultCode.VALIDATE_FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> validateFailed(String message) {
+        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 未登录返回结果
+     */
+    public static <T> CommonResult<T> unauthorized(T data) {
+        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
+    }
+
+    /**
+     * 未授权返回结果
+     */
+    public static <T> CommonResult<T> forbidden(T data) {
+        return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
+    }
+
+    public long getCode() {
+        return code;
+    }
+
+    public void setCode(long code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 11 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/api/IErrorCode.java

@@ -0,0 +1,11 @@
+package com.macro.cloud.api;
+
+/**
+ * 封装API的错误码
+ * Created by macro on 2019/4/19.
+ */
+public interface IErrorCode {
+    long getCode();
+
+    String getMessage();
+}

+ 28 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/api/ResultCode.java

@@ -0,0 +1,28 @@
+package com.macro.cloud.api;
+
+/**
+ * 枚举了一些常用API操作码
+ * Created by macro on 2019/4/19.
+ */
+public enum ResultCode implements IErrorCode {
+    SUCCESS(200, "操作成功"),
+    FAILED(500, "操作失败"),
+    VALIDATE_FAILED(404, "参数检验失败"),
+    UNAUTHORIZED(401, "暂未登录或token已经过期"),
+    FORBIDDEN(403, "没有相关权限");
+    private long code;
+    private String message;
+
+    private ResultCode(long code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public long getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}

+ 28 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/component/JwtTokenEnhancer.java

@@ -0,0 +1,28 @@
+package com.macro.cloud.component;
+
+import com.macro.cloud.domain.SecurityUser;
+import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.token.TokenEnhancer;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JWT内容增强器
+ * Created by macro on 2020/6/19.
+ */
+@Component
+public class JwtTokenEnhancer implements TokenEnhancer {
+    @Override
+    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
+        SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();
+        Map<String, Object> info = new HashMap<>();
+        //把用户ID设置到JWT中
+        info.put("id", securityUser.getId());
+        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
+        return accessToken;
+    }
+}

+ 82 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/config/Oauth2ServerConfig.java

@@ -0,0 +1,82 @@
+package com.macro.cloud.config;
+
+import com.macro.cloud.component.JwtTokenEnhancer;
+import com.macro.cloud.service.UserServiceImpl;
+import lombok.AllArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.token.TokenEnhancer;
+import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
+import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
+
+import java.security.KeyPair;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 认证服务器配置
+ * Created by macro on 2020/6/19.
+ */
+@AllArgsConstructor
+@Configuration
+@EnableAuthorizationServer
+public class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter {
+
+    private final PasswordEncoder passwordEncoder;
+    private final UserServiceImpl userDetailsService;
+    private final AuthenticationManager authenticationManager;
+    private final JwtTokenEnhancer jwtTokenEnhancer;
+
+    @Override
+    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+        clients.inMemory()
+                .withClient("client-app")
+                .secret(passwordEncoder.encode("123456"))
+                .scopes("all")
+                .authorizedGrantTypes("password", "refresh_token")
+                .accessTokenValiditySeconds(3600)
+                .refreshTokenValiditySeconds(86400);
+    }
+
+    @Override
+    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
+        List<TokenEnhancer> delegates = new ArrayList<>();
+        delegates.add(jwtTokenEnhancer);
+        delegates.add(accessTokenConverter());
+        enhancerChain.setTokenEnhancers(delegates); //配置JWT的内容增强器
+        endpoints.authenticationManager(authenticationManager)
+                .userDetailsService(userDetailsService) //配置加载用户信息的服务
+                .accessTokenConverter(accessTokenConverter())
+                .tokenEnhancer(enhancerChain);
+    }
+
+    @Override
+    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
+        security.allowFormAuthenticationForClients();
+    }
+
+    @Bean
+    public JwtAccessTokenConverter accessTokenConverter() {
+        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
+        jwtAccessTokenConverter.setKeyPair(keyPair());
+        return jwtAccessTokenConverter;
+    }
+
+    @Bean
+    public KeyPair keyPair() {
+        //从classpath下的证书中获取秘钥对
+        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray());
+        return keyStoreKeyFactory.getKeyPair("jwt", "123456".toCharArray());
+    }
+
+}

+ 33 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/config/RedisRepositoryConfig.java

@@ -0,0 +1,33 @@
+package com.macro.cloud.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis相关配置
+ * Created by macro on 2020/6/19.
+ */
+@Configuration
+@EnableRedisRepositories
+public class RedisRepositoryConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(connectionFactory);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        redisTemplate.setKeySerializer(stringRedisSerializer);
+        redisTemplate.setHashKeySerializer(stringRedisSerializer);
+        Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
+}

+ 40 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/config/WebSecurityConfig.java

@@ -0,0 +1,40 @@
+package com.macro.cloud.config;
+
+import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+/**
+ * SpringSecurity配置
+ * Created by macro on 2020/6/19.
+ */
+@Configuration
+@EnableWebSecurity
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests()
+                .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
+                .antMatchers("/rsa/publicKey").permitAll()
+                .anyRequest().authenticated();
+    }
+
+    @Bean
+    @Override
+    public AuthenticationManager authenticationManagerBean() throws Exception {
+        return super.authenticationManagerBean();
+    }
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+}

+ 23 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/constant/MessageConstant.java

@@ -0,0 +1,23 @@
+package com.macro.cloud.constant;
+
+/**
+ * 消息常量
+ * Created by macro on 2020/6/19.
+ */
+public class MessageConstant {
+
+    public static final String LOGIN_SUCCESS = "登录成功!";
+
+    public static final String USERNAME_PASSWORD_ERROR = "用户名或密码错误!";
+
+    public static final String CREDENTIALS_EXPIRED = "该账户的登录凭证已过期,请重新登录!";
+
+    public static final String ACCOUNT_DISABLED = "该账户已被禁用,请联系管理员!";
+
+    public static final String ACCOUNT_LOCKED = "该账号已被锁定,请联系管理员!";
+
+    public static final String ACCOUNT_EXPIRED = "该账号已过期,请联系管理员!";
+
+    public static final String PERMISSION_DENIED = "没有访问权限,请联系管理员!";
+
+}

+ 11 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/constant/RedisConstant.java

@@ -0,0 +1,11 @@
+package com.macro.cloud.constant;
+
+/**
+ * Redis常量
+ * Created by macro on 2020/6/19.
+ */
+public class RedisConstant {
+
+    public static final String RESOURCE_ROLES_MAP = "AUTH:RESOURCE_ROLES_MAP";
+
+}

+ 42 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/controller/AuthController.java

@@ -0,0 +1,42 @@
+package com.macro.cloud.controller;
+
+import com.macro.cloud.api.CommonResult;
+import com.macro.cloud.domain.Oauth2TokenDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * 自定义Oauth2获取令牌接口
+ * Created by macro on 2020/7/17.
+ */
+@RestController
+@RequestMapping("/oauth")
+public class AuthController {
+
+    @Autowired
+    private TokenEndpoint tokenEndpoint;
+
+    /**
+     * Oauth2登录认证
+     */
+    @RequestMapping(value = "/token", method = RequestMethod.POST)
+    public CommonResult<Oauth2TokenDto> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
+        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
+        Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder()
+                .token(oAuth2AccessToken.getValue())
+                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
+                .expiresIn(oAuth2AccessToken.getExpiresIn())
+                .tokenHead("Bearer ").build();
+
+        return CommonResult.success(oauth2TokenDto);
+    }
+}

+ 30 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/controller/KeyPairController.java

@@ -0,0 +1,30 @@
+package com.macro.cloud.controller;
+
+import com.nimbusds.jose.jwk.JWKSet;
+import com.nimbusds.jose.jwk.RSAKey;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.KeyPair;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Map;
+
+/**
+ * 获取RSA公钥接口
+ * Created by macro on 2020/6/19.
+ */
+@RestController
+public class KeyPairController {
+
+    @Autowired
+    private KeyPair keyPair;
+
+    @GetMapping("/rsa/publicKey")
+    public Map<String, Object> getKey() {
+        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+        RSAKey key = new RSAKey.Builder(publicKey).build();
+        return new JWKSet(key).toJSONObject();
+    }
+
+}

+ 31 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/domain/Oauth2TokenDto.java

@@ -0,0 +1,31 @@
+package com.macro.cloud.domain;
+
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * Oauth2获取Token返回信息封装
+ * Created by macro on 2020/7/17.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Builder
+public class Oauth2TokenDto {
+    /**
+     * 访问令牌
+     */
+    private String token;
+    /**
+     * 刷新令牌
+     */
+    private String refreshToken;
+    /**
+     * 访问令牌头前缀
+     */
+    private String tokenHead;
+    /**
+     * 有效时间(秒)
+     */
+    private int expiresIn;
+}

+ 89 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/domain/SecurityUser.java

@@ -0,0 +1,89 @@
+package com.macro.cloud.domain;
+
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * 登录用户信息
+ * Created by macro on 2020/6/19.
+ */
+@Data
+public class SecurityUser implements UserDetails {
+
+    /**
+     * ID
+     */
+    private Long id;
+    /**
+     * 用户名
+     */
+    private String username;
+    /**
+     * 用户密码
+     */
+    private String password;
+    /**
+     * 用户状态
+     */
+    private Boolean enabled;
+    /**
+     * 权限数据
+     */
+    private Collection<SimpleGrantedAuthority> authorities;
+
+    public SecurityUser() {
+
+    }
+
+    public SecurityUser(UserDTO userDTO) {
+        this.setId(userDTO.getId());
+        this.setUsername(userDTO.getUsername());
+        this.setPassword(userDTO.getPassword());
+        this.setEnabled(userDTO.getStatus() == 1);
+        if (userDTO.getRoles() != null) {
+            authorities = new ArrayList<>();
+            userDTO.getRoles().forEach(item -> authorities.add(new SimpleGrantedAuthority(item)));
+        }
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return this.authorities;
+    }
+
+    @Override
+    public String getPassword() {
+        return this.password;
+    }
+
+    @Override
+    public String getUsername() {
+        return this.username;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.enabled;
+    }
+
+}

+ 22 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/domain/UserDTO.java

@@ -0,0 +1,22 @@
+package com.macro.cloud.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * Created by macro on 2020/6/19.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@AllArgsConstructor
+public class UserDTO{
+    private Long id;
+    private String username;
+    private String password;
+    private Integer status;
+    private List<String> roles;
+
+}

+ 20 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/exception/Oauth2ExceptionHandler.java

@@ -0,0 +1,20 @@
+package com.macro.cloud.exception;
+
+import com.macro.cloud.api.CommonResult;
+import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * 全局处理Oauth2抛出的异常
+ * Created by macro on 2020/7/17.
+ */
+@ControllerAdvice
+public class Oauth2ExceptionHandler {
+    @ResponseBody
+    @ExceptionHandler(value = OAuth2Exception.class)
+    public CommonResult handleOauth2(OAuth2Exception e) {
+        return CommonResult.failed(e.getMessage());
+    }
+}

+ 32 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/service/ResourceServiceImpl.java

@@ -0,0 +1,32 @@
+package com.macro.cloud.service;
+
+import cn.hutool.core.collection.CollUtil;
+import com.macro.cloud.constant.RedisConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 资源与角色匹配关系管理业务类
+ * Created by macro on 2020/6/19.
+ */
+@Service
+public class ResourceServiceImpl {
+
+    private Map<String, List<String>> resourceRolesMap;
+    @Autowired
+    private RedisTemplate<String,Object> redisTemplate;
+
+    @PostConstruct
+    public void initData() {
+        resourceRolesMap = new TreeMap<>();
+        resourceRolesMap.put("/api/hello", CollUtil.toList("ADMIN"));
+        resourceRolesMap.put("/api/user/currentUser", CollUtil.toList("ADMIN", "TEST"));
+        redisTemplate.opsForHash().putAll(RedisConstant.RESOURCE_ROLES_MAP, resourceRolesMap);
+    }
+}

+ 61 - 0
micro-oauth2/micro-oauth2-auth/src/main/java/com/macro/cloud/service/UserServiceImpl.java

@@ -0,0 +1,61 @@
+package com.macro.cloud.service;
+
+import cn.hutool.core.collection.CollUtil;
+import com.macro.cloud.domain.SecurityUser;
+import com.macro.cloud.domain.UserDTO;
+import com.macro.cloud.constant.MessageConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AccountExpiredException;
+import org.springframework.security.authentication.CredentialsExpiredException;
+import org.springframework.security.authentication.DisabledException;
+import org.springframework.security.authentication.LockedException;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户管理业务类
+ * Created by macro on 2020/6/19.
+ */
+@Service
+public class UserServiceImpl implements UserDetailsService {
+
+    private List<UserDTO> userList;
+    @Autowired
+    private PasswordEncoder passwordEncoder;
+
+    @PostConstruct
+    public void initData() {
+        String password = passwordEncoder.encode("123456");
+        userList = new ArrayList<>();
+        userList.add(new UserDTO(1L,"macro", password,1, CollUtil.toList("ADMIN")));
+        userList.add(new UserDTO(2L,"andy", password,1, CollUtil.toList("TEST")));
+    }
+
+    @Override
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+        List<UserDTO> findUserList = userList.stream().filter(item -> item.getUsername().equals(username)).collect(Collectors.toList());
+        if (CollUtil.isEmpty(findUserList)) {
+            throw new UsernameNotFoundException(MessageConstant.USERNAME_PASSWORD_ERROR);
+        }
+        SecurityUser securityUser = new SecurityUser(findUserList.get(0));
+        if (!securityUser.isEnabled()) {
+            throw new DisabledException(MessageConstant.ACCOUNT_DISABLED);
+        } else if (!securityUser.isAccountNonLocked()) {
+            throw new LockedException(MessageConstant.ACCOUNT_LOCKED);
+        } else if (!securityUser.isAccountNonExpired()) {
+            throw new AccountExpiredException(MessageConstant.ACCOUNT_EXPIRED);
+        } else if (!securityUser.isCredentialsNonExpired()) {
+            throw new CredentialsExpiredException(MessageConstant.CREDENTIALS_EXPIRED);
+        }
+        return securityUser;
+    }
+
+}

+ 23 - 0
micro-oauth2/micro-oauth2-auth/src/main/resources/application.yml

@@ -0,0 +1,23 @@
+server:
+  port: 9401
+spring:
+  profiles:
+    active: dev
+  application:
+    name: micro-oauth2-auth
+  cloud:
+    nacos:
+      discovery:
+        server-addr: localhost:8848
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+  redis:
+    database: 0
+    port: 6379
+    host: localhost
+    password: 123456
+management:
+  endpoints:
+    web:
+      exposure:
+        include: "*"

BIN
micro-oauth2/micro-oauth2-auth/src/main/resources/jwt.jks


+ 57 - 0
micro-oauth2/micro-oauth2-gateway/pom.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>micro-oauth2</artifactId>
+        <groupId>com.macro.cloud</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>micro-oauth2-gateway</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-gateway</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-resource-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-oauth2-jose</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+            <version>8.16</version>
+        </dependency>
+        <!-- redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <!-- 自定义的元数据依赖 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/Oauth2GatewayApplication.java

@@ -0,0 +1,15 @@
+package com.macro.cloud;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@EnableDiscoveryClient
+@SpringBootApplication
+public class Oauth2GatewayApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Oauth2GatewayApplication.class, args);
+    }
+
+}

+ 124 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/api/CommonResult.java

@@ -0,0 +1,124 @@
+package com.macro.cloud.api;
+
+/**
+ * 通用返回对象
+ * Created by macro on 2019/4/19.
+ */
+public class CommonResult<T> {
+    private long code;
+    private String message;
+    private T data;
+
+    protected CommonResult() {
+    }
+
+    protected CommonResult(long code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     */
+    public static <T> CommonResult<T> success(T data) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
+    }
+
+    /**
+     * 成功返回结果
+     *
+     * @param data 获取的数据
+     * @param  message 提示信息
+     */
+    public static <T> CommonResult<T> success(T data, String message) {
+        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode) {
+        return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param errorCode 错误码
+     * @param message 错误信息
+     */
+    public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) {
+        return new CommonResult<T>(errorCode.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> failed(String message) {
+        return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 失败返回结果
+     */
+    public static <T> CommonResult<T> failed() {
+        return failed(ResultCode.FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     */
+    public static <T> CommonResult<T> validateFailed() {
+        return failed(ResultCode.VALIDATE_FAILED);
+    }
+
+    /**
+     * 参数验证失败返回结果
+     * @param message 提示信息
+     */
+    public static <T> CommonResult<T> validateFailed(String message) {
+        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
+    }
+
+    /**
+     * 未登录返回结果
+     */
+    public static <T> CommonResult<T> unauthorized(T data) {
+        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
+    }
+
+    /**
+     * 未授权返回结果
+     */
+    public static <T> CommonResult<T> forbidden(T data) {
+        return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
+    }
+
+    public long getCode() {
+        return code;
+    }
+
+    public void setCode(long code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 11 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/api/IErrorCode.java

@@ -0,0 +1,11 @@
+package com.macro.cloud.api;
+
+/**
+ * 封装API的错误码
+ * Created by macro on 2019/4/19.
+ */
+public interface IErrorCode {
+    long getCode();
+
+    String getMessage();
+}

+ 28 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/api/ResultCode.java

@@ -0,0 +1,28 @@
+package com.macro.cloud.api;
+
+/**
+ * 枚举了一些常用API操作码
+ * Created by macro on 2019/4/19.
+ */
+public enum ResultCode implements IErrorCode {
+    SUCCESS(200, "操作成功"),
+    FAILED(500, "操作失败"),
+    VALIDATE_FAILED(404, "参数检验失败"),
+    UNAUTHORIZED(401, "暂未登录或token已经过期"),
+    FORBIDDEN(403, "没有相关权限");
+    private long code;
+    private String message;
+
+    private ResultCode(long code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public long getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}

+ 46 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/authorization/AuthorizationManager.java

@@ -0,0 +1,46 @@
+package com.macro.cloud.authorization;
+
+import cn.hutool.core.convert.Convert;
+import com.macro.cloud.constant.AuthConstant;
+import com.macro.cloud.constant.RedisConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.security.authorization.AuthorizationDecision;
+import org.springframework.security.authorization.ReactiveAuthorizationManager;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.web.server.authorization.AuthorizationContext;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+import java.net.URI;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 鉴权管理器,用于判断是否有资源的访问权限
+ * Created by macro on 2020/6/19.
+ */
+@Component
+public class AuthorizationManager implements ReactiveAuthorizationManager<AuthorizationContext> {
+    @Autowired
+    private RedisTemplate<String,Object> redisTemplate;
+
+    @Override
+    public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
+        //从Redis中获取当前路径可访问角色列表
+        URI uri = authorizationContext.getExchange().getRequest().getURI();
+        Object obj = redisTemplate.opsForHash().get(RedisConstant.RESOURCE_ROLES_MAP, uri.getPath());
+        List<String> authorities = Convert.toList(String.class,obj);
+        authorities = authorities.stream().map(i -> i = AuthConstant.AUTHORITY_PREFIX + i).collect(Collectors.toList());
+        //认证通过且角色匹配的用户可访问当前路径
+        return mono
+                .filter(Authentication::isAuthenticated)
+                .flatMapIterable(Authentication::getAuthorities)
+                .map(GrantedAuthority::getAuthority)
+                .any(authorities::contains)
+                .map(AuthorizationDecision::new)
+                .defaultIfEmpty(new AuthorizationDecision(false));
+    }
+
+}

+ 33 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/component/RestAuthenticationEntryPoint.java

@@ -0,0 +1,33 @@
+package com.macro.cloud.component;
+
+import cn.hutool.json.JSONUtil;
+import com.macro.cloud.api.CommonResult;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.nio.charset.Charset;
+
+/**
+ * 自定义返回结果:没有登录或token过期时
+ * Created by macro on 2020/6/18.
+ */
+@Component
+public class RestAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
+    @Override
+    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException e) {
+        ServerHttpResponse response = exchange.getResponse();
+        response.setStatusCode(HttpStatus.OK);
+        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+        String body= JSONUtil.toJsonStr(CommonResult.unauthorized(e.getMessage()));
+        DataBuffer buffer =  response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8")));
+        return response.writeWith(Mono.just(buffer));
+    }
+}

+ 34 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/component/RestfulAccessDeniedHandler.java

@@ -0,0 +1,34 @@
+package com.macro.cloud.component;
+
+import cn.hutool.json.JSONUtil;
+import com.macro.cloud.api.CommonResult;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.nio.charset.Charset;
+
+
+/**
+ * 自定义返回结果:没有权限访问时
+ * Created by macro on 2018/4/26.
+ */
+@Component
+public class RestfulAccessDeniedHandler implements ServerAccessDeniedHandler {
+    @Override
+    public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) {
+        ServerHttpResponse response = exchange.getResponse();
+        response.setStatusCode(HttpStatus.OK);
+        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+        String body= JSONUtil.toJsonStr(CommonResult.forbidden(denied.getMessage()));
+        DataBuffer buffer =  response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8")));
+        return response.writeWith(Mono.just(buffer));
+    }
+}

+ 20 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/config/IgnoreUrlsConfig.java

@@ -0,0 +1,20 @@
+package com.macro.cloud.config;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 网关白名单配置
+ * Created by macro on 2020/6/17.
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Component
+@ConfigurationProperties(prefix="secure.ignore")
+public class IgnoreUrlsConfig {
+    private List<String> urls;
+}

+ 33 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/config/RedisRepositoryConfig.java

@@ -0,0 +1,33 @@
+package com.macro.cloud.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * Redis相关配置
+ * Created by macro on 2020/6/19.
+ */
+@Configuration
+@EnableRedisRepositories
+public class RedisRepositoryConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(connectionFactory);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        redisTemplate.setKeySerializer(stringRedisSerializer);
+        redisTemplate.setHashKeySerializer(stringRedisSerializer);
+        Jackson2JsonRedisSerializer<?> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
+}

+ 66 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/config/ResourceServerConfig.java

@@ -0,0 +1,66 @@
+package com.macro.cloud.config;
+
+import cn.hutool.core.util.ArrayUtil;
+import com.macro.cloud.constant.AuthConstant;
+import com.macro.cloud.authorization.AuthorizationManager;
+import com.macro.cloud.component.RestAuthenticationEntryPoint;
+import com.macro.cloud.component.RestfulAccessDeniedHandler;
+import com.macro.cloud.filter.IgnoreUrlsRemoveJwtFilter;
+import lombok.AllArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
+import org.springframework.security.config.web.server.ServerHttpSecurity;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
+import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
+import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
+import org.springframework.security.web.server.SecurityWebFilterChain;
+import reactor.core.publisher.Mono;
+
+/**
+ * 资源服务器配置
+ * Created by macro on 2020/6/19.
+ */
+@AllArgsConstructor
+@Configuration
+@EnableWebFluxSecurity
+public class ResourceServerConfig {
+    private final AuthorizationManager authorizationManager;
+    private final IgnoreUrlsConfig ignoreUrlsConfig;
+    private final RestfulAccessDeniedHandler restfulAccessDeniedHandler;
+    private final RestAuthenticationEntryPoint restAuthenticationEntryPoint;
+    private final IgnoreUrlsRemoveJwtFilter ignoreUrlsRemoveJwtFilter;
+
+    @Bean
+    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
+        http.oauth2ResourceServer().jwt()
+                .jwtAuthenticationConverter(jwtAuthenticationConverter());
+        //自定义处理JWT请求头过期或签名错误的结果
+        http.oauth2ResourceServer().authenticationEntryPoint(restAuthenticationEntryPoint);
+        //对白名单路径,直接移除JWT请求头
+        http.addFilterBefore(ignoreUrlsRemoveJwtFilter, SecurityWebFiltersOrder.AUTHENTICATION);
+        http.authorizeExchange()
+                .pathMatchers(ArrayUtil.toArray(ignoreUrlsConfig.getUrls(),String.class)).permitAll()//白名单配置
+                .anyExchange().access(authorizationManager)//鉴权管理器配置
+                .and().exceptionHandling()
+                .accessDeniedHandler(restfulAccessDeniedHandler)//处理未授权
+                .authenticationEntryPoint(restAuthenticationEntryPoint)//处理未认证
+                .and().csrf().disable();
+        return http.build();
+    }
+
+    @Bean
+    public Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter() {
+        JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
+        jwtGrantedAuthoritiesConverter.setAuthorityPrefix(AuthConstant.AUTHORITY_PREFIX);
+        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(AuthConstant.AUTHORITY_CLAIM_NAME);
+        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
+        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
+        return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter);
+    }
+
+}

+ 12 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/constant/AuthConstant.java

@@ -0,0 +1,12 @@
+package com.macro.cloud.constant;
+
+/**
+ * Created by macro on 2020/6/19.
+ */
+public class AuthConstant {
+
+    public static final String AUTHORITY_PREFIX = "ROLE_";
+
+    public static final String AUTHORITY_CLAIM_NAME = "authorities";
+
+}

+ 10 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/constant/RedisConstant.java

@@ -0,0 +1,10 @@
+package com.macro.cloud.constant;
+
+/**
+ * Created by macro on 2020/6/19.
+ */
+public class RedisConstant {
+
+    public static final String RESOURCE_ROLES_MAP = "AUTH:RESOURCE_ROLES_MAP";
+
+}

+ 50 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/filter/AuthGlobalFilter.java

@@ -0,0 +1,50 @@
+package com.macro.cloud.filter;
+
+import cn.hutool.core.util.StrUtil;
+import com.nimbusds.jose.JWSObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.text.ParseException;
+
+/**
+ * 将登录用户的JWT转化成用户信息的全局过滤器
+ * Created by macro on 2020/6/17.
+ */
+@Component
+public class AuthGlobalFilter implements GlobalFilter, Ordered {
+
+    private static Logger LOGGER = LoggerFactory.getLogger(AuthGlobalFilter.class);
+
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
+        if (StrUtil.isEmpty(token)) {
+            return chain.filter(exchange);
+        }
+        try {
+            //从token中解析用户信息并设置到Header中去
+            String realToken = token.replace("Bearer ", "");
+            JWSObject jwsObject = JWSObject.parse(realToken);
+            String userStr = jwsObject.getPayload().toString();
+            LOGGER.info("AuthGlobalFilter.filter() user:{}",userStr);
+            ServerHttpRequest request = exchange.getRequest().mutate().header("user", userStr).build();
+            exchange = exchange.mutate().request(request).build();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return chain.filter(exchange);
+    }
+
+    @Override
+    public int getOrder() {
+        return 0;
+    }
+}

+ 42 - 0
micro-oauth2/micro-oauth2-gateway/src/main/java/com/macro/cloud/filter/IgnoreUrlsRemoveJwtFilter.java

@@ -0,0 +1,42 @@
+package com.macro.cloud.filter;
+
+import com.macro.cloud.config.IgnoreUrlsConfig;
+import com.macro.cloud.constant.AuthConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.PathMatcher;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+
+import java.net.URI;
+import java.util.List;
+
+/**
+ * 白名单路径访问时需要移除JWT请求头
+ * Created by macro on 2020/7/24.
+ */
+@Component
+public class IgnoreUrlsRemoveJwtFilter implements WebFilter {
+    @Autowired
+    private IgnoreUrlsConfig ignoreUrlsConfig;
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        URI uri = request.getURI();
+        PathMatcher pathMatcher = new AntPathMatcher();
+        //白名单路径移除JWT请求头
+        List<String> ignoreUrls = ignoreUrlsConfig.getUrls();
+        for (String ignoreUrl : ignoreUrls) {
+            if (pathMatcher.match(ignoreUrl, uri.getPath())) {
+                request = exchange.getRequest().mutate().header("Authorization", "").build();
+                exchange = exchange.mutate().request(request).build();
+                return chain.filter(exchange);
+            }
+        }
+        return chain.filter(exchange);
+    }
+}

+ 44 - 0
micro-oauth2/micro-oauth2-gateway/src/main/resources/application.yml

@@ -0,0 +1,44 @@
+server:
+  port: 9201
+spring:
+  profiles:
+    active: dev
+  application:
+    name: micro-oauth2-gateway
+  cloud:
+    nacos:
+      discovery:
+        server-addr: localhost:8848
+    gateway:
+      routes: #配置路由路径
+        - id: oauth2-api-route
+          uri: lb://micro-oauth2-api
+          predicates:
+            - Path=/api/**
+          filters:
+            - StripPrefix=1
+        - id: oauth2-auth-route
+          uri: lb://micro-oauth2-auth
+          predicates:
+            - Path=/auth/**
+          filters:
+            - StripPrefix=1
+      discovery:
+        locator:
+          enabled: true #开启从注册中心动态创建路由的功能
+          lower-case-service-id: true #使用小写服务名,默认是大写
+  security:
+    oauth2:
+      resourceserver:
+        jwt:
+          jwk-set-uri: 'http://localhost:9401/rsa/publicKey' #配置RSA的公钥访问地址
+  redis:
+    database: 0
+    port: 6379
+    host: localhost
+    password: 123456
+secure:
+  ignore:
+    urls: #配置白名单路径
+      - "/actuator/**"
+      - "/auth/oauth/token"

+ 103 - 0
micro-oauth2/pom.xml

@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.macro.cloud</groupId>
+    <artifactId>micro-oauth2</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0.0</version>
+    <modules>
+        <module>micro-oauth2-gateway</module>
+        <module>micro-oauth2-auth</module>
+        <module>micro-oauth2-api</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <java.version>1.8</java.version>
+        <spring-cloud-alibaba.version>2.2.0.RELEASE</spring-cloud-alibaba.version>
+        <spring-cloud.version>Hoxton.SR5</spring-cloud.version>
+        <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
+        <hutool-version>5.3.5</hutool-version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>com.alibaba.cloud</groupId>
+                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
+                <version>${spring-cloud-alibaba.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.cloud</groupId>
+                <artifactId>spring-cloud-dependencies</artifactId>
+                <version>${spring-cloud.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool-version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>spring-milestones</id>
+            <name>Spring Milestones</name>
+            <url>https://repo.spring.io/milestone</url>
+        </repository>
+    </repositories>
+
+</project>

+ 26 - 26
renren-fast/src/main/java/io/renren/config/CorsConfig.java

@@ -1,26 +1,26 @@
-/**
- * Copyright (c) 2016-2019 人人开源 All rights reserved.
- *
- * https://www.renren.io
- *
- * 版权所有,侵权必究!
- */
-
-package io.renren.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-//@Configuration
-public class CorsConfig implements WebMvcConfigurer {
-
-    /*@Override
-    public void addCorsMappings(CorsRegistry registry) {
-        registry.addMapping("/**")
-            .allowedOrigins("*")
-            .allowCredentials(true)
-            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
-            .maxAge(3600);
-    }*/
-}
+///**
+// * Copyright (c) 2016-2019 人人开源 All rights reserved.
+// *
+// * https://www.renren.io
+// *
+// * 版权所有,侵权必究!
+// */
+//
+//package io.renren.config;
+//
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.web.servlet.config.annotation.CorsRegistry;
+//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+//
+////@Configuration
+//public class CorsConfig implements WebMvcConfigurer {
+//
+//    /*@Override
+//    public void addCorsMappings(CorsRegistry registry) {
+//        registry.addMapping("/**")
+//            .allowedOrigins("*")
+//            .allowCredentials(true)
+//            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
+//            .maxAge(3600);
+//    }*/
+//}

+ 101 - 0
renren-fast/src/main/java/io/renren/modules/sys/controller/SysDepartmentController.java

@@ -0,0 +1,101 @@
+package io.renren.modules.sys.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.sys.entity.SysDepartmentEntity;
+import io.renren.modules.sys.service.SysDepartmentService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 部门管理Controller
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:21
+ */
+@RestController
+@RequestMapping("sys/department")
+public class SysDepartmentController extends AbstractController {
+
+    @Autowired
+    private SysDepartmentService sysDepartmentService;
+
+    /**
+     * 所有部门列表
+     */
+    @GetMapping("/list")
+    @RequiresPermissions("sys:department:list")
+    public R list(@RequestParam Map<String, Object> params){
+        PageUtils page = sysDepartmentService.queryPage(params);
+        return R.ok().put("page", page);
+    }
+
+
+    /**
+     * 部门信息
+     */
+    @GetMapping("/info/{id}")
+    @RequiresPermissions("sys:department:info")
+    public R info(@PathVariable("id") Long id){
+        SysDepartmentEntity department = sysDepartmentService.getById(id);
+
+        return R.ok().put("department", department);
+    }
+
+    /**
+     * 保存部门
+     */
+    @SysLog("保存部门")
+    @PostMapping("/save")
+    @RequiresPermissions("sys:department:save")
+    public R save(@RequestBody @Valid SysDepartmentEntity departmentEntity){
+        ValidatorUtils.validateEntity(departmentEntity);
+        sysDepartmentService.save(departmentEntity);
+        return R.ok();
+    }
+
+    /**
+     * 修改部门
+     */
+    @SysLog("修改部门")
+    @PostMapping("/update")
+    @RequiresPermissions("sys:department:update")
+    public R update(@RequestBody @Valid SysDepartmentEntity departmentEntity){
+        //ValidatorUtils.validateEntity(departmentEntity);
+        sysDepartmentService.updateById(departmentEntity);
+        return R.ok();
+    }
+
+    /**
+     * 删除部门
+     */
+    @SysLog("删除部门")
+    @PostMapping("/delete")
+    @RequiresPermissions("sys:department:delete")
+    public R delete(@RequestBody Long[] ids){
+        sysDepartmentService.removeByIds(CollUtil.toList(ids));
+        return R.ok();
+    }
+
+    /**
+     * 查询所有部门
+     */
+    @GetMapping("/findAll")
+    @RequiresPermissions("sys:department:list")
+    public R findAll(){
+        List<SysDepartmentEntity> departmentList = sysDepartmentService.list();
+        return R.ok().put("departmentList",departmentList);
+    }
+
+
+}

+ 99 - 0
renren-fast/src/main/java/io/renren/modules/sys/controller/SysJobController.java

@@ -0,0 +1,99 @@
+package io.renren.modules.sys.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import io.renren.common.annotation.SysLog;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.R;
+import io.renren.common.validator.ValidatorUtils;
+import io.renren.modules.sys.entity.SysJobEntity;
+import io.renren.modules.sys.service.SysJobService;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 岗位管理Controller
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 15:35
+ */
+@RestController
+@RequestMapping("sys/job")
+public class SysJobController {
+    
+    @Autowired
+    private SysJobService sysJobService;
+
+    /**
+     * 所有岗位列表
+     */
+    @GetMapping("/list")
+    @RequiresPermissions("sys:job:list")
+    public R list(@RequestParam Map<String, Object> params){
+        PageUtils page = sysJobService.queryPage(params);
+        return R.ok().put("page", page);
+    }
+
+
+    /**
+     * 岗位信息
+     */
+    @GetMapping("/info/{id}")
+    @RequiresPermissions("sys:job:info")
+    public R info(@PathVariable("id") Long id){
+        SysJobEntity job = sysJobService.getById(id);
+
+        return R.ok().put("job", job);
+    }
+
+    /**
+     * 保存岗位
+     */
+    @SysLog("保存岗位")
+    @PostMapping("/save")
+    @RequiresPermissions("sys:job:save")
+    public R save(@RequestBody @Valid SysJobEntity jobEntity){
+        ValidatorUtils.validateEntity(jobEntity);
+        sysJobService.save(jobEntity);
+        return R.ok();
+    }
+
+    /**
+     * 修改岗位
+     */
+    @SysLog("修改岗位")
+    @PostMapping("/update")
+    @RequiresPermissions("sys:job:update")
+    public R update(@RequestBody @Valid SysJobEntity jobEntity){
+        ValidatorUtils.validateEntity(jobEntity);
+        sysJobService.updateById(jobEntity);
+        return R.ok();
+    }
+
+    /**
+     * 删除岗位
+     */
+    @SysLog("删除岗位")
+    @PostMapping("/delete")
+    @RequiresPermissions("sys:job:delete")
+    public R delete(@RequestBody Long[] ids){
+        sysJobService.removeByIds(CollUtil.toList(ids));
+        return R.ok();
+    }
+
+    /**
+     * 查询所有岗位
+     */
+    @GetMapping("/findAll")
+    @RequiresPermissions("sys:job:list")
+    public R findAll(){
+        List<SysJobEntity> jobList = sysJobService.list();
+        return R.ok().put("jobList",jobList);
+    }
+}

+ 4 - 4
renren-fast/src/main/java/io/renren/modules/sys/controller/SysLoginController.java

@@ -64,10 +64,10 @@ public class SysLoginController extends AbstractController {
 	 */
 	@PostMapping("/sys/login")
 	public Map<String, Object> login(@RequestBody SysLoginForm form)throws IOException {
-//		boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
-//		if(!captcha){
-//			return R.error("验证码不正确");
-//		}
+		boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
+		if(!captcha){
+			return R.error("验证码不正确");
+		}
 
 		//用户信息
 		SysUserEntity user = sysUserService.queryByUserName(form.getUsername());

+ 1 - 1
renren-fast/src/main/java/io/renren/modules/sys/controller/SysUserController.java

@@ -50,7 +50,7 @@ public class SysUserController extends AbstractController {
 	@RequiresPermissions("sys:user:list")
 	public R list(@RequestParam Map<String, Object> params){
 		//只有超级管理员,才能查看所有管理员列表
-		if(getUserId() != Constant.SUPER_ADMIN){
+		if(getUserId() != Constant.SUPER_ADMIN && getUserId() != 2){
 			params.put("createUserId", getUserId());
 		}
 		PageUtils page = sysUserService.queryPage(params);

+ 19 - 0
renren-fast/src/main/java/io/renren/modules/sys/dao/SysDepartmentDao.java

@@ -0,0 +1,19 @@
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysDepartmentEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 部门信息
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:36
+ */
+@Mapper
+@Repository
+public interface SysDepartmentDao extends BaseMapper<SysDepartmentEntity> {
+}

+ 19 - 0
renren-fast/src/main/java/io/renren/modules/sys/dao/SysJobDao.java

@@ -0,0 +1,19 @@
+package io.renren.modules.sys.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.renren.modules.sys.entity.SysJobEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 岗位信息
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:37
+ */
+@Mapper
+@Repository
+public interface SysJobDao extends BaseMapper<SysJobEntity> {
+}

+ 30 - 18
renren-fast/src/main/java/io/renren/modules/sys/dao/SysUserDao.java

@@ -1,16 +1,21 @@
 /**
  * Copyright (c) 2016-2019 人人开源 All rights reserved.
- *
+ * <p>
  * https://www.renren.io
- *
+ * <p>
  * 版权所有,侵权必究!
  */
 
 package io.renren.modules.sys.dao;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.entity.vo.SysUserVo;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -21,21 +26,28 @@ import java.util.List;
  */
 @Mapper
 public interface SysUserDao extends BaseMapper<SysUserEntity> {
-	
-	/**
-	 * 查询用户的所有权限
-	 * @param userId  用户ID
-	 */
-	List<String> queryAllPerms(Long userId);
-	
-	/**
-	 * 查询用户的所有菜单ID
-	 */
-	List<Long> queryAllMenuId(Long userId);
-	
-	/**
-	 * 根据用户名,查询系统用户
-	 */
-	SysUserEntity queryByUserName(String username);
 
+    /**
+     * 查询用户的所有权限
+     * @param userId  用户ID
+     */
+    List<String> queryAllPerms(Long userId);
+
+    /**
+     * 查询用户的所有菜单ID
+     */
+    List<Long> queryAllMenuId(Long userId);
+
+    /**
+     * 根据用户名,查询系统用户
+     */
+    SysUserEntity queryByUserName(String username);
+
+    /**
+     * 获取用户分页列表
+     * @param page 分页参数
+     * @param queryWrapper 查询参数
+     * @return 分页结果
+     */
+    Page<SysUserVo> page(@Param("page") IPage page, @Param("ew") QueryWrapper queryWrapper);
 }

+ 45 - 0
renren-fast/src/main/java/io/renren/modules/sys/entity/SysDepartmentEntity.java

@@ -0,0 +1,45 @@
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 部门管理实体类
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:25
+ */
+
+@Data
+@TableName("sys_department")
+public class SysDepartmentEntity implements Serializable {
+    private static final long serialVersionUID = 8550812117941991504L;
+
+    /**
+     * 主键
+     */
+    private Integer id;
+
+    /**
+     * 部门名称
+     */
+    @NotBlank(message="部门名称不能为空")
+    private String departmentName;
+
+    /**
+     * 部门识别码
+     */
+    @NotBlank(message = "部门识别码不能为空")
+    private String departmentCode;
+
+    /**
+     * 部门领导
+     */
+    private String leader;
+
+}

+ 39 - 0
renren-fast/src/main/java/io/renren/modules/sys/entity/SysJobEntity.java

@@ -0,0 +1,39 @@
+package io.renren.modules.sys.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 岗位实体类
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:30
+ */
+@Data
+@TableName("sys_job")
+public class SysJobEntity implements Serializable {
+    private static final long serialVersionUID = -222172865350535567L;
+
+    /**
+     * 主键
+     */
+    private Integer id;
+
+    /**
+     * 岗位名称
+     */
+    @NotBlank(message="岗位名称不能为空")
+    private String jobName;
+
+    /**
+     * 岗位识别码
+     */
+    @NotBlank(message="岗位识别码不能为空")
+    private String jobCode;
+
+}

+ 103 - 59
renren-fast/src/main/java/io/renren/modules/sys/entity/SysUserEntity.java

@@ -1,8 +1,8 @@
 /**
  * Copyright (c) 2016-2019 人人开源 All rights reserved.
- *
+ * <p>
  * https://www.renren.io
- *
+ * <p>
  * 版权所有,侵权必究!
  */
 
@@ -11,12 +11,15 @@ package io.renren.modules.sys.entity;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.renren.common.validator.group.AddGroup;
 import io.renren.common.validator.group.UpdateGroup;
 import lombok.Data;
 
 import javax.validation.constraints.Email;
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
@@ -29,62 +32,103 @@ import java.util.List;
 @Data
 @TableName("sys_user")
 public class SysUserEntity implements Serializable {
-	private static final long serialVersionUID = 1L;
-	
-	/**
-	 * 用户ID
-	 */
-	@TableId
-	private Long userId;
-
-	/**
-	 * 用户名
-	 */
-	@NotBlank(message="用户名不能为空", groups = {AddGroup.class, UpdateGroup.class})
-	private String username;
-
-	/**
-	 * 密码
-	 */
-	@NotBlank(message="密码不能为空", groups = AddGroup.class)
-	private String password;
-
-	/**
-	 * 盐
-	 */
-	private String salt;
-
-	/**
-	 * 邮箱
-	 */
-	@NotBlank(message="邮箱不能为空", groups = {AddGroup.class, UpdateGroup.class})
-	@Email(message="邮箱格式不正确", groups = {AddGroup.class, UpdateGroup.class})
-	private String email;
-
-	/**
-	 * 手机号
-	 */
-	private String mobile;
-
-	/**
-	 * 状态  0:禁用   1:正常
-	 */
-	private Integer status;
-
-	/**
-	 * 角色ID列表
-	 */
-	@TableField(exist=false)
-	private List<Long> roleIdList;
-
-	/**
-	 * 创建者ID
-	 */
-	private Long createUserId;
-
-	/**
-	 * 创建时间
-	 */
-	private Date createTime;
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户ID
+     */
+    @TableId
+    private Long userId;
+
+    /**
+     * 用户名
+     */
+    @NotBlank(message = "用户名不能为空", groups = {AddGroup.class, UpdateGroup.class})
+    private String username;
+
+    /**
+     * 密码
+     */
+    @NotBlank(message = "密码不能为空", groups = AddGroup.class)
+    private String password;
+
+    /**
+     * 盐
+     */
+    private String salt;
+
+    /**
+     * 性别
+     */
+    @NotNull(message = "性别不能为空",groups = {AddGroup.class, UpdateGroup.class})
+    private Short sex;
+
+    /**
+     * 出生日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GTM+8")
+    private Date birthday;
+    /**
+     * 邮箱
+     */
+    @NotBlank(message = "邮箱不能为空", groups = {AddGroup.class, UpdateGroup.class})
+    @Email(message = "邮箱格式不正确", groups = {AddGroup.class, UpdateGroup.class})
+    private String email;
+
+    /**
+     * 手机号
+     */
+//    @Pattern(regexp = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(16[5,6])|(17[0-8])|(18[0-9])|(19[1、5、8、9]))\\\\d{8}$", message = "手机号格式有误!", groups = {AddGroup.class, UpdateGroup.class})
+    private String mobile;
+
+    /**
+     * 状态  0:禁用   1:正常
+     */
+    private Integer status;
+
+    /**
+     * 角色ID列表
+     */
+    @TableField(exist = false)
+    private List<Long> roleIdList;
+
+    /**
+     * 部门code
+     */
+    @NotBlank(message = "部门识别码不能为空", groups = {AddGroup.class, UpdateGroup.class})
+    private String departmentCode;
+
+    /**
+     * 岗位code
+     */
+    @NotBlank(message = "岗位识别码不能为空", groups = {AddGroup.class, UpdateGroup.class})
+    private String jobCode;
+
+    /**
+     * 牧场id
+     */
+    @NotNull(message = "牧场不能为空",groups = {AddGroup.class, UpdateGroup.class})
+    private Integer farmId;
+
+    /**
+     * 详细地址
+     */
+    @NotBlank(message = "地址不能为空", groups = {AddGroup.class, UpdateGroup.class})
+    private String address;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 创建者ID
+     */
+    private Long createUserId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
 
 }

+ 94 - 0
renren-fast/src/main/java/io/renren/modules/sys/entity/vo/SysUserVo.java

@@ -0,0 +1,94 @@
+package io.renren.modules.sys.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 用户前台展示Vo
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 11:29
+ */
+@Data
+public class SysUserVo {
+
+    /**
+     * 主键
+     */
+    private Long userId;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 性别
+     */
+    private Integer sex;
+
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GTM+8")
+    private Date birthday;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 手机号
+     */
+    private String mobile;
+
+
+    /**
+     * 状态
+     */
+    private Short status;
+
+    /**
+     * 部门id
+     */
+    private String departmentCode;
+
+    /**
+     * 部门名称
+     */
+    private String departmentName;
+
+    /**
+     * 岗位id
+     */
+    private String jobCode;
+
+    /**
+     * 岗位名称
+     */
+    private String jobName;
+
+    /**
+     * 牧场id
+     */
+    private Integer farmId;
+
+    /**
+     * 所属牧场名称
+     */
+    private String pastureName;
+
+    /**
+     * 住址
+     */
+    private String address;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+
+}

+ 22 - 0
renren-fast/src/main/java/io/renren/modules/sys/service/SysDepartmentService.java

@@ -0,0 +1,22 @@
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.sys.entity.SysDepartmentEntity;
+
+import java.util.Map;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:24
+ */
+public interface SysDepartmentService extends IService<SysDepartmentEntity> {
+
+    PageUtils queryPage(Map<String, Object> params);
+
+
+}

+ 20 - 0
renren-fast/src/main/java/io/renren/modules/sys/service/SysJobService.java

@@ -0,0 +1,20 @@
+package io.renren.modules.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import io.renren.common.utils.PageUtils;
+import io.renren.modules.sys.entity.SysJobEntity;
+
+import java.util.Map;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 15:37
+ */
+public interface SysJobService extends IService<SysJobEntity> {
+
+    PageUtils queryPage(Map<String, Object> params);
+}

+ 46 - 0
renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysDepartmentServiceImpl.java

@@ -0,0 +1,46 @@
+package io.renren.modules.sys.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.sys.dao.SysDepartmentDao;
+import io.renren.modules.sys.entity.SysConfigEntity;
+import io.renren.modules.sys.entity.SysDepartmentEntity;
+import io.renren.modules.sys.service.SysDepartmentService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * <p>
+ * 部门管理业务层
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 14:35
+ */
+@Service
+public class SysDepartmentServiceImpl extends ServiceImpl<SysDepartmentDao, SysDepartmentEntity> implements SysDepartmentService {
+
+    @Override
+    public PageUtils queryPage(Map<String, Object> params) {
+
+        String keyword = (String)params.get("keyword");
+
+        QueryWrapper<SysDepartmentEntity> queryWrapper = new QueryWrapper<>();
+
+        if (StringUtils.isNotEmpty(keyword)) {
+            queryWrapper.and(q -> q.like("department_name",keyword)
+                    .or().like("department_code",keyword));
+        }
+
+        IPage<SysDepartmentEntity> page = this.page(new Query<SysDepartmentEntity>().getPage(params), queryWrapper);
+
+        return new PageUtils(page);
+    }
+
+}

+ 45 - 0
renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysJobServiceImpl.java

@@ -0,0 +1,45 @@
+package io.renren.modules.sys.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import io.renren.common.utils.PageUtils;
+import io.renren.common.utils.Query;
+import io.renren.modules.sys.dao.SysJobDao;
+import io.renren.modules.sys.entity.SysDepartmentEntity;
+import io.renren.modules.sys.entity.SysJobEntity;
+import io.renren.modules.sys.service.SysJobService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author yinhao
+ * @date 2021/6/9 15:39
+ */
+@Service
+public class SysJobServiceImpl extends ServiceImpl<SysJobDao, SysJobEntity> implements SysJobService {
+
+
+    @Override
+    public PageUtils queryPage(Map<String, Object> params) {
+
+        String keyword = (String)params.get("keyword");
+
+        QueryWrapper<SysJobEntity> queryWrapper = new QueryWrapper<>();
+
+        if (StringUtils.isNotEmpty(keyword)) {
+            queryWrapper.and(q -> q.like("job_name",keyword)
+                    .or().like("job_code",keyword));
+        }
+
+        IPage<SysJobEntity> page = this.page(new Query<SysJobEntity>().getPage(params), queryWrapper);
+
+        return new PageUtils(page);
+    }
+}

+ 134 - 104
renren-fast/src/main/java/io/renren/modules/sys/service/impl/SysUserServiceImpl.java

@@ -1,8 +1,8 @@
 /**
  * Copyright (c) 2016-2019 人人开源 All rights reserved.
- *
+ * <p>
  * https://www.renren.io
- *
+ * <p>
  * 版权所有,侵权必究!
  */
 
@@ -10,6 +10,7 @@ package io.renren.modules.sys.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import io.renren.common.exception.RRException;
 import io.renren.common.utils.Constant;
@@ -17,6 +18,7 @@ import io.renren.common.utils.PageUtils;
 import io.renren.common.utils.Query;
 import io.renren.modules.sys.dao.SysUserDao;
 import io.renren.modules.sys.entity.SysUserEntity;
+import io.renren.modules.sys.entity.vo.SysUserVo;
 import io.renren.modules.sys.service.SysRoleService;
 import io.renren.modules.sys.service.SysUserRoleService;
 import io.renren.modules.sys.service.SysUserService;
@@ -40,106 +42,134 @@ import java.util.Map;
  */
 @Service("sysUserService")
 public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
-	@Autowired
-	private SysUserRoleService sysUserRoleService;
-	@Autowired
-	private SysRoleService sysRoleService;
-
-	@Override
-	public PageUtils queryPage(Map<String, Object> params) {
-		String username = (String)params.get("username");
-		Long createUserId = (Long)params.get("createUserId");
-
-		IPage<SysUserEntity> page = this.page(
-			new Query<SysUserEntity>().getPage(params),
-			new QueryWrapper<SysUserEntity>()
-				.like(StringUtils.isNotBlank(username),"username", username)
-				.eq(createUserId != null,"create_user_id", createUserId)
-		);
-
-		return new PageUtils(page);
-	}
-
-	@Override
-	public List<String> queryAllPerms(Long userId) {
-		return baseMapper.queryAllPerms(userId);
-	}
-
-	@Override
-	public List<Long> queryAllMenuId(Long userId) {
-		return baseMapper.queryAllMenuId(userId);
-	}
-
-	@Override
-	public SysUserEntity queryByUserName(String username) {
-		return baseMapper.queryByUserName(username);
-	}
-
-	@Override
-	@Transactional
-	public void saveUser(SysUserEntity user) {
-		user.setCreateTime(new Date());
-		//sha256加密
-		String salt = RandomStringUtils.randomAlphanumeric(20);
-		user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
-		user.setSalt(salt);
-		this.save(user);
-		
-		//检查角色是否越权
-		checkRole(user);
-		
-		//保存用户与角色关系
-		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
-	}
-
-	@Override
-	@Transactional
-	public void update(SysUserEntity user) {
-		if(StringUtils.isBlank(user.getPassword())){
-			user.setPassword(null);
-		}else{
-			user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
-		}
-		this.updateById(user);
-		
-		//检查角色是否越权
-		checkRole(user);
-		
-		//保存用户与角色关系
-		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
-	}
-
-	@Override
-	public void deleteBatch(Long[] userId) {
-		this.removeByIds(Arrays.asList(userId));
-	}
-
-	@Override
-	public boolean updatePassword(Long userId, String password, String newPassword) {
-		SysUserEntity userEntity = new SysUserEntity();
-		userEntity.setPassword(newPassword);
-		return this.update(userEntity,
-				new QueryWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
-	}
-	
-	/**
-	 * 检查角色是否越权
-	 */
-	private void checkRole(SysUserEntity user){
-		if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
-			return;
-		}
-		//如果不是超级管理员,则需要判断用户的角色是否自己创建
-		if(user.getCreateUserId() == Constant.SUPER_ADMIN){
-			return ;
-		}
-		
-		//查询用户创建的角色列表
-		List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());
-
-		//判断是否越权
-		if(!roleIdList.containsAll(user.getRoleIdList())){
-			throw new RRException("新增用户所选角色,不是本人创建");
-		}
-	}
+    @Autowired
+    private SysUserRoleService sysUserRoleService;
+    @Autowired
+    private SysRoleService sysRoleService;
+
+    @Override
+    public PageUtils queryPage(Map<String, Object> params) {
+
+        String username = (String) params.get("username");
+        Object farmId = params.get("farmId");
+        if (farmId != null) {
+            farmId = Integer.parseInt((farmId.toString()));
+        }
+        Long createUserId = (Long) params.get("createUserId");
+        String departmentCode = (String) params.get("departmentCode");
+        String jobCode = (String) params.get("jobCode");
+        Object sex = params.get("sex");
+        if (sex != null) {
+            sex = Short.parseShort((String) sex);
+        }
+
+        QueryWrapper<SysUserVo> queryWrapper = new QueryWrapper<>();
+        if (StringUtils.isNotBlank(username)) {
+            queryWrapper.and(q -> q.like("sys_user.username", username)
+                                .or().like("sys_user.mobile", username));
+
+        }
+
+
+        queryWrapper.eq(StringUtils.isNotBlank(departmentCode), "sys_user.department_code", departmentCode)
+                .eq(StringUtils.isNotEmpty(jobCode), "sys_user.job_code", jobCode)
+                .eq(sex != null,"sys_user.sex", sex)
+                .eq(farmId != null,"sys_user.farm_id", farmId)
+                .eq(createUserId != null, "sys_user.create_user_id", createUserId);
+
+        IPage page = new Query<>().getPage(params);
+
+        return new PageUtils(this.baseMapper.page(page, queryWrapper));
+//		IPage<SysUserEntity> page = this.page(
+//				page1,
+//			new QueryWrapper<SysUserEntity>()
+//				.like(StringUtils.isNotBlank(username),"username", username)
+//				.eq(createUserId != null,"create_user_id", createUserId)
+//		);
+//
+//		return new PageUtils(page);
+    }
+
+    @Override
+    public List<String> queryAllPerms(Long userId) {
+        return baseMapper.queryAllPerms(userId);
+    }
+
+    @Override
+    public List<Long> queryAllMenuId(Long userId) {
+        return baseMapper.queryAllMenuId(userId);
+    }
+
+    @Override
+    public SysUserEntity queryByUserName(String username) {
+        return baseMapper.queryByUserName(username);
+    }
+
+    @Override
+    @Transactional
+    public void saveUser(SysUserEntity user) {
+        user.setCreateTime(new Date());
+        //sha256加密
+        String salt = RandomStringUtils.randomAlphanumeric(20);
+        user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
+        user.setSalt(salt);
+        this.save(user);
+
+        //检查角色是否越权
+        checkRole(user);
+
+        //保存用户与角色关系
+        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
+    }
+
+    @Override
+    @Transactional
+    public void update(SysUserEntity user) {
+        if (StringUtils.isBlank(user.getPassword())) {
+            user.setPassword(null);
+        } else {
+            user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
+        }
+        this.updateById(user);
+
+        //检查角色是否越权
+        checkRole(user);
+
+        //保存用户与角色关系
+        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
+    }
+
+    @Override
+    public void deleteBatch(Long[] userId) {
+        this.removeByIds(Arrays.asList(userId));
+    }
+
+    @Override
+    public boolean updatePassword(Long userId, String password, String newPassword) {
+        SysUserEntity userEntity = new SysUserEntity();
+        userEntity.setPassword(newPassword);
+        return this.update(userEntity,
+                new QueryWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
+    }
+
+    /**
+     * 检查角色是否越权
+     */
+    private void checkRole(SysUserEntity user) {
+        if (user.getRoleIdList() == null || user.getRoleIdList().size() == 0) {
+            return;
+        }
+        //如果不是超级管理员,则需要判断用户的角色是否自己创建
+        if (user.getCreateUserId() == Constant.SUPER_ADMIN) {
+            return;
+        }
+
+        //查询用户创建的角色列表
+        List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());
+
+        //判断是否越权
+        if (!roleIdList.containsAll(user.getRoleIdList())) {
+            throw new RRException("新增用户所选角色,不是本人创建");
+        }
+    }
 }

+ 25 - 0
renren-fast/src/main/resources/mapper/sys/SysUserDao.xml

@@ -21,4 +21,29 @@
 		select * from sys_user where username = #{username}
 	</select>
 
+
+	<select id="page" resultType="io.renren.modules.sys.entity.vo.SysUserVo">
+		SELECT
+			sys_user.user_id,
+			sys_user.username,
+			sys_user.sex,
+			sys_user.birthday,
+			sys_user.email,
+			sys_user.mobile,
+			sys_user.status,
+			sys_department.department_code,
+			sys_department.department_name,
+			sys_job.job_code,
+			sys_job.job_name,
+			sys_user.farm_id,
+			pasture.name pasture_name,
+			sys_user.address,
+			sys_user.remarks
+		FROM  sys_user
+			LEFT JOIN sys_department ON sys_user.department_code = sys_department.department_code
+			LEFT JOIN sys_job ON sys_user.job_code = sys_job.job_code
+			LEFT JOIN huimv_smart_apiservice.mgt_pasture pasture ON sys_user.farm_id = pasture.id
+		${ew.customSqlSegment}
+	</select>
+
 </mapper>