肖海南1.0

master
wenyu441069198 7 months ago
parent 69344986ec
commit d8fba50336
  1. 59
      pom.xml
  2. 9
      src/main/java/com/teaching/backend/annotation/test1.java
  3. 9
      src/main/java/com/teaching/backend/aop/test1.java
  4. 377
      src/main/java/com/teaching/backend/api/CommonConstant.java
  5. 117
      src/main/java/com/teaching/backend/api/CommonResult.java
  6. 13
      src/main/java/com/teaching/backend/api/IErrorCode.java
  7. 30
      src/main/java/com/teaching/backend/api/ResultCode.java
  8. 51
      src/main/java/com/teaching/backend/component/DynamicAccessDecisionManager.java
  9. 77
      src/main/java/com/teaching/backend/component/DynamicSecurityFilter.java
  10. 64
      src/main/java/com/teaching/backend/component/DynamicSecurityMetadataSource.java
  11. 16
      src/main/java/com/teaching/backend/component/DynamicSecurityService.java
  12. 58
      src/main/java/com/teaching/backend/component/JwtAuthenticationTokenFilter.java
  13. 27
      src/main/java/com/teaching/backend/component/RestAuthenticationEntryPoint.java
  14. 29
      src/main/java/com/teaching/backend/component/RestfulAccessDeniedHandler.java
  15. 67
      src/main/java/com/teaching/backend/config/CommonSecurityConfig.java
  16. 20
      src/main/java/com/teaching/backend/config/IgnoreUrlsConfig.java
  17. 47
      src/main/java/com/teaching/backend/config/MallSecurityConfig.java
  18. 75
      src/main/java/com/teaching/backend/config/SecurityConfig.java
  19. 17
      src/main/java/com/teaching/backend/constant/RegexPatterns.java
  20. 9
      src/main/java/com/teaching/backend/constant/test1.java
  21. 12
      src/main/java/com/teaching/backend/controller/records/LearningRecordsController.java
  22. 155
      src/main/java/com/teaching/backend/controller/umsAdmin/UmsAdminController.java
  23. 33
      src/main/java/com/teaching/backend/exception/ApiException.java
  24. 18
      src/main/java/com/teaching/backend/exception/Asserts.java
  25. 31
      src/main/java/com/teaching/backend/exception/LyException.java
  26. 9
      src/main/java/com/teaching/backend/manager/test1.java
  27. 9
      src/main/java/com/teaching/backend/mapper/umsAdmin/UmsAdminMapper.java
  28. 38
      src/main/java/com/teaching/backend/mapper/umsAdmin/UmsAdminRoleRelationMapper.java
  29. 31
      src/main/java/com/teaching/backend/mapper/umsAdmin/UmsRoleMapper.java
  30. 30
      src/main/java/com/teaching/backend/model/dto/UmsAdminParam.java
  31. 22
      src/main/java/com/teaching/backend/model/dto/UpdateAdminPasswordParam.java
  32. 192
      src/main/java/com/teaching/backend/model/entity/records/LearningRecords.java
  33. 64
      src/main/java/com/teaching/backend/model/entity/umsAdmin/AdminUserDetails.java
  34. 39
      src/main/java/com/teaching/backend/model/entity/umsAdmin/UmsAdmin.java
  35. 860
      src/main/java/com/teaching/backend/model/entity/umsAdmin/UmsAdminExample.java
  36. 18
      src/main/java/com/teaching/backend/model/entity/umsAdmin/UmsAdminRoleRelation.java
  37. 41
      src/main/java/com/teaching/backend/model/entity/umsAdmin/UmsMenu.java
  38. 33
      src/main/java/com/teaching/backend/model/entity/umsAdmin/UmsResource.java
  39. 33
      src/main/java/com/teaching/backend/model/entity/umsAdmin/UmsRole.java
  40. 9
      src/main/java/com/teaching/backend/model/enums/test1.java
  41. 104
      src/main/java/com/teaching/backend/model/vo/records/LearningRecordsVo.java
  42. 9
      src/main/java/com/teaching/backend/model/vo/test1.java
  43. 74
      src/main/java/com/teaching/backend/service/umsAdmin/UmsAdminService.java
  44. 21
      src/main/java/com/teaching/backend/service/umsAdmin/UmsRoleService.java
  45. 271
      src/main/java/com/teaching/backend/service/umsAdmin/impl/UmsAdminServiceImpl.java
  46. 26
      src/main/java/com/teaching/backend/service/umsAdmin/impl/UmsRoleServiceImpl.java
  47. 169
      src/main/java/com/teaching/backend/utils/JwtTokenUtil.java
  48. 32
      src/main/java/com/teaching/backend/utils/RegexUtils.java
  49. 26
      src/main/java/com/teaching/backend/utils/ThreadLocalUtil.java
  50. 42
      src/main/resources/application.yml
  51. 44
      src/main/resources/mapper/UmsAdminRoleRelationMapper.xml
  52. 64
      src/main/resources/mapper/UmsRoleMapper.xml

@ -97,12 +97,69 @@
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
<version>5.8.11</version> <version>5.8.11</version>
</dependency> </dependency>
<!--java jwt坐标-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<!--token-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!--SpringSecurity依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.9</version>
</dependency>
<!--解决JDK 11 兼容性问题-->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!--阿里云短信-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- &lt;!&ndash; pagehelper &ndash;&gt;--> <!-- &lt;!&ndash; pagehelper &ndash;&gt;-->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>com.github.pagehelper</groupId>--> <!-- <groupId>com.github.pagehelper</groupId>-->
<!-- <artifactId>pagehelper</artifactId>--> <!-- <artifactId>pagehelper</artifactId>-->
<!-- <version>4.1.6</version>--> <!-- <version>3.4.2</version>-->
<!-- </dependency>--> <!-- </dependency>-->
</dependencies> </dependencies>

@ -1,9 +0,0 @@
package com.teaching.backend.annotation;
/**
* @Author:youhang
* @Date:2024-05-30-18:20
* @Description:
*/
public class test1 {
}

@ -1,9 +0,0 @@
package com.teaching.backend.aop;
/**
* @Author:youhang
* @Date:2024-05-30-18:20
* @Description:
*/
public class test1 {
}

