Jelajahi Sumber

Merge remote-tracking branch 'origin/master'

weifanli 3 tahun lalu
induk
melakukan
ea34d89a0d
49 mengubah file dengan 767 tambahan dan 1363 penghapusan
  1. 23 8
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/SysUserFeignService.java
  2. 21 0
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/fallback/SysUserFeignServiceFallback.java
  3. 1 1
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/dto/SysUserQueryInfo.java
  4. 5 1
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java
  5. 11 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/SysUserService.java
  6. 7 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java
  7. 17 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java
  8. 10 3
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/UserController.java
  9. 14 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  10. 4 4
      cooleshow-mall/mall-admin/pom.xml
  11. 2 1
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/MallAdminApplication.java
  12. 0 64
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/bo/AdminUserDetails.java
  13. 0 54
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/MallSecurityConfig.java
  14. 0 24
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/OssConfig.java
  15. 41 0
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/ResourceServerConfig.java
  16. 18 2
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/WebMvcConfig.java
  17. 37 90
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/UmsAdminController.java
  18. 0 6
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/UmsResourceController.java
  19. 13 28
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/UmsAdminService.java
  20. 92 100
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/UmsAdminServiceImpl.java
  21. 22 0
      cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/SysConfigMapper.java
  22. 4 0
      cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/UmsAdminMapper.java
  23. 114 0
      cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/model/SysConfig.java
  24. 12 0
      cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/SysConfigMapper.xml
  25. 14 0
      cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/UmsAdminMapper.xml
  26. 0 41
      cooleshow-mall/mall-security/pom.xml
  27. 0 13
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/annotation/CacheException.java
  28. 0 50
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/aspect/RedisCacheAspect.java
  29. 0 51
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicAccessDecisionManager.java
  30. 0 77
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicSecurityFilter.java
  31. 0 64
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicSecurityMetadataSource.java
  32. 0 16
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicSecurityService.java
  33. 0 57
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/JwtAuthenticationTokenFilter.java
  34. 0 28
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/RestAuthenticationEntryPoint.java
  35. 0 30
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/RestfulAccessDeniedHandler.java
  36. 0 25
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/config/IgnoreUrlsConfig.java
  37. 0 127
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/config/SecurityConfig.java
  38. 0 170
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/util/JwtTokenUtil.java
  39. 0 44
      cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/util/SpringUtil.java
  40. 0 1
      cooleshow-mall/pom.xml
  41. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleDao.java
  42. 149 147
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/PracticeScheduleDto.java
  43. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VideoLessonGroupSearch.java
  44. 9 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  45. 78 20
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  46. 7 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/LiveRoomServiceImpl.java
  47. 17 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  48. 4 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/VideoLessonGroupMapper.xml
  49. 7 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/VideoLessonGroupController.java

+ 23 - 8
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/SysUserFeignService.java

@@ -1,20 +1,20 @@
 package com.yonge.cooleshow.auth.api.client;
 
-import java.util.List;
-
+import com.yonge.cooleshow.auth.api.client.fallback.SysUserFeignServiceFallback;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.common.config.FeignConfiguration;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.page.PageInfo;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 
-import com.yonge.cooleshow.auth.api.client.fallback.SysUserFeignServiceFallback;
-import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.common.config.FeignConfiguration;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
-
-import javax.validation.Valid;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 @FeignClient(contextId = "sysUserFeignService", name = "auth-server", configuration = { FeignConfiguration.class }, fallback = SysUserFeignServiceFallback.class)
 public interface SysUserFeignService {
@@ -48,4 +48,19 @@ public interface SysUserFeignService {
 
 	@PostMapping(value = "user/bindOpenId")
 	HttpResponseResult<Boolean> bindOpenId(@RequestBody SysUser user);
+
+	@PostMapping(value = "/refreshToken")
+	@ApiOperation(value = "刷新token")
+	HttpResponseResult refreshToken(@RequestParam("refreshToken")String refreshToken,
+										   @RequestParam("clientId")String clientId,
+										   @RequestParam("clientSecret")String clientSecret);
+
+	@GetMapping(value = "/remote/exit")
+	@ApiOperation(value = "退出登录")
+	public HttpResponseResult<String> remoteExit();
+
+
+	@PostMapping(value = "user/list")
+	HttpResponseResult<List<SysUser>> page(@RequestBody SysUserQueryInfo queryInfo);
+
 }

+ 21 - 0
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/fallback/SysUserFeignServiceFallback.java

@@ -3,6 +3,8 @@ package com.yonge.cooleshow.auth.api.client.fallback;
 import java.util.List;
 
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
+import com.yonge.cooleshow.common.page.PageInfo;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import org.springframework.stereotype.Component;
 
@@ -10,6 +12,8 @@ import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
+import javax.servlet.http.HttpServletRequest;
+
 @Component
 public class SysUserFeignServiceFallback implements SysUserFeignService {
 
@@ -61,4 +65,21 @@ public class SysUserFeignServiceFallback implements SysUserFeignService {
 	public HttpResponseResult<Boolean> bindOpenId(SysUser user) {
 		return HttpResponseResult.failed("请求失败");
 	}
+
+	@Override
+	public HttpResponseResult refreshToken(String refreshToken, String clientId, String clientSecret) {
+		return HttpResponseResult.failed("请求失败");
+	}
+
+	@Override
+	public HttpResponseResult<String> remoteExit() {
+		return HttpResponseResult.failed("请求失败");
+	}
+
+
+	@Override
+	public HttpResponseResult<List<SysUser>> page(SysUserQueryInfo queryInfo) {
+		return HttpResponseResult.failed("请求失败");
+	}
+
 }

+ 1 - 1
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/queryInfo/SysUserQueryInfo.java → cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/dto/SysUserQueryInfo.java

@@ -1,4 +1,4 @@
-package com.yonge.cooleshow.auth.web.controller.queryInfo;
+package com.yonge.cooleshow.auth.api.dto;
 
 import com.yonge.cooleshow.common.page.QueryInfo;
 

+ 5 - 1
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.auth.dal.dao;
 import java.util.List;
 
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
@@ -136,11 +137,14 @@ public interface SysUserDao extends BaseDAO<Long, SysUser> {
      * @updateTime 2022/3/22 11:06
      */
     void updatetSetDetail(@Param("param") UserSetReq setReq, @Param("id") Long id);
+
     /***
      * 创建用户账户
      * @author liweifan
      * @param: id
      * @updateTime 2022/4/14 17:07
      */
-    void createUserAccount(@Param("userId")Long id);
+    void createUserAccount(@Param("userId") Long id);
+
+    List<SysUser> queryEmployeeList(SysUserQueryInfo queryInfo);
 }

+ 11 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/SysUserService.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.auth.service;
 
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.SysUserInfo;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
@@ -9,6 +10,8 @@ import com.yonge.cooleshow.common.entity.ImUserModel;
 import com.yonge.cooleshow.common.service.BaseService;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 
+import java.util.List;
+
 public interface SysUserService extends BaseService<Long, SysUser> {
 
     /**
@@ -170,4 +173,12 @@ public interface SysUserService extends BaseService<Long, SysUser> {
      * @updateTime 2022/3/22 11:04
      */
     void submitSetDetail(UserSetReq setReq, Long id);
+
+    /**
+     *  商城同步管理用户
+     *
+     * @param queryInfo
+     * @return
+     */
+    List<SysUser> queryEmployeeList(SysUserQueryInfo queryInfo);
 }

+ 7 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java

@@ -4,6 +4,7 @@ import java.util.Date;
 import java.util.List;
 
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
 import com.yonge.cooleshow.auth.service.SysConfigService;
@@ -203,4 +204,10 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
         sysUserDao.updatetSetDetail(setReq, id);
     }
 
+    @Override
+    public List<SysUser> queryEmployeeList(SysUserQueryInfo queryInfo) {
+
+        return sysUserDao.queryEmployeeList(queryInfo);
+    }
+
 }

+ 17 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java

@@ -143,6 +143,23 @@ public class TokenController extends BaseController {
 		return succeed("退出成功");
 	}
 
