├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── HELP.md ├── LICENSE ├── README.md ├── doc ├── docker │ └── volume │ │ ├── api_admin │ │ └── application.yml │ │ ├── api_portal │ │ └── application.yml │ │ ├── docker-compose-app.yml │ │ ├── docker-compose-env.yml │ │ ├── docker安装平台.md │ │ ├── mysql │ │ ├── conf │ │ │ └── my.cnf │ │ └── db │ │ │ ├── test_edu.sql │ │ │ ├── test_edu_data.sql │ │ │ ├── test_edu_division.sql │ │ │ └── test_edu_index.sql │ │ ├── oss │ │ └── portal_imgs │ │ │ └── .gitignore │ │ └── redis │ │ └── conf │ │ └── redis.conf ├── pdm │ ├── Workspace.sws │ ├── test_edu.pdb │ └── test_edu.pdm └── sql │ ├── test_edu.sql │ ├── test_edu_data.sql │ ├── test_edu_division.sql │ └── test_edu_index.sql ├── edu-api-admin ├── Dockerfile ├── pom.xml ├── proguard.cfg └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── langyastudio │ │ │ └── edu │ │ │ └── admin │ │ │ ├── Application.java │ │ │ ├── bean │ │ │ ├── bo │ │ │ │ ├── AccountUserDetails.java │ │ │ │ └── AuthStateRedisCache.java │ │ │ ├── dto │ │ │ │ ├── AccessConfParam.java │ │ │ │ ├── UserImportParam.java │ │ │ │ ├── UserManagerParam.java │ │ │ │ └── UserParam.java │ │ │ └── vo │ │ │ │ ├── TokenVO.java │ │ │ │ ├── UmsApiListVO.java │ │ │ │ └── UmsDivisionVO.java │ │ │ ├── common │ │ │ ├── conf │ │ │ │ ├── AliSmsConf.java │ │ │ │ └── PmsConf.java │ │ │ ├── data │ │ │ │ └── Define.java │ │ │ ├── middleware │ │ │ │ ├── ApplicationRunnerStart.java │ │ │ │ ├── LimitInterceptor.java │ │ │ │ ├── MonitorHealthIndicator.java │ │ │ │ └── ShutDownHook.java │ │ │ ├── service │ │ │ │ └── AliSmsService.java │ │ │ └── task │ │ │ │ ├── AsyncTask.java │ │ │ │ └── SchedulingTask.java │ │ │ ├── config │ │ │ ├── AccountSecurityConfig.java │ │ │ ├── DynamicSecurityImpl.java │ │ │ ├── MybatisConfig.java │ │ │ ├── RedisConfig.java │ │ │ ├── WebConfig.java │ │ │ └── WebSocketConfig.java │ │ │ ├── controller │ │ │ ├── IndexController.java │ │ │ ├── auth │ │ │ │ ├── AuthController.java │ │ │ │ ├── RoleController.java │ │ │ │ └── UserManagerController.java │ │ │ └── monitor │ │ │ │ └── LogController.java │ │ │ └── service │ │ │ ├── AuthService.java │ │ │ ├── BaseService.java │ │ │ ├── MonitorService.java │ │ │ ├── RoleService.java │ │ │ ├── SecurityService.java │ │ │ ├── base │ │ │ ├── BaseCacheService.java │ │ │ └── impl │ │ │ │ └── BaseCacheServiceImpl.java │ │ │ └── impl │ │ │ ├── AuthServiceImpl.java │ │ │ ├── BaseServiceImpl.java │ │ │ ├── MonitorServiceImpl.java │ │ │ ├── RoleServiceImpl.java │ │ │ └── SecurityServiceImpl.java │ └── resources │ │ ├── application-dev.yml │ │ ├── application-pro.yml │ │ ├── application.yml │ │ └── files │ │ └── import_user.xls │ └── test │ └── java │ └── com │ └── langyastudio │ └── edu │ └── admin │ └── AccountApplicationTests.java ├── edu-api-portal ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── langyastudio │ │ └── edu │ │ └── portal │ │ ├── Application.java │ │ ├── bean │ │ ├── bo │ │ │ ├── AccountUserDetails.java │ │ │ └── AuthStateRedisCache.java │ │ ├── dto │ │ │ ├── FindPwdParam.java │ │ │ ├── ImgCropParam.java │ │ │ ├── LoginDeviceParam.java │ │ │ ├── LoginParam.java │ │ │ ├── LoginVerifyParam.java │ │ │ ├── RegisterParam.java │ │ │ ├── UpdateAuthParam.java │ │ │ ├── UpdatePwdParam.java │ │ │ └── UserParam.java │ │ └── vo │ │ │ ├── JsSDKSignVO.java │ │ │ ├── OauthCacheVO.java │ │ │ ├── TokenVO.java │ │ │ └── UmsDivisionVO.java │ │ ├── common │ │ ├── conf │ │ │ ├── AliOssConf.java │ │ │ ├── AliSmsConf.java │ │ │ ├── LocalImgConf.java │ │ │ └── OauthConf.java │ │ ├── data │ │ │ └── Define.java │ │ ├── middleware │ │ │ ├── ApplicationRunnerStart.java │ │ │ ├── LimitInterceptor.java │ │ │ └── ShutDownHook.java │ │ └── service │ │ │ ├── AliSmsService.java │ │ │ ├── ImgService.java │ │ │ ├── MailService.java │ │ │ └── impl │ │ │ ├── AliOssImgServiceImpl.java │ │ │ └── LocalImgServiceImpl.java │ │ ├── config │ │ ├── AccountSecurityConfig.java │ │ ├── DynamicSecurityImpl.java │ │ ├── MybatisConfig.java │ │ ├── RedisConfig.java │ │ └── WebConfig.java │ │ ├── controller │ │ ├── IndexController.java │ │ ├── common │ │ │ ├── Auth2Controller.java │ │ │ ├── CommonController.java │ │ │ ├── MediaController.java │ │ │ └── PwdController.java │ │ └── user │ │ │ └── UserController.java │ │ └── service │ │ ├── Auth2Service.java │ │ ├── AuthService.java │ │ ├── BaseService.java │ │ ├── MonitorService.java │ │ ├── PwdService.java │ │ ├── SecurityService.java │ │ ├── UserService.java │ │ └── impl │ │ ├── Auth2ServieImpl.java │ │ ├── AuthServiceImpl.java │ │ ├── BaseServiceImpl.java │ │ ├── MonitorServiceImpl.java │ │ ├── PwdServiceImpl.java │ │ ├── SecurityServiceImpl.java │ │ └── UserServiceImpl.java │ └── resources │ ├── application-dev.yml │ ├── application-pro.yml │ └── application.yml ├── edu-common ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── langyastudio │ │ └── edu │ │ └── common │ │ ├── anno │ │ ├── Desensitization.java │ │ ├── InValue.java │ │ ├── LimitField.java │ │ ├── LogField.java │ │ └── PhoneOrEmpty.java │ │ ├── config │ │ ├── BaseMybatisConfig.java │ │ └── BaseRedisConfig.java │ │ ├── data │ │ ├── BasDefine.java │ │ ├── EC.java │ │ ├── IErrorCode.java │ │ ├── PageIn.java │ │ ├── PageInfo.java │ │ ├── ResultInfo.java │ │ ├── validator │ │ │ ├── GroupInsert.java │ │ │ ├── GroupUpdate.java │ │ │ ├── InValidator.java │ │ │ └── PhoneOrEmptyValidator.java │ │ └── wrapper │ │ │ └── RequestWrapper.java │ │ ├── entity │ │ ├── DesensitizationType.java │ │ ├── FileType.java │ │ ├── LimitType.java │ │ ├── UserAgentData.java │ │ └── WebLog.java │ │ ├── exception │ │ ├── ErrController.java │ │ ├── ExceptionHandle.java │ │ └── MyException.java │ │ ├── middleware │ │ ├── Interceptor │ │ │ ├── DesensitizationInterceptor.java │ │ │ └── RequestInterceptor.java │ │ ├── aop │ │ │ ├── AyncLog.java │ │ │ ├── JsonpResponseAdvice.java │ │ │ ├── LimitAspect.java │ │ │ └── WebLogAspect.java │ │ ├── filter │ │ │ └── CorsFilterBean.java │ │ └── handler │ │ │ ├── ArgumentResolver.java │ │ │ └── MybatisHandler.java │ │ ├── service │ │ └── LogService.java │ │ ├── third │ │ ├── AliOss.java │ │ ├── AliSms.java │ │ └── JavaMail.java │ │ └── util │ │ ├── AddressT.java │ │ ├── CaptchaT.java │ │ ├── CryptoT.java │ │ ├── FileT.java │ │ ├── MybatisCache.java │ │ ├── RedisT.java │ │ ├── SnowFlakeT.java │ │ ├── SpringContextT.java │ │ ├── ThreadPoolT.java │ │ ├── Tool.java │ │ ├── WebSocketT.java │ │ └── ZipT.java │ └── resources │ ├── ip2region │ └── ip2region.db │ ├── log4j2-spring.xml │ └── mybatis-config.xml ├── edu-db ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── langyastudio │ │ └── edu │ │ └── db │ │ ├── mapper │ │ ├── UmsApiMapper.java │ │ ├── UmsDivisionMapper.java │ │ ├── UmsLogsMapper.java │ │ ├── UmsRoleApisMapper.java │ │ ├── UmsRoleMapper.java │ │ ├── UmsUserAuthMapper.java │ │ ├── UmsUserLoginLogsMapper.java │ │ ├── UmsUserMapper.java │ │ ├── UmsUserOauthsMapper.java │ │ └── UmsUserRolesMapper.java │ │ └── model │ │ ├── UmsApi.java │ │ ├── UmsDivision.java │ │ ├── UmsLogs.java │ │ ├── UmsMessage.java │ │ ├── UmsRole.java │ │ ├── UmsRoleApis.java │ │ ├── UmsUser.java │ │ ├── UmsUserAuth.java │ │ ├── UmsUserLoginLogs.java │ │ ├── UmsUserOauths.java │ │ └── UmsUserRoles.java │ └── resources │ └── mapper │ ├── UmsApiMapper.xml │ ├── UmsDivisionMapper.xml │ ├── UmsLogsMapper.xml │ ├── UmsMessageMapper.xml │ ├── UmsRoleApisMapper.xml │ ├── UmsRoleMapper.xml │ ├── UmsUserAuthMapper.xml │ ├── UmsUserLoginLogsMapper.xml │ ├── UmsUserMapper.xml │ ├── UmsUserOauthsMapper.xml │ └── UmsUserRolesMapper.xml ├── edu-security ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── langyastudio │ └── edu │ └── security │ ├── annotation │ └── CacheException.java │ ├── aspect │ └── RedisCacheAspect.java │ ├── component │ ├── DynamicAccessDecisionManager.java │ ├── DynamicSecurityFilter.java │ ├── DynamicSecurityMetadataSource.java │ ├── DynamicSecurityService.java │ ├── JwtAuthenticationTokenFilter.java │ ├── RestAuthenticationEntryPoint.java │ └── RestfulAccessDeniedHandler.java │ ├── config │ ├── IgnoreUrlsConfig.java │ └── SecurityConfig.java │ └── util │ ├── JwtTokenUtil.java │ └── SpringContextUtil.java ├── mvnw ├── mvnw.cmd └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | !**/src/main/**/build/ 29 | !**/src/test/**/build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | logs/ 34 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacfins/spring-boot-2-api/2b62246ba1f113537767d294084c4c9da4b17807/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.1/apache-maven-3.8.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /HELP.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | 5 | For further reference, please consider the following sections: 6 | 7 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 8 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.5.3/maven-plugin/reference/html/) 9 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.5.3/maven-plugin/reference/html/#build-image) 10 | * [Spring Configuration Processor](https://docs.spring.io/spring-boot/docs/2.5.3/reference/htmlsingle/#configuration-metadata-annotation-processor) 11 | * [Spring Web](https://docs.spring.io/spring-boot/docs/2.5.3/reference/htmlsingle/#boot-features-developing-web-applications) 12 | * [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/2.5.3/reference/htmlsingle/#using-boot-devtools) 13 | 14 | ### Guides 15 | 16 | The following guides illustrate how to use some features concretely: 17 | 18 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) 19 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) 20 | * [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/) 21 | 22 | -------------------------------------------------------------------------------- /doc/docker/volume/oss/portal_imgs/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacfins/spring-boot-2-api/2b62246ba1f113537767d294084c4c9da4b17807/doc/docker/volume/oss/portal_imgs/.gitignore -------------------------------------------------------------------------------- /doc/pdm/Workspace.sws: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /edu-api-admin/Dockerfile: -------------------------------------------------------------------------------- 1 | # 该镜像需要依赖的基础镜像 2 | FROM openjdk:11 3 | LABEL 说明="edu-api-admin" 4 | 5 | # 指定维护者的名字 6 | MAINTAINER langyatudio <15589933912> 7 | 8 | # 声明服务运行在8002端口 9 | EXPOSE 8002 10 | 11 | ARG JAR_FILE 12 | # 将当前目录下的jar包复制到docker容器的/目录下 13 | ADD ${JAR_FILE} /edu-admin.jar 14 | 15 | # 指定docker容器启动时运行jar包 16 | ENTRYPOINT ["java", "-Duser.timezone=GMT+8", "-jar", "/edu-admin.jar", "--spring.profiles.active=pro"] 17 | -------------------------------------------------------------------------------- /edu-api-admin/proguard.cfg: -------------------------------------------------------------------------------- 1 | #所有类(包括接口)的方法参数不混淆(包括没被keep的),如果参数混淆了,mybatis的mapper参数绑定会出错(如#{id}) 2 | -keepattributes MethodParameters 3 | 4 | #入口程序类不能混淆,混淆会导致springboot启动不了 5 | -keep class com.langyastudio.edu.admin.Application { 6 | public static void main(java.lang.String[]); 7 | } 8 | 9 | #mybatis的mapper/实体类不混淆,否则会导致xml配置的mapper找不到 10 | -keep class com.langyastudio.edu.admin.dao.* 11 | -keeppackagenames com.langyastudio.edu.admin.dao 12 | 13 | #考虑到scanBasePackages,需要包名不被修改 14 | -keeppackagenames com.langyastudio.edu 15 | -keeppackagenames com.langyastudio.edu.admin.common 16 | 17 | 18 | #一些配置类比如datasource,aopconfig如果混淆会导致各种启动报错 19 | # 比如用@Pointcut("execution(public * com.langyastudio.edu.*.controller..*.*(..))") 20 | # 指定webLog方法对应的@Pointcut作为切入点,所以包的名字不能修改 21 | -keeppackagenames com.langyastudio.edu.*.controller.** 22 | -keep class com.langyastudio.edu.admin.config.* 23 | 24 | #保留Serializable序列化的类不被混淆 25 | #例如传入/输出的Bean属性 26 | -keepclassmembers class * implements java.io.Serializable {*;} 27 | 28 | #保留空的构造函数 29 | #-keepclassmembers class com.hacfin.* { 30 | # public (...); 31 | #} -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/Application.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.springframework.beans.factory.config.BeanDefinition; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.builder.SpringApplicationBuilder; 7 | import org.springframework.context.annotation.AnnotationBeanNameGenerator; 8 | import org.springframework.scheduling.annotation.EnableAsync; 9 | import org.springframework.scheduling.annotation.EnableScheduling; 10 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.util.Objects; 14 | 15 | /** 16 | * 后台入口文件 17 | */ 18 | @SpringBootApplication(scanBasePackages = {"com.langyastudio.edu.*"}) 19 | @EnableAsync 20 | @EnableScheduling 21 | @EnableRedisHttpSession 22 | public class Application 23 | { 24 | public static void main(String[] args) 25 | { 26 | new SpringApplicationBuilder(Application.class) 27 | .beanNameGenerator(new UniqueNameGenerator()) 28 | .run(args); 29 | 30 | //SpringApplication.run(Application.class, args); 31 | } 32 | 33 | 34 | /** 35 | * 由于需要混淆代码,混淆后类都是A B C,spring 默认是把A B C当成BeanName,BeanName又不能重复导致报错 36 | * 所以需要重新定义BeanName生成策略 37 | * 不能重写generateBeanName方法,因为有些Bean会自定义BeanName,所以这些情况还需要走原来的逻辑 38 | */ 39 | @Component("UniqueNameGenerator") 40 | public static class UniqueNameGenerator extends AnnotationBeanNameGenerator 41 | { 42 | /** 43 | * 重写buildDefaultBeanName 44 | * 其他情况(如自定义BeanName)还是按原来的生成策略,只修改默认(非其他情况)生成的BeanName带上包名 45 | */ 46 | @Override 47 | public @NotNull String buildDefaultBeanName(BeanDefinition definition) 48 | { 49 | //全限定类名 50 | return Objects.requireNonNull(definition.getBeanClassName()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/bo/AccountUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.bo; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import com.langyastudio.edu.db.model.UmsUserAuth; 5 | import org.springframework.security.core.GrantedAuthority; 6 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | 9 | import java.util.Collection; 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * SpringSecurity需要的用户详情 15 | */ 16 | public class AccountUserDetails implements UserDetails 17 | { 18 | private UmsUserAuth umsAdmin; 19 | private List resourceList; 20 | 21 | public AccountUserDetails(UmsUserAuth umsAdmin, List resourceList) 22 | { 23 | this.umsAdmin = umsAdmin; 24 | this.resourceList = resourceList; 25 | } 26 | 27 | @Override 28 | public Collection getAuthorities() 29 | { 30 | //返回当前用户的角色 31 | return resourceList.stream() 32 | .map(role -> new SimpleGrantedAuthority(role.getApiId() + ":" + role.getApiName())) 33 | .collect(Collectors.toList()); 34 | } 35 | 36 | @Override 37 | public String getPassword() 38 | { 39 | return umsAdmin.getPwd(); 40 | } 41 | 42 | @Override 43 | public String getUsername() 44 | { 45 | return umsAdmin.getUserName(); 46 | } 47 | 48 | @Override 49 | public boolean isAccountNonExpired() 50 | { 51 | return true; 52 | } 53 | 54 | @Override 55 | public boolean isAccountNonLocked() 56 | { 57 | return true; 58 | } 59 | 60 | @Override 61 | public boolean isCredentialsNonExpired() 62 | { 63 | return true; 64 | } 65 | 66 | @Override 67 | public boolean isEnabled() 68 | { 69 | return umsAdmin.getEnabled().equals(Byte.valueOf("1")); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/bo/AuthStateRedisCache.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.bo; 2 | 3 | import com.langyastudio.edu.common.util.RedisT; 4 | import me.zhyd.oauth.cache.AuthCacheConfig; 5 | import me.zhyd.oauth.cache.AuthStateCache; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * 扩展Redis版的state缓存 11 | */ 12 | @Component 13 | public class AuthStateRedisCache implements AuthStateCache 14 | { 15 | @Autowired 16 | RedisT redisT; 17 | 18 | /** 19 | * 存入缓存,默认3分钟 20 | * 21 | * @param key 缓存key 22 | * @param value 缓存内容 23 | */ 24 | @Override 25 | public void cache(String key, String value) 26 | { 27 | redisT.set(key, value, AuthCacheConfig.timeout); 28 | } 29 | 30 | /** 31 | * 存入缓存 32 | * 33 | * @param key 缓存key 34 | * @param value 缓存内容 35 | * @param timeout 指定缓存过期时间(毫秒) 36 | */ 37 | @Override 38 | public void cache(String key, String value, long timeout) 39 | { 40 | redisT.set(key, value, timeout); 41 | } 42 | 43 | /** 44 | * 获取缓存内容 45 | * 46 | * @param key 缓存key 47 | * 48 | * @return 缓存内容 49 | */ 50 | @Override 51 | public String get(String key) 52 | { 53 | return redisT.get(key); 54 | } 55 | 56 | /** 57 | * 是否存在key,如果对应key的value值已过期,也返回false 58 | * 59 | * @param key 缓存key 60 | * 61 | * @return true:存在key,并且value没过期;false:key不存在或者已过期 62 | */ 63 | @Override 64 | public boolean containsKey(String key) 65 | { 66 | return redisT.hasKey(key); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/dto/AccessConfParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.dto; 2 | 3 | import com.langyastudio.edu.admin.common.data.Define; 4 | import com.langyastudio.edu.common.anno.InValue; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | * 访问配置参数 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class AccessConfParam implements Serializable 18 | { 19 | /** 20 | * 注册 21 | */ 22 | @InValue 23 | private Integer register; 24 | 25 | /** 26 | * 微信登录 27 | */ 28 | @InValue 29 | private Integer weixin; 30 | 31 | /** 32 | * 钉钉登录 33 | */ 34 | @InValue 35 | private Integer dingding; 36 | 37 | /** 38 | * 默认登录方式 39 | */ 40 | @InValue(value = {Define.YES, Define.NO, "3"}) 41 | private Integer loginType; 42 | 43 | /** 44 | * 单点登录 45 | */ 46 | @InValue 47 | private Integer singleLogin; 48 | 49 | /** 50 | * 请求频率限制 51 | */ 52 | @InValue 53 | private Integer requestLimit; 54 | 55 | /** 56 | * 敏感词过滤 57 | */ 58 | @InValue 59 | private Integer sensitive; 60 | } 61 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/dto/UserImportParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.dto; 2 | 3 | import com.alibaba.excel.annotation.ExcelProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 基础数据类 12 | * 13 | * @author Jiaju Zhuang 14 | **/ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class UserImportParam implements Serializable 19 | { 20 | /** 21 | * 用户名 22 | */ 23 | @ExcelProperty("用户名(必填)") 24 | private String userName; 25 | /** 26 | * 姓名 27 | */ 28 | @ExcelProperty("姓名") 29 | private String fullName; 30 | /** 31 | * 手机号 32 | */ 33 | @ExcelProperty("手机号") 34 | private String phoneNumber; 35 | /** 36 | * 分校列表 37 | */ 38 | @ExcelProperty("学校名称") 39 | private String pgNames; 40 | /** 41 | * 班级Id号 42 | */ 43 | @ExcelProperty("班级ID") 44 | private String classesId; 45 | /** 46 | * 执行结果 47 | */ 48 | @ExcelProperty("结果") 49 | private String result; 50 | /** 51 | * 结果信息 52 | */ 53 | @ExcelProperty("结果信息") 54 | private String resultMsg; 55 | } 56 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/dto/UserManagerParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.Max; 8 | import javax.validation.constraints.Min; 9 | import javax.validation.constraints.Size; 10 | import java.io.Serializable; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class UserManagerParam implements Serializable 16 | { 17 | /** 18 | * 用户名 19 | */ 20 | @Size(min = 2, max = 20) 21 | private String userName; 22 | 23 | /** 24 | * 状态 25 | */ 26 | @Min(1) @Max(2) 27 | private Integer enabled; 28 | 29 | /** 30 | * 机构id 31 | */ 32 | @Size(min = 32, max = 32) 33 | private String schoolId; 34 | 35 | /** 36 | * 角色id 37 | */ 38 | @Size(min = 32, max = 500) 39 | private String roleIds; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/dto/UserParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.dto; 2 | 3 | import com.langyastudio.edu.common.anno.InValue; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.validation.constraints.*; 9 | import java.io.Serializable; 10 | import java.time.LocalDate; 11 | 12 | /** 13 | * 用户传入参数 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class UserParam implements Serializable 19 | { 20 | /** 21 | * 用户名 22 | */ 23 | @Size(min=2, max = 20) 24 | private String userName; 25 | 26 | /** 27 | * 昵称 28 | */ 29 | @Size(min=2, max = 20) 30 | private String nickName; 31 | 32 | /** 33 | * 姓名 34 | */ 35 | @Size(min=2, max = 20) 36 | private String fullName; 37 | 38 | /** 39 | * 性别 40 | */ 41 | @InValue(value = {"1", "2", "3"}) 42 | private Byte sex; 43 | 44 | /** 45 | * 用户头像 46 | */ 47 | @Size(max = 128) 48 | private String avator; 49 | 50 | /** 51 | * 行政区划代码 52 | */ 53 | @PositiveOrZero 54 | private Integer pcdId; 55 | 56 | /** 57 | * 联系地址 58 | */ 59 | @Size(max = 128) 60 | private String company; 61 | 62 | /** 63 | * 生日 64 | */ 65 | @PastOrPresent 66 | private LocalDate birthday; 67 | 68 | /** 69 | * 描述信息 70 | */ 71 | @Size(max = 128) 72 | private String description; 73 | } 74 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/vo/TokenVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * jwt 返回对象 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class TokenVO implements Serializable 16 | { 17 | /** 18 | * token 19 | */ 20 | private String token; 21 | 22 | /** 23 | * token 前缀 24 | */ 25 | private String tokenHead; 26 | } 27 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/vo/UmsApiListVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.vo; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.util.List; 10 | 11 | /** 12 | * @author langyastudio 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class UmsApiListVO implements Serializable 18 | { 19 | List roleApiInfos; 20 | } 21 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/bean/vo/UmsDivisionVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.bean.vo; 2 | import com.langyastudio.edu.db.model.UmsDivision; 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @EqualsAndHashCode(callSuper = true) 16 | public class UmsDivisionVO extends UmsDivision implements Serializable 17 | { 18 | private List children; 19 | 20 | private boolean hasParent = false; 21 | private boolean hasChild = false; 22 | 23 | public void initChildren() 24 | { 25 | children = new ArrayList<>(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/conf/AliSmsConf.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.conf; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | 8 | import java.io.Serializable; 9 | import java.util.Map; 10 | 11 | /** 12 | * yml 配置文件-aliyun-sms 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @ConfigurationProperties(prefix = "aliyun.sms") 18 | public class AliSmsConf implements Serializable 19 | { 20 | private String accessKey; 21 | private String accessSecret; 22 | 23 | //signName templateCode 24 | /** 25 | * 注册 26 | */ 27 | private Map register; 28 | /** 29 | * 登录 30 | */ 31 | private Map login; 32 | /** 33 | * 找密码 34 | */ 35 | private Map findPwd; 36 | /** 37 | * 修改手机号 38 | */ 39 | private Map modifyPhone; 40 | } 41 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/conf/PmsConf.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.conf; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * 资源配置 12 | * 13 | * @author jiangjiaxiong 14 | */ 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | @ConfigurationProperties(prefix = "langyastudio.disk.pms") 19 | public class PmsConf implements Serializable 20 | { 21 | /** 22 | * 根目录 23 | */ 24 | private String root; 25 | /** 26 | * windows 根目录 27 | */ 28 | private String winRoot; 29 | 30 | /** 31 | * 文件分片合成目录,需要注意win与linux的切换 32 | */ 33 | private String rootFile; 34 | /** 35 | * 文件转码目录,需要注意win与linux的切换 36 | */ 37 | private String rootMts; 38 | /** 39 | * 文件分片上传临时目录,需要注意win与linux的切换 40 | */ 41 | private String rootTmp; 42 | /** 43 | * 可直接浏览的最大图片大小 44 | */ 45 | private Long browseImgMaxSize; 46 | /** 47 | * 可转码的最大图片大小 48 | */ 49 | private Long cvtImgMaxSize; 50 | } 51 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/data/Define.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.data; 2 | 3 | import com.langyastudio.edu.common.data.BasDefine; 4 | 5 | /** 6 | * 常量与配置文件 7 | *