@ -0,0 +1,377 @@
package com.teaching.backend.api;
public interface CommonConstant {
/**
* 未查询到信息
*/
public String delete_batch_success = "批量删除成功!";
/**
* 未查询到信息
*/
public String detail_failed = "未查询到信息";
/**
* 修改失败标志
*/
public String update_failed = "修改失败";
/**
* 修改失败标志
*/
public String update_success = "修改成功";
/**
*
* message: 添加成功
*/
public static final String MESSAGE_add_SUCCESS = "添加成功";
/**
*
* message: 添加成功
*/
public static final String MESSAGE_add__FAILED = "添加失败";
/**
*
* message: 添加成功
*/
public static final String MESSAGE_QUERY_SUCCESS = "查询成功";
/**
*
* message:删除成功
*/
public static final String MESSAGE_DELETE_SUCCESS = "删除成功";
/**
*
* message:删除失败
*/
public static final String MESSAGE_DELETE_FAILED = "删除失败";
/**
* 正常状态
*/
public static final Integer STATUS_NORMAL = 0;
/**
* 禁用状态
*/
public static final Integer STATUS_DISABLE = -1;
/**
* 删除标志
*/
public static final Integer DEL_FLAG_1 = 1;
/**
* 未删除
*/
public static final Integer DEL_FLAG_0 = 0;
/**
* 系统日志类型 登录
*/
public static final int LOG_TYPE_1 = 1;
/**
* 系统日志类型 操作
*/
public static final int LOG_TYPE_2 = 2;
/**
* 操作日志类型 查询
*/
public static final int OPERATE_TYPE_1 = 1;
/**
* 操作日志类型 添加
*/
public static final int OPERATE_TYPE_2 = 2;
/**
* 操作日志类型 更新
*/
public static final int OPERATE_TYPE_3 = 3;
/**
* 操作日志类型 删除
*/
public static final int OPERATE_TYPE_4 = 4;
/**
* 操作日志类型 倒入
*/
public static final int OPERATE_TYPE_5 = 5;
/**
* 操作日志类型 导出
*/
public static final int OPERATE_TYPE_6 = 6;
/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
/** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
public static final Integer SC_OK_200 = 200;
/**访问权限认证未通过 510*/
public static final Integer SC_JEECG_NO_AUTHZ=510;
/** 登录用户Shiro权限缓存KEY前缀 */
public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:";
/** 登录用户Token令牌缓存KEY前缀 */
public static final String PREFIX_USER_TOKEN = "prefix_user_token_";
/** Token缓存时间:3600秒即一小时 */
public static final int TOKEN_EXPIRE_TIME = 3600;
/**
* 0一级菜单
*/
public static final Integer MENU_TYPE_0 = 0;
/**
* 1子菜单
*/
public static final Integer MENU_TYPE_1 = 1;
/**
* 2按钮权限
*/
public static final Integer MENU_TYPE_2 = 2;
/**通告对象类型(USER:指定用户,ALL:全体用户)*/
public static final String MSG_TYPE_UESR = "USER";
public static final String MSG_TYPE_ALL = "ALL";
/**发布状态(0未发布,1已发布,2已撤销)*/
public static final String NO_SEND = "0";
public static final String HAS_SEND = "1";
public static final String HAS_CANCLE = "2";
/**阅读状态(0未读,1已读)*/
public static final String HAS_READ_FLAG = "1";
public static final String NO_READ_FLAG = "0";
/**优先级(L低,M中,H高)*/
public static final String PRIORITY_L = "L";
public static final String PRIORITY_M = "M";
public static final String PRIORITY_H = "H";
/**
* 短信模板方式 0 .登录模板1.注册模板2.忘记密码模板
*/
public static final String SMS_TPL_TYPE_0 = "0";
public static final String SMS_TPL_TYPE_1 = "1";
public static final String SMS_TPL_TYPE_2 = "2";
/**
* 状态(0无效1有效)
*/
public static final String STATUS_0 = "0";
public static final String STATUS_1 = "1";
/**
* 同步工作流引擎1同步0不同步
*/
public static final Integer ACT_SYNC_1 = 1;
public static final Integer ACT_SYNC_0 = 0;
/**
* 消息类型1:通知公告2:系统消息
*/
public static final String MSG_CATEGORY_1 = "1";
public static final String MSG_CATEGORY_2 = "2";
/**
* 是否配置菜单的数据权限 1是0否
*/
public static final Integer RULE_FLAG_0 = 0;
public static final Integer RULE_FLAG_1 = 1;
/**
* 是否用户已被冻结 1正常(解冻) 2冻结
*/
public static final Integer USER_UNFREEZE = 1;
public static final Integer USER_FREEZE = 2;
/**字典翻译文本后缀*/
public static final String DICT_TEXT_SUFFIX = "_dictText";
/**
* 表单设计器主表类型
*/
public static final Integer DESIGN_FORM_TYPE_MAIN = 1;
/**
* 表单设计器子表表类型
*/
public static final Integer DESIGN_FORM_TYPE_SUB = 2;
/**
* 表单设计器URL授权通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_PASSED = 1;
/**
* 表单设计器URL授权未通过
*/
public static final Integer DESIGN_FORM_URL_STATUS_NOT_PASSED = 2;
/**
* 表单设计器新增 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_ADD = "add";
/**
* 表单设计器修改 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_EDIT = "edit";
/**
* 表单设计器详情 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_DETAIL = "detail";
/**
* 表单设计器复用数据 Flag
*/
public static final String DESIGN_FORM_URL_TYPE_REUSE = "reuse";
/**
* 表单设计器编辑 Flag 已弃用
*/
public static final String DESIGN_FORM_URL_TYPE_VIEW = "view";
/**
* online参数值设置Y, N
*/
public static final String ONLINE_PARAM_VAL_IS_TURE = "Y";
public static final String ONLINE_PARAM_VAL_IS_FALSE = "N";
/**
* 文件上传类型本地localMiniominio阿里云alioss
*/
public static final String UPLOAD_TYPE_LOCAL = "local";
public static final String UPLOAD_TYPE_MINIO = "minio";
public static final String UPLOAD_TYPE_OSS = "alioss";
/**
* 文档上传自定义桶名称
*/
public static final String UPLOAD_CUSTOM_BUCKET = "eoafile";
/**
* 文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH = "eoafile";
/**
* 文件外链接有效天数
*/
public static final Integer UPLOAD_EFFECTIVE_DAYS = 1;
/**
* 员工身份 1:普通员工 2:上级
*/
public static final Integer USER_IDENTITY_1 = 1;
public static final Integer USER_IDENTITY_2 = 2;
/** sys_user 表 username 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_USERNAME = "uniq_sys_user_username";
/** sys_user 表 work_no 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_WORK_NO = "uniq_sys_user_work_no";
/** sys_user 表 phone 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_PHONE = "uniq_sys_user_phone";
/** sys_user 表 email 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_USER_EMAIL = "uniq_sys_user_email";
/** sys_quartz_job 表 job_class_name 唯一键索引 */
public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name";
/** sys_position 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_CODE = "uniq_code";
/** sys_role 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code";
/** sys_depart 表 code 唯一键索引 */
public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code";
/**
* 在线聊天 是否为默认分组
*/
public static final String IM_DEFAULT_GROUP = "1";
/**
* 在线聊天 图片文件保存路径
*/
public static final String IM_UPLOAD_CUSTOM_PATH = "imfile";
/**
* 在线聊天 用户状态
*/
public static final String IM_STATUS_ONLINE = "online";
/**
* 在线聊天 SOCKET消息类型
*/
public static final String IM_SOCKET_TYPE = "chatMessage";
/**
* 在线聊天 是否开启默认添加好友 1是 0否
*/
public static final String IM_DEFAULT_ADD_FRIEND = "1";
/**
* 在线聊天 用户好友缓存前缀
*/
public static final String IM_PREFIX_USER_FRIEND_CACHE = "sys:cache:im:im_prefix_user_friend_";
/**
* 考勤补卡业务状态 1同意 2不同意
*/
public static final String SIGN_PATCH_BIZ_STATUS_1 = "1";
public static final String SIGN_PATCH_BIZ_STATUS_2 = "2";
/**
* 公文文档上传自定义路径
*/
public static final String UPLOAD_CUSTOM_PATH_OFFICIAL = "officialdoc";
/**
* 公文文档下载自定义路径
*/
public static final String DOWNLOAD_CUSTOM_PATH_OFFICIAL = "officaldown";
/**
* WPS存储值类别(1 code文号 2 textWPS模板还是公文发文模板)
*/
public static final String WPS_TYPE_1="1";
public static final String WPS_TYPE_2="2";
public final static String X_ACCESS_TOKEN = "X-Access-Token";
public final static String X_SIGN = "X-Sign";
public final static String X_TIMESTAMP = "X-TIMESTAMP";
/**
* 多租户 请求头
*/
public final static String TENANT_ID = "tenant-id";
/**
* 微服务读取配置文件属性 服务地址
*/
public final static String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr";
/**
* 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用
*/
public final static String THIRD_LOGIN_CODE = "third_login_code";
/**
* 第三方APP同步方向本地 --> 第三方APP
*/
String THIRD_SYNC_TO_APP = "SYNC_TO_APP";
/**
* 第三方APP同步方向第三方APP --> 本地
*/
String THIRD_SYNC_TO_LOCAL = "SYNC_TO_LOCAL";
/** 系统通告消息状态:0=未发布 */
String ANNOUNCEMENT_SEND_STATUS_0 = "0";
/** 系统通告消息状态:1=已发布 */
String ANNOUNCEMENT_SEND_STATUS_1 = "1";
/** 系统通告消息状态:2=已撤销 */
String ANNOUNCEMENT_SEND_STATUS_2 = "2";
}

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

@ -0,0 +1,13 @@
package com.teaching.backend.api;
/**
* @auther macrozheng
* @description 封装API的错误码
* @date 2019/4/19
* @github https://github.com/macrozheng
*/
public interface IErrorCode {
long getCode();
String getMessage();
}

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