+	@GetMapping(value = "/remote/exit")
+	@ApiOperation(value = "退出登录")
+	public HttpResponseResult<String> remoteExit(HttpServletRequest request) {
+
+		String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
+		if (StringUtils.isBlank(authHeader)) {
+			return failed("退出失败,token 为空");
+		}
+
+		String tokenValue = authHeader.toLowerCase().replace(OAuth2AccessToken.BEARER_TYPE.toLowerCase(), StringUtils.EMPTY).trim();
+
+		tokenService.revokeToken(tokenValue);
+
+		return succeed("退出成功");
+	}
+
+
 	@PostMapping(value = "exit/{clientId}/{phone}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
 	@ApiOperation(value = "指定用户退出登录")
 	public HttpResponseResult<String> exitByPhone(@PathVariable("clientId") String clientId, @PathVariable("phone") String phone) {

+ 10 - 3
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/UserController.java

@@ -1,14 +1,15 @@
 package com.yonge.cooleshow.auth.web.controller;
 
+import com.alibaba.druid.sql.PagerUtils;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.UpdatePasswordDto;
 import com.yonge.cooleshow.auth.api.dto.UserSetReq;
-import com.yonge.cooleshow.auth.api.entity.SysConfig;
 import com.yonge.cooleshow.auth.api.entity.SysRole;
 import com.yonge.cooleshow.auth.api.vo.UserSetVo;
 import com.yonge.cooleshow.auth.service.SysConfigService;
 import com.yonge.cooleshow.common.constant.CommonConstants;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.page.PageInfo;
 import com.yonge.toolset.thirdparty.user.realname.RealnameAuthenticationPlugin;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import com.yonge.toolset.utils.idcard.IdcardValidator;
@@ -22,7 +23,6 @@ import java.util.Date;
 import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.ibatis.annotations.Param;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpStatus;
@@ -35,7 +35,7 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.service.SysRoleService;
 import com.yonge.cooleshow.auth.service.SysUserRoleService;
 import com.yonge.cooleshow.auth.service.SysUserService;
-import com.yonge.cooleshow.auth.web.controller.queryInfo.SysUserQueryInfo;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.exception.BizException;
@@ -78,6 +78,7 @@ public class UserController extends BaseController {
         return succeed(sysUserService.queryPage(queryInfo));
     }
 
+
     @ApiOperation(value = "查询用户信息接口")
     @GetMapping("/query")
     @PreAuthorize("@pcs.hasPermissions('user/query')")
@@ -543,4 +544,10 @@ public class UserController extends BaseController {
         sysUserService.update(user);
         return HttpResponseResult.succeed(true);
     }
+
+    @ApiOperation(value = "查询平台用户信息")
+    @PostMapping(value = "/list")
+    public HttpResponseResult<List<SysUser>> page(@RequestBody SysUserQueryInfo queryInfo) {
+        return succeed(sysUserService.queryEmployeeList(queryInfo));
+    }
 }

+ 14 - 0
cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml

@@ -253,4 +253,18 @@
         </set>
         WHERE id_ = #{id}
     </update>
+
+    <select id="queryEmployeeList" resultMap="SysUser">
+        select  su.*
+        from employee e
+        left join sys_user su on su.id_ = e.user_id_
+        <where>
+            <if test="createStartDate != null and createStartDate != ''">
+                and #{createStartDate} &lt;= e.create_time_
+            </if>
+            <if test="createEndDate != null and createEndDate != ''">
+                and #{createEndDate} &gt; e.create_time_
+            </if>
+        </where>
+    </select>
 </mapper>

+ 4 - 4
cooleshow-mall/mall-admin/pom.xml

@@ -36,10 +36,10 @@
             <groupId>com.yonge.cooleshow</groupId>
             <artifactId>mall-common</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.yonge.cooleshow</groupId>
-            <artifactId>mall-security</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.yonge.cooleshow</groupId>-->
+<!--            <artifactId>mall-security</artifactId>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>com.yonge.cooleshow</groupId>
             <artifactId>auth-api</artifactId>

+ 2 - 1
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/MallAdminApplication.java

@@ -15,7 +15,8 @@ import org.springframework.context.annotation.ComponentScan;
 @SpringBootApplication
 @EnableDiscoveryClient
 @MapperScan({"com.yonge.cooleshow.admin.dao","com.yonge.cooleshow.mbg.mapper"})
-@ComponentScan(basePackages = {"com.yonge.cooleshow.admin", "com.yonge.cooleshow.mbg", "com.yonge.cooleshow.mall.common" ,"com.yonge.cooleshow.mall.security"})
+@ComponentScan(basePackages = {"com.yonge.cooleshow.admin", "com.yonge.cooleshow.mbg", "com.yonge.cooleshow.mall.common",
+                               "com.yonge.cooleshow.common"})
 @EnableSwagger2Doc
 @EnableFeignClients("com.yonge.cooleshow")
 public class MallAdminApplication {

+ 0 - 64
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/bo/AdminUserDetails.java

@@ -1,64 +0,0 @@
-package com.yonge.cooleshow.admin.bo;
-
-import com.yonge.cooleshow.mbg.model.UmsAdmin;
-import com.yonge.cooleshow.mbg.model.UmsResource;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * SpringSecurity需要的用户详情
- * Created by macro on 2018/4/26.
- */
-public class AdminUserDetails implements UserDetails {
-    //后台用户
-    private UmsAdmin umsAdmin;
-    //拥有资源列表
-    private List<UmsResource> resourceList;
-    public AdminUserDetails(UmsAdmin umsAdmin, List<UmsResource> resourceList) {
-        this.umsAdmin = umsAdmin;
-        this.resourceList = resourceList;
-    }
-
-    @Override
-    public Collection<? extends GrantedAuthority> getAuthorities() {
-        //返回当前用户的角色
-        return resourceList.stream()
-                .map(role ->new SimpleGrantedAuthority(role.getId()+":"+role.getName()))
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public String getPassword() {
-        return umsAdmin.getPassword();
-    }
-
-    @Override
-    public String getUsername() {
-        return umsAdmin.getUsername();
-    }
-
-    @Override
-    public boolean isAccountNonExpired() {
-        return true;
-    }
-
-    @Override
-    public boolean isAccountNonLocked() {
-        return true;
-    }
-
-    @Override
-    public boolean isCredentialsNonExpired() {
-        return true;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return umsAdmin.getStatus().equals(1);
-    }
-}

+ 0 - 54
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/MallSecurityConfig.java

@@ -1,54 +0,0 @@
-package com.yonge.cooleshow.admin.config;
-
-import com.yonge.cooleshow.mbg.model.UmsResource;
-import com.yonge.cooleshow.mall.security.component.DynamicSecurityService;
-import com.yonge.cooleshow.mall.security.config.SecurityConfig;
-import com.yonge.cooleshow.admin.service.UmsAdminService;
-import com.yonge.cooleshow.admin.service.UmsResourceService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.access.ConfigAttribute;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.core.userdetails.UserDetailsService;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * mall-security模块相关配置
- * Created by macro on 2019/11/9.
- */
-@Configuration
-@EnableWebSecurity
-@EnableGlobalMethodSecurity(prePostEnabled = true)
-public class MallSecurityConfig extends SecurityConfig {
-
-    @Autowired
-    private UmsAdminService adminService;
-    @Autowired
-    private UmsResourceService resourceService;
-
-    @Bean
-    public UserDetailsService userDetailsService() {
-        //获取登录用户信息
-        return username -> adminService.loadUserByUsername(username);
-    }
-
-    @Bean
-    public DynamicSecurityService dynamicSecurityService() {
-        return new DynamicSecurityService() {
-            @Override
-            public Map<String, ConfigAttribute> loadDataSource() {
-                Map<String, ConfigAttribute> map = new ConcurrentHashMap<>();
-                List<UmsResource> resourceList = resourceService.listAll();
-                for (UmsResource resource : resourceList) {
-                    map.put(resource.getUrl(), new org.springframework.security.access.SecurityConfig(resource.getId() + ":" + resource.getName()));
-                }
-                return map;
-            }
-        };
-    }
-}

+ 0 - 24
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/OssConfig.java

@@ -1,24 +0,0 @@
-package com.yonge.cooleshow.admin.config;
-
-import com.aliyun.oss.OSSClient;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * OSS对象存储相关配置
- * Created by macro on 2018/5/17.
- */
-@Configuration
-public class OssConfig {
-    @Value("${aliyun.oss.endpoint}")
-    private String ALIYUN_OSS_ENDPOINT;
-    @Value("${aliyun.oss.accessKeyId}")
-    private String ALIYUN_OSS_ACCESSKEYID;
-    @Value("${aliyun.oss.accessKeySecret}")
-    private String ALIYUN_OSS_ACCESSKEYSECRET;
-    @Bean
-    public OSSClient ossClient(){
-        return new OSSClient(ALIYUN_OSS_ENDPOINT,ALIYUN_OSS_ACCESSKEYID,ALIYUN_OSS_ACCESSKEYSECRET);
-    }
-}

+ 41 - 0
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/ResourceServerConfig.java

@@ -0,0 +1,41 @@
+package com.yonge.cooleshow.admin.config;
+
+import com.yonge.cooleshow.common.security.BaseAccessDeniedHandler;
+import com.yonge.cooleshow.common.security.BaseAuthenticationEntryPoint;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
+
+@Configuration
+@EnableResourceServer
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+    @Autowired
+    private BaseAccessDeniedHandler baseAccessDeniedHandler;
+
+    @Autowired
+    private BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        http.cors().and().csrf().disable().exceptionHandling().accessDeniedHandler(baseAccessDeniedHandler).authenticationEntryPoint(baseAuthenticationEntryPoint).and()
+                .authorizeRequests()
+                .antMatchers(HttpMethod.OPTIONS)
+                .permitAll()
+            .and()
+                .authorizeRequests()
+                .antMatchers("/wechat/*","/v2/api-docs", "/code/*","/payment/callback","/admin/login")
+            .permitAll().anyRequest().authenticated().and().httpBasic();
+    }
+
+    @Override
+    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
+        resources.authenticationEntryPoint(baseAuthenticationEntryPoint).accessDeniedHandler(baseAccessDeniedHandler);
+    }
+}

+ 18 - 2
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/WebMvcConfig.java

@@ -2,11 +2,14 @@ package com.yonge.cooleshow.admin.config;
 
 import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import com.yonge.cooleshow.common.config.LocalFastJsonHttpMessageConverter;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 import java.util.ArrayList;