8 | * 注意:表字段的常量值定义到ORM 9 | */ 10 | public class Define extends BasDefine 11 | { 12 | /*-------------------------------------------------------------------------------------------------------------- */ 13 | // 常用常量定义 14 | /*-------------------------------------------------------------------------------------------------------------- */ 15 | public final static Integer SUCESSS = 1; 16 | 17 | //是 or 否 18 | public final static String YES = "1"; 19 | public final static String NO = "2"; 20 | public final static Integer YESI = 1; 21 | public final static Integer NOI = 2; 22 | 23 | //校验码 24 | public final static String VERITY_REGISTER = "1"; 25 | public final static String VERITY_MODIFY = "2"; 26 | public final static String VERITY_FINDPWD = "3"; 27 | public final static String VERITY_LOGIN = "4"; 28 | 29 | //直播类型 30 | public final static String LIVE_NOW = "1"; 31 | public final static String LIVE_WILL = "2"; 32 | public final static String LIVE_OVER = "3"; 33 | public final static String LIVE_ALL = "4"; 34 | 35 | //默认分页的起始位置 36 | public final static Integer PAGE_OFFSET = 0; 37 | //默认每页最大数量 38 | public final static Integer PAGE_MAX_SIZE = 500; 39 | 40 | /*-------------------------------------------------------------------------------------------------------------- */ 41 | // 资源 42 | /*-------------------------------------------------------------------------------------------------------------- */ 43 | //-超过2M再计算hash 44 | public final static Integer FILE_HASH_MIN_SIZE = 2097152; 45 | 46 | public final static String RESOURCE_MEDIA_NAME = "media"; 47 | } -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/middleware/ApplicationRunnerStart.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.middleware; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import lombok.extern.log4j.Log4j2; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.ApplicationArguments; 8 | import org.springframework.boot.ApplicationRunner; 9 | import org.springframework.context.ConfigurableApplicationContext; 10 | import org.springframework.core.annotation.Order; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.web.context.WebApplicationContext; 13 | 14 | import java.net.InetAddress; 15 | import java.util.Arrays; 16 | 17 | /** 18 | * 继承Application接口后项目启动时会按照执行顺序执行run方法 19 | * 通过设置Order的value来指定执行的顺序 值越小越先执行 20 | */ 21 | @Component 22 | @Log4j2 23 | @Order(value = 1) 24 | @RequiredArgsConstructor 25 | public class ApplicationRunnerStart implements ApplicationRunner 26 | { 27 | private final ConfigurableApplicationContext context; 28 | 29 | @Autowired 30 | WebApplicationContext applicationContext; 31 | 32 | @Value("${server.port}") 33 | Integer port; 34 | 35 | @Override 36 | public void run(ApplicationArguments args) throws Exception 37 | { 38 | if (context.isActive()) 39 | { 40 | String[] activeProfiles = applicationContext.getEnvironment().getActiveProfiles(); 41 | InetAddress address = InetAddress.getLocalHost(); 42 | String url = String.format("http://%s:%s", address.getHostAddress(), port); 43 | 44 | log.info(" __ ___ _ ___ _ ____ _____ ____ "); 45 | log.info("/ /` / / \\ | |\\/| | |_) | | | |_ | | | |_ "); 46 | log.info("\\_\\_, \\_\\_/ |_| | |_| |_|__ |_|__ |_| |_|__ "); 47 | log.info(" "); 48 | System.out.println("后台-运行环境:" + Arrays.toString(activeProfiles)); 49 | log.info("后台-系统启动完毕,地址:{}", url); 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/middleware/MonitorHealthIndicator.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.middleware; 2 | 3 | import org.springframework.boot.actuate.health.Health; 4 | import org.springframework.boot.actuate.health.HealthIndicator; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * actuator health 9 | * @author langyastudio 10 | */ 11 | @Component 12 | public class MonitorHealthIndicator implements HealthIndicator 13 | { 14 | @Override 15 | public Health health() 16 | { 17 | //Health.down(); 18 | return Health.up() 19 | .withDetail("error", "very good") 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/middleware/ShutDownHook.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.middleware; 2 | 3 | import lombok.extern.log4j.Log4j2; 4 | import org.springframework.context.ApplicationEvent; 5 | import org.springframework.context.event.ContextClosedEvent; 6 | import org.springframework.context.event.EventListener; 7 | import org.springframework.lang.NonNull; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * 退出进程 12 | */ 13 | @Log4j2 14 | @Component 15 | public class ShutDownHook 16 | { 17 | @EventListener(classes = {ContextClosedEvent.class}) 18 | public void onApplicationClosed(@NonNull ApplicationEvent event) 19 | { 20 | log.info("后台-系统已关闭"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/task/AsyncTask.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.task; 2 | 3 | import lombok.extern.log4j.Log4j2; 4 | import org.springframework.scheduling.annotation.Async; 5 | import org.springframework.scheduling.annotation.AsyncResult; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.util.concurrent.ListenableFuture; 8 | 9 | @Component 10 | @Log4j2 11 | public class AsyncTask 12 | { 13 | /** 14 | * 使用自定义的 ThreadPoolTaskExecutor 15 | * @param i 16 | */ 17 | @Async("customTaskExecutor") 18 | public ListenableFuture loopPrint(Integer i) 19 | { 20 | String res = "async task:" + i; 21 | log.info(res); 22 | return new AsyncResult<>(res); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/common/task/SchedulingTask.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.common.task; 2 | 3 | import lombok.extern.log4j.Log4j2; 4 | import org.springframework.scheduling.annotation.Scheduled; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * 计划任务 9 | * 10 | * @author langyastudio 11 | */ 12 | @Log4j2 13 | @Component 14 | public class SchedulingTask 15 | { 16 | @Scheduled(fixedRate = 60000) 17 | public void fixedRateSchedule() 18 | { 19 | log.info("每 60 秒钟执行fixedRate..."); 20 | } 21 | 22 | 23 | /** 24 | * initialDelay 延迟 5 秒后开始执行该任务 25 | */ 26 | @Scheduled(initialDelay = 5000, fixedDelayString = "${langyastudio.task.fixedDelaySchedule:10000}") 27 | public void fixedDelaySchedule() 28 | { 29 | log.info("在上次任务完成 10 秒后执行fixedDelay..."); 30 | } 31 | 32 | /** 33 | * cron 表达式 34 | */ 35 | @Scheduled(cron = "*/30 * * * * *") 36 | public void cronchedule() 37 | { 38 | log.info("每30秒执行cron..."); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/config/AccountSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.config; 2 | 3 | import com.langyastudio.edu.admin.service.SecurityService; 4 | import com.langyastudio.edu.security.config.SecurityConfig; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | 12 | /** 13 | * Spring Security模块相关配置 14 | */ 15 | @Configuration 16 | @EnableWebSecurity 17 | @EnableGlobalMethodSecurity(prePostEnabled = true) 18 | public class AccountSecurityConfig extends SecurityConfig 19 | { 20 | @Autowired 21 | private SecurityService securityService; 22 | 23 | @Bean 24 | @Override 25 | public UserDetailsService userDetailsService() 26 | { 27 | //获取登录用户信息 28 | return username -> securityService.loadUserByUsername(username); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/config/DynamicSecurityImpl.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.config; 2 | 3 | import com.langyastudio.edu.admin.service.SecurityService; 4 | import com.langyastudio.edu.db.model.UmsApi; 5 | import com.langyastudio.edu.security.component.DynamicSecurityService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.access.ConfigAttribute; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | /** 15 | * Spring Dynamic Security 16 | * 17 | * @author langyastudio 18 | */ 19 | @Service("dynamicSecurityService") 20 | public class DynamicSecurityImpl implements DynamicSecurityService 21 | { 22 | @Autowired 23 | private SecurityService securityService; 24 | 25 | /** 26 | * 加载资源ANT通配符和资源对应MAP 27 | */ 28 | @Override 29 | public Map loadDataSource() 30 | { 31 | Map map = new ConcurrentHashMap<>(); 32 | List resourceList = securityService.getAuthListAll(); 33 | for (UmsApi resource : resourceList) 34 | { 35 | map.put(resource.getApiUrl(), 36 | new org.springframework.security.access.SecurityConfig(resource.getApiId() + ":" + resource.getApiName())); 37 | } 38 | 39 | return map; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/config/MybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.config; 2 | 3 | import com.langyastudio.edu.common.config.BaseMybatisConfig; 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.transaction.annotation.EnableTransactionManagement; 7 | 8 | 9 | /** 10 | * Mybatis Plus 11 | */ 12 | @Configuration 13 | @EnableTransactionManagement 14 | @MapperScan({"com.langyastudio.edu.db.mapper", "com.langyastudio.edu.admin.dao"}) 15 | public class MybatisConfig extends BaseMybatisConfig 16 | { 17 | 18 | } -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.config; 2 | 3 | import com.langyastudio.edu.common.config.BaseRedisConfig; 4 | import org.springframework.cache.annotation.EnableCaching; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * redis配置类 9 | */ 10 | @Configuration 11 | @EnableCaching 12 | public class RedisConfig extends BaseRedisConfig 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/config/WebSocketConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.scheduling.TaskScheduler; 6 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 7 | import org.springframework.web.socket.server.standard.ServerEndpointExporter; 8 | 9 | /** 10 | * websocket 配置 11 | */ 12 | @Configuration 13 | public class WebSocketConfig 14 | { 15 | /** 16 | * ServerEndpointExporter 用于扫描和注册所有携带 ServerEndPoint 注解的实例, 17 | * 若部署到外部容器 则无需提供此类。 18 | */ 19 | public ServerEndpointExporter serverEndpointExporter() 20 | { 21 | return new ServerEndpointExporter(); 22 | } 23 | 24 | // 解决 不能同时使用websocket和spring的定时注解 25 | @Bean 26 | public TaskScheduler taskScheduler() 27 | { 28 | ThreadPoolTaskScheduler scheduling = new ThreadPoolTaskScheduler(); 29 | scheduling.setPoolSize(10); 30 | scheduling.initialize(); 31 | 32 | return scheduling; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.controller; 2 | 3 | import com.langyastudio.edu.common.data.ResultInfo; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * 根访问 12 | */ 13 | @RestController 14 | @RequestMapping("/") 15 | public class IndexController 16 | { 17 | /** 18 | * 当前版本 19 | */ 20 | @Value("${spring.application.version}") 21 | private String serviceVersion; 22 | 23 | /** 24 | * 打包时间 25 | */ 26 | @Value("${spring.application.package-time}") 27 | private String serviceBuildDate; 28 | 29 | /** 30 | * 主页 31 | */ 32 | @RequestMapping("/") 33 | public ResultInfo index() 34 | { 35 | return ResultInfo.data(Map.of("name", "admin api", 36 | "version", serviceVersion, 37 | "time", serviceBuildDate, 38 | "company", "郎涯工作室", 39 | "official", "https://langyastudio.blog.csdn.net/", 40 | "maintainer", "langyastudio 「15589933912」")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/controller/auth/AuthController.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.controller.auth; 2 | 3 | import com.langyastudio.edu.admin.service.AuthService; 4 | import com.langyastudio.edu.common.anno.LogField; 5 | import com.langyastudio.edu.common.data.ResultInfo; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.validation.annotation.Validated; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | import javax.validation.Valid; 12 | import javax.validation.constraints.Size; 13 | import java.util.Map; 14 | 15 | /** 16 | * 权限管理 17 | */ 18 | @Log4j2 19 | @Validated 20 | @RestController 21 | @RequestMapping("/admin/auth/auth") 22 | public class AuthController 23 | { 24 | @Autowired 25 | AuthService authService; 26 | 27 | /** 28 | * 获取权限列表 29 | * 30 | * @param roleId 权限Id号 31 | * 32 | * @return 33 | */ 34 | @GetMapping("/get_list") 35 | public ResultInfo getList(@Valid @RequestParam(value = "role_id") @Size(min = 32, max = 32) String roleId) 36 | { 37 | //登录验证 38 | String userName = authService.getUserName(true); 39 | 40 | return ResultInfo.data(authService.getAuthListByRoleId(roleId)); 41 | } 42 | 43 | /** 44 | * 修改角色权限 45 | * 46 | * @param roleApis 参数 47 | * role_id 角色id号 48 | * api_ids 权限列表(多个使用竖杠分割) 49 | * 50 | * @return 51 | */ 52 | @PostMapping("/set_rules") 53 | @LogField("修改角色权限") 54 | public ResultInfo setRules(@Valid @RequestBody Map roleApis) 55 | { 56 | //登录验证 57 | String userName = authService.getUserName(true); 58 | 59 | authService.setAuthByRoleId(roleApis.get("role_id"), roleApis.get("api_ids")); 60 | return ResultInfo.data(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/service/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.service; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import com.langyastudio.edu.common.data.PageInfo; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * 权限管理 10 | */ 11 | public interface AuthService extends BaseService 12 | { 13 | /*-------------------------------------------------------------------------------------------------------------- */ 14 | // 权限管理 15 | /*-------------------------------------------------------------------------------------------------------------- */ 16 | /** 17 | * 根据角色Id号获取API权限列表 18 | * 19 | * @param roleId 角色Id号 20 | * 21 | * @return 22 | */ 23 | PageInfo getAuthListByRoleId(String roleId); 24 | 25 | /** 26 | * 设置角色映射的API权限列表 27 | * 28 | * @param roleId 角色Id号 29 | * @param apiIds API权限Id号列表 30 | * 31 | * @return 32 | */ 33 | Integer setAuthByRoleId(String roleId, String apiIds); 34 | 35 | /*-------------------------------------------------------------------------------------------------------------- */ 36 | // 用户管理 37 | /*-------------------------------------------------------------------------------------------------------------- */ 38 | 39 | /** 40 | * 系统用户列表 41 | * 42 | * @param roleId 角色Id号 43 | * @param userNameKey 用户名关键字 44 | * @param phoneKey 电话号码关键字 45 | * @param fullNameKey 姓名关键字 46 | * @param isAsc 是否升序 47 | * @param offset 页码 48 | * @param pageSize 页数 49 | * 50 | * @return 51 | */ 52 | PageInfo> getUserList(String roleId, String userNameKey, String fullNameKey, String phoneKey, 53 | Integer isAsc, Integer offset, Integer pageSize); 54 | 55 | /** 56 | * 设置用户映射的角色 57 | * 58 | * @param userName 用户名 59 | * @param roleIds 角色Id号列表 60 | * @param schoolId 机构Id号 61 | * 62 | * @return 63 | */ 64 | Integer setUserRoles(String userName, String roleIds, String schoolId); 65 | 66 | /** 67 | * 修改系统用户 68 | * 69 | * @param userName 用户名 70 | * @param fullName 姓名 71 | * @param phone 手机号 72 | * @param sex 性别 73 | * 74 | * @return 75 | */ 76 | Integer modifyUser(String userName, String fullName, String phone, Integer sex); 77 | 78 | /** 79 | * 重置密码 80 | * 81 | * @param userName 用户名 82 | * 83 | * @return 84 | */ 85 | Integer resetPwd(String userName); 86 | } 87 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/service/BaseService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.service; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 基类 7 | */ 8 | public interface BaseService 9 | { 10 | /*-------------------------------------------------------------------------------------------------------------- */ 11 | // 机构 12 | /*-------------------------------------------------------------------------------------------------------------- */ 13 | /** 14 | * 获取登录用户名 15 | * 16 | * @param bNeedLogin 未登录是否抛出异常 17 | * 18 | * @return 用户名 19 | */ 20 | String getUserName(boolean bNeedLogin); 21 | 22 | /** 23 | * 添加系统用户 24 | * 25 | * @param userName 用户名 26 | * @param fullName 姓名 27 | * @param phone 手机号 28 | * 29 | * @return 30 | */ 31 | Map addSystemUser(String userName, String pwd, String fullName, String phone, Integer sex, 32 | Byte userType, Integer checkUserName); 33 | 34 | /** 35 | * 启用禁用用户 36 | * 37 | * @param enabled 状态 38 | * 39 | * @return 40 | */ 41 | Integer enableUser(String userName, Integer enabled); 42 | 43 | /** 44 | * 修改用户在机构或系统中的角色 45 | * 46 | * @param userName 用户名 47 | * @param roleIds 角色id号列表 48 | * @param schoolId 机构Id号 49 | * @param bDelete 是否删除角色 50 | * @param bInsert 是否新增角色 51 | * 52 | * @return 53 | */ 54 | Integer modifyUserRoleIds(String userName, String roleIds, String schoolId, boolean bDelete, boolean bInsert); 55 | } 56 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/service/MonitorService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.service; 2 | 3 | import com.langyastudio.edu.db.model.UmsUserLoginLogs; 4 | import com.langyastudio.edu.common.data.PageInfo; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.Map; 8 | 9 | /** 10 | * 监控服务 - 日志、监控、系统信息等 11 | */ 12 | public interface MonitorService extends BaseService 13 | { 14 | /*-------------------------------------------------------------------------------------------------------------- */ 15 | // 日志 16 | /*-------------------------------------------------------------------------------------------------------------- */ 17 | 18 | /** 19 | * 获取登录日志列表 20 | * 21 | * @param userName 用户名 22 | * @param offSet offSet 23 | * @param pageSize pageSize 24 | * 25 | * @return 26 | */ 27 | PageInfo getLogLoginList(String userName, Integer offSet, Integer pageSize); 28 | 29 | /** 30 | * 获取系统日志列表 31 | * 32 | * @param userNameKey 用户名关键字 33 | * @param fullNameKey 姓名关键字 34 | * @param phoneKey 电话号码关键字 35 | * @param startTime 开始时间 36 | * @param endTime 结束时间 37 | * @param offSet offset 38 | * @param pageSize pagesize 39 | * 40 | * @return 41 | */ 42 | PageInfo> getLogSystemList(String userNameKey, String fullNameKey, String phoneKey, 43 | LocalDateTime startTime, LocalDateTime endTime, 44 | Integer offSet, Integer pageSize); 45 | 46 | /*-------------------------------------------------------------------------------------------------------------- */ 47 | // 系统信息 48 | /*-------------------------------------------------------------------------------------------------------------- */ 49 | 50 | 51 | 52 | /*-------------------------------------------------------------------------------------------------------------- */ 53 | // 监控 54 | /*-------------------------------------------------------------------------------------------------------------- */ 55 | 56 | /** 57 | * 用户活跃度 58 | * 59 | * @param schoolId 60 | * @param startTime 61 | * @param endTime 62 | * @param offSet 63 | * @param pageSize 64 | * @return 65 | */ 66 | PageInfo> getLogUserList(String schoolId, LocalDateTime startTime, LocalDateTime endTime, 67 | Integer offSet, Integer pageSize); 68 | } 69 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/service/RoleService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.service; 2 | 3 | import com.langyastudio.edu.db.model.UmsRole; 4 | import com.langyastudio.edu.common.data.PageInfo; 5 | import com.langyastudio.edu.common.exception.MyException; 6 | 7 | /** 8 | * 角色管理业务逻辑层 9 | */ 10 | public interface RoleService extends BaseService 11 | { 12 | /** 13 | * 获取角色信息 14 | * 15 | * @param roleId 角色Id号 16 | * 17 | * @return UmsRole 18 | */ 19 | UmsRole getInfo(String roleId); 20 | 21 | /** 22 | * 获取角色列表 23 | * 24 | * @param isSystem 是否是系统角色 25 | * @param isAsc 是否升序 26 | * 27 | * @return 28 | */ 29 | PageInfo getList(Integer isSystem, Integer isAsc, Integer offSet, Integer pageSize); 30 | 31 | /** 32 | * 添加角色 33 | * 34 | * @param roleName 角色名称 35 | * @param viewSystem 是否访问系统 36 | * @param viewSchool 是否访问机构 37 | * @param isSystem 是否系统角色 38 | * @param description 描述信息 39 | * 40 | * @return UmsRole 41 | */ 42 | UmsRole add(String roleName, Integer viewSystem, Integer viewSchool, Integer isSystem, String description) throws MyException; 43 | 44 | /** 45 | * 修改角色 46 | * 47 | * @param roleName 角色名称 48 | * @param viewSystem 是否访问系统 49 | * @param viewSchool 是否访问机构 50 | * @param description 描述信息 51 | * 52 | * @return 53 | */ 54 | Integer modify(String roleId, String roleName, Integer viewSystem, Integer viewSchool, String description) throws MyException; 55 | 56 | /** 57 | * 移动角色 58 | * 59 | * @param roleId 原始role Id号 60 | * @param desId 目的role Id号 61 | * 62 | * @return 63 | */ 64 | Integer moveTo(String roleId, String desId) throws MyException; 65 | 66 | /** 67 | * 角色是否存在 68 | * 69 | * @param roleName 角色名称 70 | * @param isSystem 是否是系统角色 71 | * 72 | * @return 73 | */ 74 | Integer existName(String roleName, Integer isSystem); 75 | 76 | /** 77 | * 删除角色 78 | * 79 | * @param roleId 角色Id号 80 | * 81 | * @return 82 | */ 83 | Integer del(String roleId); 84 | 85 | } 86 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/service/SecurityService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.service; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Spring security 10 | * 11 | * @author jiangjiaxiong 12 | */ 13 | public interface SecurityService 14 | { 15 | /** 16 | * 是否是admin 17 | * 18 | * @param userName 用户名 19 | * 20 | * @return bool 21 | */ 22 | Boolean isAdmin(String userName); 23 | 24 | /*-------------------------------------------------------------------------------------------------------------- */ 25 | // Spring security 26 | /*-------------------------------------------------------------------------------------------------------------- */ 27 | 28 | /** 29 | * 根据角色Id号获取API权限列表 30 | * 31 | * @return 32 | */ 33 | List getAuthListAll(); 34 | 35 | /** 36 | * 获取某个用户的权限列表 37 | * 38 | * @param userName 用户名 39 | * 40 | * @return 41 | */ 42 | List getAuthListAll(String userName, String schoolId); 43 | 44 | /** 45 | * 获取用户信息 46 | */ 47 | UserDetails loadUserByUsername(String userName); 48 | } 49 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/java/com/langyastudio/edu/admin/service/base/BaseCacheService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin.service.base; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 用户缓存操作 Service 9 | * 10 | * @author jiangjiaxiong 11 | */ 12 | public interface BaseCacheService 13 | { 14 | /** 15 | * 根据角色Id号获取权限列表 16 | * 17 | * @param roleIds 角色Id号列表 18 | */ 19 | List getApiListByRoleIds(List roleIds); 20 | 21 | /** 22 | * 当角色改变时删除缓存 23 | * @param roleIds 角色Id号列表 24 | */ 25 | void delApiListByRoleIds(List roleIds); 26 | } 27 | -------------------------------------------------------------------------------- /edu-api-admin/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | version: @project.version@ 4 | package-time: @package-time@ -------------------------------------------------------------------------------- /edu-api-admin/src/main/resources/application-pro.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | version: @project.version@ 4 | package-time: @package-time@ -------------------------------------------------------------------------------- /edu-api-admin/src/main/resources/files/import_user.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacfins/spring-boot-2-api/2b62246ba1f113537767d294084c4c9da4b17807/edu-api-admin/src/main/resources/files/import_user.xls -------------------------------------------------------------------------------- /edu-api-admin/src/test/java/com/langyastudio/edu/admin/AccountApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.admin; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class AccountApplicationTests 8 | { 9 | @Test 10 | void contextLoads() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /edu-api-portal/Dockerfile: -------------------------------------------------------------------------------- 1 | # 该镜像需要依赖的基础镜像 2 | FROM openjdk:11 3 | LABEL 说明="edu-api-portal" 4 | 5 | # 指定维护者的名字 6 | MAINTAINER langyatudio <15589933912> 7 | 8 | # 声明服务运行在8001端口 9 | EXPOSE 8001 10 | 11 | ARG JAR_FILE 12 | # 将当前目录下的jar包复制到docker容器的/目录下 13 | ADD ${JAR_FILE} /edu-portal.jar 14 | 15 | # 指定docker容器启动时运行jar包 16 | ENTRYPOINT ["java", "-Duser.timezone=GMT+8","-jar", "/edu-portal.jar", "--spring.profiles.active=pro"] 17 | -------------------------------------------------------------------------------- /edu-api-portal/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | edu-api-portal 8 | ${revision} 9 | jar 10 | edu-portal 11 | edu-portal project for edu 12 | 13 | 14 | com.langyastudio.edu 15 | edu 16 | 1.3.0 17 | 18 | 19 | 20 | 21 | com.langyastudio.edu 22 | edu-security 23 | compile 24 | 25 | 26 | com.langyastudio.edu 27 | edu-db 28 | compile 29 | 30 | 31 | net.coobird 32 | thumbnailator 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-maven-plugin 41 | 42 | 43 | 44 | org.projectlombok 45 | lombok 46 | 47 | 48 | 49 | 50 | true 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | 59 | 60 | com.spotify 61 | dockerfile-maven-plugin 62 | ${dockerfile.maven.plugin.version} 63 | 64 | 65 | 74 | 75 | 76 | xxx 77 | xxx 78 | ${docker.host}/hacfin-edu/${project.artifactId} 79 | ${project.version} 80 | 81 | target/${project.build.finalName}.jar 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/Application.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 7 | 8 | /** 9 | * 前台入口文件 10 | */ 11 | @SpringBootApplication(scanBasePackages = {"com.langyastudio.edu.*"}) 12 | @EnableScheduling 13 | @EnableRedisHttpSession 14 | public class Application 15 | { 16 | public static void main(String[] args) 17 | { 18 | SpringApplication.run(Application.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/bo/AccountUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.bo; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import com.langyastudio.edu.db.model.UmsUserAuth; 5 | import org.springframework.security.core.GrantedAuthority; 6 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | 9 | import java.util.Collection; 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * SpringSecurity需要的用户详情 15 | */ 16 | public class AccountUserDetails implements UserDetails 17 | { 18 | private UmsUserAuth umsAdmin; 19 | private List resourceList; 20 | 21 | public AccountUserDetails(UmsUserAuth umsAdmin, List resourceList) 22 | { 23 | this.umsAdmin = umsAdmin; 24 | this.resourceList = resourceList; 25 | } 26 | 27 | @Override 28 | public Collection getAuthorities() 29 | { 30 | //返回当前用户的角色 31 | return resourceList.stream() 32 | .map(role -> new SimpleGrantedAuthority(role.getApiId() + ":" + role.getApiName())) 33 | .collect(Collectors.toList()); 34 | } 35 | 36 | @Override 37 | public String getPassword() 38 | { 39 | return umsAdmin.getPwd(); 40 | } 41 | 42 | @Override 43 | public String getUsername() 44 | { 45 | return umsAdmin.getUserName(); 46 | } 47 | 48 | @Override 49 | public boolean isAccountNonExpired() 50 | { 51 | return true; 52 | } 53 | 54 | @Override 55 | public boolean isAccountNonLocked() 56 | { 57 | return true; 58 | } 59 | 60 | @Override 61 | public boolean isCredentialsNonExpired() 62 | { 63 | return true; 64 | } 65 | 66 | @Override 67 | public boolean isEnabled() 68 | { 69 | return umsAdmin.getEnabled().equals(Byte.valueOf("1")); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/bo/AuthStateRedisCache.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.bo; 2 | 3 | import com.langyastudio.edu.common.util.RedisT; 4 | import me.zhyd.oauth.cache.AuthCacheConfig; 5 | import me.zhyd.oauth.cache.AuthStateCache; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * 扩展Redis版的state缓存 11 | */ 12 | @Component 13 | public class AuthStateRedisCache implements AuthStateCache 14 | { 15 | @Autowired 16 | RedisT redisT; 17 | 18 | /** 19 | * 存入缓存,默认3分钟 20 | * 21 | * @param key 缓存key 22 | * @param value 缓存内容 23 | */ 24 | @Override 25 | public void cache(String key, String value) 26 | { 27 | redisT.set(key, value, AuthCacheConfig.timeout); 28 | } 29 | 30 | /** 31 | * 存入缓存 32 | * 33 | * @param key 缓存key 34 | * @param value 缓存内容 35 | * @param timeout 指定缓存过期时间(毫秒) 36 | */ 37 | @Override 38 | public void cache(String key, String value, long timeout) 39 | { 40 | redisT.set(key, value, timeout); 41 | } 42 | 43 | /** 44 | * 获取缓存内容 45 | * 46 | * @param key 缓存key 47 | * 48 | * @return 缓存内容 49 | */ 50 | @Override 51 | public String get(String key) 52 | { 53 | return redisT.get(key); 54 | } 55 | 56 | /** 57 | * 是否存在key,如果对应key的value值已过期,也返回false 58 | * 59 | * @param key 缓存key 60 | * 61 | * @return true:存在key,并且value没过期;false:key不存在或者已过期 62 | */ 63 | @Override 64 | public boolean containsKey(String key) 65 | { 66 | return redisT.hasKey(key); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/FindPwdParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.Size; 7 | 8 | /** 9 | * 找回密码参数 10 | */ 11 | @Data 12 | public class FindPwdParam 13 | { 14 | /** 15 | * 手机号 or 邮箱 16 | */ 17 | @NotEmpty 18 | private String name; 19 | 20 | /** 21 | * 新密码 22 | */ 23 | @NotEmpty 24 | @Size(min = 6, max = 20) 25 | private String newPwd; 26 | 27 | /** 28 | * 校验码 29 | */ 30 | private String verifyCode; 31 | } 32 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/ImgCropParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotBlank; 6 | import javax.validation.constraints.Positive; 7 | import javax.validation.constraints.PositiveOrZero; 8 | 9 | /** 10 | * 图像裁剪参数 11 | */ 12 | @Data 13 | public class ImgCropParam 14 | { 15 | /** 16 | * 头像路径 17 | */ 18 | @NotBlank 19 | private String imgPath; 20 | 21 | /** 22 | * x 坐标 23 | */ 24 | @PositiveOrZero 25 | private Integer x; 26 | 27 | /** 28 | * y 坐标 29 | */ 30 | @PositiveOrZero 31 | private Integer y; 32 | 33 | /** 34 | * 裁剪宽度 35 | */ 36 | @Positive 37 | private Integer width; 38 | 39 | /** 40 | * 裁剪高度 41 | */ 42 | @Positive 43 | private Integer height; 44 | } 45 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/LoginDeviceParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | import javax.validation.constraints.NotBlank; 7 | 8 | /** 9 | * 设备登录 10 | * 11 | * @author jiangjiaxiong 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | public class LoginDeviceParam 16 | { 17 | /** 18 | * 签名后的值 19 | */ 20 | @NotBlank 21 | private String signature; 22 | 23 | /** 24 | * 签名方法 hmac-sha1 25 | */ 26 | @NotBlank 27 | private String signatureMethod; 28 | /** 29 | * guid 防止截获攻击 30 | */ 31 | @NotBlank 32 | private String signatureNonce; 33 | /** 34 | * 版本 1.0 35 | */ 36 | @NotBlank 37 | private String signatureVersion; 38 | /** 39 | * access_key 40 | */ 41 | @NotBlank 42 | private String accessKey; 43 | /** 44 | * 日期 防止截获攻击 45 | */ 46 | @NotBlank 47 | private String timestamp; 48 | /** 49 | * 格式 json 50 | */ 51 | @NotBlank 52 | private String format; 53 | } 54 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/LoginParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | import javax.validation.constraints.NotEmpty; 7 | import javax.validation.constraints.Size; 8 | 9 | /** 10 | * 用户登录参数 11 | */ 12 | @Data 13 | @EqualsAndHashCode(callSuper = false) 14 | public class LoginParam 15 | { 16 | /** 17 | * 用户名or手机号 18 | */ 19 | @NotEmpty 20 | @Size(min = 2, max=20) 21 | private String userName; 22 | 23 | /** 24 | * 密码 25 | */ 26 | @NotEmpty 27 | @Size(min = 2, max = 20) 28 | private String pwd; 29 | } 30 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/LoginVerifyParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | import javax.validation.constraints.NotEmpty; 7 | 8 | /** 9 | * 一键登录or注册 10 | */ 11 | @Data 12 | @EqualsAndHashCode(callSuper = false) 13 | public class LoginVerifyParam 14 | { 15 | /** 16 | * 手机号 or 邮箱 17 | */ 18 | @NotEmpty 19 | private String name; 20 | 21 | /** 22 | * 密码 23 | */ 24 | @NotEmpty 25 | private String verifyCode; 26 | } 27 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/RegisterParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.Size; 7 | 8 | /** 9 | * 用户注册参数 10 | */ 11 | @Data 12 | public class RegisterParam 13 | { 14 | /** 15 | * 用户名 16 | */ 17 | @NotEmpty 18 | private String userName; 19 | 20 | /** 21 | * 密码 22 | */ 23 | @NotEmpty 24 | @Size(min = 6, max = 20) 25 | private String pwd; 26 | 27 | /** 28 | * 手机号 or 邮箱 29 | */ 30 | @NotEmpty 31 | private String name; 32 | 33 | /** 34 | * 检验码 35 | */ 36 | private String verifyCode; 37 | } 38 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/UpdateAuthParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.Size; 7 | 8 | /** 9 | * 校验码参数 10 | * 例如:更新手机号、一键登录or注册 11 | */ 12 | @Data 13 | public class UpdateAuthParam 14 | { 15 | /** 16 | * 用户名 17 | */ 18 | @Size(min = 2, max = 20) 19 | private String userName; 20 | 21 | /** 22 | * 手机号 or 邮箱 23 | */ 24 | @NotEmpty 25 | private String name; 26 | 27 | /** 28 | * 校验码 29 | */ 30 | @NotEmpty 31 | private String verifyCode; 32 | } 33 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/UpdatePwdParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.NotEmpty; 6 | import javax.validation.constraints.Size; 7 | 8 | /** 9 | * 修改用户名密码参数 10 | */ 11 | @Data 12 | public class UpdatePwdParam 13 | { 14 | /** 15 | * 用户名 16 | */ 17 | @Size(min = 2, max = 20) 18 | private String userName; 19 | 20 | /** 21 | * 旧密码 22 | */ 23 | @NotEmpty 24 | @Size(min = 6, max = 20) 25 | private String oldPwd; 26 | 27 | /** 28 | * 新密码 29 | */ 30 | @NotEmpty 31 | @Size(min = 6, max = 20) 32 | private String newPwd; 33 | } 34 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/dto/UserParam.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.dto; 2 | 3 | import com.langyastudio.edu.common.anno.InValue; 4 | import lombok.Data; 5 | 6 | import javax.validation.constraints.PastOrPresent; 7 | import javax.validation.constraints.PositiveOrZero; 8 | import javax.validation.constraints.Size; 9 | import java.time.LocalDate; 10 | 11 | /** 12 | * 用户传入参数 13 | */ 14 | @Data 15 | public class UserParam 16 | { 17 | /** 18 | * 用户名 19 | */ 20 | @Size(min=2, max = 20) 21 | private String userName; 22 | 23 | /** 24 | * 昵称 25 | */ 26 | @Size(min=2, max = 20) 27 | private String nickName; 28 | 29 | /** 30 | * 姓名 31 | */ 32 | @Size(min=2, max = 20) 33 | private String fullName; 34 | 35 | /** 36 | * 性别 37 | */ 38 | @InValue(value = {"1", "2", "3"}) 39 | private Byte sex; 40 | 41 | /** 42 | * 用户头像 43 | */ 44 | @Size(max = 128) 45 | private String avator; 46 | 47 | /** 48 | * 行政区划代码 49 | */ 50 | @PositiveOrZero 51 | private Integer pcdId; 52 | 53 | /** 54 | * 联系地址 55 | */ 56 | @Size(max = 128) 57 | private String company; 58 | 59 | /** 60 | * 生日 61 | */ 62 | @PastOrPresent 63 | private LocalDate birthday; 64 | 65 | /** 66 | * 描述信息 67 | */ 68 | @Size(max = 128) 69 | private String description; 70 | } 71 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/vo/JsSDKSignVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.vo; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * weixin jssdk 签名 7 | * 8 | * @author langyastudio 9 | */ 10 | @Data 11 | public class JsSDKSignVO 12 | { 13 | /** 14 | * 返回url地址 15 | */ 16 | private String url; 17 | /** 18 | * 公众号的唯一标识 19 | */ 20 | private String appId; 21 | 22 | /** 23 | * 生成签名的时间戳 24 | */ 25 | private String nonceStr; 26 | 27 | /** 28 | * 生成签名的随机串 29 | */ 30 | private String timestamp; 31 | 32 | /** 33 | * 签名 34 | */ 35 | private String signature; 36 | } 37 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/vo/OauthCacheVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.vo; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 第三方登录的缓存信息 7 | */ 8 | @Data 9 | public class OauthCacheVO 10 | { 11 | /** 12 | * 唯一标识符 13 | */ 14 | private String key; 15 | /** 16 | * 类型,如dingding 17 | */ 18 | private String provider; 19 | /** 20 | * 是否是登录请求 21 | */ 22 | private Integer isLogin; 23 | /** 24 | * ui回调地址 25 | */ 26 | private String uiUrl; 27 | /** 28 | * 状态码 29 | */ 30 | private Integer statue; 31 | /** 32 | * 状态消息 33 | */ 34 | private String msg; 35 | /** 36 | * 登录成功的授权信息 37 | */ 38 | private TokenVO tokenVO; 39 | /** 40 | * 用户名 41 | */ 42 | private String userName; 43 | 44 | //------------------------- 第三方服务获取到的信息 ---------------------// 45 | /** 46 | * 第三方open id号 47 | */ 48 | private String openId; 49 | /** 50 | * 用户头像地址 51 | */ 52 | private String avatar; 53 | /** 54 | * 用户头像地址 55 | */ 56 | private String nickName; 57 | } 58 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/vo/TokenVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | /** 7 | * jwt 返回对象 8 | */ 9 | @Data 10 | @AllArgsConstructor 11 | public class TokenVO 12 | { 13 | /** 14 | * token 15 | */ 16 | private String token; 17 | 18 | /** 19 | * token 前缀 20 | */ 21 | private String tokenHead; 22 | } 23 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/bean/vo/UmsDivisionVO.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.bean.vo; 2 | import com.langyastudio.edu.db.model.UmsDivision; 3 | import lombok.Data; 4 | import lombok.EqualsAndHashCode; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Data 10 | @EqualsAndHashCode(callSuper = true) 11 | public class UmsDivisionVO extends UmsDivision 12 | { 13 | private List children; 14 | 15 | private boolean hasParent = false; 16 | private boolean hasChild = false; 17 | 18 | public void initChildren() 19 | { 20 | children = new ArrayList<>(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/conf/AliOssConf.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.conf; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | 7 | /** 8 | * aliyun oss 配置 9 | */ 10 | @Data 11 | @ConfigurationProperties(prefix = "aliyun.oss") 12 | public class AliOssConf 13 | { 14 | private String accessKey; 15 | private String accessSecret; 16 | 17 | /** 18 | * oss对外服务的访问域名 19 | */ 20 | private String endPoint; 21 | /** 22 | * oss的存储空间 23 | */ 24 | private String bucketName; 25 | /** 26 | * 存储路径前缀 27 | */ 28 | private String dirPrefix; 29 | /** 30 | * 上传文件大小(M) 31 | */ 32 | private String maxSize; 33 | /** 34 | * 签名有效期(S) 35 | */ 36 | private String policyExpire; 37 | /** 38 | * 文件上传成功后的回调地址 39 | */ 40 | private String callback; 41 | } 42 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/conf/AliSmsConf.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.conf; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * yml 配置文件-aliyun-sms 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "aliyun.sms") 13 | public class AliSmsConf 14 | { 15 | private String accessKey; 16 | private String accessSecret; 17 | 18 | //signName templateCode 19 | /** 20 | * 注册 21 | */ 22 | private Map register; 23 | /** 24 | * 登录 25 | */ 26 | private Map login; 27 | /** 28 | * 找密码 29 | */ 30 | private Map findPwd; 31 | /** 32 | * 修改手机号 33 | */ 34 | private Map modifyPhone; 35 | } 36 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/conf/LocalImgConf.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.conf; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | * 资源配置 8 | * 9 | * @author jiangjiaxiong 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "langyastudio.storage.imgs") 13 | public class LocalImgConf 14 | { 15 | /** 16 | * 图像目录 17 | */ 18 | private String root; 19 | /** 20 | * windows 图像目录 21 | */ 22 | private String winRoot; 23 | } 24 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/conf/OauthConf.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.conf; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * 第三方登录配置 10 | */ 11 | @Data 12 | @ConfigurationProperties(prefix = "oauth") 13 | public class OauthConf 14 | { 15 | /** 16 | * 是否启用 17 | */ 18 | private Boolean enabled; 19 | 20 | /** 21 | * 第三方授权列表 22 | */ 23 | private Map provider; 24 | 25 | /** 26 | * 授权登录URL前缀 27 | * /auth2/authorization 28 | */ 29 | private String authLoginUrlPrefix; 30 | 31 | /** 32 | * 重定向前缀 33 | * /portal/auth2/callback 34 | */ 35 | private String redirectUrlPrefix; 36 | 37 | /** 38 | * api 域名地址 39 | * http://account-test.bogo365.net 40 | */ 41 | private String domain; 42 | } 43 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/data/Define.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.data; 2 | 3 | import com.langyastudio.edu.common.data.BasDefine; 4 | 5 | /** 6 | * 常量与配置文件 7 | *

8 | * 注意:表字段的常量值定义到ORM 9 | */ 10 | public class Define extends BasDefine 11 | { 12 | /*-------------------------------------------------------------------------------------------------------------- */ 13 | // 常用常量定义 14 | /*-------------------------------------------------------------------------------------------------------------- */ 15 | public final static Integer SUCESSS = 1; 16 | 17 | //是 or 否 18 | public final static String YES = "1"; 19 | public final static String NO = "2"; 20 | public final static Integer YESI = 1; 21 | public final static Integer NOI = 2; 22 | 23 | //校验码 24 | public final static String VERITY_REGISTER = "1"; 25 | public final static String VERITY_MODIFY = "2"; 26 | public final static String VERITY_FINDPWD = "3"; 27 | public final static String VERITY_LOGIN = "4"; 28 | 29 | //默认分页的起始位置 30 | public final static Integer PAGE_OFFSET = 0; 31 | //默认每页最大数量 32 | public final static Integer PAGE_MAX_SIZE = 500; 33 | 34 | 35 | /*-------------------------------------------------------------------------------------------------------------- */ 36 | // 资源 37 | /*-------------------------------------------------------------------------------------------------------------- */ 38 | //-超过2M再计算hash 39 | public final static Integer FILE_HASH_MIN_SIZE = 2097152; 40 | 41 | public final static String RESOURCE_MEDIA_NAME = "media"; 42 | } -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/middleware/ApplicationRunnerStart.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.middleware; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import lombok.extern.log4j.Log4j2; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.ApplicationArguments; 8 | import org.springframework.boot.ApplicationRunner; 9 | import org.springframework.context.ConfigurableApplicationContext; 10 | import org.springframework.core.annotation.Order; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.web.context.WebApplicationContext; 13 | 14 | import java.net.InetAddress; 15 | import java.util.Arrays; 16 | 17 | /** 18 | * 继承Application接口后项目启动时会按照执行顺序执行run方法 19 | * 通过设置Order的value来指定执行的顺序 值越小越先执行 20 | */ 21 | @Component 22 | @Log4j2 23 | @Order(value = 1) 24 | @RequiredArgsConstructor 25 | public class ApplicationRunnerStart implements ApplicationRunner 26 | { 27 | private final ConfigurableApplicationContext context; 28 | 29 | @Autowired 30 | WebApplicationContext applicationContext; 31 | 32 | @Value("${server.port}") 33 | Integer port; 34 | 35 | @Override 36 | public void run(ApplicationArguments args) throws Exception 37 | { 38 | if (context.isActive()) 39 | { 40 | String[] activeProfiles = applicationContext.getEnvironment().getActiveProfiles(); 41 | InetAddress address = InetAddress.getLocalHost(); 42 | String url = String.format("http://%s:%s", address.getHostAddress(), port); 43 | 44 | log.info(" __ ___ _ ___ _ ____ _____ ____ "); 45 | log.info("/ /` / / \\ | |\\/| | |_) | | | |_ | | | |_ "); 46 | log.info("\\_\\_, \\_\\_/ |_| | |_| |_|__ |_|__ |_| |_|__ "); 47 | log.info(" "); 48 | System.out.println("前台-运行环境:" + Arrays.toString(activeProfiles)); 49 | log.info("前台-系统启动完毕,地址:{}", url); 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/middleware/LimitInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.middleware; 2 | 3 | import com.langyastudio.edu.common.exception.MyException; 4 | import com.langyastudio.edu.common.middleware.Interceptor.RequestInterceptor; 5 | import com.langyastudio.edu.common.util.Tool; 6 | import lombok.RequiredArgsConstructor; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.data.redis.core.script.DefaultRedisScript; 11 | import org.springframework.data.redis.core.script.RedisScript; 12 | import org.springframework.stereotype.Component; 13 | import org.springframework.web.servlet.ModelAndView; 14 | 15 | import javax.servlet.http.HttpServletRequest; 16 | import javax.servlet.http.HttpServletResponse; 17 | import java.util.List; 18 | 19 | /** 20 | * 请求拦截器 21 | */ 22 | @Component 23 | @RequiredArgsConstructor 24 | public class LimitInterceptor extends RequestInterceptor 25 | { 26 | private final RedisTemplate redisTemplate; 27 | 28 | @Override 29 | public boolean preHandle(@NotNull HttpServletRequest request, 30 | @NotNull HttpServletResponse response, 31 | @NotNull Object handler) throws MyException 32 | { 33 | 34 | String ip = Tool.getClientIp(request); 35 | int limitPeriod = 60; 36 | int limitCount = 100; 37 | String keys = "limit_" + ip; 38 | 39 | String luaScript = buildLuaScript(); 40 | RedisScript redisScript = new DefaultRedisScript<>(luaScript, Long.class); 41 | Long count = redisTemplate.execute(redisScript, List.of(keys), limitCount, 42 | limitPeriod); 43 | if (count != null && count.intValue() <= limitCount) 44 | { 45 | 46 | } 47 | else 48 | { 49 | throw new MyException("接口访问超出频率限制"); 50 | } 51 | 52 | return super.preHandle(request, response, handler); 53 | } 54 | 55 | /** 56 | * 限流脚本 57 | * 调用的时候不超过阈值,则直接返回并执行计算器自加。 58 | * 59 | * @return lua脚本 60 | */ 61 | private String buildLuaScript() 62 | { 63 | return "local c" + 64 | "\nc = redis.call('get',KEYS[1])" + 65 | "\nif c and tonumber(c) > tonumber(ARGV[1]) then" + 66 | "\nreturn c;" + 67 | "\nend" + 68 | "\nc = redis.call('incr',KEYS[1])" + 69 | "\nif tonumber(c) == 1 then" + 70 | "\nredis.call('expire',KEYS[1],ARGV[2])" + 71 | "\nend" + 72 | "\nreturn c;"; 73 | } 74 | 75 | @Override 76 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 77 | ModelAndView modelAndView) throws Exception 78 | { 79 | 80 | } 81 | 82 | @Override 83 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, 84 | Exception ex) throws Exception 85 | { 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/middleware/ShutDownHook.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.middleware; 2 | 3 | import lombok.extern.log4j.Log4j2; 4 | import org.springframework.context.ApplicationEvent; 5 | import org.springframework.context.event.ContextClosedEvent; 6 | import org.springframework.context.event.EventListener; 7 | import org.springframework.lang.NonNull; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | * 退出进程 12 | */ 13 | @Log4j2 14 | @Component 15 | public class ShutDownHook 16 | { 17 | @EventListener(classes = {ContextClosedEvent.class}) 18 | public void onApplicationClosed(@NonNull ApplicationEvent event) 19 | { 20 | log.info("前台-系统已关闭"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/service/ImgService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.service; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.springframework.web.multipart.MultipartFile; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * 图像服务 11 | */ 12 | public interface ImgService 13 | { 14 | /** 15 | * 文件上传到图像服务器 16 | * 17 | * @param file 文件 18 | * 19 | * @return 20 | */ 21 | String upload(@NotNull MultipartFile file); 22 | 23 | /** 24 | * 缩放图片 25 | * 26 | * @param request HttpServletRequest 27 | * @param response HttpServletResponse 28 | * @param relativePath 本地相对路径 29 | */ 30 | void resize(HttpServletRequest request, HttpServletResponse response, String relativePath, int width, int height); 31 | 32 | /** 33 | * 图像文件在线裁剪 34 | * 35 | * @param imgPath 图像文件全路径 36 | * @param sx 左上角x坐标 37 | * @param sy 左上角y坐标 38 | * @param width 宽度 39 | * @param height 高度 40 | * 41 | * @return 42 | */ 43 | String crop(String imgPath, Integer sx, Integer sy, Integer width, Integer height); 44 | } 45 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/common/service/impl/AliOssImgServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.common.service.impl; 2 | 3 | import com.langyastudio.edu.common.third.AliOss; 4 | import com.langyastudio.edu.portal.common.conf.AliOssConf; 5 | import com.langyastudio.edu.portal.common.service.ImgService; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | 15 | /** 16 | * 阿里云Oss服务 17 | */ 18 | @Service 19 | @ConditionalOnProperty(value = "langyastudio.storage.imgs.type", havingValue = "aliyun") 20 | public class AliOssImgServiceImpl implements ImgService 21 | { 22 | @Autowired 23 | AliOssConf aliOssConf; 24 | 25 | @Autowired 26 | AliOss aliOss; 27 | 28 | /** 29 | * 文件上传到OSS 30 | * 31 | * @param file 文件 32 | * 33 | * @return 34 | */ 35 | @Override 36 | public String upload(@NotNull MultipartFile file) 37 | { 38 | return aliOss.upload(aliOssConf.getAccessKey(), aliOssConf.getAccessSecret(), aliOssConf.getEndPoint(), 39 | aliOssConf.getBucketName(), aliOssConf.getDirPrefix(), file); 40 | } 41 | 42 | /** 43 | * 缩放图片 44 | * 45 | * @param request HttpServletRequest 46 | * @param response HttpServletResponse 47 | * @param relativePath 本地相对路径 48 | */ 49 | @Override 50 | public void resize(HttpServletRequest request, HttpServletResponse response, String relativePath, int width, int height) 51 | { 52 | 53 | } 54 | 55 | /** 56 | * OSS文件在线裁剪 57 | * 58 | * @param imgPath oss文件全路径 59 | * @param sx 左上角x坐标 60 | * @param sy 左上角y坐标 61 | * @param width 宽度 62 | * @param height 高度 63 | * 64 | * @return 65 | */ 66 | @Override 67 | public String crop(String imgPath, Integer sx, Integer sy, Integer width, Integer height) 68 | { 69 | return aliOss.crop(aliOssConf.getAccessKey(), aliOssConf.getAccessSecret(), aliOssConf.getEndPoint(), 70 | aliOssConf.getBucketName(), aliOssConf.getDirPrefix(), 71 | imgPath, sx, sy, width, height); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/config/AccountSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.config; 2 | 3 | import com.langyastudio.edu.portal.service.SecurityService; 4 | import com.langyastudio.edu.security.config.SecurityConfig; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 9 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | 12 | /** 13 | * security模块相关配置 14 | */ 15 | @Configuration 16 | @EnableWebSecurity 17 | @EnableGlobalMethodSecurity(prePostEnabled = true) 18 | public class AccountSecurityConfig extends SecurityConfig 19 | { 20 | @Autowired 21 | private SecurityService securityService; 22 | 23 | @Bean 24 | @Override 25 | public UserDetailsService userDetailsService() 26 | { 27 | //获取登录用户信息 28 | return username -> securityService.loadUserByUsername(username); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/config/DynamicSecurityImpl.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.config; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import com.langyastudio.edu.portal.service.SecurityService; 5 | import com.langyastudio.edu.security.component.DynamicSecurityService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.security.access.ConfigAttribute; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | /** 15 | * Spring Dynamic Security 16 | * 17 | * @author langyastudio 18 | */ 19 | @Service("dynamicSecurityService") 20 | public class DynamicSecurityImpl implements DynamicSecurityService 21 | { 22 | @Autowired 23 | private SecurityService securityService; 24 | 25 | /** 26 | * 加载资源ANT通配符和资源对应MAP 27 | */ 28 | @Override 29 | public Map loadDataSource() 30 | { 31 | Map map = new ConcurrentHashMap<>(); 32 | List resourceList = securityService.getAuthListAll(); 33 | for (UmsApi resource : resourceList) 34 | { 35 | map.put(resource.getApiUrl(), 36 | new org.springframework.security.access.SecurityConfig(resource.getApiId() + ":" + resource.getApiName())); 37 | } 38 | 39 | return map; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/config/MybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.config; 2 | 3 | import com.langyastudio.edu.common.config.BaseMybatisConfig; 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.transaction.annotation.EnableTransactionManagement; 7 | 8 | 9 | /** 10 | * Mybatis Plus 11 | */ 12 | @Configuration 13 | @EnableTransactionManagement 14 | @MapperScan("com.langyastudio.edu.db.mapper") 15 | public class MybatisConfig extends BaseMybatisConfig 16 | { 17 | 18 | } -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.config; 2 | 3 | import com.langyastudio.edu.common.config.BaseRedisConfig; 4 | import org.springframework.cache.annotation.EnableCaching; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * redis配置类 9 | */ 10 | @Configuration 11 | @EnableCaching 12 | public class RedisConfig extends BaseRedisConfig 13 | { 14 | } 15 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.controller; 2 | 3 | import com.langyastudio.edu.common.data.ResultInfo; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * 根访问 12 | */ 13 | @RestController 14 | @RequestMapping("/") 15 | public class IndexController 16 | { 17 | /** 18 | * 当前版本 19 | */ 20 | @Value("${spring.application.version}") 21 | private String serviceVersion; 22 | 23 | /** 24 | * 打包时间 25 | */ 26 | @Value("${spring.application.package-time}") 27 | private String serviceBuildDate; 28 | 29 | /** 30 | * 索引页 31 | */ 32 | @RequestMapping("/") 33 | public ResultInfo index() 34 | { 35 | return ResultInfo.data(Map.of("name", "portal api", 36 | "version", serviceVersion, 37 | "time", serviceBuildDate, 38 | "company", "郎涯工作室", 39 | "official", "https://langyastudio.blog.csdn.net/", 40 | "maintainer", "langyastudio 「15589933912」")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/controller/common/MediaController.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.controller.common; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.langyastudio.edu.common.data.EC; 5 | import com.langyastudio.edu.common.exception.MyException; 6 | import com.langyastudio.edu.portal.common.service.ImgService; 7 | import lombok.extern.log4j.Log4j2; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.validation.annotation.Validated; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RequestParam; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | 17 | /** 18 | * 资源访问 19 | * 20 | * @author langyastudio 21 | */ 22 | @Log4j2 23 | @Validated 24 | @RestController 25 | public class MediaController 26 | { 27 | @Autowired 28 | ImgService imgService; 29 | 30 | /** 31 | * 播放-数据 32 | * 33 | * @param request 请求 34 | * @param response 响应 35 | * 36 | * http://192.168.123.100:8511/media/2021/09/30/20210930143358019608114.png?x-oss-process=style/resize-400 37 | */ 38 | @GetMapping(path = "/media/**") 39 | public void playMedia(HttpServletRequest request, 40 | HttpServletResponse response, 41 | @RequestParam(value = "x-oss-process", required = false) String process) 42 | { 43 | String relativePath = request.getRequestURI(); 44 | if (StrUtil.isBlankIfStr(relativePath) || relativePath.length() < 10) 45 | { 46 | throw new MyException(EC.ERROR_PARAM_EXCEPTION); 47 | } 48 | 49 | // /media/** 50 | relativePath = relativePath.substring(7); 51 | 52 | //resize 53 | int width = 0; 54 | if(StrUtil.isNotBlank(process) && process.length() > 13) 55 | { 56 | process = process.substring(13); 57 | try 58 | { 59 | width = Integer.parseInt(process); 60 | } 61 | catch (NumberFormatException e) 62 | { 63 | 64 | } 65 | } 66 | 67 | imgService.resize(request, response, relativePath, width, width); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/Auth2Service.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | import com.langyastudio.edu.portal.bean.vo.JsSDKSignVO; 4 | import com.langyastudio.edu.portal.bean.vo.OauthCacheVO; 5 | import me.zhyd.oauth.model.AuthCallback; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * 第三方登录服务 11 | */ 12 | public interface Auth2Service extends BaseService 13 | { 14 | /*-------------------------------------------------------------------------------------------------------------- */ 15 | // JsSDK 16 | /*-------------------------------------------------------------------------------------------------------------- */ 17 | /** 18 | * 获取JS-SDK sign 签名信息 19 | * 20 | * @param url 要分享的URL地址 21 | * 22 | * @return 23 | */ 24 | JsSDKSignVO jsSDKSign(String url); 25 | 26 | /*-------------------------------------------------------------------------------------------------------------- */ 27 | // 扫码登录 28 | /*-------------------------------------------------------------------------------------------------------------- */ 29 | 30 | /** 31 | * 检测授权状态 32 | * 33 | * @param key 存储与statue中,类似于唯一标识符 34 | * 35 | * @return 36 | */ 37 | OauthCacheVO checkStatus(String key); 38 | 39 | /** 40 | * 获取授权地址 41 | * 42 | * @param provider 第三方类型 43 | * @param uiUrl ui URL地址 44 | * @param isLogin 是否登录 45 | * 46 | * @return Map 47 | */ 48 | Map getAuthUrl(String userName, String provider, String uiUrl, Integer isLogin); 49 | 50 | /** 51 | * 回调接口 52 | * 53 | * @param provider 第三方类型 54 | * @param authCallback callback返回参数,如code、statue等 55 | * 56 | * @return 重定向地址 57 | */ 58 | String callback(String provider, AuthCallback authCallback); 59 | 60 | /*-------------------------------------------------------------------------------------------------------------- */ 61 | // 绑定与解绑 62 | /*-------------------------------------------------------------------------------------------------------------- */ 63 | 64 | /** 65 | * 是否绑定 66 | * 67 | * @param userName 用户名 68 | * @param provider 第三方类型 69 | * 70 | * @return YES or NO 71 | */ 72 | Integer isBind(String userName, String provider); 73 | 74 | /** 75 | * 删除绑定 76 | * 77 | * @param userName 用户名 78 | * @param provider 第三方类型 79 | * 80 | * @return YES or NO 81 | */ 82 | Integer delBind(String userName, String provider); 83 | 84 | /** 85 | * 登录绑定 86 | * 87 | * @param key 唯一标识符 88 | * @param name 用户名or手机号 89 | * @param pwd 密码 90 | * 91 | * @return 92 | */ 93 | Integer loginBind(String key, String name, String pwd); 94 | 95 | /** 96 | * 自动绑定 97 | * 98 | * @param key 唯一标识符 99 | * 100 | * @return 101 | */ 102 | Integer autoBind(String key); 103 | } 104 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 权限管理 7 | */ 8 | public interface AuthService extends BaseService 9 | { 10 | /** 11 | * 用户菜单视图 12 | * 13 | * @param schoolId 机构Id号,不传时表示获取系统菜单视图 14 | * 15 | * @return 16 | */ 17 | Map getViewList(String schoolId); 18 | } 19 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/BaseService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 基础服务 7 | */ 8 | public interface BaseService 9 | { 10 | /** 11 | * 获取登录用户名 12 | * 13 | * @param bNeedLogin 未登录是否抛出异常 14 | * 15 | * @return 用户名 16 | */ 17 | String getUserName(boolean bNeedLogin); 18 | 19 | /** 20 | * 是否是admin 21 | * 22 | * @param userName 用户名 23 | * @return bool 24 | */ 25 | Boolean isAdmin(String userName); 26 | 27 | /** 28 | * 登录功能 29 | * 30 | * @param username 用户名 31 | * @param password 密码 32 | * 33 | * @return 生成的JWT的token 34 | */ 35 | String login(String username, String password); 36 | 37 | /** 38 | * 添加系统用户 39 | * 40 | * @param userName 用户名 41 | * @param fullName 姓名 42 | * @param phone 手机号 43 | * 44 | * @return 45 | */ 46 | Map addSystemUser(String userName, String pwd, String fullName, String phone, Integer sex); 47 | } 48 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/MonitorService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | /** 4 | * 监控服务 5 | */ 6 | public interface MonitorService extends BaseService 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/PwdService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | import com.langyastudio.edu.common.data.PageInfo; 4 | import com.langyastudio.edu.portal.bean.dto.FindPwdParam; 5 | import com.langyastudio.edu.portal.bean.dto.LoginDeviceParam; 6 | import com.langyastudio.edu.portal.bean.dto.LoginVerifyParam; 7 | import com.langyastudio.edu.portal.bean.dto.RegisterParam; 8 | import com.langyastudio.edu.portal.bean.vo.UmsDivisionVO; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * 密码服务 14 | */ 15 | public interface PwdService extends BaseService 16 | { 17 | /*-------------------------------------------------------------------------------------------------------------- */ 18 | // 登录注册 19 | /*-------------------------------------------------------------------------------------------------------------- */ 20 | 21 | /** 22 | * 用户名是否存在 23 | */ 24 | Map existName(String userName); 25 | 26 | /** 27 | * 手机号是否存在 28 | */ 29 | Map existPhone(String phone, String except); 30 | 31 | /** 32 | * 注册功能 33 | */ 34 | Map register(RegisterParam param); 35 | 36 | /** 37 | * 手机号一键登录 38 | * 39 | * @param verifyParam 校验码参数 40 | * 41 | * @return 42 | */ 43 | String loginSms(LoginVerifyParam verifyParam); 44 | 45 | /** 46 | * 设备加密登录 47 | * 48 | * @param deviceParam 登录参数 49 | * 50 | * @return 51 | */ 52 | String loginDevice(LoginDeviceParam deviceParam); 53 | 54 | /** 55 | * 退出登录 56 | * 57 | * @param userName 用户名 58 | * 59 | * @return 60 | */ 61 | Integer logout(String userName, String token); 62 | 63 | /** 64 | * 刷新token的功能 65 | * 66 | * @param oldToken 旧的token 67 | */ 68 | String refreshToken(String oldToken); 69 | 70 | /** 71 | * 手机号找回密码 72 | * 73 | * @param param 找回密码参数 74 | * 75 | * @return 76 | */ 77 | Integer findPwd(FindPwdParam param); 78 | 79 | /** 80 | * 获取省市区列表 81 | * 82 | * @param parentId 父节点 83 | * @param lever 层级 84 | * 85 | * @return 86 | */ 87 | PageInfo getListAddress(Integer parentId, Integer lever); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/SecurityService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | import com.langyastudio.edu.db.model.UmsApi; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Spring security 10 | * 11 | * @author jiangjiaxiong 12 | */ 13 | public interface SecurityService 14 | { 15 | Boolean isAdmin(String userName); 16 | 17 | /*-------------------------------------------------------------------------------------------------------------- */ 18 | // Spring security 19 | /*-------------------------------------------------------------------------------------------------------------- */ 20 | 21 | /** 22 | * 根据角色Id号获取API权限列表 23 | * 24 | * @return 25 | */ 26 | List getAuthListAll(); 27 | 28 | /** 29 | * 获取某个用户的权限列表 30 | * 31 | * @param userName 用户名 32 | * 33 | * @return 34 | */ 35 | List getAuthListAll(String userName, String schoolId); 36 | 37 | /** 38 | * 获取用户信息 39 | * 40 | * @param userName 用户名 41 | */ 42 | UserDetails loadUserByUsername(String userName); 43 | } 44 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/java/com/langyastudio/edu/portal/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.portal.service; 2 | 3 | import com.langyastudio.edu.portal.bean.dto.UpdateAuthParam; 4 | import com.langyastudio.edu.portal.bean.dto.UpdatePwdParam; 5 | import com.langyastudio.edu.portal.bean.dto.UserParam; 6 | 7 | import java.util.Map; 8 | 9 | /** 10 | * 账号管理 11 | */ 12 | public interface UserService extends BaseService 13 | { 14 | /*-------------------------------------------------------------------------------------------------------------- */ 15 | // 账号设置 16 | /*-------------------------------------------------------------------------------------------------------------- */ 17 | 18 | /** 19 | * 获取用户信息 20 | * 21 | * @param userName 用户名 22 | * 23 | * @return 24 | */ 25 | Map getInfo(String userName); 26 | 27 | /** 28 | * 修改用户 29 | * 30 | * @param userInfo 用户信息 31 | * 32 | * @return 33 | */ 34 | Integer modify(UserParam userInfo); 35 | 36 | /** 37 | * 修改用户 38 | * 39 | * @param authParam 授权信息 40 | * 41 | * @return 42 | */ 43 | Integer modifyPhone(UpdateAuthParam authParam); 44 | 45 | /** 46 | * 修改密码 47 | * 48 | * @param pwdParam 密码参数 49 | */ 50 | Integer modifyPassword(UpdatePwdParam pwdParam); 51 | 52 | /** 53 | * 保存用户头像 54 | * 55 | * @param userName 用户名 56 | * @param imgPath 图像完整路径 57 | * 58 | * @return 59 | */ 60 | Integer modifyAvator(String userName, String imgPath); 61 | } 62 | -------------------------------------------------------------------------------- /edu-api-portal/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | version: @project.version@ 4 | package-time: @package-time@ -------------------------------------------------------------------------------- /edu-api-portal/src/main/resources/application-pro.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | version: @project.version@ 4 | package-time: @package-time@ -------------------------------------------------------------------------------- /edu-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | edu-common 8 | 1.3.0 9 | jar 10 | edu-common 11 | edu-common project for edu 12 | 13 | 14 | com.langyastudio.edu 15 | edu 16 | 1.3.0 17 | 18 | 19 | 20 | 21 | 22 | org.mybatis.spring.boot 23 | mybatis-spring-boot-starter 24 | 25 | 26 | 27 | com.baomidou 28 | mybatis-plus-boot-starter 29 | 30 | 31 | 32 | com.alibaba 33 | druid-spring-boot-starter 34 | 35 | 36 | 37 | mysql 38 | mysql-connector-java 39 | runtime 40 | 41 | 42 | 43 | 44 | com.sun.mail 45 | javax.mail 46 | 47 | 48 | 49 | org.lionsoul 50 | ip2region 51 | 52 | 53 | 54 | com.alibaba 55 | easyexcel 56 | 57 | 58 | 59 | 60 | com.aliyun 61 | dysmsapi20170525 62 | 63 | 64 | 65 | 66 | com.aliyun.oss 67 | aliyun-sdk-oss 68 | 69 | 70 | 71 | org.glassfish.jaxb 72 | jaxb-runtime 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/anno/Desensitization.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.anno; 2 | 3 | import com.langyastudio.edu.common.entity.DesensitizationType; 4 | import org.apache.logging.log4j.util.Strings; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * 脱敏 13 | * 14 | * @author langyastudio 15 | */ 16 | @Target(ElementType.FIELD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface Desensitization 19 | { 20 | /** 21 | * 脱敏规则类型 22 | */ 23 | DesensitizationType type(); 24 | 25 | /** 26 | * 附加值, 自定义正则表达式等 27 | */ 28 | String[] attach() default Strings.EMPTY; 29 | } 30 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/anno/InValue.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.anno; 2 | 3 | import com.langyastudio.edu.common.data.validator.InValidator; 4 | 5 | import javax.validation.Constraint; 6 | import javax.validation.Payload; 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | /** 13 | * 状态值是否在指定范围内 14 | * 15 | * @author langyastudio 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.PARAMETER}) 19 | @Constraint(validatedBy = InValidator.class) 20 | public @interface InValue 21 | { 22 | String[] value() default {"1", "2"}; 23 | 24 | String message() default "参数值异常"; 25 | 26 | Class[] groups() default {}; 27 | 28 | Class[] payload() default {}; 29 | } 30 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/anno/LimitField.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.anno; 2 | 3 | import com.langyastudio.edu.common.entity.LimitType; 4 | import org.apache.logging.log4j.util.Strings; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * API 请求限流 13 | * 14 | * @author langyastudio 15 | */ 16 | @Target(ElementType.METHOD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface LimitField 19 | { 20 | /** 21 | * 资源名称,用于描述接口功能 22 | */ 23 | String name() default Strings.EMPTY; 24 | 25 | /** 26 | * 资源 key 27 | */ 28 | String key() default Strings.EMPTY; 29 | 30 | /** 31 | * key prefix 32 | */ 33 | String prefix() default Strings.EMPTY; 34 | 35 | /** 36 | * 时间范围,单位秒 37 | */ 38 | int period() default 60; 39 | 40 | /** 41 | * 限制访问次数 42 | */ 43 | int count() default 10; 44 | 45 | /** 46 | * 限制类型 47 | */ 48 | LimitType limitType() default LimitType.CUSTOMER; 49 | } 50 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/anno/LogField.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.anno; 2 | 3 | import org.apache.logging.log4j.util.Strings; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 日志注解 12 | * 13 | * @author langyastudio 14 | */ 15 | @Target(ElementType.METHOD) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface LogField 18 | { 19 | /** 20 | * 名称 21 | */ 22 | String value() default Strings.EMPTY; 23 | } 24 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/anno/PhoneOrEmpty.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.anno; 2 | 3 | import com.langyastudio.edu.common.data.validator.PhoneOrEmptyValidator; 4 | 5 | import javax.validation.Constraint; 6 | import javax.validation.Payload; 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | /** 13 | * 手机号 or 空字符串 14 | * 15 | * @author langyastudio 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.PARAMETER}) 19 | @Constraint(validatedBy = PhoneOrEmptyValidator.class) 20 | public @interface PhoneOrEmpty 21 | { 22 | String message() default "手机号错误"; 23 | 24 | Class[] groups() default {}; 25 | 26 | Class[] payload() default {}; 27 | } 28 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/config/BaseMybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; 6 | import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; 7 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 8 | import org.springframework.context.annotation.Bean; 9 | 10 | /** 11 | * Mybatis Plus 12 | * 13 | * 【需要被继承】 14 | * 15 | * @author langyastudio 16 | */ 17 | public class BaseMybatisConfig 18 | { 19 | @Bean 20 | public MybatisPlusInterceptor mybatisPlusInterceptor() 21 | { 22 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 23 | 24 | // 【分页】 25 | // 新的分页插件,一缓和二缓遵循mybatis的规则 26 | // 需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除) 27 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 28 | 29 | // 【安全】 30 | // 防止全表更新与删除 31 | interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); 32 | 33 | // 【乐观锁】 34 | // 当要更新一条记录的时候,希望这条记录没有被别人更新 35 | // 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime 36 | // 整数类型下 newVersion = oldVersion + 1 37 | // newVersion 会回写到 bean 中 38 | // 仅支持 updateById(id) 与 update(entity, wrapper) 方法 39 | interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); 40 | return interceptor; 41 | } 42 | } -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/BasDefine.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data; 2 | 3 | 4 | /** 5 | * 常量与配置文件 6 | *

7 | * 注意:表字段的常量值定义到ORM 8 | */ 9 | public class BasDefine 10 | { 11 | /** 12 | * 系统机构Id号 13 | */ 14 | public final static String SHOOL_SYSTEM_ID = "b4585b987a5e4f6aae3f334ab4a5c944"; 15 | 16 | public final static String PATTERN_USER_NAME = "^([a-zA-Z]{1}[_a-zA-Z0-9]{3,19})$"; 17 | public final static String PATTERN_PHONE = "^1[3,4,5,6,7,8,9]{1}[0-9]{9}$"; 18 | } -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/IErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data; 2 | 3 | /** 4 | * 封装API的错误码 5 | */ 6 | public interface IErrorCode 7 | { 8 | Integer getCode(); 9 | 10 | String getMsg(); 11 | } 12 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/PageIn.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.core.metadata.OrderItem; 5 | 6 | import java.util.*; 7 | 8 | 9 | /** 10 | * 自定义分页封装 11 | * 12 | * @param 13 | */ 14 | public class PageIn implements IPage 15 | { 16 | private static final long serialVersionUID = 1L; 17 | 18 | protected long offSet; 19 | protected long pageSize; 20 | protected List orders; 21 | 22 | protected long total; 23 | protected List list; 24 | 25 | public static PageIn of(long offSet, long pageSize) 26 | { 27 | return new PageIn<>(offSet, pageSize); 28 | } 29 | 30 | public PageIn(long offSet, long pageSize) 31 | { 32 | this(offSet, pageSize, null); 33 | } 34 | 35 | public PageIn(long offSet, long pageSize, List orders) 36 | { 37 | if (offSet < 0L) 38 | { 39 | this.offSet = 0; 40 | } 41 | if (orders == null) 42 | { 43 | orders = new ArrayList(); 44 | } 45 | 46 | this.offSet = offSet; 47 | this.pageSize = pageSize; 48 | this.orders = orders; 49 | this.list = Collections.emptyList(); 50 | } 51 | 52 | @Override 53 | public List getRecords() 54 | { 55 | return this.list; 56 | } 57 | 58 | @Override 59 | public PageIn setRecords(List records) 60 | { 61 | this.list = records; 62 | return this; 63 | } 64 | 65 | @Override 66 | public long getTotal() 67 | { 68 | return this.total; 69 | } 70 | 71 | @Override 72 | public PageIn setTotal(long total) 73 | { 74 | this.total = total; 75 | return this; 76 | } 77 | 78 | @Override 79 | public long getSize() 80 | { 81 | return this.pageSize; 82 | } 83 | 84 | @Override 85 | public PageIn setSize(long size) 86 | { 87 | this.pageSize = size; 88 | return this; 89 | } 90 | 91 | @Override 92 | public long offset() 93 | { 94 | return this.offSet; 95 | } 96 | 97 | @Override 98 | public List orders() 99 | { 100 | return this.getOrders(); 101 | } 102 | 103 | public List getOrders() 104 | { 105 | return this.orders; 106 | } 107 | 108 | public void setOrders(final List orders) 109 | { 110 | this.orders = orders; 111 | } 112 | 113 | @Override 114 | public Long maxLimit() 115 | { 116 | return 1000L; 117 | } 118 | 119 | @Override 120 | public long getCurrent() 121 | { 122 | return -1; 123 | } 124 | 125 | @Override 126 | public PageIn setCurrent(long current) 127 | { 128 | return this; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/PageInfo.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class PageInfo 13 | { 14 | /** 15 | * 总条数 16 | */ 17 | private Long total; 18 | /** 19 | * 列表 20 | */ 21 | private List list; 22 | } 23 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/ResultInfo.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data; 2 | 3 | import lombok.Data; 4 | import lombok.extern.log4j.Log4j2; 5 | 6 | /** 7 | * 返回值类 8 | */ 9 | @Data 10 | @Log4j2 11 | public class ResultInfo 12 | { 13 | private Integer code; 14 | private String msg; 15 | private Long time; 16 | private Object result; 17 | 18 | private ResultInfo(Integer code, String msg, Object result) 19 | { 20 | this.setCode(code); 21 | this.setResult(result); 22 | this.setMsg(msg); 23 | this.setTime(System.currentTimeMillis()); 24 | } 25 | 26 | /** 27 | * 返回正确提示 28 | * 29 | * @return Rv 30 | */ 31 | public static ResultInfo data() 32 | { 33 | return data(EC.SUCCESS.getCode(), EC.SUCCESS.getMsg(), null); 34 | } 35 | 36 | /** 37 | * 返回正确后的数据 38 | * 39 | * @param data 数据 40 | * 41 | * @return Rv 42 | */ 43 | public static ResultInfo data(Object data) 44 | { 45 | return data(EC.SUCCESS.getCode(), EC.SUCCESS.getMsg(), data); 46 | } 47 | 48 | /** 49 | * 返回状态码和信息 50 | * 51 | * @param code 状态码 52 | * @param msg 信息 53 | * 54 | * @return Rv 55 | */ 56 | public static ResultInfo data(Integer code, String msg) 57 | { 58 | return data(code, msg, null); 59 | } 60 | 61 | /** 62 | * 返回状态码,信息,数据 63 | * 64 | * @param code 状态码 65 | * @param msg 信息 66 | * @param data 数据 67 | * 68 | * @return Rv 69 | */ 70 | public static ResultInfo data(Integer code, String msg, Object data) 71 | { 72 | return new ResultInfo(code, msg, data); 73 | } 74 | 75 | /** 76 | * 返回错误提示 77 | * 78 | * @param ec EC 79 | * 80 | * @return 81 | */ 82 | public static ResultInfo data(IErrorCode ec) 83 | { 84 | return data(ec.getCode(), ec.getMsg(), null); 85 | } 86 | 87 | /** 88 | * 返回错误提示与数据 89 | * 90 | * @param ec EC 91 | * 92 | * @return 93 | */ 94 | public static ResultInfo data(IErrorCode ec, String msg) 95 | { 96 | return data(ec.getCode(), msg); 97 | } 98 | 99 | /** 100 | * 返回错误提示与数据 101 | * 102 | * @param ec EC 103 | * 104 | * @return 105 | */ 106 | public static ResultInfo data(IErrorCode ec, Object data) 107 | { 108 | return data(ec.getCode(), ec.getMsg(), data); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/validator/GroupInsert.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data.validator; 2 | 3 | import javax.validation.groups.Default; 4 | 5 | /** 6 | * 分组校验 - 添加操作 7 | * 8 | * @author jiangjiaxiong 9 | */ 10 | public interface GroupInsert extends Default 11 | { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/validator/GroupUpdate.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data.validator; 2 | 3 | import javax.validation.groups.Default; 4 | 5 | /** 6 | * 分组校验 - 更新操作 7 | * 8 | * @author jiangjiaxiong 9 | */ 10 | public interface GroupUpdate extends Default 11 | { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/validator/InValidator.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data.validator; 2 | 3 | import com.langyastudio.edu.common.anno.InValue; 4 | 5 | import javax.validation.ConstraintValidator; 6 | import javax.validation.ConstraintValidatorContext; 7 | 8 | /** 9 | * 状态值是否是指定值的校验器 10 | */ 11 | public class InValidator implements ConstraintValidator 12 | { 13 | private String[] values; 14 | 15 | @Override 16 | public void initialize(InValue flagValidator) 17 | { 18 | this.values = flagValidator.value(); 19 | } 20 | 21 | @Override 22 | public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) 23 | { 24 | boolean isValid = false; 25 | 26 | if (value == null) 27 | { 28 | //当状态为空时使用默认值 29 | return true; 30 | } 31 | 32 | for (String s : values) 33 | { 34 | if (s.equals(String.valueOf(value))) 35 | { 36 | isValid = true; 37 | break; 38 | } 39 | } 40 | 41 | return isValid; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/validator/PhoneOrEmptyValidator.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data.validator; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.langyastudio.edu.common.anno.PhoneOrEmpty; 5 | import com.langyastudio.edu.common.data.BasDefine; 6 | 7 | import javax.validation.ConstraintValidator; 8 | import javax.validation.ConstraintValidatorContext; 9 | 10 | /** 11 | * 手机号 or empty 12 | * 13 | * @author langyastudio 14 | */ 15 | public class PhoneOrEmptyValidator implements ConstraintValidator 16 | { 17 | @Override 18 | public void initialize(PhoneOrEmpty flagValidator) 19 | { 20 | } 21 | 22 | @Override 23 | public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) 24 | { 25 | if (StrUtil.isNotBlank(value)) 26 | { 27 | if (value.matches(BasDefine.PATTERN_PHONE)) 28 | { 29 | return true; 30 | } 31 | 32 | return false; 33 | } 34 | 35 | //当状态为空时使用默认值 36 | return true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/data/wrapper/RequestWrapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.data.wrapper; 2 | 3 | import javax.servlet.ReadListener; 4 | import javax.servlet.ServletInputStream; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletRequestWrapper; 7 | import java.io.*; 8 | 9 | 10 | /** 11 | * Request 请求数据复制 12 | * can replace by ContentCachingRequestWrapper 13 | */ 14 | public class RequestWrapper extends HttpServletRequestWrapper 15 | { 16 | private final byte[] body; 17 | private final ServletInputStream inputStream; 18 | private BufferedReader reader; 19 | 20 | public RequestWrapper(HttpServletRequest request) throws IOException 21 | { 22 | super(request); 23 | 24 | //读一次 然后缓存起来 25 | body = request.getInputStream().readAllBytes();; 26 | inputStream = new RequestCachingInputStream(body); 27 | } 28 | 29 | public byte[] getBody() 30 | { 31 | return body; 32 | } 33 | 34 | @Override 35 | public ServletInputStream getInputStream() throws IOException 36 | { 37 | if (inputStream != null) 38 | { 39 | return inputStream; 40 | } 41 | return super.getInputStream(); 42 | } 43 | 44 | @Override 45 | public BufferedReader getReader() throws IOException 46 | { 47 | if (reader == null) 48 | { 49 | reader = new BufferedReader(new InputStreamReader(inputStream, getCharacterEncoding())); 50 | } 51 | return reader; 52 | } 53 | 54 | //代理一下ServletInputStream 里面真是内容为当前缓存的bytes 55 | private static class RequestCachingInputStream extends ServletInputStream 56 | { 57 | private final ByteArrayInputStream inputStream; 58 | 59 | public RequestCachingInputStream(byte[] bytes) 60 | { 61 | inputStream = new ByteArrayInputStream(bytes); 62 | } 63 | 64 | @Override 65 | public int read() throws IOException 66 | { 67 | return inputStream.read(); 68 | } 69 | 70 | @Override 71 | public boolean isFinished() 72 | { 73 | return inputStream.available() == 0; 74 | } 75 | 76 | @Override 77 | public boolean isReady() 78 | { 79 | return true; 80 | } 81 | 82 | @Override 83 | public void setReadListener(ReadListener readlistener) 84 | { 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/entity/DesensitizationType.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.entity; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author MrBird 7 | */ 8 | @Getter 9 | public enum DesensitizationType 10 | { 11 | /** 12 | * 手机号脱敏 13 | */ 14 | PHONE("phone", "11位手机号", "^(\\d{3})\\d{4}(\\d{4})$", "$1****$2"), 15 | /** 16 | * 身份证号脱敏 17 | */ 18 | ID_CARD("idCard", "16或者18身份证号", "^(\\d{4})\\d{8,10}(\\w{4})$", "$1****$2"), 19 | /** 20 | * 银行卡号脱敏 21 | */ 22 | BANK_CARD("bankCardNo", "银行卡号", "^(\\d{4})\\d*(\\d{4})$", "$1****$2"), 23 | /** 24 | * 姓名脱敏 25 | */ 26 | NAME("name", "真实姓名", "(?<=.{1}).*(?=.{1})", "*"), 27 | /** 28 | * 邮箱脱敏 29 | */ 30 | EMAIL("email", "电子邮箱", "(\\w+)\\w{5}@(\\w+)", "$1***@$2"); 31 | 32 | String type; 33 | String describe; 34 | String[] regular; 35 | 36 | DesensitizationType(String type, String describe, String... regular) { 37 | this.type = type; 38 | this.describe = describe; 39 | this.regular = regular; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/entity/FileType.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.entity; 2 | 3 | /** 4 | * 文件类型 5 | * 6 | * @author jiangjiaxiong 7 | * @date 2021年05月13日 10:40 8 | */ 9 | public interface FileType 10 | { 11 | //-文件类型 12 | //文件夹 13 | public final static byte DIRECTORY = 0; 14 | //视频 15 | public final static byte VIDEO = 1; 16 | //图片 17 | public final static byte PICTURE = 2; 18 | //文本 19 | public final static byte TEXT = 3; 20 | //音频 21 | public final static byte AUDIO = 4; 22 | //其他 23 | public final static byte OTHER = 5; 24 | //压缩文件 25 | public final static byte RAR = 100; 26 | } 27 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/entity/LimitType.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.entity; 2 | 3 | public enum LimitType 4 | { 5 | /** 6 | * 传统类型 7 | */ 8 | CUSTOMER, 9 | /** 10 | * 根据 IP地址限制 11 | */ 12 | IP 13 | } 14 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/entity/UserAgentData.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.entity; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class UserAgentData 7 | { 8 | /** 9 | * 操作地点(济南) 10 | */ 11 | private String location; 12 | 13 | /** 14 | * 操作ip 15 | */ 16 | private Long ip; 17 | 18 | /** 19 | * 操作系统(Windows 10, MacOS 10) 20 | */ 21 | private String osName; 22 | 23 | /** 24 | * 浏览器(如 Chrome 87) 25 | */ 26 | private String browseName; 27 | } 28 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/entity/WebLog.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * 操作日志 9 | */ 10 | @Data 11 | public class WebLog 12 | { 13 | /** 14 | * 扩展信息 15 | */ 16 | private String schoolId; 17 | 18 | /** 19 | * 扩展信息 20 | */ 21 | private String userName; 22 | 23 | /** 24 | * 操作描述 25 | */ 26 | private String description; 27 | 28 | /** 29 | * 操作时间 30 | */ 31 | private Long startTime; 32 | 33 | /** 34 | * 消耗时间 35 | */ 36 | private Integer spendTime; 37 | 38 | /** 39 | * 根路径 40 | */ 41 | private String basePath; 42 | 43 | /** 44 | * URI 45 | */ 46 | private String uri; 47 | 48 | /** 49 | * URL 50 | */ 51 | private String url; 52 | 53 | /** 54 | * agent 55 | */ 56 | private UserAgentData userAgent; 57 | 58 | /** 59 | * 请求类型 60 | */ 61 | private String method; 62 | 63 | /** 64 | * 请求参数 65 | */ 66 | private Map parameter; 67 | 68 | /** 69 | * 请求返回的结果 70 | */ 71 | private Object result; 72 | } 73 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/exception/MyException.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.exception; 2 | 3 | import com.langyastudio.edu.common.data.EC; 4 | import com.langyastudio.edu.common.data.IErrorCode; 5 | 6 | /** 7 | * 自定义异常处理 8 | */ 9 | public class MyException extends RuntimeException 10 | { 11 | private Integer code; 12 | 13 | public MyException(IErrorCode ec) 14 | { 15 | super(ec.getMsg()); 16 | this.code = ec.getCode(); 17 | } 18 | 19 | public MyException(String msg) 20 | { 21 | super(msg); 22 | this.code = EC.ERROR.getCode(); 23 | } 24 | 25 | public MyException(Integer code, String msg) 26 | { 27 | super(msg); 28 | this.code = code; 29 | } 30 | 31 | public Integer getCode() 32 | { 33 | return code; 34 | } 35 | 36 | public void setCode(Integer code) 37 | { 38 | this.code = code; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/middleware/Interceptor/RequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.middleware.Interceptor; 2 | 3 | import com.langyastudio.edu.common.data.EC; 4 | import com.langyastudio.edu.common.exception.MyException; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.servlet.HandlerInterceptor; 7 | import org.springframework.web.servlet.ModelAndView; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | /** 13 | * 请求拦截器 14 | */ 15 | @Component 16 | public class RequestInterceptor implements HandlerInterceptor 17 | { 18 | @Override 19 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws MyException 20 | { 21 | String method = request.getMethod(); 22 | if (method != null && (!"GET".equals(method) && !"POST".equals(method))) 23 | { 24 | throw new MyException(EC.ERROR_REQUEST_METHOD_NOT_SUPPORT.getCode(), "仅支持GET和POST请求"); 25 | } 26 | 27 | String contentType = request.getContentType(); 28 | if (!"GET".equals(method) && contentType != null && (!contentType.contains("application/json") && 29 | !contentType.contains("multipart/form-data"))) 30 | { 31 | throw new MyException(EC.ERROR_REQUEST_METHOD_NOT_SUPPORT.getCode(),"POST请求仅支持application/json和multipart/form-data"); 32 | } 33 | 34 | return true; 35 | } 36 | 37 | @Override 38 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 39 | ModelAndView modelAndView) throws Exception 40 | { 41 | 42 | } 43 | 44 | @Override 45 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, 46 | Exception ex) throws Exception 47 | { 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/middleware/filter/CorsFilterBean.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.middleware.filter; 2 | 3 | import javax.servlet.*; 4 | 5 | import cn.hutool.core.util.StrUtil; 6 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.annotation.PostConstruct; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.io.IOException; 14 | import java.util.List; 15 | 16 | /** 17 | * Cors 跨域 18 | * 19 | * @author jiangjiaxiong 20 | */ 21 | @Order(1) 22 | @Component 23 | public class CorsFilterBean extends FilterRegistrationBean 24 | { 25 | @PostConstruct 26 | public void init() 27 | { 28 | setFilter(new CorsFilter()); 29 | setUrlPatterns(List.of("/admin/*", "/portal/*")); 30 | } 31 | 32 | class CorsFilter implements Filter 33 | { 34 | @Override 35 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 36 | throws IOException, ServletException 37 | { 38 | HttpServletRequest req = (HttpServletRequest) request; 39 | HttpServletResponse resp = (HttpServletResponse) response; 40 | 41 | // 跨域 42 | String uiDomain = null; 43 | String origin = req.getHeader("origin"); 44 | if (StrUtil.isNotBlank(origin)) 45 | { 46 | uiDomain = origin; 47 | } 48 | 49 | if (StrUtil.isNotBlank(uiDomain)) 50 | { 51 | String method = req.getMethod(); 52 | 53 | if ("OPTIONS".equals(method) || "POST".equals(method)) 54 | { 55 | resp.addHeader("Access-Control-Allow-Origin", uiDomain); 56 | resp.addHeader("Access-Control-Allow-Headers", "access-control-allow-origin," + 57 | "Authorization," + "school_id," + 58 | "token,Content-Type,Cookie,Origin, Referer,If-Match, If-Modified-Since, If-None-Match," + 59 | "If-Unmodified-Since, X-Requested-With,X_Requested_With"); 60 | resp.addHeader("Access-Control-Allow-Method", "GET, POST"); 61 | resp.addHeader("Access-Control-Allow-Credentials", "true"); 62 | 63 | // 在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据 64 | resp.addHeader("Access-Control-Max-Age", "1440"); 65 | } 66 | 67 | //P3P 68 | //跨域向IE写入cookie 69 | resp.addHeader("P3P", "CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI " + 70 | "DSP COR\""); 71 | 72 | // OPTIONS请求 73 | if ("OPTIONS".equals(method)) 74 | { 75 | //204 empty 76 | resp.setStatus(HttpServletResponse.SC_NO_CONTENT); 77 | return; 78 | } 79 | } 80 | resp.addHeader("Keep-Alive", "timeout=5, max=60"); 81 | 82 | chain.doFilter(request, response); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/middleware/handler/MybatisHandler.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.middleware.handler; 2 | 3 | import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; 4 | import lombok.extern.log4j.Log4j2; 5 | import org.apache.ibatis.reflection.MetaObject; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | /** 11 | * Mybatis 自动填充 12 | * xml语句需要有update_time create_time 字段! 13 | */ 14 | @Log4j2 15 | @Component 16 | public class MybatisHandler implements MetaObjectHandler 17 | { 18 | @Override 19 | public void insertFill(MetaObject metaObject) 20 | { 21 | this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); 22 | this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 23 | } 24 | 25 | @Override 26 | public void updateFill(MetaObject metaObject) 27 | { 28 | this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/service/LogService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.service; 2 | 3 | import com.langyastudio.edu.common.entity.WebLog; 4 | 5 | /** 6 | * 日志服务 7 | */ 8 | public interface LogService 9 | { 10 | /** 11 | * 写入系统日志 12 | * @param webLog 13 | */ 14 | void addLog(WebLog webLog); 15 | } 16 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/third/AliSms.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.third; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.aliyun.dysmsapi20170525.models.*; 5 | import com.aliyun.teaopenapi.models.*; 6 | import com.langyastudio.edu.common.exception.MyException; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Map; 10 | 11 | /** 12 | * 短信服务 13 | */ 14 | @Component 15 | public class AliSms 16 | { 17 | /** 18 | * 发送短信 19 | * 20 | * @param telPhone 手机号 21 | * @param accessKeyId accessKey 22 | * @param accessKeySecret secretKey 23 | * @param signName sign Name 24 | * @param templateCode template Name 25 | * @param mapParam param 26 | * 27 | * @return bool 28 | * 29 | * @throws Exception 30 | */ 31 | public Boolean sendMsg(String telPhone, String accessKeyId, String accessKeySecret, 32 | String signName, String templateCode, Map mapParam) throws Exception 33 | { 34 | //1.0 使用AK&SK初始化账号Client 35 | Config config = new Config() 36 | .setAccessKeyId(accessKeyId) 37 | .setAccessKeySecret(accessKeySecret); 38 | 39 | // 访问的域名 40 | config.endpoint = "dysmsapi.aliyuncs.com"; 41 | com.aliyun.dysmsapi20170525.Client client = new com.aliyun.dysmsapi20170525.Client(config); 42 | 43 | //2.0 设置短信发送参数 44 | SendSmsRequest sendSmsRequest = new SendSmsRequest() 45 | .setPhoneNumbers(telPhone) 46 | .setSignName(signName) 47 | .setTemplateCode(templateCode) 48 | .setTemplateParam(JSON.toJSONString(mapParam)); 49 | 50 | //3.0 发送短信 51 | SendSmsResponseBody response = client.sendSms(sendSmsRequest).getBody(); 52 | 53 | if ("OK".equals(response.getCode())) 54 | { 55 | return true; 56 | } 57 | 58 | throw new MyException(response.getMessage()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/util/AddressT.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.util; 2 | 3 | import cn.hutool.core.io.IoUtil; 4 | import cn.hutool.core.net.NetUtil; 5 | import lombok.Cleanup; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.lionsoul.ip2region.DataBlock; 8 | import org.lionsoul.ip2region.DbConfig; 9 | import org.lionsoul.ip2region.DbSearcher; 10 | import org.lionsoul.ip2region.Util; 11 | 12 | import java.io.*; 13 | import java.lang.reflect.Method; 14 | 15 | /** 16 | * @author MrBird 17 | */ 18 | @Log4j2 19 | public class AddressT 20 | { 21 | @SuppressWarnings("all") 22 | public static String getCityInfo(String ip) 23 | { 24 | if(NetUtil.isInnerIP(ip)) 25 | { 26 | return ""; 27 | } 28 | 29 | DbSearcher searcher = null; 30 | try 31 | { 32 | String dbPath = AddressT.class.getResource("/ip2region/ip2region.db").getPath(); 33 | File file = new File(dbPath); 34 | if (!file.exists()) 35 | { 36 | String tmpDir = System.getProperties().getProperty("java.io.tmpdir"); 37 | dbPath = tmpDir + "ip.db"; 38 | 39 | file = new File(dbPath); 40 | @Cleanup OutputStream outputStream = new FileOutputStream(file); 41 | @Cleanup InputStream inputStream = AddressT.class.getClassLoader() 42 | .getResourceAsStream("classpath:ip2region/ip2region.db"); 43 | 44 | IoUtil.copy(inputStream, outputStream); 45 | } 46 | 47 | int algorithm = DbSearcher.BTREE_ALGORITHM; 48 | DbConfig config = new DbConfig(); 49 | searcher = new DbSearcher(config, dbPath); 50 | Method method = null; 51 | switch (algorithm) 52 | { 53 | case DbSearcher.BTREE_ALGORITHM: 54 | method = searcher.getClass().getMethod("btreeSearch", String.class); 55 | break; 56 | case DbSearcher.BINARY_ALGORITHM: 57 | method = searcher.getClass().getMethod("binarySearch", String.class); 58 | break; 59 | case DbSearcher.MEMORY_ALGORITYM: 60 | method = searcher.getClass().getMethod("memorySearch", String.class); 61 | break; 62 | } 63 | 64 | DataBlock dataBlock = null; 65 | if (!Util.isIpAddress(ip)) 66 | { 67 | log.error("Error: Invalid ip address"); 68 | } 69 | dataBlock = (DataBlock) method.invoke(searcher, ip); 70 | 71 | return dataBlock.getRegion(); 72 | } 73 | catch (Exception e) 74 | { 75 | log.error("获取IP地址失败,{}", e.getMessage()); 76 | } 77 | finally 78 | { 79 | if (searcher != null) 80 | { 81 | try 82 | { 83 | searcher.close(); 84 | } 85 | catch (IOException e) 86 | { 87 | e.printStackTrace(); 88 | } 89 | } 90 | } 91 | return null; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/util/CryptoT.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.util; 2 | 3 | import cn.hutool.core.codec.Base64; 4 | import cn.hutool.core.util.StrUtil; 5 | import cn.hutool.crypto.symmetric.SymmetricAlgorithm; 6 | import cn.hutool.crypto.symmetric.SymmetricCrypto; 7 | import com.langyastudio.edu.common.exception.MyException; 8 | 9 | /** 10 | * 加密解密 11 | */ 12 | public class CryptoT 13 | { 14 | //随机生成密钥: Base64.encode(SecureUtil.generateKey(SymmetricAlgorithm.DESede.getValue()).getEncoded()); 15 | private static final String KEY_STR = "sxUWiV56j4UyLPF5MgFk4zJ/+xrmzfe6"; 16 | 17 | public static String encryptHex(String content) 18 | { 19 | byte[] key = Base64.decode(KEY_STR); 20 | SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DESede, key); 21 | 22 | //加密为16进制字符串(Hex表示) 23 | return des.encryptHex(content); 24 | } 25 | 26 | public static String decryptStr(String encryptHex) throws MyException 27 | { 28 | byte[] key = Base64.decode(KEY_STR); 29 | SymmetricCrypto des = new SymmetricCrypto(SymmetricAlgorithm.DESede, key); 30 | 31 | //解密为字符串 32 | String decryptStr; 33 | try 34 | { 35 | decryptStr = des.decryptStr(encryptHex); 36 | } 37 | catch (Exception e) 38 | { 39 | throw new MyException("解密失败:" + e.getMessage()); 40 | } 41 | 42 | if (StrUtil.isNotBlank(encryptHex) && StrUtil.isBlank(decryptStr)) 43 | { 44 | throw new MyException("解密失败"); 45 | } 46 | 47 | return decryptStr; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /edu-common/src/main/java/com/langyastudio/edu/common/util/SpringContextT.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.common.util; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * spring 上下文工具类 10 | */ 11 | @Component 12 | public class SpringContextT implements ApplicationContextAware 13 | { 14 | /** 15 | * 上下文对象实例 16 | */ 17 | private static ApplicationContext applicationContext; 18 | 19 | @Override 20 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 21 | { 22 | SpringContextT.applicationContext = applicationContext; 23 | } 24 | 25 | /** 26 | * 获取applicationContext 27 | * 28 | * @return 29 | */ 30 | public static ApplicationContext getApplicationContext() 31 | { 32 | return applicationContext; 33 | } 34 | 35 | /** 36 | * 通过name获取 Bean. 37 | * 38 | * @param name 39 | * 40 | * @return 41 | */ 42 | public static Object getBean(String name) 43 | { 44 | return getApplicationContext().getBean(name); 45 | } 46 | 47 | /** 48 | * 通过class获取Bean. 49 | * 50 | * @param clazz 51 | * @param 52 | * 53 | * @return 54 | */ 55 | public static T getBean(Class clazz) 56 | { 57 | return getApplicationContext().getBean(clazz); 58 | } 59 | 60 | /** 61 | * 通过name,以及Clazz返回指定的Bean 62 | * 63 | * @param name 64 | * @param clazz 65 | * @param 66 | * 67 | * @return 68 | */ 69 | public static T getBean(String name, Class clazz) 70 | { 71 | return getApplicationContext().getBean(name, clazz); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /edu-common/src/main/resources/ip2region/ip2region.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hacfins/spring-boot-2-api/2b62246ba1f113537767d294084c4c9da4b17807/edu-common/src/main/resources/ip2region/ip2region.db -------------------------------------------------------------------------------- /edu-common/src/main/resources/log4j2-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level}[%thread] %style{%logger{36}}{cyan} : %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /edu-common/src/main/resources/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsApiMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import java.util.List; 4 | import com.baomidou.mybatisplus.core.mapper.Mapper; 5 | import com.langyastudio.edu.db.model.UmsApi; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.cache.annotation.CacheConfig; 8 | import org.springframework.cache.annotation.Cacheable; 9 | 10 | /** 11 | * API 权限表 12 | * 逻辑Id号 - api_id 13 | */ 14 | @CacheConfig(cacheNames = "db" + ":umsapimapper") 15 | public interface UmsApiMapper extends Mapper 16 | { 17 | /*-------------------------------------------------------------------------------------------------------------- */ 18 | // cache 19 | /*-------------------------------------------------------------------------------------------------------------- */ 20 | /** 21 | * 根据 api_id 获取APi权限信息 22 | * @return 23 | */ 24 | @Cacheable(key = "#apiId", unless = "#result == null") 25 | UmsApi getInfoByApiId(@Param("apiId")String apiId); 26 | 27 | /** 28 | * 获取所有的ApiIds 29 | * @return 30 | */ 31 | List getApiIdsAll(); 32 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsDivisionMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsDivision; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.cache.annotation.CacheConfig; 7 | import org.springframework.cache.annotation.Cacheable; 8 | 9 | import java.util.List; 10 | 11 | @CacheConfig(cacheNames = "db" + ":umsdivisionmapper") 12 | public interface UmsDivisionMapper extends Mapper 13 | { 14 | /*-------------------------------------------------------------------------------------------------------------- */ 15 | // cache 16 | /*-------------------------------------------------------------------------------------------------------------- */ 17 | /** 18 | * 详情 19 | * @param pcdId 20 | * @return 21 | */ 22 | @Cacheable(key = "#pcdId", unless = "#result == null") 23 | UmsDivision getByPcdId(@Param("pcdId")Integer pcdId); 24 | 25 | /*-------------------------------------------------------------------------------------------------------------- */ 26 | // other 27 | /*-------------------------------------------------------------------------------------------------------------- */ 28 | /** 29 | * 30 | * 省市区列表 31 | * 32 | * @param parentId 33 | * @param level 34 | * @param self 35 | * @param path 36 | * @param min 37 | * @param max 38 | * @return 39 | */ 40 | List getPcdIdBySchoolIdAndSgId(@Param("parentId")Integer parentId, 41 | @Param("level")Integer level, @Param("self") Integer self, 42 | @Param("path") String path, @Param("min")Integer min, 43 | @Param("max")Integer max); 44 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsLogsMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.langyastudio.edu.common.data.PageIn; 4 | import org.apache.ibatis.annotations.Param; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.List; 8 | 9 | import com.baomidou.mybatisplus.core.mapper.Mapper; 10 | import com.langyastudio.edu.db.model.UmsLogs; 11 | 12 | /** 13 | * 操作日志 14 | * 逻辑Id号 - opId 15 | */ 16 | public interface UmsLogsMapper extends Mapper 17 | { 18 | /** 19 | * 插入日志记录 20 | * 21 | * @param record 日志 22 | * 23 | * @return 24 | */ 25 | int insertLog(UmsLogs record); 26 | 27 | /** 28 | * 日志列表 29 | * 30 | * @param schoolId 机构id号 31 | * @param likeSgPaths 分校 32 | * @param minCreateTime 开始时间 33 | * @param maxCreateTime 结束时间 34 | * @param likeUserName 用户名检索关键字 35 | * @param likeFullName 姓名检索关键字 36 | * @param likePhone 手机号检索关键字 37 | * @param userType 用户类型 38 | * @param range 分页 39 | * 40 | * @return 41 | */ 42 | PageIn getListBySchoolId(@Param("schoolId") String schoolId, 43 | @Param("likeSgPaths") List likeSgPaths, 44 | @Param("minCreateTime") LocalDateTime minCreateTime, 45 | @Param("maxCreateTime") LocalDateTime maxCreateTime, 46 | @Param("likeUserName") String likeUserName, 47 | @Param("likeFullName") String likeFullName, 48 | @Param("likePhone") String likePhone, 49 | @Param("userType") Byte userType, 50 | PageIn range); 51 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsRoleApisMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsRoleApis; 5 | 6 | import java.util.List; 7 | 8 | import org.apache.ibatis.annotations.Param; 9 | 10 | /** 11 | * UmsRole Api 映射表 12 | * 逻辑Id号 - roleId + apiId 13 | */ 14 | public interface UmsRoleApisMapper extends Mapper 15 | { 16 | /** 17 | * 批量插入roleId apiId映射数据 18 | * 19 | * @param list RoleApi 列表 20 | * 21 | * @return 22 | */ 23 | Integer batchInsertRoleApis(@Param("list") List list); 24 | 25 | /** 26 | * 批量删除 27 | * 28 | * @param roleId 角色Id号 29 | * @param apiIds apiId列表 30 | * 31 | * @return 32 | */ 33 | Integer batchDeleteByRoleId(@Param("roleId") String roleId, @Param("apiIds") List apiIds); 34 | 35 | /** 36 | * 获取ApiIds 37 | * 38 | * @param roleIds 角色Id号 39 | * 40 | * @return 41 | */ 42 | List getApiIdsByRoleId(@Param("roleIds") List roleIds); 43 | 44 | /** 45 | * 获取所有菜单的api_id 46 | * 47 | * @return 48 | */ 49 | List getMenuApiIds(@Param("roleIds") List roleIds); 50 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsRole; 5 | import com.langyastudio.edu.common.data.PageIn; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.cache.annotation.CacheConfig; 8 | import org.springframework.cache.annotation.CacheEvict; 9 | import org.springframework.cache.annotation.Cacheable; 10 | 11 | /** 12 | * 角色表 13 | * 14 | * 逻辑Id号 - role_id 15 | */ 16 | @CacheConfig(cacheNames = "db" + ":umsrolemapper") 17 | public interface UmsRoleMapper extends Mapper 18 | { 19 | /*-------------------------------------------------------------------------------------------------------------- */ 20 | // cache 21 | /*-------------------------------------------------------------------------------------------------------------- */ 22 | /** 23 | * 新增数据 24 | */ 25 | Integer insertRole(UmsRole record); 26 | 27 | /** 28 | * 根据角色Id号获取角色信息 29 | */ 30 | @Cacheable(key = "#roleId", unless = "#result == null") 31 | UmsRole getInfoByRoleId(@Param("roleId") String roleId); 32 | 33 | /** 34 | * 更新数据 35 | */ 36 | @CacheEvict(key = "#record.roleId", beforeInvocation=false) 37 | Integer updateRoleByRoleId(UmsRole record); 38 | 39 | /** 40 | * 删除数据 41 | */ 42 | @CacheEvict(key = "#roleId", beforeInvocation=false) 43 | Integer deleteByRoleId(@Param("roleId")String roleId); 44 | 45 | /*-------------------------------------------------------------------------------------------------------------- */ 46 | // other 47 | /*-------------------------------------------------------------------------------------------------------------- */ 48 | /** 49 | * 获取角色列表 50 | */ 51 | PageIn getRoleIdList(@Param("isSystem") Integer isSystem, @Param("isAsc") Integer isAsc, PageIn range); 52 | 53 | /** 54 | * 根据名称获取角色信息 55 | */ 56 | String existByRoleName(@Param("roleName")String roleName, @Param("roleId")String roleId); 57 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsUserAuthMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsUserAuth; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.cache.annotation.CacheConfig; 7 | import org.springframework.cache.annotation.CacheEvict; 8 | import org.springframework.cache.annotation.Cacheable; 9 | 10 | /** 11 | * 用户账号密钥 12 | * 逻辑Id号 - user_name 13 | * 14 | * 可以使用用户名或手机号登录 15 | */ 16 | @CacheConfig(cacheNames = "db" + ":umsuserauthmapper") 17 | public interface UmsUserAuthMapper extends Mapper 18 | { 19 | /*-------------------------------------------------------------------------------------------------------------- */ 20 | // cache 21 | /*-------------------------------------------------------------------------------------------------------------- */ 22 | /** 23 | * 插入用户账号 24 | * 25 | * @param umsUserAuth Bean 26 | * 27 | * @return 28 | */ 29 | Integer insertUserAuth(UmsUserAuth umsUserAuth); 30 | 31 | /** 32 | * 根据用户名获取用户信息 33 | * 34 | * @param userName 用户名 35 | * 36 | * @return 37 | */ 38 | @Cacheable(key = "#userName", unless = "#result == null") 39 | UmsUserAuth getInfoByUserName(@Param("userName") String userName); 40 | 41 | /** 42 | * 更新用户账号 43 | * @param record bean 44 | * @return 45 | */ 46 | @CacheEvict(key = "#record.userName", beforeInvocation=false) 47 | Integer updateByUserName(UmsUserAuth record); 48 | 49 | /*-------------------------------------------------------------------------------------------------------------- */ 50 | // other 51 | /*-------------------------------------------------------------------------------------------------------------- */ 52 | /** 53 | * 根据用户名获取用户密码信息 54 | * 55 | * !!这个函数较为特殊,没有使用缓存功能 56 | * 57 | * @param userName 用户名 58 | * @return 59 | */ 60 | UmsUserAuth getInfoByUserNameEx(@Param("userName") String userName); 61 | 62 | /** 63 | * 根据手机号获取用户名 64 | * 65 | * @param phone 手机号 66 | * 67 | * @return 68 | */ 69 | String getUserNameByPhone(@Param("phone") String phone); 70 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsUserLoginLogsMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.common.data.PageIn; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import com.langyastudio.edu.db.model.UmsUserLoginLogs; 8 | 9 | import java.time.LocalDateTime; 10 | import java.util.Map; 11 | 12 | /** 13 | * 用户登录表 14 | * 逻辑Id号 - id 15 | */ 16 | public interface UmsUserLoginLogsMapper extends Mapper 17 | { 18 | /** 19 | * 插入数据 20 | * 21 | * @param record 记录 22 | * @return 23 | */ 24 | int insertUserLoginLogs(UmsUserLoginLogs record); 25 | 26 | /** 27 | * 获取登录日志表 28 | * @param userName 用户名 29 | * 30 | * @return 31 | */ 32 | PageIn getListByUserName(@Param("userName")String userName, PageIn range); 33 | 34 | /** 35 | * 用户活跃度 36 | * 37 | * @param schoolId 38 | * @param minCreateTime 39 | * @param maxCreateTime 40 | * @param range 41 | * @return 42 | */ 43 | PageIn> getListByActive(@Param("schoolId") String schoolId, 44 | @Param("minCreateTime") LocalDateTime minCreateTime, 45 | @Param("maxCreateTime") LocalDateTime maxCreateTime, 46 | PageIn range); 47 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsUserMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsUser; 5 | import com.langyastudio.edu.common.data.PageIn; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.springframework.cache.annotation.CacheConfig; 8 | import org.springframework.cache.annotation.CacheEvict; 9 | import org.springframework.cache.annotation.Cacheable; 10 | 11 | /** 12 | * 用户表 13 | * 逻辑Id号 - user_name 14 | */ 15 | @CacheConfig(cacheNames = "db" + ":umsusermapper") 16 | public interface UmsUserMapper extends Mapper 17 | { 18 | /*-------------------------------------------------------------------------------------------------------------- */ 19 | // cache 20 | /*-------------------------------------------------------------------------------------------------------------- */ 21 | /** 22 | * 插入用户 23 | * 24 | * @param umsUser 用户bean 25 | * 26 | * @return 27 | */ 28 | Integer insertUser(UmsUser umsUser); 29 | 30 | /** 31 | * 获取用户信息 32 | * 33 | * @param userName 用户名 34 | * 35 | * @return 36 | */ 37 | @Cacheable(key = "#userName", unless = "#result == null") 38 | UmsUser getInfoByUserName(@Param("userName") String userName); 39 | 40 | /** 41 | * 根据user_name更新bean 42 | * 43 | * @param record UmsUser 44 | * 45 | * @return 46 | */ 47 | @CacheEvict(key = "#record.userName", beforeInvocation=false) 48 | Integer updateByUserName(UmsUser record); 49 | 50 | /*-------------------------------------------------------------------------------------------------------------- */ 51 | // other 52 | /*-------------------------------------------------------------------------------------------------------------- */ 53 | /** 54 | * 获取系统用户列表 55 | * 56 | * @param roleId 角色Id号 57 | * @param userNameKey 用户检索关键字 58 | * @param fullNameKey 姓名检索关键字 59 | * @param phoneKey 电话号码检索关键字 60 | * @param isAsc 是否升序 61 | * @param pageIn 分页 62 | * 63 | * @return 64 | */ 65 | PageIn getUserNameList(@Param("roleId") String roleId, 66 | @Param("userNameKey") String userNameKey, @Param("fullNameKey") String fullNameKey, 67 | @Param("phoneKey") String phoneKey, 68 | @Param("userType") Byte userType, 69 | @Param("isAsc") Integer isAsc, PageIn pageIn); 70 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsUserOauthsMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsUserOauths; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | /** 8 | * 第三方授权信息表 9 | * 逻辑Id号 - oauthId or userName + oAuthType 10 | */ 11 | public interface UmsUserOauthsMapper extends Mapper 12 | { 13 | /** 14 | * 插入数据 15 | * 16 | * @param record username+oauthtype 17 | * @return 18 | */ 19 | int insertUserOauth(UmsUserOauths record); 20 | 21 | /** 22 | * 软删除记录 23 | * 24 | * @param userName 用户名 25 | * @param oAuthType 第三方类型 26 | * 27 | * @return int 28 | */ 29 | int deleteByUserName(@Param("userName") String userName, @Param("oAuthType") Byte oAuthType); 30 | 31 | /** 32 | * 根据用户名获取第三方授权信息 33 | * 34 | * @param userName 用户名 35 | * @param oAuthType 第三方类型 36 | * 37 | * @return UmsUserOauths 38 | */ 39 | UmsUserOauths getByUserName(@Param("userName") String userName, @Param("oAuthType") Byte oAuthType); 40 | 41 | /** 42 | * 根据openid获取第三方授权信息 43 | * @param oauthId openid 44 | * @return 45 | */ 46 | String getUserNameByOauthId(@Param("oauthId")String oauthId); 47 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/mapper/UmsUserRolesMapper.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.Mapper; 4 | import com.langyastudio.edu.db.model.UmsUserRoles; 5 | 6 | import java.util.List; 7 | 8 | import org.apache.ibatis.annotations.Param; 9 | 10 | /** 11 | * 用户角色映射表 12 | * 逻辑Id号 - user_name+school_id 13 | * 14 | * 系统后台也理解为一个机构Id号 15 | */ 16 | public interface UmsUserRolesMapper extends Mapper 17 | { 18 | /** 19 | * 批量插入username school - roleid映射数据 20 | * 21 | * @param list UserRoles列表 22 | * 23 | * @return 24 | */ 25 | Integer batchInsertUserRoles(@Param("list") List list); 26 | 27 | /** 28 | * 批量删除 username school - roleid映射数据 29 | * 30 | * @param userName 用户名 31 | * @param schoolId 机构Id号 32 | * @param roleIds 角色Id号列表 33 | * 34 | * @return 35 | */ 36 | Integer batchDeleteByUserName(@Param("userName") String userName, 37 | @Param("schoolId") String schoolId, 38 | @Param("roleIds") List roleIds); 39 | 40 | /** 41 | * 获取用户对应的RoleId号列表 42 | * 43 | * @param userName 用户名 44 | * @param schoolIds 机构Id号列表 45 | * 46 | * @return 47 | */ 48 | List getRoleIdsByUserName(@Param("userName") String userName, 49 | @Param("schoolIds") List schoolIds); 50 | 51 | /** 52 | * 角色下时候有用户 53 | * 54 | * @param roleId 角色Id号 55 | * 56 | * @return 57 | */ 58 | String existUserNameByRoleId(@Param("roleId") String roleId); 59 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsApi.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 权限表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsApi 21 | { 22 | @JSONField(serialize = false) 23 | @TableId(type = IdType.AUTO) 24 | private Integer id; 25 | 26 | /** 27 | * 是否拥有该权限 28 | */ 29 | private Integer status; 30 | 31 | /** 32 | * 权限id号 33 | */ 34 | private String apiId; 35 | 36 | /** 37 | * 名称 38 | */ 39 | private String apiName; 40 | 41 | /** 42 | * 模块组 43 | */ 44 | private String apiModule; 45 | 46 | /** 47 | * 地址 48 | */ 49 | private String apiUrl; 50 | 51 | /** 52 | * 更新时间 53 | */ 54 | @JSONField(serialize = false) 55 | @TableField(fill = FieldFill.INSERT_UPDATE) 56 | private LocalDateTime updateTime; 57 | 58 | /** 59 | * 删除标记 60 | */ 61 | @JSONField(serialize = false) 62 | private LocalDateTime deleteTime; 63 | 64 | /** 65 | * 创建时间 66 | */ 67 | @JSONField(serialize = false) 68 | @TableField(fill = FieldFill.INSERT) 69 | private LocalDateTime createTime; 70 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsDivision.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 省市区表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsDivision 21 | { 22 | public static final int TOP_NODE_ID = 0; 23 | 24 | /** 25 | * 省市区id号 26 | */ 27 | @TableId(type = IdType.AUTO, value = "pcd_id") 28 | private Integer pcdId; 29 | 30 | /** 31 | * 名称 32 | */ 33 | private String pcdName; 34 | 35 | /** 36 | * 路径(A/B/C) 37 | */ 38 | private String pcdPath; 39 | 40 | /** 41 | * 父节点id号 42 | */ 43 | private Integer parentId; 44 | 45 | /** 46 | * 层级 47 | */ 48 | private Integer level; 49 | 50 | /** 51 | * 排序值 52 | */ 53 | private Integer sort; 54 | 55 | /** 56 | * 更新时间 57 | */ 58 | @JSONField(serialize = false) 59 | @TableField(fill = FieldFill.INSERT_UPDATE) 60 | private LocalDateTime updateTime; 61 | 62 | /** 63 | * 删除标记 64 | */ 65 | private LocalDateTime deleteTime; 66 | 67 | /** 68 | * 创建时间 69 | */ 70 | @JSONField(serialize = false) 71 | @TableField(fill = FieldFill.INSERT) 72 | private LocalDateTime createTime; 73 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsLogs.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 操作日志表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsLogs 21 | { 22 | @JSONField(serialize = false) 23 | @TableId(type = IdType.AUTO) 24 | private Integer id; 25 | 26 | /** 27 | * 操作id号 28 | */ 29 | private String opId; 30 | 31 | /** 32 | * 用户名 33 | */ 34 | private String userName; 35 | 36 | /** 37 | * 机构id号(系统也理解为一个机构) 38 | */ 39 | @JSONField(serialize = false) 40 | private String schoolId; 41 | 42 | /** 43 | * 操作的url(请求的URL地址) 44 | */ 45 | private String opUrl; 46 | 47 | /** 48 | * 操作说明 49 | */ 50 | private String opComment; 51 | 52 | /** 53 | * 操作的参数 54 | */ 55 | private String opParams; 56 | 57 | /** 58 | * 操作结果(操作成功/操作失败/操作异常等) 59 | */ 60 | private Integer opResult; 61 | 62 | /** 63 | * 耗时(微秒) 64 | */ 65 | private Integer useTime; 66 | 67 | /** 68 | * 操作地点(济南) 69 | */ 70 | private String location; 71 | 72 | /** 73 | * 操作ip 74 | */ 75 | private Long ip; 76 | 77 | /** 78 | * 操作系统(Windows 10, MacOS 10) 79 | */ 80 | private String osName; 81 | 82 | /** 83 | * 浏览器(如 Chrome 87) 84 | */ 85 | private String browseName; 86 | 87 | /** 88 | * 更新时间 89 | */ 90 | @JSONField(serialize = false) 91 | @TableField(fill = FieldFill.INSERT_UPDATE) 92 | private LocalDateTime updateTime; 93 | 94 | /** 95 | * 删除时间 96 | */ 97 | private LocalDateTime deleteTime; 98 | 99 | /** 100 | * 操作时间 101 | */ 102 | @TableField(fill = FieldFill.INSERT) 103 | private LocalDateTime createTime; 104 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsMessage.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 消息通知 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsMessage { 21 | 22 | /** 23 | * 机构、教室号、班级、用户 24 | */ 25 | public static final byte TYPE_SCHOOL = 1; 26 | public static final byte TYPE_ROOM = 2; 27 | public static final byte TYPE_CLASSES = 3; 28 | public static final byte TYPE_USER = 4; 29 | 30 | /** 31 | * 订阅、评论、点赞、通知 32 | */ 33 | public static final byte QUEUE_SUB = 1; 34 | public static final byte QUEUE_CHAT = 2; 35 | public static final byte QUEUE_UPVOTE = 3; 36 | public static final byte QUEUE_NOTICE = 4; 37 | 38 | private Integer id; 39 | 40 | /** 41 | * 消息id号 42 | */ 43 | private String msgId; 44 | 45 | /** 46 | * 发送消息者id号 47 | */ 48 | private String sendId; 49 | 50 | /** 51 | * 发送消息者类型(机构、教室号、班级、用户) 52 | */ 53 | private Integer sendType; 54 | 55 | /** 56 | * 接收消息者id号 57 | */ 58 | private String toId; 59 | 60 | /** 61 | * 接收消息者(机构、教室号、班级、用户) 62 | */ 63 | private Integer toType; 64 | 65 | /** 66 | * 事件id号(消息触发者) 67 | */ 68 | private String eventId; 69 | 70 | /** 71 | * 消息类型(订阅、评论、点赞、通知等) 72 | */ 73 | private Integer queue; 74 | 75 | /** 76 | * 消息标题 77 | */ 78 | private String msgTitle; 79 | 80 | /** 81 | * 消息内容(没有时,为空) 82 | */ 83 | private String msgContent; 84 | 85 | /** 86 | * 未读、已读 87 | */ 88 | private Byte status; 89 | 90 | /** 91 | * 更新时间 92 | */ 93 | @JSONField(serialize = false) 94 | @TableField(fill = FieldFill.INSERT_UPDATE) 95 | private LocalDateTime updateTime; 96 | 97 | /** 98 | * 删除标记 99 | */ 100 | private LocalDateTime deleteTime; 101 | 102 | /** 103 | * 创建时间 104 | */ 105 | @TableField(fill = FieldFill.INSERT) 106 | private LocalDateTime createTime; 107 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsRole.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.Data; 11 | 12 | /** 13 | * 角色表 14 | */ 15 | @Data 16 | public class UmsRole 17 | { 18 | /** 19 | * 访客角色Id号 20 | */ 21 | public final static String ROLE_GUEST_ID = "f477cce7e3ae44d0999ecbafae4fd6a4"; 22 | /** 23 | * 普通用户角色Id号 24 | */ 25 | public final static String ROLE_USER_ID = "4ba77b3d79ff4007bbf2b6a92bde35ee"; 26 | 27 | 28 | /** 29 | * 机构设备账号 30 | */ 31 | public final static String ROLE_SCHOOL_DEVICE_ID = "dcfd5a42fcc74ec0b12c67d68ed8545e"; 32 | /** 33 | * 机构讲师 34 | */ 35 | public final static String ROLE_SCHOOL_TEACHER_ID = "a1d03c0f5838466db325e2959782ca9f"; 36 | /** 37 | * 机构管理员角色Id号 38 | */ 39 | public final static String ROLE_SCHOOL_ADMIN_ID = "ed2691cb33a5494db472b79d76738aa4"; 40 | 41 | @JSONField(serialize = false) 42 | @TableId(type = IdType.AUTO) 43 | private Integer id; 44 | 45 | /** 46 | * 角色id号 47 | */ 48 | private String roleId; 49 | 50 | /** 51 | * 角色名称 52 | */ 53 | private String roleName; 54 | 55 | /** 56 | * 访问后台管理(1是、2否) 57 | */ 58 | @JSONField(serialize = false) 59 | private Integer viewSystem; 60 | 61 | /** 62 | * 访问机构管理(1是、2否) 63 | */ 64 | @JSONField(serialize = false) 65 | private Integer viewSchool; 66 | 67 | /** 68 | * 是否是系统类型(1,是;2,否) 69 | */ 70 | private Integer isSystem; 71 | 72 | /** 73 | * 角色类型(内置角色(不可删除)、普通角色) 74 | */ 75 | private Integer roleType; 76 | 77 | /** 78 | * 排序字段 79 | */ 80 | private Integer sort; 81 | 82 | /** 83 | * 描述信息 84 | */ 85 | private String description; 86 | 87 | /** 88 | * 更新时间 89 | */ 90 | @JSONField(serialize = false) 91 | @TableField(fill = FieldFill.INSERT_UPDATE) 92 | private LocalDateTime updateTime; 93 | 94 | /** 95 | * 删除标记 96 | */ 97 | private LocalDateTime deleteTime; 98 | 99 | /** 100 | * 创建时间 101 | */ 102 | @JSONField(serialize = false) 103 | @TableField(fill = FieldFill.INSERT) 104 | private LocalDateTime createTime; 105 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsRoleApis.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 角色权限映射表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsRoleApis 21 | { 22 | @JSONField(serialize = false) 23 | @TableId(type = IdType.AUTO) 24 | private Integer id; 25 | 26 | /** 27 | * 角色id号 28 | */ 29 | private String roleId; 30 | 31 | /** 32 | * 权限id号 33 | */ 34 | private String apiId; 35 | 36 | /** 37 | * 更新时间 38 | */ 39 | @JSONField(serialize = false) 40 | @TableField(fill = FieldFill.INSERT_UPDATE) 41 | private LocalDateTime updateTime; 42 | 43 | /** 44 | * 删除时间 45 | */ 46 | private LocalDateTime deleteTime; 47 | 48 | /** 49 | * 创建时间 50 | */ 51 | @JSONField(serialize = false) 52 | @TableField(fill = FieldFill.INSERT) 53 | private LocalDateTime createTime; 54 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsUser.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDate; 4 | import java.time.LocalDateTime; 5 | 6 | import com.alibaba.fastjson.annotation.JSONField; 7 | import com.baomidou.mybatisplus.annotation.FieldFill; 8 | import com.baomidou.mybatisplus.annotation.IdType; 9 | import com.baomidou.mybatisplus.annotation.TableField; 10 | import com.baomidou.mybatisplus.annotation.TableId; 11 | import lombok.AllArgsConstructor; 12 | import lombok.Data; 13 | import lombok.NoArgsConstructor; 14 | 15 | /** 16 | * 用户信息表 17 | */ 18 | @Data 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | public class UmsUser 22 | { 23 | /** 24 | * 账户 25 | */ 26 | public final static byte USER_TYPE_USER = 1; 27 | /** 28 | * 教室号账户 29 | */ 30 | public final static byte USER_TYPE_ROOM = 2; 31 | 32 | 33 | /** 34 | * 未知性别 35 | */ 36 | public final static String USER_SEX_UNKNOWN = "3"; 37 | public final static Integer USER_SEX_UNKNOWN_I = 3; 38 | 39 | /** 40 | * admin 用户名 41 | */ 42 | public final static String USER_ADMIN_NAME = "admin"; 43 | 44 | @JSONField(serialize = false) 45 | @TableId(type = IdType.AUTO) 46 | private Integer id; 47 | 48 | /** 49 | * 用户名 50 | */ 51 | private String userName; 52 | 53 | /** 54 | * 昵称 55 | */ 56 | private String nickName; 57 | 58 | /** 59 | * 姓名 60 | */ 61 | private String fullName; 62 | 63 | /** 64 | * 性别 65 | */ 66 | private Byte sex; 67 | 68 | /** 69 | * 用户头像 70 | */ 71 | private String avator; 72 | 73 | /** 74 | * 行政区划代码 75 | */ 76 | private Integer pcdId; 77 | 78 | /** 79 | * 联系地址 80 | */ 81 | private String company; 82 | 83 | /** 84 | * 生日 85 | */ 86 | private LocalDate birthday; 87 | 88 | /** 89 | * 描述信息 90 | */ 91 | private String description; 92 | 93 | /** 94 | * 注册IP 95 | */ 96 | private Long regIp; 97 | 98 | /** 99 | * 账户类型 100 | */ 101 | private Byte userType; 102 | 103 | /** 104 | * 更新时间 105 | */ 106 | @JSONField(serialize = false) 107 | @TableField(fill = FieldFill.INSERT_UPDATE) 108 | private LocalDateTime updateTime; 109 | 110 | /** 111 | * 删除时间 112 | */ 113 | private LocalDateTime deleteTime; 114 | 115 | /** 116 | * 创建时间 117 | */ 118 | @TableField(fill = FieldFill.INSERT) 119 | private LocalDateTime createTime; 120 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsUserAuth.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 本地授权信息表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsUserAuth 21 | { 22 | /** 23 | * 可用 24 | */ 25 | public static final byte USER_AUTH_ENABLED_YES = 1; 26 | /** 27 | * 不可用 28 | */ 29 | public static final byte USER_AUTH_ENABLED_NO = 2; 30 | 31 | /** 32 | * 未知性别 33 | */ 34 | public static final String USER_AUTH_PWD = "123456a"; 35 | 36 | @JSONField(serialize = false) 37 | @TableId(type = IdType.AUTO) 38 | private Integer id; 39 | 40 | /** 41 | * 用户名 42 | */ 43 | private String userName; 44 | 45 | /** 46 | * 密码 47 | */ 48 | @JSONField(serialize = false) 49 | private String pwd; 50 | 51 | /** 52 | * 手机号码 53 | */ 54 | private String phone; 55 | 56 | /** 57 | * 邮箱 58 | */ 59 | private String email; 60 | 61 | /** 62 | * 状态 63 | */ 64 | private Byte enabled; 65 | 66 | /** 67 | * 锁 68 | */ 69 | private Byte locked; 70 | 71 | /** 72 | * 更新时间 73 | */ 74 | @JSONField(serialize = false) 75 | @TableField(fill = FieldFill.INSERT_UPDATE) 76 | private LocalDateTime updateTime; 77 | 78 | /** 79 | * 删除时间 80 | */ 81 | @JSONField(serialize = false) 82 | private LocalDateTime deleteTime; 83 | 84 | /** 85 | * 创建时间 86 | */ 87 | @JSONField(serialize = false) 88 | @TableField(fill = FieldFill.INSERT) 89 | private LocalDateTime createTime; 90 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsUserLoginLogs.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 用户登录表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsUserLoginLogs 21 | { 22 | @JSONField(serialize = false) 23 | @TableId(type = IdType.AUTO) 24 | private Integer id; 25 | 26 | /** 27 | * 用户名 28 | */ 29 | private String userName; 30 | 31 | /** 32 | * 操作地点(济南) 33 | */ 34 | private String location; 35 | 36 | /** 37 | * 操作ip 38 | */ 39 | private Long ip; 40 | 41 | /** 42 | * 操作系统(Windows 10, MacOS 10) 43 | */ 44 | private String osName; 45 | 46 | /** 47 | * 浏览器(如 Chrome 87) 48 | */ 49 | private String browseName; 50 | 51 | /** 52 | * 更新时间 53 | */ 54 | @JSONField(serialize = false) 55 | @TableField(fill = FieldFill.INSERT_UPDATE) 56 | private LocalDateTime updateTime; 57 | 58 | /** 59 | * 删除时间 60 | */ 61 | private LocalDateTime deleteTime; 62 | 63 | /** 64 | * 登录时间 65 | */ 66 | @TableField(fill = FieldFill.INSERT) 67 | private LocalDateTime createTime; 68 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsUserOauths.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 第三方授权信息表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsUserOauths 21 | { 22 | @JSONField(serialize = false) 23 | @TableId(type = IdType.AUTO) 24 | private Integer id; 25 | 26 | /** 27 | * 第三方应用的唯一标识 28 | */ 29 | private String oauthId; 30 | 31 | /** 32 | * 用户名 33 | */ 34 | private String userName; 35 | 36 | /** 37 | * 第三方应用类型 38 | */ 39 | private Byte oauthType; 40 | 41 | /** 42 | * 更新时间 43 | */ 44 | @JSONField(serialize = false) 45 | @TableField(fill = FieldFill.INSERT_UPDATE) 46 | private LocalDateTime updateTime; 47 | 48 | /** 49 | * 删除时间 50 | */ 51 | private LocalDateTime deleteTime; 52 | 53 | /** 54 | * 创建时间 55 | */ 56 | @JSONField(serialize = false) 57 | @TableField(fill = FieldFill.INSERT) 58 | private LocalDateTime createTime; 59 | } -------------------------------------------------------------------------------- /edu-db/src/main/java/com/langyastudio/edu/db/model/UmsUserRoles.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.db.model; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.alibaba.fastjson.annotation.JSONField; 6 | import com.baomidou.mybatisplus.annotation.FieldFill; 7 | import com.baomidou.mybatisplus.annotation.IdType; 8 | import com.baomidou.mybatisplus.annotation.TableField; 9 | import com.baomidou.mybatisplus.annotation.TableId; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | /** 15 | * 用户角色映射表 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class UmsUserRoles 21 | { 22 | @JSONField(serialize = false) 23 | @TableId(type = IdType.AUTO) 24 | private Integer id; 25 | 26 | /** 27 | * 用户名 28 | */ 29 | private String userName; 30 | 31 | /** 32 | * 角色id号 33 | */ 34 | private String roleId; 35 | 36 | /** 37 | * 机构id号(系统也理解为一个机构) 38 | */ 39 | private String schoolId; 40 | 41 | /** 42 | * 更新时间 43 | */ 44 | @JSONField(serialize = false) 45 | @TableField(fill = FieldFill.INSERT_UPDATE) 46 | private LocalDateTime updateTime; 47 | 48 | /** 49 | * 删除时间 50 | */ 51 | private LocalDateTime deleteTime; 52 | 53 | /** 54 | * 创建时间 55 | */ 56 | @JSONField(serialize = false) 57 | @TableField(fill = FieldFill.INSERT) 58 | private LocalDateTime createTime; 59 | } -------------------------------------------------------------------------------- /edu-db/src/main/resources/mapper/UmsApiMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | id, api_id, api_name, api_module, api_url, update_time, delete_time, create_time 20 | 21 | 22 | 23 | 31 | 32 | 33 | 38 | -------------------------------------------------------------------------------- /edu-db/src/main/resources/mapper/UmsDivisionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | pcd_id, pcd_name, pcd_path, parent_id, `level`, sort, update_time, delete_time, create_time 20 | 21 | 22 | 23 | 31 | 32 | 33 | 49 | 50 | -------------------------------------------------------------------------------- /edu-db/src/main/resources/mapper/UmsUserRolesMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | id, user_name, role_id, school_id, update_time, delete_time, create_time 19 | 20 | 21 | 22 | 23 | insert into ums_user_roles 24 | (user_name, role_id, school_id, update_time, create_time) 25 | values 26 | 27 | (#{item.userName,jdbcType=VARCHAR}, #{item.roleId,jdbcType=CHAR}, #{item.schoolId,jdbcType=CHAR}, 28 | #{item.updateTime,jdbcType=TIMESTAMP}, #{item.createTime,jdbcType=TIMESTAMP}) 29 | 30 | 31 | 32 | 33 | 34 | update ums_user_roles 35 | set delete_time = now() 36 | where user_name = #{userName,jdbcType=VARCHAR} 37 | and school_id = #{schoolId,jdbcType=CHAR} 38 | and role_id in 39 | 40 | (#{roleId,jdbcType=CHAR}) 41 | 42 | 43 | 44 | 45 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /edu-security/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | edu-security 8 | 1.3.0 9 | jar 10 | edu-security 11 | edu-security project for edu 12 | 13 | 14 | com.langyastudio.edu 15 | edu 16 | 1.3.0 17 | 18 | 19 | 20 | 21 | com.langyastudio.edu 22 | edu-common 23 | 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-security 29 | 30 | 31 | 32 | me.zhyd.oauth 33 | JustAuth 34 | 35 | 36 | 37 | io.jsonwebtoken 38 | jjwt 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/annotation/CacheException.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 自定义注解,有该注解的缓存方法会抛出异常 7 | */ 8 | @Documented 9 | @Target(ElementType.METHOD) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | public @interface CacheException { 12 | } 13 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/aspect/RedisCacheAspect.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.aspect; 2 | 3 | import com.langyastudio.edu.security.annotation.CacheException; 4 | import lombok.extern.log4j.Log4j2; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.Signature; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | import org.aspectj.lang.reflect.MethodSignature; 11 | import org.springframework.core.annotation.Order; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.lang.reflect.Method; 15 | 16 | /** 17 | * Redis缓存切面,防止Redis宕机影响正常业务逻辑 18 | * Created by macro on 2020/3/17. 19 | */ 20 | @Aspect 21 | @Component 22 | @Order(2) 23 | @Log4j2 24 | public class RedisCacheAspect 25 | { 26 | @Pointcut("execution(public * com.langyastudio.admin.service.*CacheService.*(..)) || execution(public * com.langyastudio" + 27 | ".course.service.*CacheService.*(..))") 28 | public void cacheAspect() 29 | { 30 | } 31 | 32 | @Around("cacheAspect()") 33 | public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable 34 | { 35 | Signature signature = joinPoint.getSignature(); 36 | MethodSignature methodSignature = (MethodSignature) signature; 37 | Method method = methodSignature.getMethod(); 38 | Object result = null; 39 | 40 | try 41 | { 42 | result = joinPoint.proceed(); 43 | } 44 | catch (Throwable throwable) 45 | { 46 | //有CacheException注解的方法需要抛出异常 47 | if (method.isAnnotationPresent(CacheException.class)) 48 | { 49 | throw throwable; 50 | } 51 | else 52 | { 53 | log.error(throwable.getMessage()); 54 | } 55 | } 56 | 57 | return result; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/component/DynamicAccessDecisionManager.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.component; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import org.springframework.security.access.AccessDecisionManager; 5 | import org.springframework.security.access.AccessDeniedException; 6 | import org.springframework.security.access.ConfigAttribute; 7 | import org.springframework.security.authentication.InsufficientAuthenticationException; 8 | import org.springframework.security.core.Authentication; 9 | import org.springframework.security.core.GrantedAuthority; 10 | import org.springframework.security.core.userdetails.UserDetails; 11 | 12 | import java.util.Collection; 13 | import java.util.Iterator; 14 | import java.util.Objects; 15 | 16 | /** 17 | * 动态权限决策管理器 - 用于判断用户是否有访问权限 18 | */ 19 | public class DynamicAccessDecisionManager implements AccessDecisionManager 20 | { 21 | @Override 22 | public void decide(Authentication authentication, Object object, 23 | Collection configAttributes) throws AccessDeniedException, 24 | InsufficientAuthenticationException 25 | { 26 | // 当接口未被配置资源时直接放行 27 | if (CollUtil.isEmpty(configAttributes)) 28 | { 29 | return; 30 | } 31 | 32 | // Todo: 是否有更好方案 33 | // 超级管理员 34 | Object principal = authentication.getPrincipal(); 35 | if (principal instanceof UserDetails) 36 | { 37 | String userName = ((UserDetails) principal).getUsername(); 38 | if(Objects.nonNull(userName) && "admin".equals(userName)) 39 | { 40 | return; 41 | } 42 | } 43 | 44 | Iterator iterator = configAttributes.iterator(); 45 | while (iterator.hasNext()) 46 | { 47 | ConfigAttribute configAttribute = iterator.next(); 48 | 49 | //将访问所需资源或用户拥有资源进行比对 50 | String needAuthority = configAttribute.getAttribute(); 51 | for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) 52 | { 53 | if (needAuthority.trim().equals(grantedAuthority.getAuthority())) 54 | { 55 | return; 56 | } 57 | } 58 | } 59 | 60 | throw new AccessDeniedException("抱歉,您没有访问权限"); 61 | } 62 | 63 | @Override 64 | public boolean supports(ConfigAttribute configAttribute) 65 | { 66 | return true; 67 | } 68 | 69 | @Override 70 | public boolean supports(Class aClass) 71 | { 72 | return true; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/component/DynamicSecurityFilter.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.component; 2 | 3 | import com.langyastudio.edu.security.config.IgnoreUrlsConfig; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.http.HttpMethod; 6 | import org.springframework.security.access.SecurityMetadataSource; 7 | import org.springframework.security.access.intercept.AbstractSecurityInterceptor; 8 | import org.springframework.security.access.intercept.InterceptorStatusToken; 9 | import org.springframework.security.web.FilterInvocation; 10 | import org.springframework.util.AntPathMatcher; 11 | import org.springframework.util.PathMatcher; 12 | 13 | import javax.servlet.*; 14 | import javax.servlet.http.HttpServletRequest; 15 | import java.io.IOException; 16 | 17 | /** 18 | * 动态权限过滤器 - 用于实现基于路径的动态权限过滤 19 | */ 20 | public class DynamicSecurityFilter extends AbstractSecurityInterceptor implements Filter 21 | { 22 | @Autowired 23 | private DynamicSecurityMetadataSource dynamicSecurityMetadataSource; 24 | @Autowired 25 | private IgnoreUrlsConfig ignoreUrlsConfig; 26 | 27 | @Autowired 28 | public void setMyAccessDecisionManager(DynamicAccessDecisionManager dynamicAccessDecisionManager) 29 | { 30 | super.setAccessDecisionManager(dynamicAccessDecisionManager); 31 | } 32 | 33 | @Override 34 | public void init(FilterConfig filterConfig) throws ServletException 35 | { 36 | } 37 | 38 | @Override 39 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException 40 | { 41 | HttpServletRequest request = (HttpServletRequest) servletRequest; 42 | FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain); 43 | 44 | //OPTIONS请求直接放行 45 | if (request.getMethod().equals(HttpMethod.OPTIONS.toString())) 46 | { 47 | fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); 48 | return; 49 | } 50 | 51 | String uri = request.getRequestURI(); 52 | 53 | //白名单请求直接放行 54 | PathMatcher pathMatcher = new AntPathMatcher(); 55 | for (String path : ignoreUrlsConfig.getUrls()) 56 | { 57 | if (pathMatcher.match(path, uri)) 58 | { 59 | fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); 60 | return; 61 | } 62 | } 63 | 64 | //此处会调用AccessDecisionManager中的decide方法进行鉴权操作 65 | InterceptorStatusToken token = super.beforeInvocation(fi); 66 | try 67 | { 68 | fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); 69 | } 70 | finally 71 | { 72 | super.afterInvocation(token, null); 73 | } 74 | } 75 | 76 | @Override 77 | public void destroy() 78 | { 79 | } 80 | 81 | @Override 82 | public Class getSecureObjectClass() 83 | { 84 | return FilterInvocation.class; 85 | } 86 | 87 | @Override 88 | public SecurityMetadataSource obtainSecurityMetadataSource() 89 | { 90 | return dynamicSecurityMetadataSource; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/component/DynamicSecurityMetadataSource.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.component; 2 | 3 | import cn.hutool.core.util.URLUtil; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.security.access.ConfigAttribute; 6 | import org.springframework.security.web.FilterInvocation; 7 | import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; 8 | import org.springframework.util.AntPathMatcher; 9 | import org.springframework.util.PathMatcher; 10 | 11 | import javax.annotation.PostConstruct; 12 | import java.util.*; 13 | 14 | /** 15 | * 动态权限数据源,用于获取动态权限规则 16 | */ 17 | public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource 18 | { 19 | private static Map configAttributeMap = null; 20 | @Autowired 21 | private DynamicSecurityService dynamicSecurityService; 22 | 23 | @PostConstruct 24 | public void loadDataSource() 25 | { 26 | configAttributeMap = dynamicSecurityService.loadDataSource(); 27 | } 28 | 29 | public void clearDataSource() 30 | { 31 | configAttributeMap.clear(); 32 | configAttributeMap = null; 33 | } 34 | 35 | @Override 36 | public Collection getAttributes(Object o) throws IllegalArgumentException 37 | { 38 | if (configAttributeMap == null) 39 | { 40 | this.loadDataSource(); 41 | } 42 | 43 | //获取当前访问的路径 44 | String url = ((FilterInvocation) o).getRequestUrl(); 45 | String path = URLUtil.getPath(url); 46 | PathMatcher pathMatcher = new AntPathMatcher(); 47 | Iterator iterator = configAttributeMap.keySet().iterator(); 48 | 49 | //获取访问该路径所需资源 50 | List configAttributes = new ArrayList<>(); 51 | while (iterator.hasNext()) 52 | { 53 | String pattern = iterator.next(); 54 | if (pathMatcher.match(pattern, path)) 55 | { 56 | configAttributes.add(configAttributeMap.get(pattern)); 57 | } 58 | } 59 | 60 | // 未设置操作请求权限,返回空集合 61 | return configAttributes; 62 | } 63 | 64 | @Override 65 | public Collection getAllConfigAttributes() 66 | { 67 | return null; 68 | } 69 | 70 | @Override 71 | public boolean supports(Class aClass) 72 | { 73 | return true; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/component/DynamicSecurityService.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.component; 2 | 3 | import org.springframework.security.access.ConfigAttribute; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * 动态权限相关业务类 9 | */ 10 | public interface DynamicSecurityService 11 | { 12 | /** 13 | * 加载资源ANT通配符和资源对应MAP 14 | */ 15 | Map loadDataSource(); 16 | } 17 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/component/RestAuthenticationEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.component; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.json.JSONUtil; 5 | import com.alibaba.fastjson.JSON; 6 | import com.langyastudio.edu.common.data.EC; 7 | import com.langyastudio.edu.common.data.ResultInfo; 8 | import org.springframework.security.core.AuthenticationException; 9 | import org.springframework.security.web.AuthenticationEntryPoint; 10 | 11 | import javax.servlet.ServletException; 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.io.IOException; 15 | import java.util.regex.Pattern; 16 | 17 | /** 18 | * 自定义返回结果:未登录或登录过期 19 | */ 20 | public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint 21 | { 22 | private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*"); 23 | 24 | @Override 25 | public void commence(HttpServletRequest request, HttpServletResponse response, 26 | AuthenticationException authException) throws IOException, ServletException 27 | { 28 | response.setHeader("Cache-Control", "no-cache"); 29 | response.setCharacterEncoding("UTF-8"); 30 | 31 | ResultInfo resultInfo = ResultInfo.data(EC.ERROR_USER_UNAUTHORIZED, authException.getMessage()); 32 | 33 | //兼容jsonp请求 34 | String functionName = request.getParameter("callback"); 35 | if (functionName != null && this.isValidJsonpQueryParam(functionName)) 36 | { 37 | String text = JSON.toJSONString(resultInfo); 38 | String jsonpText = functionName + "(" + text + ")"; 39 | 40 | //jsonp content 41 | response.setStatus(200); 42 | response.setContentType("application/javascript"); 43 | response.getWriter().print(jsonpText); 44 | } 45 | else 46 | { 47 | // 跨域 48 | String uiDomain = null; 49 | String origin = request.getHeader("origin"); 50 | if (StrUtil.isNotBlank(origin)) 51 | { 52 | uiDomain = origin; 53 | } 54 | 55 | if (StrUtil.isNotBlank(uiDomain)) 56 | { 57 | String method = request.getMethod(); 58 | if ("OPTIONS".equals(method) || "POST".equals(method)) 59 | { 60 | response.addHeader("Access-Control-Allow-Origin", uiDomain); 61 | response.addHeader("Access-Control-Allow-Credentials", "true"); 62 | 63 | // 在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据 64 | response.addHeader("Access-Control-Max-Age", "1440"); 65 | } 66 | } 67 | 68 | //返回数据 69 | response.setContentType("application/json"); 70 | response.getWriter().println(JSONUtil.parse(resultInfo)); 71 | } 72 | 73 | response.getWriter().flush(); 74 | } 75 | 76 | protected boolean isValidJsonpQueryParam(String value) 77 | { 78 | return CALLBACK_PARAM_PATTERN.matcher(value).matches(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/component/RestfulAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.component; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.json.JSONUtil; 5 | import com.alibaba.fastjson.JSON; 6 | import org.springframework.security.access.AccessDeniedException; 7 | import org.springframework.security.web.access.AccessDeniedHandler; 8 | 9 | import javax.servlet.ServletException; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.IOException; 13 | import java.util.regex.Pattern; 14 | 15 | import com.langyastudio.edu.common.data.EC; 16 | import com.langyastudio.edu.common.data.ResultInfo; 17 | 18 | /** 19 | * 自定义返回结果:没有权限访问时 20 | */ 21 | public class RestfulAccessDeniedHandler implements AccessDeniedHandler 22 | { 23 | private static final Pattern CALLBACK_PARAM_PATTERN = Pattern.compile("[0-9A-Za-z_\\.]*"); 24 | 25 | @Override 26 | public void handle(HttpServletRequest request, 27 | HttpServletResponse response, 28 | AccessDeniedException e) throws IOException, ServletException 29 | { 30 | response.setHeader("Cache-Control", "no-cache"); 31 | response.setCharacterEncoding("UTF-8"); 32 | 33 | ResultInfo resultInfo = ResultInfo.data(EC.ERROR_USER_FORBIDDEN, e.getMessage()); 34 | 35 | //兼容jsonp请求 36 | String functionName = request.getParameter("callback"); 37 | if (functionName != null && this.isValidJsonpQueryParam(functionName)) 38 | { 39 | String text = JSON.toJSONString(resultInfo); 40 | String jsonpText = functionName + "(" + text + ")"; 41 | 42 | //jsonp content 43 | response.setContentType("application/javascript"); 44 | response.getWriter().print(jsonpText); 45 | } 46 | else 47 | { 48 | // 跨域 49 | String uiDomain = null; 50 | String origin = request.getHeader("origin"); 51 | if (StrUtil.isNotBlank(origin)) 52 | { 53 | uiDomain = origin; 54 | } 55 | 56 | if (StrUtil.isNotBlank(uiDomain)) 57 | { 58 | String method = request.getMethod(); 59 | if ("OPTIONS".equals(method) || "POST".equals(method)) 60 | { 61 | response.addHeader("Access-Control-Allow-Origin", uiDomain); 62 | response.addHeader("Access-Control-Allow-Credentials", "true"); 63 | 64 | // 在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据 65 | response.addHeader("Access-Control-Max-Age", "1440"); 66 | } 67 | } 68 | 69 | //返回数据 70 | response.setContentType("application/json"); 71 | response.getWriter().println(JSONUtil.parse(resultInfo)); 72 | } 73 | 74 | response.getWriter().flush(); 75 | } 76 | 77 | protected boolean isValidJsonpQueryParam(String value) 78 | { 79 | return CALLBACK_PARAM_PATTERN.matcher(value).matches(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/config/IgnoreUrlsConfig.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * 用于配置白名单资源路径 11 | */ 12 | @Data 13 | @ConfigurationProperties(prefix = "secure.ignored") 14 | public class IgnoreUrlsConfig 15 | { 16 | private List urls = new ArrayList<>(); 17 | } 18 | -------------------------------------------------------------------------------- /edu-security/src/main/java/com/langyastudio/edu/security/util/SpringContextUtil.java: -------------------------------------------------------------------------------- 1 | package com.langyastudio.edu.security.util; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * spring 上下文工具类 10 | */ 11 | @Component 12 | public class SpringContextUtil implements ApplicationContextAware 13 | { 14 | /** 15 | * 上下文对象实例 16 | */ 17 | private static ApplicationContext applicationContext; 18 | 19 | @Override 20 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 21 | { 22 | SpringContextUtil.applicationContext = applicationContext; 23 | } 24 | 25 | /** 26 | * 获取applicationContext 27 | * 28 | * @return 29 | */ 30 | public static ApplicationContext getApplicationContext() 31 | { 32 | return applicationContext; 33 | } 34 | 35 | /** 36 | * 通过name获取 Bean. 37 | * 38 | * @param name 39 | * 40 | * @return 41 | */ 42 | public static Object getBean(String name) 43 | { 44 | return getApplicationContext().getBean(name); 45 | } 46 | 47 | /** 48 | * 通过class获取Bean. 49 | * 50 | * @param clazz 51 | * @param 52 | * 53 | * @return 54 | */ 55 | public static T getBean(Class clazz) 56 | { 57 | return getApplicationContext().getBean(clazz); 58 | } 59 | 60 | /** 61 | * 通过name,以及Clazz返回指定的Bean 62 | * 63 | * @param name 64 | * @param clazz 65 | * @param 66 | * 67 | * @return 68 | */ 69 | public static T getBean(String name, Class clazz) 70 | { 71 | return getApplicationContext().getBean(name, clazz); 72 | } 73 | } 74 | --------------------------------------------------------------------------------