@ -0,0 +1,51 @@
package com.teaching.backend.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,0 +1,77 @@
package com.teaching.backend.component;
import com.teaching.backend.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,0 +1,64 @@
package com.teaching.backend.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,0 +1,16 @@
package com.teaching.backend.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,0 +1,58 @@
package com.teaching.backend.component;
import com.teaching.backend.utils.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,0 +1,27 @@
package com.teaching.backend.component;
import cn.hutool.json.JSONUtil;
import com.teaching.backend.api.CommonResult;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 自定义未登录或者token失效时的返回结果
* 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,0 +1,29 @@
package com.teaching.backend.component;
import cn.hutool.json.JSONUtil;
import com.teaching.backend.api.CommonResult;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
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,0 +1,67 @@
package com.teaching.backend.config;
import com.teaching.backend.component.*;
import com.teaching.backend.utils.JwtTokenUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* SpringSecurity通用配置
* 包括通用BeanSecurity通用Bean及动态权限通用Bean
* Created by macro on 2022/5/20.
*/
@Configuration
public class CommonSecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public IgnoreUrlsConfig ignoreUrlsConfig() {
return new IgnoreUrlsConfig();
}
@Bean
public JwtTokenUtil jwtTokenUtil() {
return new JwtTokenUtil();
}
@Bean
public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
return new RestfulAccessDeniedHandler();
}
@Bean
public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
return new RestAuthenticationEntryPoint();
}
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
return new JwtAuthenticationTokenFilter();
}
@ConditionalOnBean(name = "dynamicSecurityService")
@Bean
public DynamicAccessDecisionManager dynamicAccessDecisionManager() {
return new DynamicAccessDecisionManager();
}
@ConditionalOnBean(name = "dynamicSecurityService")
@Bean
public DynamicSecurityMetadataSource dynamicSecurityMetadataSource() {
return new DynamicSecurityMetadataSource();
}
@ConditionalOnBean(name = "dynamicSecurityService")
@Bean
public DynamicSecurityFilter dynamicSecurityFilter(){
return new DynamicSecurityFilter();
}
}

@ -0,0 +1,20 @@
package com.teaching.backend.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
/**
* SpringSecurity白名单资源路径配置
* Created by macro on 2018/11/5.
*/
@Getter
@Setter
@ConfigurationProperties(prefix = "secure.ignored")
public class IgnoreUrlsConfig {
private List<String> urls = new ArrayList<>();
}

@ -0,0 +1,47 @@
package com.teaching.backend.config;
import com.teaching.backend.service.umsAdmin.UmsAdminService;
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.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
public class MallSecurityConfig {
@Autowired
private UmsAdminService umsadminService;
// @Autowired
// private UmsResourceService resourceService;
@Bean
public UserDetailsService userDetailsService() {
//获取登录用户信息
return username -> umsadminService.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,0 +1,75 @@
package com.teaching.backend.config;
import com.teaching.backend.component.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* SpringSecurity相关配置仅用于配置SecurityFilterChain
* Created by macro on 2019/11/5.
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Autowired
private IgnoreUrlsConfig ignoreUrlsConfig;
@Autowired
private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Autowired(required = false)
private DynamicSecurityService dynamicSecurityService;
@Autowired(required = false)
private DynamicSecurityFilter dynamicSecurityFilter;
@Bean
SecurityFilterChain filterChain(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);
}
return httpSecurity.build();
}
}

@ -0,0 +1,17 @@
package com.teaching.backend.constant;
public abstract class RegexPatterns {
/**
* 手机号正则
*/
public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";
/**
* 密码正则4~32位的字母数字下划线
*/
public static final String PASSWORD_REGEX = "^\\w{4,32}$";
/**
* 验证码正则, 6位数字或字母
*/
public static final String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$";
}

@ -1,9 +0,0 @@
package com.teaching.backend.constant;
/**
* @Author:youhang
* @Date:2024-05-30-18:20
* @Description:
*/
public class test1 {
}

@ -36,7 +36,7 @@
// @RequestParam(value = "pagenum", defaultValue = "1") int pagenum, // @RequestParam(value = "pagenum", defaultValue = "1") int pagenum,
// @RequestParam(value = "pagesize", defaultValue = "15") int pagesize, // @RequestParam(value = "pagesize", defaultValue = "15") int pagesize,
// @RequestParam String userId){ // @RequestParam String userId){
// PageHelper.startPage(pagenum,pagesize,"id desc"); // PageHelper.startPage(pagenum,pagesize);
// List<LearningRecordsVo> cs= learningRecordsService.getAll(userId); // List<LearningRecordsVo> cs= learningRecordsService.getAll(userId);
// List<LearningRecordsVo> pageCs = new ArrayList<>(); // List<LearningRecordsVo> pageCs = new ArrayList<>();
// //当前页面 // //当前页面
@ -48,12 +48,12 @@
// System.out.println("当前页面大小:"+pagesize); // System.out.println("当前页面大小:"+pagesize);
// System.out.println("当前页面内容:"+pageCs); // System.out.println("当前页面内容:"+pageCs);
//// PageInfo<LearningRecordsVo> pageInfo = new PageInfo<>(cs); //// PageInfo<LearningRecordsVo> pageInfo = new PageInfo<>(cs);
// pageInfo.setPageSize(pagesize);//设置当前页面大小 //// pageInfo.setPageSize(pagesize);//设置当前页面大小
// pageInfo.setPageNum(pagenum);//设置当前页码 //// pageInfo.setPageNum(pagenum);//设置当前页码
// pageInfo.setSize(pagesize);//不知道是啥,--------- //// pageInfo.setSize(pagesize);//不知道是啥,---------
// pageInfo.setTotal(cs.size());//设置总条数 //// pageInfo.setTotal(cs.size());//设置总条数
// long total = pageInfo.getTotal(); // 总记录数 // long total = pageInfo.getTotal(); // 总记录数
// pageInfo.setPages((int)(Math.ceil((double) total / pagesize)));//设置总页数 //// pageInfo.setPages((int)(Math.ceil((double) total / pagesize)));//设置总页数
// return ResultUtils.success(pageInfo); // return ResultUtils.success(pageInfo);
// } // }
// //

@ -0,0 +1,155 @@
package com.teaching.backend.controller.umsAdmin;
import cn.hutool.core.collection.CollUtil;
import com.teaching.backend.api.CommonResult;
import com.teaching.backend.model.dto.UmsAdminParam;
import com.teaching.backend.model.dto.UpdateAdminPasswordParam;
import com.teaching.backend.model.entity.umsAdmin.UmsAdmin;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import com.teaching.backend.service.umsAdmin.UmsAdminService;
import com.teaching.backend.service.umsAdmin.UmsRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
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;
import java.util.stream.Collectors;
/**
* @Author:xhn
* @Date:2024-05-30-18:15
* @Description:login
*/
@RestController
@Api(tags = "UmsAdminController")
@RequestMapping("/user")
@Slf4j
public class UmsAdminController {
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;
@Autowired
private UmsAdminService umsAdminService;
@Autowired
private UmsRoleService umsRoleService;
@ApiOperation(value = "用户注册")
@PostMapping("/register")
public CommonResult<UmsAdmin> register(@Validated @RequestBody UmsAdminParam umsAdminParam) {
if (umsAdminParam == null) {
return CommonResult.failed();
}
UmsAdmin umsAdmin = umsAdminService.register(umsAdminParam);
return CommonResult.success(umsAdmin);
}
@ApiOperation(value = "登录以后返回token")
@PostMapping("/login")
public CommonResult login(@Validated @RequestBody UmsAdmin umsAdmin) {
String token = umsAdminService.login(umsAdmin.getUsername(), umsAdmin.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);
}
/**
* 发送短信
* @param phone
* @return
*/
@ApiOperation(value = "发送短信返回验证码")
@PostMapping("/code")
public CommonResult<String> sendVerifyCode(@RequestParam("phone")String phone){
return CommonResult.success(umsAdminService.sendVerifyCode(phone));
}
@ApiOperation(value = "手机号注册")
@PostMapping("/phone/register")
public CommonResult<UmsAdmin> phoneRegister(@Validated @RequestBody UmsAdminParam umsAdminParam) {
if (umsAdminParam == null) {
return CommonResult.failed();
}
UmsAdmin umsAdmin = umsAdminService.phoneRegister(umsAdminParam);
return CommonResult.success(umsAdmin);
}
@ApiOperation(value = "刷新token")
@GetMapping("/refreshToken")
public CommonResult refreshToken(HttpServletRequest request) {
String token = request.getHeader(tokenHeader);
String refreshToken = umsAdminService.refreshToken(token);
if (refreshToken == null) {
return CommonResult.failed("token已经过期!");
}
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", refreshToken);
tokenMap.put("tokenHead", tokenHead);
return CommonResult.success(tokenMap);
}
@ApiOperation(value = "获取当前登录用户信息")
@GetMapping ("/info")
public CommonResult getAdminInfo(Principal principal) {
if(principal == null){
return CommonResult.unauthorized(null);
}
String username = principal.getName();
UmsAdmin umsAdmin = umsAdminService.getAdminByUsername(username);
Map<String, Object> data = new HashMap<>();
data.put("id",umsAdmin.getId());
data.put("username", umsAdmin.getUsername());
data.put("menus", umsRoleService.getMenuList(umsAdmin.getId()));
data.put("phone", umsAdmin.getPhone());
data.put("nickName", umsAdmin.getNickName());
data.put("icon", umsAdmin.getIcon());
List<UmsRole> roleList = umsAdminService.getRoleList(umsAdmin.getId());
if(CollUtil.isNotEmpty(roleList)){
List<String> roles = roleList.stream().map(UmsRole::getName).collect(Collectors.toList());
data.put("roles",roles);
}
return CommonResult.success(data);
}
@ApiOperation("修改指定用户信息")
@PostMapping("/update")
public CommonResult updateUms(@RequestBody UmsAdmin umsadmin) {
boolean count = umsAdminService.updateUms(umsadmin);
if (count == true) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("修改指定用户密码")
@PostMapping("/updatePassword")
public CommonResult updatePassword(@Validated @RequestBody UpdateAdminPasswordParam updatePasswordParam) {
int status = umsAdminService.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();
}
}
}