@@ -16,7 +19,6 @@ import java.util.List;
 public class WebMvcConfig implements WebMvcConfigurer {
 
 
-
 	/**
 	 * 枚举类的转换器 addConverterFactory
 	 */
@@ -25,11 +27,25 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		registry.addConverterFactory(new EnumConverterFactory());
 	}
 
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		// addPathPatterns 用于添加拦截规则, 这里假设拦截 /url 后面的全部链接
+		List<String> includePathPatterns = new ArrayList<String>();
+		includePathPatterns.add("/**");
+
+		// excludePathPatterns 用户排除拦截
+		List<String> excludePathPatterns = new ArrayList<String>();
+		excludePathPatterns.add("/login");
+
+		// registry.addInterceptor(mdcInterceptor).addPathPatterns(includePathPatterns).excludePathPatterns(excludePathPatterns);
+
+//		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
+	}
 
 	@Bean
 	public HttpMessageConverters fastJsonHttpMessageConverters() {
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
-		List<MediaType> fastMediaTypes = new ArrayList<>();
+		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
 		fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
 		converter.setSupportedMediaTypes(fastMediaTypes);
 		return new HttpMessageConverters(converter);

+ 37 - 90
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/UmsAdminController.java

@@ -1,27 +1,25 @@
 package com.yonge.cooleshow.admin.controller;
 
 import cn.hutool.core.collection.CollUtil;
+import com.yonge.cooleshow.admin.dto.UmsAdminLoginParam;
+import com.yonge.cooleshow.admin.service.UmsAdminService;
+import com.yonge.cooleshow.admin.service.UmsRoleService;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.mall.common.api.CommonPage;
 import com.yonge.cooleshow.mall.common.api.CommonResult;
-import com.yonge.cooleshow.admin.dto.UmsAdminLoginParam;
-import com.yonge.cooleshow.admin.dto.UmsAdminParam;
-import com.yonge.cooleshow.admin.dto.UpdateAdminPasswordParam;
+import com.yonge.cooleshow.mall.common.api.ResultCode;
 import com.yonge.cooleshow.mbg.model.UmsAdmin;
 import com.yonge.cooleshow.mbg.model.UmsRole;
-import com.yonge.cooleshow.admin.service.UmsAdminService;
-import com.yonge.cooleshow.admin.service.UmsRoleService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
-import java.security.Principal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,10 +33,6 @@ import java.util.stream.Collectors;
 @Api(tags = "UmsAdminController", description = "后台用户管理")
 @RequestMapping("/admin")
 public class UmsAdminController {
-    @Value("${jwt.tokenHeader}")
-    private String tokenHeader;
-    @Value("${jwt.tokenHead}")
-    private String tokenHead;
     @Autowired
     private UmsAdminService adminService;
     @Autowired
@@ -46,85 +40,51 @@ public class UmsAdminController {
     @Autowired
     private SysUserFeignService sysUserFeignService;
 
-    @ApiOperation(value = "用户注册")
-    @RequestMapping(value = "/register", method = RequestMethod.POST)
-    @ResponseBody
-    public CommonResult<UmsAdmin> register(@Validated @RequestBody UmsAdminParam umsAdminParam) {
-        UmsAdmin umsAdmin = adminService.register(umsAdminParam);
-        if (umsAdmin == null) {
-            return CommonResult.failed();
-        }
-        return CommonResult.success(umsAdmin);
-    }
 
     @ApiOperation(value = "登录以后返回token")
     @RequestMapping(value = "/login", method = RequestMethod.POST)
     @ResponseBody
     public CommonResult login(@Validated @RequestBody UmsAdminLoginParam umsAdminLoginParam) {
-        String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());
-        if (token == null) {
-            return CommonResult.validateFailed("用户名或密码错误");
-        }
-        Map<String, String> tokenMap = new HashMap<>();
-        tokenMap.put("token", token);
-        tokenMap.put("tokenHead", tokenHead);
-        return CommonResult.success(tokenMap);
-    }
-
-
-    @ApiOperation(value = "登录以后返回token")
-    @RequestMapping(value = "/login/token", method = RequestMethod.POST)
-    @ResponseBody
-    public CommonResult login() {
-        SysUser sysUser = sysUserFeignService.queryUserInfo();
-
-        UmsAdmin admin = adminService.getAdminById(sysUser.getId());
-        // 设置首次登录 拥有全部权限
-        if (admin == null || admin.getId() == null) {
-            admin = new UmsAdmin();
-            admin.setId(sysUser.getId());
-            admin.setCreateTime(sysUser.getCreateTime());
-            admin.setUsername(sysUser.getUsername());
-            admin.setPassword(sysUser.getPassword());
-            admin.setStatus(1);
-            admin.setIcon(sysUser.getAvatar());
-            adminService.createRootAdmin(admin);
-        }
 
-        String token = adminService.login(admin.getUsername(), admin.getPassword());
-        if (token == null) {
-            return CommonResult.validateFailed("用户名或密码错误");
-        }
         Map<String, String> tokenMap = new HashMap<>();
-        tokenMap.put("token", token);
-        tokenMap.put("tokenHead", tokenHead);
+        tokenMap.put("token", "token");
+        tokenMap.put("tokenHead", "tokenHead");
         return CommonResult.success(tokenMap);
     }
 
+
     @ApiOperation(value = "刷新token")
     @RequestMapping(value = "/refreshToken", method = RequestMethod.GET)
     @ResponseBody
-    public CommonResult refreshToken(HttpServletRequest request) {
-        String token = request.getHeader(tokenHeader);
-        String refreshToken = adminService.refreshToken(token);
-        if (refreshToken == null) {
-            return CommonResult.failed("token已经过期!");
+    public CommonResult refreshToken(String refreshToken, String clientId, String clientSecret) {
+
+        HttpResponseResult httpResponseResult = sysUserFeignService.refreshToken(refreshToken, clientId, clientSecret);
+        if (httpResponseResult.getStatus()) {
+            return CommonResult.success(httpResponseResult.getData());
+        } else {
+            return CommonResult.failed(httpResponseResult.getMsg());
         }
-        Map<String, String> tokenMap = new HashMap<>();
-        tokenMap.put("token", refreshToken);
-        tokenMap.put("tokenHead", tokenHead);
-        return CommonResult.success(tokenMap);
     }
 
     @ApiOperation(value = "获取当前登录用户信息")
     @RequestMapping(value = "/info", method = RequestMethod.GET)
     @ResponseBody
-    public CommonResult getAdminInfo(Principal principal) {
-        if(principal==null){
-            return CommonResult.unauthorized(null);
+    public CommonResult getAdminInfo() {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return CommonResult.failed(ResultCode.FORBIDDEN, "请登录");
+        }
+
+        adminService.saveAdmin();
+
+        UmsAdmin umsAdmin = adminService.getAdminById(sysUser.getId());
+        if (umsAdmin == null) {
+            return CommonResult.failed("用户同步失败");
+        }
+        if (umsAdmin.getStatus() == 0) {
+            return CommonResult.failed("用户被禁用");
         }
-        String username = principal.getName();
-        UmsAdmin umsAdmin = adminService.getAdminByUsername(username);
         Map<String, Object> data = new HashMap<>();
         data.put("username", umsAdmin.getUsername());
         data.put("menus", roleService.getMenuList(umsAdmin.getId()));
@@ -140,8 +100,13 @@ public class UmsAdminController {
     @ApiOperation(value = "登出功能")
     @RequestMapping(value = "/logout", method = RequestMethod.POST)
     @ResponseBody
-    public CommonResult logout() {
-        return CommonResult.success(null);
+    public CommonResult logout(HttpServletRequest request) {
+        HttpResponseResult<String> logout = sysUserFeignService.remoteExit();
+        if (logout.getStatus()) {
+            return CommonResult.success(logout.getData());
+        } else {
+            return CommonResult.failed(logout.getMsg());
+        }
     }
 
     @ApiOperation("根据用户名或姓名分页获取用户列表")
@@ -173,24 +138,6 @@ public class UmsAdminController {
         return CommonResult.failed();
     }
 
-    @ApiOperation("修改指定用户密码")
-    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
-    @ResponseBody
-    public CommonResult updatePassword(@Validated @RequestBody UpdateAdminPasswordParam updatePasswordParam) {
-        int status = adminService.updatePassword(updatePasswordParam);
-        if (status > 0) {
-            return CommonResult.success(status);
-        } else if (status == -1) {
-            return CommonResult.failed("提交参数不合法");
-        } else if (status == -2) {
-            return CommonResult.failed("找不到该用户");
-        } else if (status == -3) {
-            return CommonResult.failed("旧密码错误");
-        } else {
-            return CommonResult.failed();
-        }
-    }
-
     @ApiOperation("删除指定用户信息")
     @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
     @ResponseBody

+ 0 - 6
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/UmsResourceController.java

@@ -3,7 +3,6 @@ package com.yonge.cooleshow.admin.controller;
 import com.yonge.cooleshow.mall.common.api.CommonPage;
 import com.yonge.cooleshow.mall.common.api.CommonResult;
 import com.yonge.cooleshow.mbg.model.UmsResource;
-import com.yonge.cooleshow.mall.security.component.DynamicSecurityMetadataSource;
 import com.yonge.cooleshow.admin.service.UmsResourceService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -24,15 +23,12 @@ public class UmsResourceController {
 
     @Autowired
     private UmsResourceService resourceService;
-    @Autowired
-    private DynamicSecurityMetadataSource dynamicSecurityMetadataSource;
 
     @ApiOperation("添加后台资源")
     @RequestMapping(value = "/create", method = RequestMethod.POST)
     @ResponseBody
     public CommonResult create(@RequestBody UmsResource umsResource) {
         int count = resourceService.create(umsResource);
-        dynamicSecurityMetadataSource.clearDataSource();
         if (count > 0) {
             return CommonResult.success(count);
         } else {
@@ -46,7 +42,6 @@ public class UmsResourceController {
     public CommonResult update(@PathVariable Long id,
                                @RequestBody UmsResource umsResource) {
         int count = resourceService.update(id, umsResource);
-        dynamicSecurityMetadataSource.clearDataSource();
         if (count > 0) {
             return CommonResult.success(count);
         } else {
@@ -67,7 +62,6 @@ public class UmsResourceController {
     @ResponseBody
     public CommonResult delete(@PathVariable Long id) {
         int count = resourceService.delete(id);
-        dynamicSecurityMetadataSource.clearDataSource();
         if (count > 0) {
             return CommonResult.success(count);
         } else {

+ 13 - 28
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/UmsAdminService.java

@@ -20,24 +20,6 @@ public interface UmsAdminService {
      */
     UmsAdmin getAdminByUsername(String username);
 
-    /**
-     * 注册功能
-     */
-    UmsAdmin register(UmsAdminParam umsAdminParam);
-
-    /**
-     * 登录功能
-     * @param username 用户名
-     * @param password 密码
-     * @return 生成的JWT的token
-     */
-    String login(String username,String password);
-
-    /**
-     * 刷新token的功能
-     * @param oldToken 旧的token
-     */
-    String refreshToken(String oldToken);
 
     /**
      * 根据用户id获取用户
@@ -76,16 +58,6 @@ public interface UmsAdminService {
     List<UmsResource> getResourceList(Long adminId);
 
     /**
-     * 修改密码
-     */
-    int updatePassword(UpdateAdminPasswordParam updatePasswordParam);
-
-    /**
-     * 获取用户信息
-     */
-    UserDetails loadUserByUsername(String username);
-
-    /**
      * 获取用户信息
      *
      * @param id id
@@ -100,4 +72,17 @@ public interface UmsAdminService {
      * @return
      */
     boolean createRootAdmin(UmsAdmin admin);
+
+    /**
+     * 创建root用户
+     *
+     * @param adminList
+     */
+    boolean addRootAdmin(List<UmsAdmin> adminList);
+
+    /**
+     * 同步远程用户
+     */
+    @Transactional
+    void saveAdmin();
 }

+ 92 - 100
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/UmsAdminServiceImpl.java

@@ -1,31 +1,26 @@
 package com.yonge.cooleshow.admin.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.StrUtil;
 import com.github.pagehelper.PageHelper;
-import com.yonge.cooleshow.admin.bo.AdminUserDetails;
-import com.yonge.cooleshow.mall.common.exception.Asserts;
-import com.yonge.cooleshow.mall.common.util.RequestUtil;
 import com.yonge.cooleshow.admin.dao.UmsAdminRoleRelationDao;
-import com.yonge.cooleshow.admin.dto.UmsAdminParam;
-import com.yonge.cooleshow.admin.dto.UpdateAdminPasswordParam;
+import com.yonge.cooleshow.admin.service.UmsAdminCacheService;
+import com.yonge.cooleshow.admin.service.UmsAdminService;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.dto.SysUserQueryInfo;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.page.PageInfo;
+import com.yonge.cooleshow.mall.common.util.RequestUtil;
+import com.yonge.cooleshow.mbg.mapper.SysConfigMapper;
 import com.yonge.cooleshow.mbg.mapper.UmsAdminLoginLogMapper;
 import com.yonge.cooleshow.mbg.mapper.UmsAdminMapper;
 import com.yonge.cooleshow.mbg.mapper.UmsAdminRoleRelationMapper;
 import com.yonge.cooleshow.mbg.model.*;
-import com.yonge.cooleshow.mall.security.util.JwtTokenUtil;
-import com.yonge.cooleshow.admin.service.UmsAdminCacheService;
-import com.yonge.cooleshow.admin.service.UmsAdminService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
@@ -33,9 +28,10 @@ import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 后台用户管理Service实现类
@@ -45,9 +41,7 @@ import java.util.List;
 public class UmsAdminServiceImpl implements UmsAdminService {
     private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);
     @Autowired
-    private JwtTokenUtil jwtTokenUtil;
-    @Autowired
-    private PasswordEncoder passwordEncoder;
+    private SysUserFeignService sysUserFeignService;
     @Autowired
     private UmsAdminMapper adminMapper;
     @Autowired
@@ -59,6 +53,9 @@ public class UmsAdminServiceImpl implements UmsAdminService {
     @Autowired
     private UmsAdminCacheService adminCacheService;
 
+    @Autowired
+    private SysConfigMapper configMapper;
+
     @Override
     public UmsAdmin getAdminByUsername(String username) {
         UmsAdmin admin = adminCacheService.getAdmin(username);
@@ -74,48 +71,6 @@ public class UmsAdminServiceImpl implements UmsAdminService {
         return null;
     }
 
-    @Override
-    public UmsAdmin register(UmsAdminParam umsAdminParam) {
-        UmsAdmin umsAdmin = new UmsAdmin();
-        BeanUtils.copyProperties(umsAdminParam, umsAdmin);
-        umsAdmin.setCreateTime(new Date());
-        umsAdmin.setStatus(1);
-        //查询是否有相同用户名的用户
-        UmsAdminExample example = new UmsAdminExample();
-        example.createCriteria().andUsernameEqualTo(umsAdmin.getUsername());
-        List<UmsAdmin> umsAdminList = adminMapper.selectByExample(example);
-        if (umsAdminList.size() > 0) {
-            return null;
-        }
-        //将密码进行加密操作
-        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
-        umsAdmin.setPassword(encodePassword);
-        adminMapper.insert(umsAdmin);
-        return umsAdmin;
-    }
-
-    @Override
-    public String login(String username, String password) {
-        String token = null;
-        //密码需要客户端加密后传递
-        try {
-            UserDetails userDetails = loadUserByUsername(username);
-            // if(!passwordEncoder.matches(password,userDetails.getPassword())){
-            //     Asserts.fail("密码不正确");
-            // }
-            if(!userDetails.isEnabled()){
-                Asserts.fail("帐号已被禁用");
-            }
-            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
-            SecurityContextHolder.getContext().setAuthentication(authentication);
-            token = jwtTokenUtil.generateToken(userDetails);
-//            updateLoginTimeByUsername(username);
-            insertLoginLog(username);
-        } catch (AuthenticationException e) {
-            LOGGER.warn("登录异常:{}", e.getMessage());
-        }
-        return token;
-    }
 
     /**
      * 添加登录记录
@@ -144,10 +99,6 @@ public class UmsAdminServiceImpl implements UmsAdminService {
         adminMapper.updateByExampleSelective(record, example);
     }
 
-    @Override
-    public String refreshToken(String oldToken) {
-        return jwtTokenUtil.refreshHeadToken(oldToken);
-    }
 
     @Override
     public UmsAdmin getItem(Long id) {
@@ -178,7 +129,7 @@ public class UmsAdminServiceImpl implements UmsAdminService {
             if(StrUtil.isEmpty(admin.getPassword())){
                 admin.setPassword(null);
             }else{
-                admin.setPassword(passwordEncoder.encode(admin.getPassword()));
+                admin.setPassword(null);
             }
         }
         int count = adminMapper.updateByPrimaryKeySelective(admin);
@@ -234,39 +185,7 @@ public class UmsAdminServiceImpl implements UmsAdminService {
         return resourceList;
     }
 
-    @Override
-    public int updatePassword(UpdateAdminPasswordParam param) {
-        if(StrUtil.isEmpty(param.getUsername())
-                ||StrUtil.isEmpty(param.getOldPassword())
-                ||StrUtil.isEmpty(param.getNewPassword())){
-            return -1;
-        }
-        UmsAdminExample example = new UmsAdminExample();
-        example.createCriteria().andUsernameEqualTo(param.getUsername());
-        List<UmsAdmin> adminList = adminMapper.selectByExample(example);
-        if(CollUtil.isEmpty(adminList)){
-            return -2;
-        }
-        UmsAdmin umsAdmin = adminList.get(0);
-        if(!passwordEncoder.matches(param.getOldPassword(),umsAdmin.getPassword())){
-            return -3;
-        }
-        umsAdmin.setPassword(passwordEncoder.encode(param.getNewPassword()));
-        adminMapper.updateByPrimaryKey(umsAdmin);
-        adminCacheService.delAdmin(umsAdmin.getId());
-        return 1;
-    }
 
-    @Override
-    public UserDetails loadUserByUsername(String username){
-        //获取用户信息
-        UmsAdmin admin = getAdminByUsername(username);
-        if (admin != null) {
-            List<UmsResource> resourceList = getResourceList(admin.getId());
-            return new AdminUserDetails(admin,resourceList);
-        }
-        throw new UsernameNotFoundException("用户名或密码错误");
-    }
 
     @Override
     public UmsAdmin getAdminById(Long id) {
@@ -280,4 +199,77 @@ public class UmsAdminServiceImpl implements UmsAdminService {
         roleIds.add(1L);
         return updateRole(admin.getId(),roleIds) > 0;
     }
+
+    @Override
+    public boolean addRootAdmin(List<UmsAdmin> adminList) {
+
+        if (CollUtil.isEmpty(adminList)) {
+            return true;
+        }
+        adminMapper.saveRootAdminList(adminList);
+        return addAdminRootRole(adminList);
+    }
+
+    @Override
+    public void saveAdmin() {
+        // 调用远程,保存用户
+        SysUserQueryInfo sysUserQueryInfo = new SysUserQueryInfo();
+        String now = LocalDateTimeUtil.format(LocalDateTime.now(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+        String syncTime = configMapper.getConfig(SysConfig.SYNC_TIME);
+        sysUserQueryInfo.setCreateEndDate(now);
+        sysUserQueryInfo.setCreateStartDate(syncTime);
+        HttpResponseResult<List<SysUser>> result = sysUserFeignService.page(sysUserQueryInfo);
+        if (result.getStatus()) {
+            List<SysUser> rows = result.getData();
+            List<UmsAdmin> adminList = new ArrayList<>();
+            for (SysUser row : rows) {
+                UmsAdmin admin = new UmsAdmin();
+                admin.setId(row.getId());
+                admin.setCreateTime(row.getCreateTime());
+                admin.setUsername(row.getUsername());
+                admin.setPassword(row.getPassword());
+                admin.setStatus(1);
+                admin.setIcon(row.getAvatar());
+                adminList.add(admin);
+            }
+            addRootAdmin(adminList);
+        }
+        configMapper.setConfig(SysConfig.SYNC_TIME,now);
+    }
+
+    /**
+     * 添加默认权限
+     *
+     * @param adminList
+     */
+    private boolean addAdminRootRole(List<UmsAdmin> adminList) {
+        List<Long> adminIdList = adminList.stream().map(UmsAdmin::getId).collect(Collectors.toList());
+
+        // 已经设置里权限的不做处理
+        UmsAdminRoleRelationExample adminRoleRelationExample = new UmsAdminRoleRelationExample();
+        adminRoleRelationExample.createCriteria().andAdminIdIn(adminIdList);
+        List<UmsAdminRoleRelation> umsAdminRoleRelations = adminRoleRelationMapper.selectByExample(
+                adminRoleRelationExample);
+        Set<Long> hasRoleAdminIdList = new HashSet<>();
+        if (CollUtil.isNotEmpty(umsAdminRoleRelations)) {
+            hasRoleAdminIdList = umsAdminRoleRelations.stream()
+                                                     .map(UmsAdminRoleRelation::getAdminId)
+                                                     .collect(Collectors.toSet());
+        }
+        Set<Long> finalHasRoleAdminIdList = hasRoleAdminIdList;
+        adminIdList = adminIdList.stream()
+                                 .filter(id -> !finalHasRoleAdminIdList.contains(id))
+                                 .collect(Collectors.toList());
+
+        // 设置权限
+        List<UmsAdminRoleRelation> list = new ArrayList<>();
+        for (Long adminId : adminIdList) {
+            UmsAdminRoleRelation roleRelation = new UmsAdminRoleRelation();
+            roleRelation.setAdminId(adminId);
+            roleRelation.setRoleId(1L);
+            list.add(roleRelation);
+        }
+        return adminRoleRelationDao.insertList(list) > 0;
+
+    }
 }

+ 22 - 0
cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/SysConfigMapper.java

@@ -0,0 +1,22 @@
+package com.yonge.cooleshow.mbg.mapper;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface SysConfigMapper {
+    /**
+     * 获取配置信息
+     *
+     * @param config 配置名
+     * @return
+     */
+    String getConfig(String config);
+
+    /**
+     * 设置配置信息
+     *
+     * @param configName  配置名
+     * @param configValue 配置值
+     * @return
+     */
+    int setConfig(@Param("configName") String configName, @Param("configValue") String configValue);
+}

+ 4 - 0
cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/UmsAdminMapper.java

@@ -2,7 +2,9 @@ package com.yonge.cooleshow.mbg.mapper;
 
 import com.yonge.cooleshow.mbg.model.UmsAdmin;
 import com.yonge.cooleshow.mbg.model.UmsAdminExample;
+
 import java.util.List;
+
 import org.apache.ibatis.annotations.Param;
 
 public interface UmsAdminMapper {
@@ -29,4 +31,6 @@ public interface UmsAdminMapper {
     int updateByPrimaryKey(UmsAdmin record);
 
     int addRootAdmin(UmsAdmin admin);
+
+    int saveRootAdminList(@Param("adminList") List<UmsAdmin> adminList);
 }

+ 114 - 0
cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/model/SysConfig.java

@@ -0,0 +1,114 @@
+package com.yonge.cooleshow.mbg.model;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * 对应数据库表(sys_config):
+ */
+public class SysConfig {
+
+	/**
+	 * 人员同步时间
+	 */
+	public static final String SYNC_TIME = "sync_time";
+
+	/**  */
+	private Long id;
+	
+	/** 参数名称 */
+	@ApiModelProperty(value = "参数名称", required = true)
+	private String paramName;
+	
+	/** 参数值 */
+	@ApiModelProperty(value = "参数值", required = true)
+	private String paramValue;
+	
+	/** 描述 */
+	@ApiModelProperty(value = "描述", required = true)
+	private String description;
+	
+	/** 创建时间 */
+	private java.util.Date createOn;
+	
+	/** 修改时间 */
+	private java.util.Date modifyOn;
+	
+	private Long modifyBy;
+	
+	@ApiModelProperty(value = "消息组", required = true)
+	private String group;
+	
+	public void setId(Long id){
+		this.id = id;
+	}
+	
+	public Long getId(){
+		return this.id;
+	}
+			
+	public void setParamName(String paramName){
+		this.paramName = paramName;
+	}
+	
+	public String getParamName(){
+		return this.paramName;
+	}
+			
+	public void setParamValue(String paramValue){
+		this.paramValue = paramValue;
+	}
+	
+	public String getParamValue(){
+		return this.paramValue;
+	}
+
+	public <T> T getParamValue(Class<T> cla){
+		try {
+			return cla.cast(cla.getMethod("valueOf", String.class).invoke(cla.getInterfaces(),this.paramValue));
+		} catch (Exception e) {
+			return (T)this.paramValue.getClass();
+		}
+	}
+			
+	public void setDescription(String description){
+		this.description = description;
+	}
+	
+	public String getDescription(){
+		return this.description;
+	}
+			
+	public void setCreateOn(java.util.Date createOn){
+		this.createOn = createOn;
+	}
+	
+	public java.util.Date getCreateOn(){
+		return this.createOn;
+	}
+			
+	public void setModifyOn(java.util.Date modifyOn){
+		this.modifyOn = modifyOn;
+	}
+	
+	public java.util.Date getModifyOn(){
+		return this.modifyOn;
+	}
+			
+	public String getGroup() {
+		return group;
+	}
+
+	public void setGroup(String group) {
+		this.group = group;
+	}
+
+	public Long getModifyBy() {
+		return modifyBy;
+	}
+
+	public void setModifyBy(Long modifyBy) {
+		this.modifyBy = modifyBy;
+	}
+
+
+}

+ 12 - 0
cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/SysConfigMapper.xml

@@ -0,0 +1,12 @@
+<?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.yonge.cooleshow.mbg.mapper.SysConfigMapper">
+
+<select id="getConfig" resultType="java.lang.String">
+    select param_value_ from sys_config where param_name_ = #{config,jdbcType=VARCHAR}
+    </select>
+
+<update id="setConfig">
+    update sys_config set param_value_ = #{configValue} where param_name_ = #{configName}
+    </update>
+</mapper>

+ 14 - 0
cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/UmsAdminMapper.xml

@@ -298,4 +298,18 @@
     #{createTime,jdbcType=TIMESTAMP}, #{loginTime,jdbcType=TIMESTAMP}, #{status,jdbcType=INTEGER}
     )
   </insert>
+
+  <insert id="saveRootAdminList">
+    replace into ums_admin (id,username, password, icon,
+    email, nick_name, note,
+    create_time, login_time, status
+    )
+    values
+    <foreach collection="adminList" separator="," close="" open="" item="item">
+      (#{item.id,jdbcType=BIGINT},#{item.username,jdbcType=VARCHAR}, #{item.password,jdbcType=VARCHAR}, #{item.icon,jdbcType=VARCHAR},
+      #{item.email,jdbcType=VARCHAR}, #{item.nickName,jdbcType=VARCHAR}, #{item.note,jdbcType=VARCHAR},
+      #{item.createTime,jdbcType=TIMESTAMP}, #{item.loginTime,jdbcType=TIMESTAMP}, #{item.status,jdbcType=INTEGER}
+      )
+    </foreach>
+  </insert>
 </mapper>

+ 0 - 41
cooleshow-mall/mall-security/pom.xml

@@ -1,41 +0,0 @@
-<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-    <artifactId>mall-security</artifactId>
-    <version>1.0</version>
-    <packaging>jar</packaging>
-
-    <name>mall-security</name>
-    <description>mall-security project for mall</description>
-
-    <parent>
-        <groupId>com.yonge.cooleshow</groupId>
-        <artifactId>cooleshow-mall</artifactId>
-        <version>1.0</version>
-    </parent>
-
-    <dependencies>
-        <dependency>
-            <groupId>com.yonge.cooleshow</groupId>
-            <artifactId>mall-common</artifactId>
-        </dependency>
-        <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.boot</groupId>
-            <artifactId>spring-boot-starter-data-redis</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt</artifactId>
-        </dependency>
-    </dependencies>
-
-</project>

+ 0 - 13
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/annotation/CacheException.java

@@ -1,13 +0,0 @@
-package com.yonge.cooleshow.mall.security.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 自定义注解,有该注解的缓存方法会抛出异常
- * Created by macro on 2020/3/17.
- */
-@Documented
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface CacheException {
-}

+ 0 - 50
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/aspect/RedisCacheAspect.java

@@ -1,50 +0,0 @@
-package com.yonge.cooleshow.mall.security.aspect;
-
-import com.yonge.cooleshow.mall.security.annotation.CacheException;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.Signature;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import java.lang.reflect.Method;
-
-/**
- * Redis缓存切面,防止Redis宕机影响正常业务逻辑
- * Created by macro on 2020/3/17.
- */
-@Aspect
-@Component
-@Order(2)
-public class RedisCacheAspect {
-    private static Logger LOGGER = LoggerFactory.getLogger(RedisCacheAspect.class);
-
-    @Pointcut("execution(public * com.yonge.cooleshow.admin.service.*CacheService.*(..)) || execution(public * com.yonge.cooleshow.admin.service.*CacheService.*(..))")
-    public void cacheAspect() {
-    }
-
-    @Around("cacheAspect()")
-    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
-        Signature signature = joinPoint.getSignature();
-        MethodSignature methodSignature = (MethodSignature) signature;
-        Method method = methodSignature.getMethod();
-        Object result = null;
-        try {
-            result = joinPoint.proceed();
-        } catch (Throwable throwable) {
-            //有CacheException注解的方法需要抛出异常
-            if (method.isAnnotationPresent(CacheException.class)) {
-                throw throwable;
-            } else {
-                LOGGER.error(throwable.getMessage());
-            }
-        }
-        return result;
-    }
-
-}

+ 0 - 51
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicAccessDecisionManager.java

@@ -1,51 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import cn.hutool.core.collection.CollUtil;
-import org.springframework.security.access.AccessDecisionManager;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.ConfigAttribute;
-import org.springframework.security.authentication.InsufficientAuthenticationException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * 动态权限决策管理器,用于判断用户是否有访问权限
- * Created by macro on 2020/2/7.
- */
-public class DynamicAccessDecisionManager implements AccessDecisionManager {
-
-    @Override
-    public void decide(Authentication authentication, Object object,
-                       Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
-        // 当接口未被配置资源时直接放行
-        if (CollUtil.isEmpty(configAttributes)) {
-            return;
-        }
-        Iterator<ConfigAttribute> iterator = configAttributes.iterator();
-        while (iterator.hasNext()) {
-            ConfigAttribute configAttribute = iterator.next();
-            //将访问所需资源或用户拥有资源进行比对
-            String needAuthority = configAttribute.getAttribute();
-            for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
-                if (needAuthority.trim().equals(grantedAuthority.getAuthority())) {
-                    return;
-                }
-            }
-        }
-        throw new AccessDeniedException("抱歉,您没有访问权限");
-    }
-
-    @Override
-    public boolean supports(ConfigAttribute configAttribute) {
-        return true;
-    }
-
-    @Override
-    public boolean supports(Class<?> aClass) {
-        return true;
-    }
-
-}

+ 0 - 77
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicSecurityFilter.java

@@ -1,77 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import com.yonge.cooleshow.mall.security.config.IgnoreUrlsConfig;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.access.SecurityMetadataSource;
-import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
-import org.springframework.security.access.intercept.InterceptorStatusToken;
-import org.springframework.security.web.FilterInvocation;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.PathMatcher;
-
-import javax.servlet.*;
-import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
-
-/**
- * 动态权限过滤器,用于实现基于路径的动态权限过滤
- * Created by macro on 2020/2/7.
- */
-public class DynamicSecurityFilter extends AbstractSecurityInterceptor implements Filter {
-
-    @Autowired
-    private DynamicSecurityMetadataSource dynamicSecurityMetadataSource;
-    @Autowired
-    private IgnoreUrlsConfig ignoreUrlsConfig;
-
-    @Autowired
-    public void setMyAccessDecisionManager(DynamicAccessDecisionManager dynamicAccessDecisionManager) {
-        super.setAccessDecisionManager(dynamicAccessDecisionManager);
-    }
-
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-    }
-
-    @Override
-    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
-        HttpServletRequest request = (HttpServletRequest) servletRequest;
-        FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain);
-        //OPTIONS请求直接放行
-        if(request.getMethod().equals(HttpMethod.OPTIONS.toString())){
-            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
-            return;
-        }
-        //白名单请求直接放行
-        PathMatcher pathMatcher = new AntPathMatcher();
-        for (String path : ignoreUrlsConfig.getUrls()) {
-            if(pathMatcher.match(path,request.getRequestURI())){
-                fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
-                return;
-            }
-        }
-        //此处会调用AccessDecisionManager中的decide方法进行鉴权操作
-        InterceptorStatusToken token = super.beforeInvocation(fi);
-        try {
-            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
-        } finally {
-            super.afterInvocation(token, null);
-        }
-    }
-
-    @Override
-    public void destroy() {
-    }
-
-    @Override
-    public Class<?> getSecureObjectClass() {
-        return FilterInvocation.class;
-    }
-
-    @Override
-    public SecurityMetadataSource obtainSecurityMetadataSource() {
-        return dynamicSecurityMetadataSource;
-    }
-
-}

+ 0 - 64
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicSecurityMetadataSource.java

@@ -1,64 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import cn.hutool.core.util.URLUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.ConfigAttribute;
-import org.springframework.security.web.FilterInvocation;
-import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.PathMatcher;
-
-import javax.annotation.PostConstruct;
-import java.util.*;
-
-/**
- * 动态权限数据源,用于获取动态权限规则
- * Created by macro on 2020/2/7.
- */
-public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
-
-    private static Map<String, ConfigAttribute> configAttributeMap = null;
-    @Autowired
-    private DynamicSecurityService dynamicSecurityService;
-
-    @PostConstruct
-    public void loadDataSource() {
-        configAttributeMap = dynamicSecurityService.loadDataSource();
-    }
-
-    public void clearDataSource() {
-        configAttributeMap.clear();
-        configAttributeMap = null;
-    }
-
-    @Override
-    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
-        if (configAttributeMap == null) this.loadDataSource();
-        List<ConfigAttribute>  configAttributes = new ArrayList<>();
-        //获取当前访问的路径
-        String url = ((FilterInvocation) o).getRequestUrl();
-        String path = URLUtil.getPath(url);
-        PathMatcher pathMatcher = new AntPathMatcher();
-        Iterator<String> iterator = configAttributeMap.keySet().iterator();
-        //获取访问该路径所需资源
-        while (iterator.hasNext()) {
-            String pattern = iterator.next();
-            if (pathMatcher.match(pattern, path)) {
-                configAttributes.add(configAttributeMap.get(pattern));
-            }
-        }
-        // 未设置操作请求权限,返回空集合
-        return configAttributes;
-    }
-
-    @Override
-    public Collection<ConfigAttribute> getAllConfigAttributes() {
-        return null;
-    }
-
-    @Override
-    public boolean supports(Class<?> aClass) {
-        return true;
-    }
-
-}

+ 0 - 16
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/DynamicSecurityService.java

@@ -1,16 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import org.springframework.security.access.ConfigAttribute;
-
-import java.util.Map;
-
-/**
- * 动态权限相关业务类
- * Created by macro on 2020/2/7.
- */
-public interface DynamicSecurityService {
-    /**
-     * 加载资源ANT通配符和资源对应MAP
-     */
-    Map<String, ConfigAttribute> loadDataSource();
-}

+ 0 - 57
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/JwtAuthenticationTokenFilter.java

@@ -1,57 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import com.yonge.cooleshow.mall.security.util.JwtTokenUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * JWT登录授权过滤器
- * Created by macro on 2018/4/26.
- */
-public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
-    private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
-    @Autowired
-    private UserDetailsService userDetailsService;
-    @Autowired
-    private JwtTokenUtil jwtTokenUtil;
-    @Value("${jwt.tokenHeader}")
-    private String tokenHeader;
-    @Value("${jwt.tokenHead}")
-    private String tokenHead;
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest request,
-                                    HttpServletResponse response,
-                                    FilterChain chain) throws ServletException, IOException {
-        String authHeader = request.getHeader(this.tokenHeader);
-        if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
-            String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer "
-            String username = jwtTokenUtil.getUserNameFromToken(authToken);
-            LOGGER.info("checking username:{}", username);
-            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
-                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
-                if (jwtTokenUtil.validateToken(authToken, userDetails)) {
-                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
-                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-                    LOGGER.info("authenticated user:{}", username);
-                    SecurityContextHolder.getContext().setAuthentication(authentication);
-                }
-            }
-        }
-        chain.doFilter(request, response);
-    }
-}

+ 0 - 28
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/RestAuthenticationEntryPoint.java

@@ -1,28 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import cn.hutool.json.JSONUtil;
-import com.yonge.cooleshow.mall.common.api.CommonResult;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * 自定义返回结果:未登录或登录过期
- * Created by macro on 2018/5/14.
- */
-public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
-    @Override
-    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
-        response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Cache-Control","no-cache");
-        response.setCharacterEncoding("UTF-8");
-        response.setContentType("application/json");
-        response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage())));
-        response.getWriter().flush();
-    }
-}

+ 0 - 30
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/component/RestfulAccessDeniedHandler.java

@@ -1,30 +0,0 @@
-package com.yonge.cooleshow.mall.security.component;
-
-import cn.hutool.json.JSONUtil;
-import com.yonge.cooleshow.mall.common.api.CommonResult;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.web.access.AccessDeniedHandler;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * 自定义返回结果:没有权限访问时
- * Created by macro on 2018/4/26.
- */
-public class RestfulAccessDeniedHandler implements AccessDeniedHandler{
-    @Override
-    public void handle(HttpServletRequest request,
-                       HttpServletResponse response,
-                       AccessDeniedException e) throws IOException, ServletException {
-        response.setHeader("Access-Control-Allow-Origin", "*");
-        response.setHeader("Cache-Control","no-cache");
-        response.setCharacterEncoding("UTF-8");
-        response.setContentType("application/json");
-        response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));
-        response.getWriter().flush();
-    }
-}