@ -0,0 +1,33 @@
package com.teaching.backend.exception;
import com.teaching.backend.api.IErrorCode;
/**
* 自定义API异常
* Created by macro on 2020/2/27.
*/
public class ApiException extends RuntimeException {
private IErrorCode errorCode;
public ApiException(IErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
public ApiException(String message) {
super(message);
}
public ApiException(Throwable cause) {
super(cause);
}
public ApiException(String message, Throwable cause) {
super(message, cause);
}
public IErrorCode getErrorCode() {
return errorCode;
}
}

@ -0,0 +1,18 @@
package com.teaching.backend.exception;
import com.teaching.backend.api.IErrorCode;
/**
* 断言处理类用于抛出各种API异常
* Created by macro on 2020/2/27.
*/
public class Asserts {
public static void fail(String message) {
throw new ApiException(message);
}
public static void fail(IErrorCode errorCode) {
throw new ApiException(errorCode);
}
}

@ -0,0 +1,31 @@
package com.teaching.backend.exception;
import lombok.Getter;
@Getter
public class LyException extends RuntimeException {
/**
* 异常状态码信息
*/
private int status;
public LyException(int status) {
this.status = status;
}
public LyException(int status, String message) {
super(message);
this.status = status;
}
public LyException(int status, String message, Throwable cause) {
super(message, cause);
this.status = status;
}
public LyException(int status, Throwable cause) {
super(cause);
this.status = status;
}
}

@ -1,9 +0,0 @@
package com.teaching.backend.manager;
/**
* @Author:youhang
* @Date:2024-05-30-18:20
* @Description:
*/
public class test1 {
}

@ -0,0 +1,9 @@
package com.teaching.backend.mapper.umsAdmin;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.teaching.backend.model.entity.umsAdmin.UmsAdmin;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UmsAdminMapper extends BaseMapper<UmsAdmin> {
}

@ -0,0 +1,38 @@
package com.teaching.backend.mapper.umsAdmin;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.teaching.backend.model.entity.umsAdmin.UmsAdminRoleRelation;
import com.teaching.backend.model.entity.umsAdmin.UmsResource;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 后台用户与角色关系管理自定义Dao
* Created by macro on 2018/10/8.
*/
@Mapper
public interface UmsAdminRoleRelationMapper extends BaseMapper<UmsAdminRoleRelation> {
// /**
// * 批量插入用户角色关系
// */
// int insertList(@Param("list") List<UmsAdminRoleRelation> adminRoleRelationList);
/**
* 获取用于所有角色
*/
List<UmsRole> getRoleList(@Param("adminId") Long adminId);
/**
* 获取用户所有可访问资源
*/
List<UmsResource> getResourceList(@Param("adminId") Long adminId);
// /**
// * 获取资源相关用户ID列表
// */
// List<Long> getAdminIdList(@Param("resourceId") Long resourceId);
}

@ -0,0 +1,31 @@
package com.teaching.backend.mapper.umsAdmin;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.teaching.backend.model.entity.umsAdmin.UmsAdminRoleRelation;
import com.teaching.backend.model.entity.umsAdmin.UmsMenu;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 后台角色管理自定义Dao
* Created by macro on 2020/2/2.
*/
@Mapper
public interface UmsRoleMapper extends BaseMapper<UmsRole> {
/**
* 根据后台用户ID获取菜单
*/
List<UmsMenu> getMenuList(@Param("adminId") Long adminId);
// /**
// * 根据角色ID获取菜单
// */
// List<UmsMenu> getMenuListByRoleId(@Param("roleId") Long roleId);
// /**
// * 根据角色ID获取资源
// */
// List<UmsResource> getResourceListByRoleId(@Param("roleId") Long roleId);
}

@ -0,0 +1,30 @@
package com.teaching.backend.model.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("ums_admin")
public class UmsAdminParam implements Serializable {
//用户名
private String username;
//密码
private String password;
//手机号
private String phone;
//昵称
private String nickName;
//头像
private String icon;
}

@ -0,0 +1,22 @@
package com.teaching.backend.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 修改用户名密码参数
* Created by macro on 2019/10/9.
*/
@Data
public class UpdateAdminPasswordParam {
// @NotEmpty
@ApiModelProperty(value = "用户名", required = true)
private String username;
// @NotEmpty
@ApiModelProperty(value = "旧密码", required = true)
private String oldPassword;
// @NotEmpty
@ApiModelProperty(value = "新密码", required = true)
private String newPassword;
}

@ -1,96 +1,96 @@
package com.teaching.backend.model.entity.records; //package com.teaching.backend.model.entity.records;
//
//
import com.baomidou.mybatisplus.annotation.IdType; //import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; //import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; //import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; //import lombok.Data;
import lombok.EqualsAndHashCode; //import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; //import lombok.experimental.Accessors;
//
import java.time.LocalDateTime; //import java.time.LocalDateTime;
//
//
@Data //@Data
@EqualsAndHashCode(callSuper = false) //@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) //@Accessors(chain = true)
@TableName("learning_records") //@TableName("learning_records")
public class LearningRecords { //public class LearningRecords {
private static final long serialVersionUID = 1L; // private static final long serialVersionUID = 1L;
//
/** // /**
* 内部编号 // * 内部编号
*/ // */
@TableId(value = "id", type = IdType.ASSIGN_ID) // @TableId(value = "id", type = IdType.ASSIGN_ID)
private String id; // private String id;
//
/** // /**
* 用户id // * 用户id
*/ // */
private String userId; // private String userId;
//
/** // /**
* 课程id // * 课程id
*/ // */
private String coursesId; // private String coursesId;
/** // /**
* 章节id // * 章节id
*/ // */
private String chapterId; // private String chapterId;
/** // /**
* 知识点id // * 知识点id
*/ // */
private String knowledgePointId; // private String knowledgePointId;
/** // /**
* 资源id // * 资源id
*/ // */
private String resourceId; // private String resourceId;
/** // /**
* 访问时间 // * 访问时间
*/ // */
private LocalDateTime accessTime; // private LocalDateTime accessTime;
//
/** // /**
* 学习方式:打开; 1,打开过,2未打开 // * 学习方式:打开; 1,打开过,2未打开
*/ // */
private String learningMethod1; // private String learningMethod1;
/** // /**
* 学习方式:下载; 1下载过, 2未下载 // * 学习方式:下载; 1下载过, 2未下载
*/ // */
private String learningMethod2; // private String learningMethod2;
/** // /**
*视频学习时长 // *视频学习时长
*/ // */
private String videoDuration; // private String videoDuration;
//
/** // /**
*是否完成观看1已完成0未完成 // *是否完成观看:1,已完成,0未完成
*/ // */
private String isCompleted; // private String isCompleted;
//
/** // /**
* 记录封面图片 // * 记录封面图片
*/ // */
private String content; // private String content;
/** // /**
* 资源地址 // * 资源地址
*/ // */
private String address; // private String address;
//
/** // /**
* 是否存在: 1存在;0不存在; // * 是否存在: 1存在;0不存在;
*/ // */
private String status; // private String status;
/** // /**
* 类型, :1,课程; 2,章节; 3,知识点; 4,学习资源 // * 类型, 如:1,课程; 2,章节; 3,知识点; 4,学习资源
*/ // */
private String type; // private String type;
/** // /**
* 父节点 // * 父节点
*/ // */
private String parentNode; // private String parentNode;
//
//
//
//
} //}

@ -0,0 +1,64 @@
package com.teaching.backend.model.entity.umsAdmin;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* SpringSecurity需要的用户信息封装类
* Created by macro on 2018/4/26.
*/
public class AdminUserDetails implements UserDetails {
//后台用户
private final UmsAdmin umsAdmin;
//拥有资源列表
private final 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(resource ->new SimpleGrantedAuthority(resource.getId()+":"+resource.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,0 +1,39 @@
package com.teaching.backend.model.entity.umsAdmin;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@TableName("ums_admin")
public class UmsAdmin implements Serializable {
//主键
@TableId(type = IdType.AUTO)
private Long id;
//用户名
private String username;
//密码
private String password;
//手机号
private String phone;
//昵称
private String nickName;
//头像
private String icon;
//注册时间
private LocalDateTime createTime;
//账号状态
private Integer status;
}

@ -0,0 +1,860 @@
package com.teaching.backend.model.entity.umsAdmin;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class UmsAdminExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public UmsAdminExample() {
oredCriteria = new ArrayList<>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andIdIsNull() {
addCriterion("id is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("id is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Long value) {
addCriterion("id =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Long value) {
addCriterion("id <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Long value) {
addCriterion("id >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Long value) {
addCriterion("id >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Long value) {
addCriterion("id <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Long value) {
addCriterion("id <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Long> values) {
addCriterion("id in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Long> values) {
addCriterion("id not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Long value1, Long value2) {
addCriterion("id between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Long value1, Long value2) {
addCriterion("id not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andUsernameIsNull() {
addCriterion("username is null");
return (Criteria) this;
}
public Criteria andUsernameIsNotNull() {
addCriterion("username is not null");
return (Criteria) this;
}
public Criteria andUsernameEqualTo(String value) {
addCriterion("username =", value, "username");
return (Criteria) this;
}
public Criteria andUsernameNotEqualTo(String value) {
addCriterion("username <>", value, "username");
return (Criteria) this;
}
public Criteria andUsernameGreaterThan(String value) {
addCriterion("username >", value, "username");
return (Criteria) this;
}
public Criteria andUsernameGreaterThanOrEqualTo(String value) {
addCriterion("username >=", value, "username");
return (Criteria) this;
}
public Criteria andUsernameLessThan(String value) {
addCriterion("username <", value, "username");
return (Criteria) this;
}
public Criteria andUsernameLessThanOrEqualTo(String value) {
addCriterion("username <=", value, "username");
return (Criteria) this;
}
public Criteria andUsernameLike(String value) {
addCriterion("username like", value, "username");
return (Criteria) this;
}
public Criteria andUsernameNotLike(String value) {
addCriterion("username not like", value, "username");
return (Criteria) this;
}
public Criteria andUsernameIn(List<String> values) {
addCriterion("username in", values, "username");
return (Criteria) this;
}
public Criteria andUsernameNotIn(List<String> values) {
addCriterion("username not in", values, "username");
return (Criteria) this;
}
public Criteria andUsernameBetween(String value1, String value2) {
addCriterion("username between", value1, value2, "username");
return (Criteria) this;
}
public Criteria andUsernameNotBetween(String value1, String value2) {
addCriterion("username not between", value1, value2, "username");
return (Criteria) this;
}
public Criteria andPasswordIsNull() {
addCriterion("password is null");
return (Criteria) this;
}
public Criteria andPasswordIsNotNull() {
addCriterion("password is not null");
return (Criteria) this;
}
public Criteria andPasswordEqualTo(String value) {
addCriterion("password =", value, "password");
return (Criteria) this;
}
public Criteria andPasswordNotEqualTo(String value) {
addCriterion("password <>", value, "password");
return (Criteria) this;
}
public Criteria andPasswordGreaterThan(String value) {
addCriterion("password >", value, "password");
return (Criteria) this;
}
public Criteria andPasswordGreaterThanOrEqualTo(String value) {
addCriterion("password >=", value, "password");
return (Criteria) this;
}
public Criteria andPasswordLessThan(String value) {
addCriterion("password <", value, "password");
return (Criteria) this;
}
public Criteria andPasswordLessThanOrEqualTo(String value) {
addCriterion("password <=", value, "password");
return (Criteria) this;
}
public Criteria andPasswordLike(String value) {
addCriterion("password like", value, "password");
return (Criteria) this;
}
public Criteria andPasswordNotLike(String value) {
addCriterion("password not like", value, "password");
return (Criteria) this;
}
public Criteria andPasswordIn(List<String> values) {
addCriterion("password in", values, "password");
return (Criteria) this;
}
public Criteria andPasswordNotIn(List<String> values) {
addCriterion("password not in", values, "password");
return (Criteria) this;
}
public Criteria andPasswordBetween(String value1, String value2) {
addCriterion("password between", value1, value2, "password");
return (Criteria) this;
}
public Criteria andPasswordNotBetween(String value1, String value2) {
addCriterion("password not between", value1, value2, "password");
return (Criteria) this;
}
public Criteria andIconIsNull() {
addCriterion("icon is null");
return (Criteria) this;
}
public Criteria andIconIsNotNull() {
addCriterion("icon is not null");
return (Criteria) this;
}
public Criteria andIconEqualTo(String value) {
addCriterion("icon =", value, "icon");
return (Criteria) this;
}
public Criteria andIconNotEqualTo(String value) {
addCriterion("icon <>", value, "icon");
return (Criteria) this;
}
public Criteria andIconGreaterThan(String value) {
addCriterion("icon >", value, "icon");
return (Criteria) this;
}
public Criteria andIconGreaterThanOrEqualTo(String value) {
addCriterion("icon >=", value, "icon");
return (Criteria) this;
}
public Criteria andIconLessThan(String value) {
addCriterion("icon <", value, "icon");
return (Criteria) this;
}
public Criteria andIconLessThanOrEqualTo(String value) {
addCriterion("icon <=", value, "icon");
return (Criteria) this;
}
public Criteria andIconLike(String value) {
addCriterion("icon like", value, "icon");
return (Criteria) this;
}
public Criteria andIconNotLike(String value) {
addCriterion("icon not like", value, "icon");
return (Criteria) this;
}
public Criteria andIconIn(List<String> values) {
addCriterion("icon in", values, "icon");
return (Criteria) this;
}
public Criteria andIconNotIn(List<String> values) {
addCriterion("icon not in", values, "icon");
return (Criteria) this;
}
public Criteria andIconBetween(String value1, String value2) {
addCriterion("icon between", value1, value2, "icon");
return (Criteria) this;
}
public Criteria andIconNotBetween(String value1, String value2) {
addCriterion("icon not between", value1, value2, "icon");
return (Criteria) this;
}
public Criteria andEmailIsNull() {
addCriterion("email is null");
return (Criteria) this;
}
public Criteria andEmailIsNotNull() {
addCriterion("email is not null");
return (Criteria) this;
}
public Criteria andEmailEqualTo(String value) {
addCriterion("email =", value, "email");
return (Criteria) this;
}
public Criteria andEmailNotEqualTo(String value) {
addCriterion("email <>", value, "email");
return (Criteria) this;
}
public Criteria andEmailGreaterThan(String value) {
addCriterion("email >", value, "email");
return (Criteria) this;
}
public Criteria andEmailGreaterThanOrEqualTo(String value) {
addCriterion("email >=", value, "email");
return (Criteria) this;
}
public Criteria andEmailLessThan(String value) {
addCriterion("email <", value, "email");
return (Criteria) this;
}
public Criteria andEmailLessThanOrEqualTo(String value) {
addCriterion("email <=", value, "email");
return (Criteria) this;
}
public Criteria andEmailLike(String value) {
addCriterion("email like", value, "email");
return (Criteria) this;
}
public Criteria andEmailNotLike(String value) {
addCriterion("email not like", value, "email");
return (Criteria) this;
}
public Criteria andEmailIn(List<String> values) {
addCriterion("email in", values, "email");
return (Criteria) this;
}
public Criteria andEmailNotIn(List<String> values) {
addCriterion("email not in", values, "email");
return (Criteria) this;
}
public Criteria andEmailBetween(String value1, String value2) {
addCriterion("email between", value1, value2, "email");
return (Criteria) this;
}
public Criteria andEmailNotBetween(String value1, String value2) {
addCriterion("email not between", value1, value2, "email");
return (Criteria) this;
}
public Criteria andNickNameIsNull() {
addCriterion("nick_name is null");
return (Criteria) this;
}
public Criteria andNickNameIsNotNull() {
addCriterion("nick_name is not null");
return (Criteria) this;
}
public Criteria andNickNameEqualTo(String value) {
addCriterion("nick_name =", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameNotEqualTo(String value) {
addCriterion("nick_name <>", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameGreaterThan(String value) {
addCriterion("nick_name >", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameGreaterThanOrEqualTo(String value) {
addCriterion("nick_name >=", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameLessThan(String value) {
addCriterion("nick_name <", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameLessThanOrEqualTo(String value) {
addCriterion("nick_name <=", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameLike(String value) {
addCriterion("nick_name like", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameNotLike(String value) {
addCriterion("nick_name not like", value, "nickName");
return (Criteria) this;
}
public Criteria andNickNameIn(List<String> values) {
addCriterion("nick_name in", values, "nickName");
return (Criteria) this;
}
public Criteria andNickNameNotIn(List<String> values) {
addCriterion("nick_name not in", values, "nickName");
return (Criteria) this;
}
public Criteria andNickNameBetween(String value1, String value2) {
addCriterion("nick_name between", value1, value2, "nickName");
return (Criteria) this;
}
public Criteria andNickNameNotBetween(String value1, String value2) {
addCriterion("nick_name not between", value1, value2, "nickName");
return (Criteria) this;
}
public Criteria andNoteIsNull() {
addCriterion("note is null");
return (Criteria) this;
}
public Criteria andNoteIsNotNull() {
addCriterion("note is not null");
return (Criteria) this;
}
public Criteria andNoteEqualTo(String value) {
addCriterion("note =", value, "note");
return (Criteria) this;
}
public Criteria andNoteNotEqualTo(String value) {
addCriterion("note <>", value, "note");
return (Criteria) this;
}
public Criteria andNoteGreaterThan(String value) {
addCriterion("note >", value, "note");
return (Criteria) this;
}
public Criteria andNoteGreaterThanOrEqualTo(String value) {
addCriterion("note >=", value, "note");
return (Criteria) this;
}
public Criteria andNoteLessThan(String value) {
addCriterion("note <", value, "note");
return (Criteria) this;
}
public Criteria andNoteLessThanOrEqualTo(String value) {
addCriterion("note <=", value, "note");
return (Criteria) this;
}
public Criteria andNoteLike(String value) {
addCriterion("note like", value, "note");
return (Criteria) this;
}
public Criteria andNoteNotLike(String value) {
addCriterion("note not like", value, "note");
return (Criteria) this;
}
public Criteria andNoteIn(List<String> values) {
addCriterion("note in", values, "note");
return (Criteria) this;
}
public Criteria andNoteNotIn(List<String> values) {
addCriterion("note not in", values, "note");
return (Criteria) this;
}
public Criteria andNoteBetween(String value1, String value2) {
addCriterion("note between", value1, value2, "note");
return (Criteria) this;
}
public Criteria andNoteNotBetween(String value1, String value2) {
addCriterion("note not between", value1, value2, "note");
return (Criteria) this;
}
public Criteria andCreateTimeIsNull() {
addCriterion("create_time is null");
return (Criteria) this;
}
public Criteria andCreateTimeIsNotNull() {
addCriterion("create_time is not null");
return (Criteria) this;
}
public Criteria andCreateTimeEqualTo(Date value) {
addCriterion("create_time =", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotEqualTo(Date value) {
addCriterion("create_time <>", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeGreaterThan(Date value) {
addCriterion("create_time >", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeGreaterThanOrEqualTo(Date value) {
addCriterion("create_time >=", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeLessThan(Date value) {
addCriterion("create_time <", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeLessThanOrEqualTo(Date value) {
addCriterion("create_time <=", value, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeIn(List<Date> values) {
addCriterion("create_time in", values, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotIn(List<Date> values) {
addCriterion("create_time not in", values, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeBetween(Date value1, Date value2) {
addCriterion("create_time between", value1, value2, "createTime");
return (Criteria) this;
}
public Criteria andCreateTimeNotBetween(Date value1, Date value2) {
addCriterion("create_time not between", value1, value2, "createTime");
return (Criteria) this;
}
public Criteria andLoginTimeIsNull() {
addCriterion("login_time is null");
return (Criteria) this;
}
public Criteria andLoginTimeIsNotNull() {
addCriterion("login_time is not null");
return (Criteria) this;
}
public Criteria andLoginTimeEqualTo(Date value) {
addCriterion("login_time =", value, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeNotEqualTo(Date value) {
addCriterion("login_time <>", value, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeGreaterThan(Date value) {
addCriterion("login_time >", value, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeGreaterThanOrEqualTo(Date value) {
addCriterion("login_time >=", value, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeLessThan(Date value) {
addCriterion("login_time <", value, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeLessThanOrEqualTo(Date value) {
addCriterion("login_time <=", value, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeIn(List<Date> values) {
addCriterion("login_time in", values, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeNotIn(List<Date> values) {
addCriterion("login_time not in", values, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeBetween(Date value1, Date value2) {
addCriterion("login_time between", value1, value2, "loginTime");
return (Criteria) this;
}
public Criteria andLoginTimeNotBetween(Date value1, Date value2) {
addCriterion("login_time not between", value1, value2, "loginTime");
return (Criteria) this;
}
public Criteria andStatusIsNull() {
addCriterion("status is null");
return (Criteria) this;
}
public Criteria andStatusIsNotNull() {
addCriterion("status is not null");
return (Criteria) this;
}
public Criteria andStatusEqualTo(Integer value) {
addCriterion("status =", value, "status");
return (Criteria) this;
}
public Criteria andStatusNotEqualTo(Integer value) {
addCriterion("status <>", value, "status");
return (Criteria) this;
}
public Criteria andStatusGreaterThan(Integer value) {
addCriterion("status >", value, "status");
return (Criteria) this;
}
public Criteria andStatusGreaterThanOrEqualTo(Integer value) {
addCriterion("status >=", value, "status");
return (Criteria) this;
}
public Criteria andStatusLessThan(Integer value) {
addCriterion("status <", value, "status");
return (Criteria) this;
}
public Criteria andStatusLessThanOrEqualTo(Integer value) {
addCriterion("status <=", value, "status");
return (Criteria) this;
}
public Criteria andStatusIn(List<Integer> values) {
addCriterion("status in", values, "status");
return (Criteria) this;
}
public Criteria andStatusNotIn(List<Integer> values) {
addCriterion("status not in", values, "status");
return (Criteria) this;
}
public Criteria andStatusBetween(Integer value1, Integer value2) {
addCriterion("status between", value1, value2, "status");
return (Criteria) this;
}
public Criteria andStatusNotBetween(Integer value1, Integer value2) {
addCriterion("status not between", value1, value2, "status");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

@ -0,0 +1,18 @@
package com.teaching.backend.model.entity.umsAdmin;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("ums_admin_role_relation")
public class UmsAdminRoleRelation implements Serializable {
private Long id;
private Long adminId;
private Long roleId;
private static final long serialVersionUID = 1L;
}

@ -0,0 +1,41 @@
package com.teaching.backend.model.entity.umsAdmin;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("ums_menu")
public class UmsMenu implements Serializable {
private Long id;
@ApiModelProperty(value = "父级ID")
private Long parentId;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "菜单名称")
private String title;
@ApiModelProperty(value = "菜单级数")
private Integer level;
@ApiModelProperty(value = "菜单排序")
private Integer sort;
@ApiModelProperty(value = "前端名称")
private String name;
@ApiModelProperty(value = "前端图标")
private String icon;
@ApiModelProperty(value = "前端隐藏")
private Integer hidden;
private static final long serialVersionUID = 1L;
}

@ -0,0 +1,33 @@
package com.teaching.backend.model.entity.umsAdmin;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("ums_resource")
public class UmsResource implements Serializable {
private Long id;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "资源名称")
private String name;
@ApiModelProperty(value = "资源URL")
private String url;
@ApiModelProperty(value = "描述")
private String description;
@ApiModelProperty(value = "资源分类ID")
private Long categoryId;
// private static final long serialVersionUID = 1L;
}

@ -0,0 +1,33 @@
package com.teaching.backend.model.entity.umsAdmin;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("ums_role")
public class UmsRole implements Serializable {
private Long id;
@ApiModelProperty(value = "名称")
private String name;
@ApiModelProperty(value = "描述")
private String description;
@ApiModelProperty(value = "后台用户数量")
private Integer adminCount;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "启用状态:0->禁用;1->启用")
private Integer status;
private Integer sort;
private static final long serialVersionUID = 1L;
}

@ -1,9 +0,0 @@
package com.teaching.backend.model.enums;
/**
* @Author:youhang
* @Date:2024-05-30-18:20
* @Description:
*/
public class test1 {
}

@ -1,59 +1,59 @@
package com.teaching.backend.model.vo.records; //package com.teaching.backend.model.vo.records;
//
import lombok.Data; //import lombok.Data;
import lombok.EqualsAndHashCode; //import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; //import lombok.experimental.Accessors;
//
@Data //@Data
@EqualsAndHashCode(callSuper = false) //@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true) //@Accessors(chain = true)
public class LearningRecordsVo { //public class LearningRecordsVo {
// private static final long serialVersionUID = 1L; //// private static final long serialVersionUID = 1L;
//
/**
* 内部编号
*/
private String id;
/**
* 课程名称
*/
private String coursesName;
// /** // /**
// * 资源类型 // * 内部编号
// */ // */
// private String type; // private String id;
//
/**
* 封面
*/
private String content;
/**
* 资源观看人数
*/
private Long number;
/**
* 上次观看时间
*/
private String time;
/**
* 地址
*/
private String address;
// /** // /**
// * 创建日期 // * 课程名称
// */ // */
// private LocalDateTime createTime; // private String coursesName;
//
//// /**
//// * 资源类型
//// */
//// private String type;
// //
// /** // /**
// * 更新日期 // * 封面
// */ // */
// private LocalDateTime updateTime; // private String content;
//
// /**
// * 资源观看人数
} // */
// private Long number;
//
//
// /**
// * 上次观看时间
// */
// private String time;
// /**
// * 地址
// */
// private String address;
//// /**
//// * 创建日期
//// */
//// private LocalDateTime createTime;
////
//// /**
//// * 更新日期
//// */
//// private LocalDateTime updateTime;
//
//
//
//}

@ -1,9 +0,0 @@
package com.teaching.backend.model.vo;
/**
* @Author:youhang
* @Date:2024-05-30-18:20
* @Description:
*/
public class test1 {
}

@ -0,0 +1,74 @@
package com.teaching.backend.service.umsAdmin;
import com.baomidou.mybatisplus.extension.service.IService;
import com.teaching.backend.model.dto.UmsAdminParam;
import com.teaching.backend.model.dto.UpdateAdminPasswordParam;
import com.teaching.backend.model.entity.umsAdmin.UmsAdmin;
import com.teaching.backend.model.entity.umsAdmin.UmsResource;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.List;
public interface UmsAdminService extends IService<UmsAdmin> {
/**
* 注册功能
*/
UmsAdmin register(UmsAdminParam umsAdminParam);
/**
* 登录功能
* @param username 用户名
* @param password 密码
* @return 生成的JWT的token
*/
String login(String username, String password);
/**
* 根据用户名获取后台管理员
*/
UmsAdmin getAdminByUsername(String username);
/**
* 获取指定用户的可访问的资源
*/
List<UmsResource> getResourceList(Long adminId);
/**
* 获取用户信息
*/
UserDetails loadUserByUsername(String username);
/**
* 刷新token的功能
* @param oldToken 旧的token
*/
String refreshToken(String oldToken);
/**
* 获取用户对应角色
*/
List<UmsRole> getRoleList(Long adminId);
/**
* 修改指定用户信息
*/
boolean updateUms(UmsAdmin umsadmin);
/**
* 修改密码
*/
int updatePassword(UpdateAdminPasswordParam updatePasswordParam);
/**
* 发送短信
*/
String sendVerifyCode(String phone);
/**
* 手机号注册
*/
UmsAdmin phoneRegister(UmsAdminParam umsAdminParam);
}

@ -0,0 +1,21 @@
package com.teaching.backend.service.umsAdmin;
import com.teaching.backend.model.entity.umsAdmin.UmsMenu;
import com.teaching.backend.model.entity.umsAdmin.UmsResource;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 后台角色管理Service
* Created by macro on 2018/9/30.
*/
public interface UmsRoleService {
/**
* 根据管理员ID获取对应菜单
*/
List<UmsMenu> getMenuList(Long adminId);
}

@ -0,0 +1,271 @@
package com.teaching.backend.service.umsAdmin.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.teaching.backend.exception.Asserts;
import com.teaching.backend.exception.LyException;
import com.teaching.backend.mapper.umsAdmin.UmsAdminMapper;
import com.teaching.backend.mapper.umsAdmin.UmsAdminRoleRelationMapper;
import com.teaching.backend.model.dto.UmsAdminParam;
import com.teaching.backend.model.dto.UpdateAdminPasswordParam;
import com.teaching.backend.model.entity.umsAdmin.AdminUserDetails;
import com.teaching.backend.model.entity.umsAdmin.UmsAdmin;
import com.teaching.backend.model.entity.umsAdmin.UmsResource;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import com.teaching.backend.service.umsAdmin.UmsAdminService;
import com.teaching.backend.utils.JwtTokenUtil;
import com.teaching.backend.utils.RegexUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
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 com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
public class UmsAdminServiceImpl extends ServiceImpl<UmsAdminMapper, UmsAdmin> implements UmsAdminService {
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
private static final int USERNAME_LENGTH = 10; // 用户名长度
private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class);
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UmsAdminRoleRelationMapper adminRoleRelation;
@Autowired
private AmqpTemplate amqpTemplate;
@Autowired
private StringRedisTemplate redisTemplate;
private final String KEY_PREFIX = "ly:sms:phone:";
@Override
public UmsAdmin register(UmsAdminParam umsAdminParam) {
UmsAdmin umsAdmin = new UmsAdmin();
BeanUtils.copyProperties(umsAdminParam, umsAdmin);
umsAdmin.setCreateTime(LocalDateTime.now());
umsAdmin.setStatus(1);
//查询是否有相同用户名的用户
List<UmsAdmin> umsAdminList = lambdaQuery()
.eq(UmsAdmin::getUsername, umsAdmin.getUsername())
.list();
if (umsAdminList.size() > 0) {
return null;
}
//将密码进行加密操作
String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
umsAdmin.setPassword(encodePassword);
save(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);
} catch (AuthenticationException e) {
LOGGER.warn("登录异常:{}", e.getMessage());
}
return token;
}
@Override
public boolean updateUms(UmsAdmin umsadmin) {
if (umsadmin.getPassword().length() > 0){
Asserts.fail("修改操作错误1");
}
if (umsadmin.getCreateTime() != null){
Asserts.fail("修改操作错误2");
}
return updateById(umsadmin);
}
@Override
public int updatePassword(UpdateAdminPasswordParam param) {
if(StrUtil.isEmpty(param.getUsername())
||StrUtil.isEmpty(param.getOldPassword())
||StrUtil.isEmpty(param.getNewPassword())){
return -1;
}
List<UmsAdmin> adminList = lambdaQuery()
.eq(UmsAdmin::getUsername, param.getUsername())
.list();
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()));
updateById(umsAdmin);
return 1;
}
@Override
public String sendVerifyCode(String phone) {
if (!RegexUtils.isPhone(phone)) {
throw new LyException(400, "手机号格式错误");
}
UmsAdmin admin = lambdaQuery()
.eq(UmsAdmin::getPhone, phone)
.one();
if (admin != null){
// throw new ;
return null;
}
String code = RandomStringUtils.randomNumeric(5);
String ALIBABA_CLOUD_ACCESS_KEY_ID = "LTAI5tF7fcDC5VTj1cVWKDU6";
String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "T7kQwaOxqWgmKzTZkzpCaPVhJuaw4T";
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET);
IAcsClient client = new DefaultAcsClient(profile);
SendSmsRequest request = new SendSmsRequest();
request.setPhoneNumbers(phone);
request.setSignName("智慧系统");
request.setTemplateCode("SMS_468225027");
request.setTemplateParam("{\"code\":\""+code+"\"}");
try {
SendSmsResponse response = client.getAcsResponse(request);
System.out.println("11112"+new Gson().toJson(response));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
//存入,redis,存5min
this.redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
return code;
}
@Override
public UmsAdmin phoneRegister(UmsAdminParam umsAdminParam) {
UmsAdmin umsAdmin = new UmsAdmin();
BeanUtils.copyProperties(umsAdminParam, umsAdmin);
umsAdmin.setCreateTime(LocalDateTime.now());
umsAdmin.setStatus(1);
//查询是否有相同手机号的用户
List<UmsAdmin> umsAdminList = lambdaQuery()
.eq(UmsAdmin::getPhone,umsAdminParam.getPhone())
.list();
if (umsAdminList.size() > 0 ) {
return null;
}
//将密码进行加密操作
String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
umsAdmin.setUsername(randomUsername());
umsAdmin.setPassword(encodePassword);
save(umsAdmin);
return umsAdmin;
}
/*
随机生成用户名
*/
private String randomUsername(){
String username;
UmsAdmin newUsername = new UmsAdmin();
do {
UUID uuid = UUID.randomUUID();
// 这里只是简单地截取UUID的一部分作为用户名,但你可以根据需要进行更复杂的处理
username = uuid.toString().substring(0, 10); // 截取前10个字符作
newUsername = lambdaQuery().eq(UmsAdmin::getUsername, username)
.one();
} while ( newUsername != null); // 如果用户名已存在,则重新生成
return username;
}
@Override
public String refreshToken(String oldToken) {
return jwtTokenUtil.refreshHeadToken(oldToken);
}
@Override
public List<UmsRole> getRoleList(Long adminId) {
return adminRoleRelation.getRoleList(adminId);
}
@Override
public UmsAdmin getAdminByUsername(String username) {
//从数据库中获取
UmsAdmin admin = lambdaQuery().eq(UmsAdmin::getUsername, username)
.one();
if (admin != null) {
return admin;
}
return null;
}
@Override
public List<UmsResource> getResourceList(Long adminId) {
//从数据库中获取
List<UmsResource> resourceList = adminRoleRelation.getResourceList(adminId);
return resourceList;
}
@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("用户名或密码错误");
}
}

@ -0,0 +1,26 @@
package com.teaching.backend.service.umsAdmin.impl;
import com.teaching.backend.mapper.umsAdmin.UmsRoleMapper;
import com.teaching.backend.model.entity.umsAdmin.UmsMenu;
import com.teaching.backend.model.entity.umsAdmin.UmsRole;
import com.teaching.backend.service.umsAdmin.UmsRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 后台角色管理Service实现类
* Created by macro on 2018/9/30.
*/
@Service
public class UmsRoleServiceImpl implements UmsRoleService {
@Autowired
private UmsRoleMapper umsRoleMapper;
@Override
public List<UmsMenu> getMenuList(Long adminId) {
return umsRoleMapper.getMenuList(adminId);
}
}

@ -0,0 +1,169 @@
package com.teaching.backend.utils;
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,0 +1,32 @@
package com.teaching.backend.utils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.teaching.backend.constant.RegexPatterns;
public class RegexUtils {
/**
* 是否符合手机格式
* @param phone 要校验的手机号
* @return true:符合false不符合
*/
public static boolean isPhone(String phone){
return matches(phone, RegexPatterns.PHONE_REGEX);
}
/**
* 是否符合验证码格式
* @param code 要校验的验证码
* @return true:符合false不符合
*/
public static boolean isCodeValid(String code){
return matches(code, RegexPatterns.VERIFY_CODE_REGEX);
}
private static boolean matches(String str, String regex){
if (StringUtils.isBlank(str)) {
return false;
}
return str.matches(regex);
}
}

@ -0,0 +1,26 @@
package com.teaching.backend.utils;
/**
* ThreadLocal 工具类
*/
@SuppressWarnings("all")
public class ThreadLocalUtil {
//提供ThreadLocal对象,
private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();
//根据键获取值
public static <T> T get(){
return (T) THREAD_LOCAL.get();
}
//存储键值对
public static void set(Object value){
THREAD_LOCAL.set(value);
}
//清除ThreadLocal 防止内存泄漏
public static void remove(){
THREAD_LOCAL.remove();
}
}

@ -10,22 +10,52 @@ spring:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/teaching_db url: jdbc:mysql://localhost:3306/teaching_db
username: root username: root
password: 1234567788 password: root
mybatis: mybatis:
configuration: configuration:
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
mapper-locations:
- classpath:dao/*.xml # 自定义jwt key
- classpath*:com/**/mapper/*.xml jwt:
tokenHeader: Authorization #JWT存储的请求头
secret: mySecret #JWT加解密使用的密钥
expiration: 604800 #JWT的超期限时间(60*60*24)一天
tokenHead: Bearer #JWT负载中拿到开头
knife4j: knife4j:
enable: true enable: true
openapi: openapi:
title: "" title: 用户管理接口文档
version: 1.0 description: "用户管理接口文档"
concat: zjh
version: v1.0.0
group: group:
default: default:
group-name: default
api-rule: package api-rule: package
api-rule-resources: api-rule-resources:
- com.teaching.backend.controller - com.teaching.backend.controller
secure:
ignored:
urls: #安全路径白名单
- /swagger-ui/
- /swagger-resources/**
- /**/v2/api-docs
- /**/*.html
- /**/*.js
- /**/*.css
- /**/*.png
- /**/*.map
- /favicon.ico
- /actuator/**
- /druid/**
- /user/**
- /user/login
- /user/register
- /user/info
- /user/logout
- /minio/upload
mapper-locations:
- classpath:dao/*.xml
- classpath*:com/**/mapper/*.xml

@ -0,0 +1,44 @@
<?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.teaching.backend.mapper.umsAdmin.UmsAdminRoleRelationMapper">
<!-- &lt;!&ndash;批量新增回写主键支持&ndash;&gt;-->
<!-- <insert id="insertList">-->
<!-- INSERT INTO ums_admin_role_relation (admin_id, role_id) VALUES-->
<!-- <foreach collection="list" separator="," item="item" index="index">-->
<!-- (#{item.adminId,jdbcType=BIGINT},-->
<!-- #{item.roleId,jdbcType=BIGINT})-->
<!-- </foreach>-->
<!-- </insert>-->
<select id="getRoleList" resultType="com.teaching.backend.model.entity.umsAdmin.UmsRole">
select r.*
from ums_admin_role_relation ar left join ums_role r on ar.role_id = r.id
where ar.admin_id = #{adminId}
</select>
<select id="getResourceList" resultType="com.teaching.backend.model.entity.umsAdmin.UmsResource">
SELECT
ur.id id,
ur.create_time createTime,
ur.`name` `name`,
ur.url url,
ur.description description,
ur.category_id categoryId
FROM
ums_admin_role_relation ar
LEFT JOIN ums_role r ON ar.role_id = r.id
LEFT JOIN ums_role_resource_relation rrr ON r.id = rrr.role_id
LEFT JOIN ums_resource ur ON ur.id = rrr.resource_id
WHERE
ar.admin_id = #{adminId}
AND ur.id IS NOT NULL
GROUP BY
ur.id
</select>
<!-- <select id="getAdminIdList" resultType="java.lang.Long">-->
<!-- SELECT-->
<!-- DISTINCT ar.admin_id-->
<!-- FROM-->
<!-- ums_role_resource_relation rr-->
<!-- LEFT JOIN ums_admin_role_relation ar ON rr.role_id = ar.role_id-->
<!-- WHERE rr.resource_id=#{resourceId}-->
<!-- </select>-->
</mapper>

@ -0,0 +1,64 @@
<?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.teaching.backend.mapper.umsAdmin.UmsRoleMapper">
<select id="getMenuList" resultType="com.teaching.backend.model.entity.umsAdmin.UmsMenu">
SELECT
m.id id,
m.parent_id parentId,
m.create_time createTime,
m.title title,
m.level level,
m.sort sort,
m.name name,
m.icon icon,
m.hidden hidden
FROM
ums_admin_role_relation arr
LEFT JOIN ums_role r ON arr.role_id = r.id
LEFT JOIN ums_role_menu_relation rmr ON r.id = rmr.role_id
LEFT JOIN ums_menu m ON rmr.menu_id = m.id
WHERE
arr.admin_id = #{adminId}
AND m.id IS NOT NULL
GROUP BY
m.id
</select>
<!-- <select id="getMenuListByRoleId" resultType="com.teaching.backend.model.entity.umsAdmin.UmsMenu">-->
<!-- SELECT-->
<!-- m.id id,-->
<!-- m.parent_id parentId,-->
<!-- m.create_time createTime,-->
<!-- m.title title,-->
<!-- m.level level,-->
<!-- m.sort sort,-->
<!-- m.name name,-->
<!-- m.icon icon,-->
<!-- m.hidden hidden-->
<!-- FROM-->
<!-- ums_role_menu_relation rmr-->
<!-- LEFT JOIN ums_menu m ON rmr.menu_id = m.id-->
<!-- WHERE-->
<!-- rmr.role_id = #{roleId}-->
<!-- AND m.id IS NOT NULL-->
<!-- GROUP BY-->
<!-- m.id-->
<!-- </select>-->
<!-- <select id="getResourceListByRoleId" resultType="com.teaching.backend.model.entity.umsAdmin.UmsMenu">-->
<!-- SELECT-->
<!-- r.id id,-->
<!-- r.create_time createTime,-->
<!-- r.`name` `name`,-->
<!-- r.url url,-->
<!-- r.description description,-->
<!-- r.category_id categoryId-->
<!-- FROM-->
<!-- ums_role_resource_relation rrr-->
<!-- LEFT JOIN ums_resource r ON rrr.resource_id = r.id-->
<!-- WHERE-->
<!-- rrr.role_id = #{roleId}-->
<!-- AND r.id IS NOT NULL-->
<!-- GROUP BY-->
<!-- r.id-->
<!-- </select>-->
</mapper>
Loading…
Cancel
Save