+ 0 - 25
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/config/IgnoreUrlsConfig.java

@@ -1,25 +0,0 @@
-package com.yonge.cooleshow.mall.security.config;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * SpringSecurity白名单资源路径配置
- * Created by macro on 2018/11/5.
- */
-
-@ConfigurationProperties(prefix = "secure.ignored")
-public class IgnoreUrlsConfig {
-
-    private List<String> urls = new ArrayList<>();
-
-    public List<String> getUrls() {
-        return urls;
-    }
-
-    public void setUrls(List<String> urls) {
-        this.urls = urls;
-    }
-}

+ 0 - 127
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/config/SecurityConfig.java

@@ -1,127 +0,0 @@
-package com.yonge.cooleshow.mall.security.config;
-
-import com.yonge.cooleshow.mall.security.component.*;
-import com.yonge.cooleshow.mall.security.util.JwtTokenUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
-
-/**
- * 对SpringSecurity配置类的扩展,支持自定义白名单资源路径和查询用户逻辑
- * Created by macro on 2019/11/5.
- */
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
-    @Autowired(required = false)
-    private DynamicSecurityService dynamicSecurityService;
-
-    @Override
-    protected void configure(HttpSecurity httpSecurity) throws Exception {
-        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity
-                .authorizeRequests();
-        // 不需要保护的资源路径允许访问
-        for (String url : ignoreUrlsConfig().getUrls()) {
-            registry.antMatchers(url).permitAll();
-        }
-        // 允许跨域的OPTIONS请求
-        registry.antMatchers(HttpMethod.OPTIONS)
-                .permitAll();
-        // 其他任何请求都需要身份认证
-        registry.and()
-                .authorizeRequests()
-                .anyRequest()
-                .authenticated()
-                // 关闭跨站请求防护及不使用session
-                .and()
-                .csrf()
-                .disable()
-                .sessionManagement()
-                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
-                // 自定义权限拒绝处理类
-                .and()
-                .exceptionHandling()
-                .accessDeniedHandler(restfulAccessDeniedHandler())
-                .authenticationEntryPoint(restAuthenticationEntryPoint())
-                // 自定义权限拦截器JWT过滤器
-                .and()
-                .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
-        //有动态权限配置时添加动态权限校验过滤器
-        if(dynamicSecurityService!=null){
-            registry.and().addFilterBefore(dynamicSecurityFilter(), FilterSecurityInterceptor.class);
-        }
-    }
-
-    @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-        auth.userDetailsService(userDetailsService())
-                .passwordEncoder(passwordEncoder());
-    }
-
-    @Bean
-    public PasswordEncoder passwordEncoder() {
-        return new BCryptPasswordEncoder();
-    }
-
-    @Bean
-    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
-        return new JwtAuthenticationTokenFilter();
-    }
-
-    @Bean
-    @Override
-    public AuthenticationManager authenticationManagerBean() throws Exception {
-        return super.authenticationManagerBean();
-    }
-
-    @Bean
-    public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
-        return new RestfulAccessDeniedHandler();
-    }
-
-    @Bean
-    public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
-        return new RestAuthenticationEntryPoint();
-    }
-
-    @Bean
-    public IgnoreUrlsConfig ignoreUrlsConfig() {
-        return new IgnoreUrlsConfig();
-    }
-
-    @Bean
-    public JwtTokenUtil jwtTokenUtil() {
-        return new JwtTokenUtil();
-    }
-
-    @ConditionalOnBean(name = "dynamicSecurityService")
-    @Bean
-    public DynamicAccessDecisionManager dynamicAccessDecisionManager() {
-        return new DynamicAccessDecisionManager();
-    }
-
-
-    @ConditionalOnBean(name = "dynamicSecurityService")
-    @Bean
-    public DynamicSecurityFilter dynamicSecurityFilter() {
-        return new DynamicSecurityFilter();
-    }
-
-    @ConditionalOnBean(name = "dynamicSecurityService")
-    @Bean
-    public DynamicSecurityMetadataSource dynamicSecurityMetadataSource() {
-        return new DynamicSecurityMetadataSource();
-    }
-
-}

+ 0 - 170
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/util/JwtTokenUtil.java

@@ -1,170 +0,0 @@
-package com.yonge.cooleshow.mall.security.util;
-
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.util.StrUtil;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * JwtToken生成的工具类
- * JWT token的格式:header.payload.signature
- * header的格式(算法、token的类型):
- * {"alg": "HS512","typ": "JWT"}
- * payload的格式(用户名、创建时间、生成时间):
- * {"sub":"wang","created":1489079981393,"exp":1489684781}
- * signature的生成算法:
- * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
- * Created by macro on 2018/4/26.
- */
-public class JwtTokenUtil {
-    private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
-    private static final String CLAIM_KEY_USERNAME = "sub";
-    private static final String CLAIM_KEY_CREATED = "created";
-    @Value("${jwt.secret}")
-    private String secret;
-    @Value("${jwt.expiration}")
-    private Long expiration;
-    @Value("${jwt.tokenHead}")
-    private String tokenHead;
-
-    /**
-     * 根据负责生成JWT的token
-     */
-    private String generateToken(Map<String, Object> claims) {
-        return Jwts.builder()
-                .setClaims(claims)
-                .setExpiration(generateExpirationDate())
-                .signWith(SignatureAlgorithm.HS512, secret)
-                .compact();
-    }
-
-    /**
-     * 从token中获取JWT中的负载
-     */
-    private Claims getClaimsFromToken(String token) {
-        Claims claims = null;
-        try {
-            claims = Jwts.parser()
-                    .setSigningKey(secret)
-                    .parseClaimsJws(token)
-                    .getBody();
-        } catch (Exception e) {
-            LOGGER.info("JWT格式验证失败:{}", token);
-        }
-        return claims;
-    }
-
-    /**
-     * 生成token的过期时间
-     */
-    private Date generateExpirationDate() {
-        return new Date(System.currentTimeMillis() + expiration * 1000);
-    }
-
-    /**
-     * 从token中获取登录用户名
-     */
-    public String getUserNameFromToken(String token) {
-        String username;
-        try {
-            Claims claims = getClaimsFromToken(token);
-            username = claims.getSubject();
-        } catch (Exception e) {
-            username = null;
-        }
-        return username;
-    }
-
-    /**
-     * 验证token是否还有效
-     *
-     * @param token       客户端传入的token
-     * @param userDetails 从数据库中查询出来的用户信息
-     */
-    public boolean validateToken(String token, UserDetails userDetails) {
-        String username = getUserNameFromToken(token);
-        return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
-    }
-
-    /**
-     * 判断token是否已经失效
-     */
-    private boolean isTokenExpired(String token) {
-        Date expiredDate = getExpiredDateFromToken(token);
-        return expiredDate.before(new Date());
-    }
-
-    /**
-     * 从token中获取过期时间
-     */
-    private Date getExpiredDateFromToken(String token) {
-        Claims claims = getClaimsFromToken(token);
-        return claims.getExpiration();
-    }
-
-    /**
-     * 根据用户信息生成token
-     */
-    public String generateToken(UserDetails userDetails) {
-        Map<String, Object> claims = new HashMap<>();
-        claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
-        claims.put(CLAIM_KEY_CREATED, new Date());
-        return generateToken(claims);
-    }
-
-    /**
-     * 当原来的token没过期时是可以刷新的
-     *
-     * @param oldToken 带tokenHead的token
-     */
-    public String refreshHeadToken(String oldToken) {
-        if(StrUtil.isEmpty(oldToken)){
-            return null;
-        }
-        String token = oldToken.substring(tokenHead.length());
-        if(StrUtil.isEmpty(token)){
-            return null;
-        }
-        //token校验不通过
-        Claims claims = getClaimsFromToken(token);
-        if(claims==null){
-            return null;
-        }
-        //如果token已经过期,不支持刷新
-        if(isTokenExpired(token)){
-            return null;
-        }
-        //如果token在30分钟之内刚刷新过,返回原token
-        if(tokenRefreshJustBefore(token,30*60)){
-            return token;
-        }else{
-            claims.put(CLAIM_KEY_CREATED, new Date());
-            return generateToken(claims);
-        }
-    }
-
-    /**
-     * 判断token在指定时间内是否刚刚刷新过
-     * @param token 原token
-     * @param time 指定时间(秒)
-     */
-    private boolean tokenRefreshJustBefore(String token, int time) {
-        Claims claims = getClaimsFromToken(token);
-        Date created = claims.get(CLAIM_KEY_CREATED, Date.class);
-        Date refreshDate = new Date();
-        //刷新时间在创建时间的指定时间内
-        if(refreshDate.after(created)&&refreshDate.before(DateUtil.offsetSecond(created,time))){
-            return true;
-        }
-        return false;
-    }
-}

+ 0 - 44
cooleshow-mall/mall-security/src/main/java/com/yonge/cooleshow/mall/security/util/SpringUtil.java

@@ -1,44 +0,0 @@
-package com.yonge.cooleshow.mall.security.util;
-
-import org.springframework.beans.BeansException;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.stereotype.Component;
-
-/**
- * Spring工具类
- * Created by macro on 2020/3/3.
- */
-@Component
-public class SpringUtil implements ApplicationContextAware {
-
-    private static ApplicationContext applicationContext;
-
-    // 获取applicationContext
-    public static ApplicationContext getApplicationContext() {
-        return applicationContext;
-    }
-
-    @Override
-    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-        if (SpringUtil.applicationContext == null) {
-            SpringUtil.applicationContext = applicationContext;
-        }
-    }
-
-    // 通过name获取Bean
-    public static Object getBean(String name) {
-        return getApplicationContext().getBean(name);
-    }
-
-    // 通过class获取Bean
-    public static <T> T getBean(Class<T> clazz) {
-        return getApplicationContext().getBean(clazz);
-    }
-
-    // 通过name,以及Clazz返回指定的Bean
-    public static <T> T getBean(String name, Class<T> clazz) {
-        return getApplicationContext().getBean(name, clazz);
-    }
-
-}

+ 0 - 1
cooleshow-mall/pom.xml

@@ -90,6 +90,5 @@
         <module>mall-admin</module>
         <module>mall-common</module>
         <module>mall-portal</module>
-        <module>mall-security</module>
     </modules>
 </project>

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleDao.java

@@ -114,5 +114,8 @@ public interface CourseScheduleDao extends BaseMapper<CourseSchedule> {
      *              <p> - type PRACTICE 陪练课 LIVE 直播课
      */
     <T> IPage<T> queryStudentLiveCourse(Page<T> page, @Param("param") Map<String, Object> param);
+
+    //更新lock
+    void updateLock(List<Long> list);
 }
 

+ 149 - 147
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/PracticeScheduleDto.java

@@ -1,10 +1,10 @@
 package com.yonge.cooleshow.biz.dal.dto;
 
-import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
-import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.yonge.cooleshow.biz.dal.entity.CourseScheduleDate;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -17,154 +17,156 @@ import java.util.List;
  */
 @ApiModel(value = "PracticeScheduleDto")
 public class PracticeScheduleDto implements Serializable {
-	@ApiModelProperty(value = "课程组id")
-	private Long groupId;
-	@ApiModelProperty(value = "学生id")
-	private Long studentId;
-	@ApiModelProperty(value = "老师id")
-	private Long teacherId;
-	@ApiModelProperty(value = "类型 practice陪练课 live直播课")
-	private String type;
-	@ApiModelProperty(value = "课程组名称")
-	private String courseGroupName;
-	@ApiModelProperty(value = "声部id")
-	private String subjectId;
-	@ApiModelProperty(value = "单课时长")
-	private Integer singleCourseMinutes;
-	@ApiModelProperty(value = "课程数")
-	private Integer courseNum;
-	@ApiModelProperty(value = "课程介绍")
-	private String courseIntroduce;
-	@ApiModelProperty(value = "课程组售价")
-	private BigDecimal coursePrice;
-	@ApiModelProperty(value = "课程单价")
-	private BigDecimal unitPrice;
-	@ApiModelProperty(value = "课程组状态 ING进行中 COMPLETE已完成 DISSOLVE-未成课(解散课程) CANCEL已取消-未开始报名前可取消 APPLY报名中 NOT_SALE未开售")
-	private String status;
-	@ApiModelProperty(value = "最少成课人数")
-	private Integer mixStudentNum;
-	@ApiModelProperty(value = "课程开始时间")
-	private Date courseStartTime;
-	@ApiModelProperty(value = "上课时间")
-	private List<CourseScheduleDate> classTime;
-
-	public BigDecimal getUnitPrice() {
-		return unitPrice;
-	}
-
-	public void setUnitPrice(BigDecimal unitPrice) {
-		this.unitPrice = unitPrice;
-	}
-
-	public Long getGroupId() {
-		return groupId;
-	}
-
-	public void setGroupId(Long groupId) {
-		this.groupId = groupId;
-	}
-
-	public Long getStudentId() {
-		return studentId;
-	}
-
-	public void setStudentId(Long studentId) {
-		this.studentId = studentId;
-	}
-
-	public Long getTeacherId() {
-		return teacherId;
-	}
-
-	public void setTeacherId(Long teacherId) {
-		this.teacherId = teacherId;
-	}
-
-	public String getType() {
-		return type;
-	}
-
-	public void setType(String type) {
-		this.type = type;
-	}
-
-	public String getCourseGroupName() {
-		return courseGroupName;
-	}
-
-	public void setCourseGroupName(String courseGroupName) {
-		this.courseGroupName = courseGroupName;
-	}
-
-	public String getSubjectId() {
-		return subjectId;
-	}
-
-	public void setSubjectId(String subjectId) {
-		this.subjectId = subjectId;
-	}
-
-	public Integer getSingleCourseMinutes() {
-		return singleCourseMinutes;
-	}
-
-	public void setSingleCourseMinutes(Integer singleCourseMinutes) {
-		this.singleCourseMinutes = singleCourseMinutes;
-	}
-
-	public Integer getCourseNum() {
-		return courseNum;
-	}
-
-	public void setCourseNum(Integer courseNum) {
-		this.courseNum = courseNum;
-	}
-
-	public String getCourseIntroduce() {
-		return courseIntroduce;
-	}
-
-	public void setCourseIntroduce(String courseIntroduce) {
-		this.courseIntroduce = courseIntroduce;
-	}
-
-	public BigDecimal getCoursePrice() {
-		return coursePrice;
-	}
-
-	public void setCoursePrice(BigDecimal coursePrice) {
-		this.coursePrice = coursePrice;
-	}
-
-	public String getStatus() {
-		return status;
-	}
-
-	public void setStatus(String status) {
-		this.status = status;
-	}
-
-	public Integer getMixStudentNum() {
-		return mixStudentNum;
-	}
+    @ApiModelProperty(value = "课程组id")
+    private Long groupId;
+    @ApiModelProperty(value = "学生id")
+    private Long studentId;
+    @ApiModelProperty(value = "老师id")
+    private Long teacherId;
+    @ApiModelProperty(value = "类型 practice陪练课 live直播课")
+    private String type;
+    @ApiModelProperty(value = "课程组名称")
+    private String courseGroupName;
+    @ApiModelProperty(value = "声部id")
+    private String subjectId;
+    @ApiModelProperty(value = "单课时长")
+    private Integer singleCourseMinutes;
+    @ApiModelProperty(value = "课程数")
+    private Integer courseNum;
+    @ApiModelProperty(value = "课程介绍")
+    private String courseIntroduce;
+    @ApiModelProperty(value = "课程组售价")
+    private BigDecimal coursePrice;
+    @ApiModelProperty(value = "课程单价")
+    private BigDecimal unitPrice;
+    @ApiModelProperty(value = "课程组状态 ING进行中 COMPLETE已完成 DISSOLVE-未成课(解散课程) CANCEL已取消-未开始报名前可取消 APPLY报名中 NOT_SALE未开售")
+    private String status;
+    @ApiModelProperty(value = "最少成课人数")
+    private Integer mixStudentNum;
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty(value = "课程开始时间")
+    private Date courseStartTime;
+    @ApiModelProperty(value = "上课时间")
+    private List<CourseScheduleDate> classTime;
+
+    public BigDecimal getUnitPrice() {
+        return unitPrice;
+    }
+
+    public void setUnitPrice(BigDecimal unitPrice) {
+        this.unitPrice = unitPrice;
+    }
+
+    public Long getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(Long groupId) {
+        this.groupId = groupId;
+    }
+
+    public Long getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
+
+    public Long getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(Long teacherId) {
+        this.teacherId = teacherId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getCourseGroupName() {
+        return courseGroupName;
+    }
+
+    public void setCourseGroupName(String courseGroupName) {
+        this.courseGroupName = courseGroupName;
+    }
+
+    public String getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(String subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public Integer getSingleCourseMinutes() {
+        return singleCourseMinutes;
+    }
+
+    public void setSingleCourseMinutes(Integer singleCourseMinutes) {
+        this.singleCourseMinutes = singleCourseMinutes;
+    }
+
+    public Integer getCourseNum() {
+        return courseNum;
+    }
+
+    public void setCourseNum(Integer courseNum) {
+        this.courseNum = courseNum;
+    }
+
+    public String getCourseIntroduce() {
+        return courseIntroduce;
+    }
+
+    public void setCourseIntroduce(String courseIntroduce) {
+        this.courseIntroduce = courseIntroduce;
+    }
+
+    public BigDecimal getCoursePrice() {
+        return coursePrice;
+    }
+
+    public void setCoursePrice(BigDecimal coursePrice) {
+        this.coursePrice = coursePrice;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Integer getMixStudentNum() {
+        return mixStudentNum;
+    }
 
-	public void setMixStudentNum(Integer mixStudentNum) {
-		this.mixStudentNum = mixStudentNum;
-	}
+    public void setMixStudentNum(Integer mixStudentNum) {
+        this.mixStudentNum = mixStudentNum;
+    }
 
-	public Date getCourseStartTime() {
-		return courseStartTime;
-	}
+    public Date getCourseStartTime() {
+        return courseStartTime;
+    }
 
-	public void setCourseStartTime(Date courseStartTime) {
-		this.courseStartTime = courseStartTime;
-	}
+    public void setCourseStartTime(Date courseStartTime) {
+        this.courseStartTime = courseStartTime;
+    }
 
-	public List<CourseScheduleDate> getClassTime() {
-		return classTime;
-	}
+    public List<CourseScheduleDate> getClassTime() {
+        return classTime;
+    }
 
-	public void setClassTime(List<CourseScheduleDate> classTime) {
-		this.classTime = classTime;
-	}
+    public void setClassTime(List<CourseScheduleDate> classTime) {
+        this.classTime = classTime;
+    }
 }

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VideoLessonGroupSearch.java

@@ -23,6 +23,17 @@ public class VideoLessonGroupSearch extends QueryInfo {
     @ApiModelProperty(value = "学生id")
     private Long studentId;
 
+    @ApiModelProperty(value = "老师id")
+    private Long teacherId;
+
+    public Long getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(Long teacherId) {
+        this.teacherId = teacherId;
+    }
+
     public Long getStudentId() {
         return studentId;
     }

+ 9 - 8
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java

@@ -3,20 +3,17 @@ package com.yonge.cooleshow.biz.dal.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
-import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
+import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
-import com.yonge.cooleshow.biz.dal.vo.CourseStudent;
-import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
-import com.yonge.cooleshow.biz.dal.vo.PracticeTeacherVo;
-import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
+import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.page.PageInfo;
-import org.apache.ibatis.annotations.Param;
 
-import javax.validation.Valid;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -179,6 +176,10 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
      */
     PageInfo<CourseStudent> queryStudentLiveCourse(Map<String, Object> param);
 
-    void creatPractice(PracticeScheduleDto scheduleDto);
+    HttpResponseResult<OrderCreateRes> buyPracticeCourse(OrderReq.OrderReqInfo orderReqInfo);
+
+    void buyPracticeCourseSuccess(UserOrderDetailVo orderParam);
+
+    void buyPracticeCourseFailed(String orderNo);
 }
 

+ 78 - 20
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java

@@ -1,30 +1,33 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleRepliedDao;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentPaymentDao;
 import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
 import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
+import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.CourseGroupEnum;
 import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.PageUtil;
 import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
-import com.yonge.cooleshow.biz.dal.vo.CourseStudent;
-import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
-import com.yonge.cooleshow.biz.dal.vo.PracticeTeacherVo;
-import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
+import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.exception.BizException;
 import com.yonge.cooleshow.common.page.PageInfo;
 import com.yonge.toolset.utils.date.DateUtil;
@@ -43,6 +46,7 @@ import java.time.temporal.TemporalAdjusters;
 import java.util.*;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * 老师课程表(CourseSchedule)表服务实现类
@@ -787,24 +791,30 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         param.put("endDate", lastDay.toString());
         Page<CourseStudent> pageInfo = PageUtil.getPageInfo(param);
         pageInfo.setAsc(" cs.start_time_");
-       return PageUtil.pageInfo(baseMapper.queryStudentLiveCourse(pageInfo,param));
+        return PageUtil.pageInfo(baseMapper.queryStudentLiveCourse(pageInfo, param));
     }
 
-
     /**
-     * @Description: 创建陪练课
+     * @Description: 学生购买陪练课
      * @Author: cy
-     * @Date: 2022/4/20
+     * @Date: 2022/4/21
      */
     @Transactional(rollbackFor = Exception.class)
-    public void creatPractice(PracticeScheduleDto scheduleDto){
-        //创建单号
-        String orderNo="";
+    public HttpResponseResult<OrderCreateRes> buyPracticeCourse(OrderReq.OrderReqInfo orderReqInfo) {
+        log.info("学生购买陪练课,请求参数:{}", JSON.toJSONString(orderReqInfo));
+        Long studentId = orderReqInfo.getUserId();
+
+//        PracticeScheduleDto scheduleDto= (PracticeScheduleDto) orderReqInfo.getBizContent();
+        ObjectMapper objectMapper = new ObjectMapper();
+        PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderReqInfo.getBizContent(), PracticeScheduleDto.class);
+
+        String orderNo = orderReqInfo.getOrderNo();
         scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
         scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
         scheduleDto.setMixStudentNum(1);
+        scheduleDto.setStudentId(studentId);
 
-        //写入course_group
+        //course_group
         baseMapper.addCourseGroup(scheduleDto);
         Long groupId = scheduleDto.getGroupId();
 
@@ -818,12 +828,12 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             schedule.setEndTime(date.getEndTime());
             schedule.setCourseGroupId(groupId);
             schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
-            schedule.classNum(i+1);
+            schedule.classNum(i + 1);
             schedule.setTeacherId(scheduleDto.getTeacherId());
             schedule.setLock(1);
             schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
             schedule.setCreatedBy(scheduleDto.getStudentId());
-            //写入course_schedule
+            //course_schedule
             baseMapper.insert(schedule);
 
             Long scheduleId = schedule.getId();
@@ -836,17 +846,65 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             payment.setOriginalPrice(unitPrice);
             payment.setExpectPrice(unitPrice);
             payment.setActualPrice(unitPrice);
-            //course_schedule_student_payment
+            //course_schedule_student_payment
             courseScheduleStudentPaymentService.save(payment);
         }
+
+        OrderCreateRes orderCreateRes = new OrderCreateRes();
+        orderCreateRes.setRes(true);
+        orderCreateRes.setMerchId(scheduleDto.getTeacherId());
+        orderCreateRes.setBizId(groupId);
+        orderCreateRes.setOriginalPrice(scheduleDto.getCoursePrice());
+        orderCreateRes.setExpectPrice(scheduleDto.getCoursePrice());
+        orderCreateRes.setGoodNum(scheduleDto.getCourseNum());
+        orderCreateRes.setGoodType(GoodTypeEnum.PRACTICE);
+        HttpResponseResult<OrderCreateRes> httpResponseResult = new HttpResponseResult<>();
+        httpResponseResult.setData(orderCreateRes);
+        return httpResponseResult;
     }
 
     /**
-     * 陪练课下单
-     *
-     * 调用下单接口
-     * 成功:将course_schedule中lock_改为0
-     * 失败:回滚以上数据
+     * 学生购买陪练课-成功-回调
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void buyPracticeCourseSuccess(UserOrderDetailVo orderParam) {
+        log.info("学生购买陪练课-成功-回调,请求参数:{}", JSON.toJSONString(orderParam));
+        String orderNo = orderParam.getOrderNo();
+        List<CourseScheduleStudentPayment> paymentList = paymentDao.selectList(Wrappers.<CourseScheduleStudentPayment>lambdaQuery()
+                .eq(CourseScheduleStudentPayment::getOrderNo, orderNo));
+        if (paymentList.isEmpty()) {
+            throw new BizException("订单不存在!");
+        }
+
+        //course_schedule中lock_改为0
+        List<Long> scheduleIds = paymentList.stream().map(CourseScheduleStudentPayment::getCourseId).collect(Collectors.toList());
+        baseMapper.updateLock(scheduleIds);
+    }
+
+    /**
+     * 学生购买陪练课-失败-回调
      */
+    @Transactional(rollbackFor = Exception.class)
+    public void buyPracticeCourseFailed(String orderNo) {
+        List<CourseScheduleStudentPayment> paymentList = paymentDao.selectList(Wrappers.<CourseScheduleStudentPayment>lambdaQuery()
+                .eq(CourseScheduleStudentPayment::getOrderNo, orderNo));
+        if (paymentList.isEmpty()) {
+            throw new BizException("订单不存在!");
+        }
+
+        List<Long> scheduleIds = paymentList.stream().map(CourseScheduleStudentPayment::getCourseId).collect(Collectors.toList());
+        Long courseGroupId = paymentList.get(0).getCourseGroupId();
+
+        //删除course_schedule_student_payment数据
+        courseScheduleStudentPaymentService.remove(Wrappers.<CourseScheduleStudentPayment>lambdaQuery()
+                .eq(CourseScheduleStudentPayment::getOrderNo, orderNo));
+        //删除course_schedule数据
+        this.removeByIds(scheduleIds);
+        //删除course_group数据
+        courseGroupService.removeById(courseGroupId);
+
+        //修改订单为失败
+    }
+
 }
 

+ 7 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/LiveRoomServiceImpl.java

@@ -379,6 +379,7 @@ public class LiveRoomServiceImpl extends ServiceImpl<LiveRoomDao, LiveRoom> impl
                     roomInfoCache.set(roomInfo);
                     return;
                 }
+                roomInfo.setSpeakerState(1);
                 roomInfo.setExitRoomTime(now);
                 log.info("opsRoom>>>> exit roomInfo {}", JSONObject.toJSONString(roomInfo));
                 roomInfoCache.set(roomInfo);
@@ -398,19 +399,20 @@ public class LiveRoomServiceImpl extends ServiceImpl<LiveRoomDao, LiveRoom> impl
             }
             //查询到用户数据
             RoomUserInfoCache userInfo = roomTotalUser.get(userId);
-            //用户是在房间的状态 并且 突然离线 - 那么融云会发送用户离线消息-此刻就发送退出房间消息给主讲人
-            if (userInfo.getState() == 0 && user.getStatus().equals("1")) {
+            //用户突然离线 - 那么融云会发送用户离线消息-此刻就发送退出房间消息给主讲人
+            if (user.getStatus().equals("1")) {
                 ImRoomMessage message = new ImRoomMessage();
                 message.setFromUserId(userId.toString());
+                message.setContent(userId.toString());
                 message.setToChatroomId(roomUid);
                 message.setObjectName(ImRoomMessage.RC_CHATROOM_LEAVE);
                 try {
                     publishRoomMessage(message);
                 } catch (Exception e) {
-                    log.error("opsRoom>>>>  looker error {}", e.getMessage());
-                    log.error("opsRoom>>>>  looker error sendMessage {} : leave : {}", message, JSONObject.toJSONString(userInfo));
+                    log.error("opsRoom>>>>  looker leave error {}", e.getMessage());
+                    log.error("opsRoom>>>>  looker leave error sendMessage {} : userInfo : {}", message, JSONObject.toJSONString(userInfo));
                 }
-                log.info("opsRoom>>>> looker leave : {}", JSONObject.toJSONString(userInfo));
+                log.info("opsRoom>>>> looker leave userInfo : {}", JSONObject.toJSONString(userInfo));
             }
             //记录退出时间 并写入缓存
             userInfo.setLastOutTime(now);

+ 17 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -281,6 +281,14 @@
         WHERE cs.type_='LIVE'
         AND cs.teacher_id_=#{param.teacherId}
         AND cs.class_date_=#{param.classDate}
+        AND cs.id_ IN(
+            SELECT c.id_
+            FROM course_schedule_student_payment p,course_schedule c
+            WHERE p.course_id_=c.id_
+            AND p.course_group_id_ = c.course_group_id_
+            AND c.teacher_id_=#{param.teacherId}
+            AND c.class_date_=#{param.classDate}
+            AND c.type_='LIVE')
         UNION
         SELECT
             p.course_id_ AS courseId,
@@ -430,8 +438,15 @@
 
     <insert id="addCourseGroup" parameterType="com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto" useGeneratedKeys="true" keyProperty="groupId">
         Insert INTO course_group(teacher_id_,type_,name_,subject_id_,single_course_minutes_,course_num_,course_introduce_,
-        course_price_,status_,created_by_,mix_student_num_,course_start_time_)
+        course_price_,status_,created_by_,mix_student_num_,course_start_time_,pre_student_num_)
         VALUES (#{teacherId},#{type},#{courseGroupName},#{subjectId},#{singleCourseMinutes},#{courseNum},#{courseIntroduce},
-        #{coursePrice},#{status},#{studentId},#{mixStudentNum},#{courseStartTime})
+        #{coursePrice},#{status},#{studentId},#{mixStudentNum},#{courseStartTime},1)
     </insert>
+
+    <update id="updateLock" parameterType="java.util.List">
+        UPDATE course_schedule SET lock_ = 0 WHERE id_ IN
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </update>
 </mapper>

+ 4 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/VideoLessonGroupMapper.xml

@@ -72,7 +72,7 @@
 	</update>
 	<select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupVo">
 		SELECT
-			<include refid="baseColumns"/>,
+			<include refid="baseColumns"/>
 			s.username_ AS username,
 			s.avatar_ AS avatar,
 			(SELECT COUNT(1) FROM video_lesson_purchase_record r WHERE r.video_lesson_group_id_=g.id_) AS countStudent
@@ -85,6 +85,9 @@
 			<if test="param.groupId !=null">
 				AND g.id_ = #{param.groupId}
 			</if>
+			<if test="param.teacherId !=null">
+				AND g.teacher_id_ = #{param.teacherId}
+			</if>
 		</where>
 	</select>
 	<select id="selectStudentPage" resultType="com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentDetailVo">

+ 7 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/VideoLessonGroupController.java

@@ -13,6 +13,7 @@ import com.yonge.cooleshow.biz.dal.vo.VideoLessonVo;
 import com.yonge.cooleshow.common.page.PageInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -50,6 +51,12 @@ public class VideoLessonGroupController extends BaseController {
     @ApiOperation(value = "查询视频课组")
     @PostMapping(value = "/page")
     public HttpResponseResult<PageInfo<VideoLessonGroupVo>> page(@RequestBody VideoLessonGroupSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        query.setTeacherId(sysUser.getId());
         IPage<VideoLessonGroupVo> pages = videoLessonGroupService.selectPage(PageUtil.getPage(query), query);
         return succeed(PageUtil.pageInfo(pages));
     }