Commit 98761ef1d3ea070d1b547d556c27da06c880a5dc
Committed by
Gitee
!44 增加 yudao-user-server 服务
Merge pull request !44 from 芋道源码/feature/user-admin-server
Showing
56 changed files
with
1691 additions
and
26 deletions
pom.xml
| @@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
| 11 | <module>yudao-dependencies</module> | 11 | <module>yudao-dependencies</module> |
| 12 | <module>yudao-framework</module> | 12 | <module>yudao-framework</module> |
| 13 | <module>yudao-admin-server</module> | 13 | <module>yudao-admin-server</module> |
| 14 | + <module>yudao-user-server</module> | ||
| 14 | </modules> | 15 | </modules> |
| 15 | 16 | ||
| 16 | <name>${artifactId}</name> | 17 | <name>${artifactId}</name> |
| @@ -18,7 +19,7 @@ | @@ -18,7 +19,7 @@ | ||
| 18 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | 19 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 19 | 20 | ||
| 20 | <properties> | 21 | <properties> |
| 21 | - <revision>1.0.0</revision> | 22 | + <revision>1.1.0-snapshot</revision> |
| 22 | <!-- Maven 相关 --> | 23 | <!-- Maven 相关 --> |
| 23 | <java.version>1.8</java.version> | 24 | <java.version>1.8</java.version> |
| 24 | <maven.compiler.source>${java.version}</maven.compiler.source> | 25 | <maven.compiler.source>${java.version}</maven.compiler.source> |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/framework/security/SecurityConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.adminserver.framework.security; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.web.config.WebProperties; | ||
| 4 | +import org.springframework.beans.factory.annotation.Value; | ||
| 5 | +import org.springframework.context.annotation.Bean; | ||
| 6 | +import org.springframework.context.annotation.Configuration; | ||
| 7 | +import org.springframework.security.config.Customizer; | ||
| 8 | +import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 9 | +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | ||
| 10 | + | ||
| 11 | +import javax.annotation.Resource; | ||
| 12 | + | ||
| 13 | +@Configuration | ||
| 14 | +public class SecurityConfiguration { | ||
| 15 | + | ||
| 16 | + @Resource | ||
| 17 | + private WebProperties webProperties; | ||
| 18 | + | ||
| 19 | + @Value("${spring.boot.admin.context-path:''}") | ||
| 20 | + private String adminSeverContextPath; | ||
| 21 | + | ||
| 22 | + @Bean | ||
| 23 | + public Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() { | ||
| 24 | + return registry -> { | ||
| 25 | + // 通用的接口,可匿名访问 TODO 芋艿:需要抽象出去 | ||
| 26 | + registry.antMatchers(api("/system/captcha/**")).anonymous(); | ||
| 27 | + // Spring Boot Admin Server 的安全配置 TODO 芋艿:需要抽象出去 | ||
| 28 | + registry.antMatchers(adminSeverContextPath).anonymous() | ||
| 29 | + .antMatchers(adminSeverContextPath + "/**").anonymous(); | ||
| 30 | + // 短信回调 API | ||
| 31 | + registry.antMatchers(api("/system/sms/callback/**")).anonymous(); | ||
| 32 | + }; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + private String api(String url) { | ||
| 36 | + return webProperties.getApiPrefix() + url; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | +} |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/infra/service/logger/impl/InfApiAccessLogServiceImpl.java
| @@ -32,10 +32,9 @@ public class InfApiAccessLogServiceImpl implements InfApiAccessLogService { | @@ -32,10 +32,9 @@ public class InfApiAccessLogServiceImpl implements InfApiAccessLogService { | ||
| 32 | @Override | 32 | @Override |
| 33 | @Async | 33 | @Async |
| 34 | public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { | 34 | public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { |
| 35 | - // 插入 | ||
| 36 | InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO); | 35 | InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO); |
| 37 | int insert = apiAccessLogMapper.insert(apiAccessLog); | 36 | int insert = apiAccessLogMapper.insert(apiAccessLog); |
| 38 | - return new AsyncResult<>(insert == 1); | 37 | + return new AsyncResult<>(insert > 1); |
| 39 | } | 38 | } |
| 40 | 39 | ||
| 41 | @Override | 40 | @Override |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/SysUserController.java
| @@ -167,7 +167,7 @@ public class SysUserController { | @@ -167,7 +167,7 @@ public class SysUserController { | ||
| 167 | @PreAuthorize("@ss.hasPermission('system:user:import')") | 167 | @PreAuthorize("@ss.hasPermission('system:user:import')") |
| 168 | public CommonResult<SysUserImportRespVO> importExcel(@RequestParam("file") MultipartFile file, | 168 | public CommonResult<SysUserImportRespVO> importExcel(@RequestParam("file") MultipartFile file, |
| 169 | @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { | 169 | @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { |
| 170 | - List<SysUserImportExcelVO> list = ExcelUtils.raed(file, SysUserImportExcelVO.class); | 170 | + List<SysUserImportExcelVO> list = ExcelUtils.read(file, SysUserImportExcelVO.class); |
| 171 | return success(userService.importUsers(list, updateSupport)); | 171 | return success(userService.importUsers(list, updateSupport)); |
| 172 | } | 172 | } |
| 173 | 173 |
yudao-admin-ui/src/views/system/role/index.vue
| @@ -66,7 +66,7 @@ | @@ -66,7 +66,7 @@ | ||
| 66 | </el-table-column> | 66 | </el-table-column> |
| 67 | </el-table> | 67 | </el-table> |
| 68 | 68 | ||
| 69 | - <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" | 69 | + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" |
| 70 | @pagination="getList"/> | 70 | @pagination="getList"/> |
| 71 | 71 | ||
| 72 | <!-- 添加或修改角色配置对话框 --> | 72 | <!-- 添加或修改角色配置对话框 --> |
yudao-dependencies/pom.xml
| @@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
| 14 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | 14 | <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |
| 15 | 15 | ||
| 16 | <properties> | 16 | <properties> |
| 17 | - <revision>1.0.0</revision> | 17 | + <revision>1.1.0-snapshot</revision> |
| 18 | <!-- 统一依赖管理 --> | 18 | <!-- 统一依赖管理 --> |
| 19 | <spring.boot.version>2.4.5</spring.boot.version> | 19 | <spring.boot.version>2.4.5</spring.boot.version> |
| 20 | <!-- Web 相关 --> | 20 | <!-- Web 相关 --> |
yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
| @@ -39,7 +39,7 @@ public class ExcelUtils { | @@ -39,7 +39,7 @@ public class ExcelUtils { | ||
| 39 | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); | 39 | response.setContentType("application/vnd.ms-excel;charset=UTF-8"); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | - public static <T> List<T> raed(MultipartFile file, Class<T> head) throws IOException { | 42 | + public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException { |
| 43 | return EasyExcel.read(file.getInputStream(), head, null) | 43 | return EasyExcel.read(file.getInputStream(), head, null) |
| 44 | .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 | 44 | .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理 |
| 45 | .doReadAllSync(); | 45 | .doReadAllSync(); |
yudao-framework/yudao-spring-boot-starter-security/pom.xml
| @@ -19,7 +19,12 @@ | @@ -19,7 +19,12 @@ | ||
| 19 | <dependency> | 19 | <dependency> |
| 20 | <groupId>cn.iocoder.boot</groupId> | 20 | <groupId>cn.iocoder.boot</groupId> |
| 21 | <artifactId>yudao-common</artifactId> | 21 | <artifactId>yudao-common</artifactId> |
| 22 | - <version>${revision}</version> | 22 | + </dependency> |
| 23 | + | ||
| 24 | + <!-- Spring 核心 --> | ||
| 25 | + <dependency> | ||
| 26 | + <groupId>org.springframework.boot</groupId> | ||
| 27 | + <artifactId>spring-boot-starter-aop</artifactId> | ||
| 23 | </dependency> | 28 | </dependency> |
| 24 | 29 | ||
| 25 | <!-- Web 相关 --> | 30 | <!-- Web 相关 --> |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoSecurityAutoConfiguration.java
| 1 | package cn.iocoder.yudao.framework.security.config; | 1 | package cn.iocoder.yudao.framework.security.config; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.security.core.aop.PreAuthenticatedAspect; | ||
| 3 | import cn.iocoder.yudao.framework.security.core.filter.JwtAuthenticationTokenFilter; | 4 | import cn.iocoder.yudao.framework.security.core.filter.JwtAuthenticationTokenFilter; |
| 4 | import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl; | 5 | import cn.iocoder.yudao.framework.security.core.handler.AccessDeniedHandlerImpl; |
| 5 | import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl; | 6 | import cn.iocoder.yudao.framework.security.core.handler.AuthenticationEntryPointImpl; |
| @@ -33,6 +34,14 @@ public class YudaoSecurityAutoConfiguration { | @@ -33,6 +34,14 @@ public class YudaoSecurityAutoConfiguration { | ||
| 33 | private SecurityProperties securityProperties; | 34 | private SecurityProperties securityProperties; |
| 34 | 35 | ||
| 35 | /** | 36 | /** |
| 37 | + * 处理用户未登陆拦截的切面的 Bean | ||
| 38 | + */ | ||
| 39 | + @Bean | ||
| 40 | + public PreAuthenticatedAspect preAuthenticatedAspect() { | ||
| 41 | + return new PreAuthenticatedAspect(); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + /** | ||
| 36 | * 认证失败处理类 Bean | 45 | * 认证失败处理类 Bean |
| 37 | */ | 46 | */ |
| 38 | @Bean | 47 | @Bean |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java
| @@ -14,10 +14,12 @@ import org.springframework.context.annotation.Bean; | @@ -14,10 +14,12 @@ import org.springframework.context.annotation.Bean; | ||
| 14 | import org.springframework.context.annotation.Configuration; | 14 | import org.springframework.context.annotation.Configuration; |
| 15 | import org.springframework.http.HttpMethod; | 15 | import org.springframework.http.HttpMethod; |
| 16 | import org.springframework.security.authentication.AuthenticationManager; | 16 | import org.springframework.security.authentication.AuthenticationManager; |
| 17 | +import org.springframework.security.config.Customizer; | ||
| 17 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | 18 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
| 18 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; | 19 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; |
| 19 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | 20 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| 20 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | 21 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
| 22 | +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | ||
| 21 | import org.springframework.security.config.http.SessionCreationPolicy; | 23 | import org.springframework.security.config.http.SessionCreationPolicy; |
| 22 | import org.springframework.security.core.userdetails.UserDetailsService; | 24 | import org.springframework.security.core.userdetails.UserDetailsService; |
| 23 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | 25 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| @@ -41,9 +43,6 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -41,9 +43,6 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 41 | @Resource | 43 | @Resource |
| 42 | private WebProperties webProperties; | 44 | private WebProperties webProperties; |
| 43 | 45 | ||
| 44 | - @Value("${spring.boot.admin.context-path:''}") | ||
| 45 | - private String adminSeverContextPath; | ||
| 46 | - | ||
| 47 | /** | 46 | /** |
| 48 | * 自定义用户【认证】逻辑 | 47 | * 自定义用户【认证】逻辑 |
| 49 | */ | 48 | */ |
| @@ -74,6 +73,13 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -74,6 +73,13 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 74 | */ | 73 | */ |
| 75 | @Resource | 74 | @Resource |
| 76 | private JwtAuthenticationTokenFilter authenticationTokenFilter; | 75 | private JwtAuthenticationTokenFilter authenticationTokenFilter; |
| 76 | + /** | ||
| 77 | + * 自定义的权限映射 Bean | ||
| 78 | + * | ||
| 79 | + * @see #configure(HttpSecurity) | ||
| 80 | + */ | ||
| 81 | + @Resource | ||
| 82 | + private Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer; | ||
| 77 | 83 | ||
| 78 | /** | 84 | /** |
| 79 | * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入 | 85 | * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入 |
| @@ -121,15 +127,16 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -121,15 +127,16 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 121 | .csrf().disable() | 127 | .csrf().disable() |
| 122 | // 基于 token 机制,所以不需要 Session | 128 | // 基于 token 机制,所以不需要 Session |
| 123 | .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() | 129 | .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() |
| 130 | + .headers().frameOptions().disable().and() | ||
| 124 | // 一堆自定义的 Spring Security 处理器 | 131 | // 一堆自定义的 Spring Security 处理器 |
| 125 | .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) | 132 | .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint) |
| 126 | .accessDeniedHandler(accessDeniedHandler).and() | 133 | .accessDeniedHandler(accessDeniedHandler).and() |
| 127 | - // 设置每个请求的权限 | ||
| 128 | - .authorizeRequests() | 134 | + .logout().logoutUrl(api("/logout")).logoutSuccessHandler(logoutSuccessHandler); // 登出 |
| 135 | + | ||
| 136 | + // 设置每个请求的权限 ①:全局共享规则 | ||
| 137 | + httpSecurity.authorizeRequests() | ||
| 129 | // 登陆的接口,可匿名访问 | 138 | // 登陆的接口,可匿名访问 |
| 130 | .antMatchers(api("/login")).anonymous() | 139 | .antMatchers(api("/login")).anonymous() |
| 131 | - // 通用的接口,可匿名访问 TODO 芋艿:需要抽象出去 | ||
| 132 | - .antMatchers(api("/system/captcha/**")).anonymous() | ||
| 133 | // 静态资源,可匿名访问 | 140 | // 静态资源,可匿名访问 |
| 134 | .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() | 141 | .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() |
| 135 | // 文件的获取接口,可匿名访问 | 142 | // 文件的获取接口,可匿名访问 |
| @@ -139,21 +146,15 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -139,21 +146,15 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 139 | .antMatchers("/swagger-resources/**").anonymous() | 146 | .antMatchers("/swagger-resources/**").anonymous() |
| 140 | .antMatchers("/webjars/**").anonymous() | 147 | .antMatchers("/webjars/**").anonymous() |
| 141 | .antMatchers("/*/api-docs").anonymous() | 148 | .antMatchers("/*/api-docs").anonymous() |
| 142 | - // Spring Boot Admin Server 的安全配置 TODO 芋艿:需要抽象出去 | ||
| 143 | - .antMatchers(adminSeverContextPath).anonymous() | ||
| 144 | - .antMatchers(adminSeverContextPath + "/**").anonymous() | ||
| 145 | // Spring Boot Actuator 的安全配置 | 149 | // Spring Boot Actuator 的安全配置 |
| 146 | .antMatchers("/actuator").anonymous() | 150 | .antMatchers("/actuator").anonymous() |
| 147 | .antMatchers("/actuator/**").anonymous() | 151 | .antMatchers("/actuator/**").anonymous() |
| 148 | - // Druid 监控 TODO 芋艿:需要抽象出去 | 152 | + // Druid 监控 TODO 芋艿:等对接了 druid admin 后,在调整下。 |
| 149 | .antMatchers("/druid/**").anonymous() | 153 | .antMatchers("/druid/**").anonymous() |
| 150 | - // 短信回调 API TODO 芋艿:需要抽象出去 | ||
| 151 | - .antMatchers(api("/system/sms/callback/**")).anonymous() | ||
| 152 | - // 除上面外的所有请求全部需要鉴权认证 | ||
| 153 | - .anyRequest().authenticated() | ||
| 154 | - .and() | ||
| 155 | - .headers().frameOptions().disable(); | ||
| 156 | - httpSecurity.logout().logoutUrl(api("/logout")).logoutSuccessHandler(logoutSuccessHandler); | 154 | + // 设置每个请求的权限 ②:每个项目的自定义规则 |
| 155 | + .and().authorizeRequests(authorizeRequestsCustomizer) | ||
| 156 | + // 设置每个请求的权限 ③:兜底规则,必须认证 | ||
| 157 | + .authorizeRequests().anyRequest().authenticated(); | ||
| 157 | // 添加 JWT Filter | 158 | // 添加 JWT Filter |
| 158 | httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); | 159 | httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); |
| 159 | } | 160 | } |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/annotations/PreAuthenticated.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.security.core.annotations; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.*; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 声明用户需要登陆 | ||
| 7 | + * | ||
| 8 | + * 为什么不使用 {@link org.springframework.security.access.prepost.PreAuthorize} 注解,原因是不通过时,抛出的是认证不通过,而不是未登陆 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Target({ElementType.METHOD}) | ||
| 13 | +@Retention(RetentionPolicy.RUNTIME) | ||
| 14 | +@Inherited | ||
| 15 | +@Documented | ||
| 16 | +public @interface PreAuthenticated { | ||
| 17 | +} |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/core/aop/PreAuthenticatedAspect.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.security.core.aop; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | ||
| 4 | +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.aspectj.lang.ProceedingJoinPoint; | ||
| 7 | +import org.aspectj.lang.annotation.Around; | ||
| 8 | +import org.aspectj.lang.annotation.Aspect; | ||
| 9 | + | ||
| 10 | +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED; | ||
| 11 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 12 | + | ||
| 13 | +@Aspect | ||
| 14 | +@Slf4j | ||
| 15 | +public class PreAuthenticatedAspect { | ||
| 16 | + | ||
| 17 | + @Around("@annotation(preAuthenticated)") | ||
| 18 | + public Object around(ProceedingJoinPoint joinPoint, PreAuthenticated preAuthenticated) throws Throwable { | ||
| 19 | + if (SecurityFrameworkUtils.getLoginUser() == null) { | ||
| 20 | + throw exception(UNAUTHORIZED); | ||
| 21 | + } | ||
| 22 | + return joinPoint.proceed(); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | +} |
yudao-user-server/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | + <parent> | ||
| 6 | + <groupId>cn.iocoder.boot</groupId> | ||
| 7 | + <artifactId>yudao</artifactId> | ||
| 8 | + <version>${revision}</version> | ||
| 9 | + </parent> | ||
| 10 | + <modelVersion>4.0.0</modelVersion> | ||
| 11 | + | ||
| 12 | + <artifactId>yudao-user-server</artifactId> | ||
| 13 | + <packaging>jar</packaging> | ||
| 14 | + | ||
| 15 | + <name>yudao-admin-server</name> | ||
| 16 | + <description>用户前台 Server,提供其 API 接口</description> | ||
| 17 | + <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | ||
| 18 | + | ||
| 19 | + <dependencies> | ||
| 20 | + <!-- 业务组件 --> | ||
| 21 | + <dependency> | ||
| 22 | + <groupId>cn.iocoder.boot</groupId> | ||
| 23 | + <artifactId>yudao-spring-boot-starter-biz-dict</artifactId> | ||
| 24 | + </dependency> | ||
| 25 | + <dependency> | ||
| 26 | + <groupId>cn.iocoder.boot</groupId> | ||
| 27 | + <artifactId>yudao-spring-boot-starter-biz-sms</artifactId> | ||
| 28 | + </dependency> | ||
| 29 | + | ||
| 30 | + <!-- Web 相关 --> | ||
| 31 | + <dependency> | ||
| 32 | + <groupId>cn.iocoder.boot</groupId> | ||
| 33 | + <artifactId>yudao-spring-boot-starter-web</artifactId> | ||
| 34 | + </dependency> | ||
| 35 | + | ||
| 36 | + <dependency> | ||
| 37 | + <groupId>cn.iocoder.boot</groupId> | ||
| 38 | + <artifactId>yudao-spring-boot-starter-security</artifactId> | ||
| 39 | + </dependency> | ||
| 40 | + | ||
| 41 | + <!-- DB 相关 --> | ||
| 42 | + <dependency> | ||
| 43 | + <groupId>cn.iocoder.boot</groupId> | ||
| 44 | + <artifactId>yudao-spring-boot-starter-mybatis</artifactId> | ||
| 45 | + </dependency> | ||
| 46 | + | ||
| 47 | + <dependency> | ||
| 48 | + <groupId>cn.iocoder.boot</groupId> | ||
| 49 | + <artifactId>yudao-spring-boot-starter-redis</artifactId> | ||
| 50 | + </dependency> | ||
| 51 | + | ||
| 52 | + <!-- Config 配置中心相关 --> | ||
| 53 | + <dependency> | ||
| 54 | + <groupId>cn.iocoder.boot</groupId> | ||
| 55 | + <artifactId>yudao-spring-boot-starter-config</artifactId> | ||
| 56 | + </dependency> | ||
| 57 | + | ||
| 58 | + <!-- Job 定时任务相关 --> | ||
| 59 | + | ||
| 60 | + <!-- 消息队列相关 --> | ||
| 61 | + <dependency> | ||
| 62 | + <groupId>cn.iocoder.boot</groupId> | ||
| 63 | + <artifactId>yudao-spring-boot-starter-mq</artifactId> | ||
| 64 | + </dependency> | ||
| 65 | + | ||
| 66 | + <!-- 服务保障相关 --> | ||
| 67 | + <dependency> | ||
| 68 | + <groupId>cn.iocoder.boot</groupId> | ||
| 69 | + <artifactId>yudao-spring-boot-starter-protection</artifactId> | ||
| 70 | + </dependency> | ||
| 71 | + | ||
| 72 | + <!-- 监控相关 --> | ||
| 73 | + <dependency> | ||
| 74 | + <groupId>cn.iocoder.boot</groupId> | ||
| 75 | + <artifactId>yudao-spring-boot-starter-monitor</artifactId> | ||
| 76 | + </dependency> | ||
| 77 | + | ||
| 78 | + <!-- Test 测试相关 --> | ||
| 79 | + <dependency> | ||
| 80 | + <groupId>cn.iocoder.boot</groupId> | ||
| 81 | + <artifactId>yudao-spring-boot-starter-test</artifactId> | ||
| 82 | + <scope>test</scope> | ||
| 83 | + </dependency> | ||
| 84 | + | ||
| 85 | + <!-- 工具类相关 --> | ||
| 86 | + | ||
| 87 | + </dependencies> | ||
| 88 | + | ||
| 89 | + <build> | ||
| 90 | + <!-- 设置构建的 jar 包名 --> | ||
| 91 | + <finalName>${artifactId}</finalName> | ||
| 92 | + <plugins> | ||
| 93 | + <!-- 打包 --> | ||
| 94 | + <plugin> | ||
| 95 | + <groupId>org.springframework.boot</groupId> | ||
| 96 | + <artifactId>spring-boot-maven-plugin</artifactId> | ||
| 97 | + <configuration> | ||
| 98 | + <fork>true</fork> | ||
| 99 | + </configuration> | ||
| 100 | + <executions> | ||
| 101 | + <execution> | ||
| 102 | + <goals> | ||
| 103 | + <goal>repackage</goal> <!-- 将引入的 jar 打入其中 --> | ||
| 104 | + </goals> | ||
| 105 | + </execution> | ||
| 106 | + </executions> | ||
| 107 | + </plugin> | ||
| 108 | + </plugins> | ||
| 109 | + </build> | ||
| 110 | + | ||
| 111 | +</project> |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/UserServerApplication.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver; | ||
| 2 | + | ||
| 3 | +import org.springframework.boot.SpringApplication; | ||
| 4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| 5 | + | ||
| 6 | +@SpringBootApplication | ||
| 7 | +public class UserServerApplication { | ||
| 8 | + | ||
| 9 | + public static void main(String[] args) { | ||
| 10 | + SpringApplication.run(UserServerApplication.class, args); | ||
| 11 | + } | ||
| 12 | + | ||
| 13 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/async/config/AsyncConfiguration.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/async/package-info.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/async/《芋道 Spring Boot 异步任务入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/Async-Job/?yudao> |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/package-info.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/framework/security/SecurityConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.framework.security; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.web.config.WebProperties; | ||
| 4 | +import org.springframework.context.annotation.Bean; | ||
| 5 | +import org.springframework.context.annotation.Configuration; | ||
| 6 | +import org.springframework.security.config.Customizer; | ||
| 7 | +import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 8 | +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | ||
| 9 | + | ||
| 10 | +import javax.annotation.Resource; | ||
| 11 | + | ||
| 12 | +@Configuration | ||
| 13 | +public class SecurityConfiguration { | ||
| 14 | + | ||
| 15 | + @Resource | ||
| 16 | + private WebProperties webProperties; | ||
| 17 | + | ||
| 18 | + @Bean | ||
| 19 | + public Customizer<ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry> authorizeRequestsCustomizer() { | ||
| 20 | + return registry -> { | ||
| 21 | + registry.antMatchers(api("/**")).anonymous(); // 默认 API 都是用户可访问 | ||
| 22 | + }; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + private String api(String url) { | ||
| 26 | + return webProperties.getApiPrefix() + url; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/controller/HelloController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.controller; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | ||
| 4 | +import lombok.extern.slf4j.Slf4j; | ||
| 5 | +import org.springframework.security.access.annotation.Secured; | ||
| 6 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 7 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 8 | +import org.springframework.web.bind.annotation.RestController; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * @author weir | ||
| 12 | + */ | ||
| 13 | +@Slf4j | ||
| 14 | +@RestController | ||
| 15 | +public class HelloController { | ||
| 16 | + | ||
| 17 | + @RequestMapping("/user/hello") | ||
| 18 | + public String hello(String hello) { | ||
| 19 | + return "echo + " + hello; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + @RequestMapping("/user/info") | ||
| 23 | + @PreAuthenticated | ||
| 24 | + public String xx() { | ||
| 25 | + return "none"; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/convert/logger/InfApiAccessLogConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.convert.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateDTO; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger.InfApiAccessLogDO; | ||
| 5 | +import org.mapstruct.Mapper; | ||
| 6 | +import org.mapstruct.factory.Mappers; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * API 访问日志 Convert | ||
| 10 | + * | ||
| 11 | + * @author 芋道源码 | ||
| 12 | + */ | ||
| 13 | +@Mapper | ||
| 14 | +public interface InfApiAccessLogConvert { | ||
| 15 | + | ||
| 16 | + InfApiAccessLogConvert INSTANCE = Mappers.getMapper(InfApiAccessLogConvert.class); | ||
| 17 | + | ||
| 18 | + InfApiAccessLogDO convert(ApiAccessLogCreateDTO bean); | ||
| 19 | + | ||
| 20 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/convert/logger/InfApiErrorLogConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.convert.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateDTO; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger.InfApiErrorLogDO; | ||
| 5 | +import org.mapstruct.Mapper; | ||
| 6 | +import org.mapstruct.factory.Mappers; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * API 错误日志 Convert | ||
| 10 | + * | ||
| 11 | + * @author 芋道源码 | ||
| 12 | + */ | ||
| 13 | +@Mapper | ||
| 14 | +public interface InfApiErrorLogConvert { | ||
| 15 | + | ||
| 16 | + InfApiErrorLogConvert INSTANCE = Mappers.getMapper(InfApiErrorLogConvert.class); | ||
| 17 | + | ||
| 18 | + InfApiErrorLogDO convert(ApiErrorLogCreateDTO bean); | ||
| 19 | + | ||
| 20 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/convert/package-info.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
0 → 100644
| 1 | +<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao> |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/dataobject/config/InfConfigDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.config; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.TableField; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import lombok.EqualsAndHashCode; | ||
| 9 | +import lombok.ToString; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 参数配置表 | ||
| 13 | + * | ||
| 14 | + * @author ruoyi | ||
| 15 | + */ | ||
| 16 | +@TableName("inf_config") | ||
| 17 | +@Data | ||
| 18 | +@EqualsAndHashCode(callSuper = true) | ||
| 19 | +@ToString(callSuper = true) | ||
| 20 | +public class InfConfigDO extends BaseDO { | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 参数主键 | ||
| 24 | + */ | ||
| 25 | + @TableId | ||
| 26 | + private Long id; | ||
| 27 | + /** | ||
| 28 | + * 参数分组 | ||
| 29 | + */ | ||
| 30 | + @TableField("`group`") | ||
| 31 | + private String group; | ||
| 32 | + /** | ||
| 33 | + * 参数名称 | ||
| 34 | + */ | ||
| 35 | + private String name; | ||
| 36 | + /** | ||
| 37 | + * 参数键名 | ||
| 38 | + */ | ||
| 39 | + @TableField("`key`") | ||
| 40 | + private String key; | ||
| 41 | + /** | ||
| 42 | + * 参数键值 | ||
| 43 | + */ | ||
| 44 | + private String value; | ||
| 45 | + /** | ||
| 46 | + * 参数类型 | ||
| 47 | + * | ||
| 48 | + * 枚举 {@link InfConfigTypeEnum} | ||
| 49 | + */ | ||
| 50 | + @TableField("`type`") | ||
| 51 | + private Integer type; | ||
| 52 | + /** | ||
| 53 | + * 是否敏感 | ||
| 54 | + * | ||
| 55 | + * 对于敏感配置,需要管理权限才能查看 | ||
| 56 | + */ | ||
| 57 | + @TableField("`sensitive`") | ||
| 58 | + private Boolean sensitive; | ||
| 59 | + /** | ||
| 60 | + * 备注 | ||
| 61 | + */ | ||
| 62 | + private String remark; | ||
| 63 | + | ||
| 64 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/dataobject/file/InfFileDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.file; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.IdType; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableField; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 7 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 8 | +import lombok.*; | ||
| 9 | + | ||
| 10 | +import java.io.InputStream; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 文件表 | ||
| 14 | + * | ||
| 15 | + * @author 芋道源码 | ||
| 16 | + */ | ||
| 17 | +@Data | ||
| 18 | +@TableName("inf_file") | ||
| 19 | +@EqualsAndHashCode(callSuper = true) | ||
| 20 | +@ToString(callSuper = true) | ||
| 21 | +@Builder | ||
| 22 | +@NoArgsConstructor | ||
| 23 | +@AllArgsConstructor | ||
| 24 | +public class InfFileDO extends BaseDO { | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 文件路径 | ||
| 28 | + */ | ||
| 29 | + @TableId(type = IdType.INPUT) | ||
| 30 | + private String id; | ||
| 31 | + /** | ||
| 32 | + * 文件类型 | ||
| 33 | + * | ||
| 34 | + * 通过 {@link cn.hutool.core.io.FileTypeUtil#getType(InputStream)} 获取 | ||
| 35 | + */ | ||
| 36 | + @TableField(value = "`type`") | ||
| 37 | + private String type; | ||
| 38 | + /** | ||
| 39 | + * 文件内容 | ||
| 40 | + */ | ||
| 41 | + private byte[] content; | ||
| 42 | + | ||
| 43 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/dataobject/logger/InfApiAccessLogDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 7 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 8 | +import lombok.*; | ||
| 9 | + | ||
| 10 | +import java.util.Date; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * API 访问日志 | ||
| 14 | + * | ||
| 15 | + * @author 芋道源码 | ||
| 16 | + */ | ||
| 17 | +@TableName("inf_api_access_log") | ||
| 18 | +@Data | ||
| 19 | +@EqualsAndHashCode(callSuper = true) | ||
| 20 | +@ToString(callSuper = true) | ||
| 21 | +@Builder | ||
| 22 | +@NoArgsConstructor | ||
| 23 | +@AllArgsConstructor | ||
| 24 | +public class InfApiAccessLogDO extends BaseDO { | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 编号 | ||
| 28 | + */ | ||
| 29 | + @TableId | ||
| 30 | + private Integer id; | ||
| 31 | + /** | ||
| 32 | + * 链路追踪编号 | ||
| 33 | + * | ||
| 34 | + * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 | ||
| 35 | + */ | ||
| 36 | + private String traceId; | ||
| 37 | + /** | ||
| 38 | + * 用户编号 | ||
| 39 | + */ | ||
| 40 | + private Long userId; | ||
| 41 | + /** | ||
| 42 | + * 用户类型 | ||
| 43 | + * | ||
| 44 | + * 枚举 {@link UserTypeEnum} | ||
| 45 | + */ | ||
| 46 | + private Integer userType; | ||
| 47 | + /** | ||
| 48 | + * 应用名 | ||
| 49 | + * | ||
| 50 | + * 目前读取 `spring.application.name` 配置项 | ||
| 51 | + */ | ||
| 52 | + private String applicationName; | ||
| 53 | + | ||
| 54 | + // ========== 请求相关字段 ========== | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 请求方法名 | ||
| 58 | + */ | ||
| 59 | + private String requestMethod; | ||
| 60 | + /** | ||
| 61 | + * 访问地址 | ||
| 62 | + */ | ||
| 63 | + private String requestUrl; | ||
| 64 | + /** | ||
| 65 | + * 请求参数 | ||
| 66 | + * | ||
| 67 | + * query: Query String | ||
| 68 | + * body: Quest Body | ||
| 69 | + */ | ||
| 70 | + private String requestParams; | ||
| 71 | + /** | ||
| 72 | + * 用户 IP | ||
| 73 | + */ | ||
| 74 | + private String userIp; | ||
| 75 | + /** | ||
| 76 | + * 浏览器 UA | ||
| 77 | + */ | ||
| 78 | + private String userAgent; | ||
| 79 | + | ||
| 80 | + // ========== 执行相关字段 ========== | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * 开始请求时间 | ||
| 84 | + */ | ||
| 85 | + private Date beginTime; | ||
| 86 | + /** | ||
| 87 | + * 结束请求时间 | ||
| 88 | + */ | ||
| 89 | + private Date endTime; | ||
| 90 | + /** | ||
| 91 | + * 执行时长,单位:毫秒 | ||
| 92 | + */ | ||
| 93 | + private Integer duration; | ||
| 94 | + /** | ||
| 95 | + * 结果码 | ||
| 96 | + * | ||
| 97 | + * 目前使用的 {@link CommonResult#getCode()} 属性 | ||
| 98 | + */ | ||
| 99 | + private Integer resultCode; | ||
| 100 | + /** | ||
| 101 | + * 结果提示 | ||
| 102 | + * | ||
| 103 | + * 目前使用的 {@link CommonResult#getMsg()} 属性 | ||
| 104 | + */ | ||
| 105 | + private String resultMsg; | ||
| 106 | + | ||
| 107 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/dataobject/logger/InfApiErrorLogDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 7 | +import lombok.*; | ||
| 8 | + | ||
| 9 | +import java.util.Date; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * API 异常数据 | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@TableName("inf_api_error_log") | ||
| 17 | +@Data | ||
| 18 | +@EqualsAndHashCode(callSuper = true) | ||
| 19 | +@ToString(callSuper = true) | ||
| 20 | +@Builder | ||
| 21 | +@NoArgsConstructor | ||
| 22 | +@AllArgsConstructor | ||
| 23 | +public class InfApiErrorLogDO extends BaseDO { | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * 编号 | ||
| 27 | + */ | ||
| 28 | + private Long id; | ||
| 29 | + /** | ||
| 30 | + * 用户编号 | ||
| 31 | + */ | ||
| 32 | + private Long userId; | ||
| 33 | + /** | ||
| 34 | + * 链路追踪编号 | ||
| 35 | + * | ||
| 36 | + * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 | ||
| 37 | + */ | ||
| 38 | + private String traceId; | ||
| 39 | + /** | ||
| 40 | + * 用户类型 | ||
| 41 | + * | ||
| 42 | + * 枚举 {@link UserTypeEnum} | ||
| 43 | + */ | ||
| 44 | + private Integer userType; | ||
| 45 | + /** | ||
| 46 | + * 应用名 | ||
| 47 | + * | ||
| 48 | + * 目前读取 spring.application.name | ||
| 49 | + */ | ||
| 50 | + private String applicationName; | ||
| 51 | + | ||
| 52 | + // ========== 请求相关字段 ========== | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 请求方法名 | ||
| 56 | + */ | ||
| 57 | + private String requestMethod; | ||
| 58 | + /** | ||
| 59 | + * 访问地址 | ||
| 60 | + */ | ||
| 61 | + private String requestUrl; | ||
| 62 | + /** | ||
| 63 | + * 请求参数 | ||
| 64 | + * | ||
| 65 | + * query: Query String | ||
| 66 | + * body: Quest Body | ||
| 67 | + */ | ||
| 68 | + private String requestParams; | ||
| 69 | + /** | ||
| 70 | + * 用户 IP | ||
| 71 | + */ | ||
| 72 | + private String userIp; | ||
| 73 | + /** | ||
| 74 | + * 浏览器 UA | ||
| 75 | + */ | ||
| 76 | + private String userAgent; | ||
| 77 | + | ||
| 78 | + // ========== 异常相关字段 ========== | ||
| 79 | + | ||
| 80 | + /** | ||
| 81 | + * 异常发生时间 | ||
| 82 | + */ | ||
| 83 | + private Date exceptionTime; | ||
| 84 | + /** | ||
| 85 | + * 异常名 | ||
| 86 | + * | ||
| 87 | + * {@link Throwable#getClass()} 的类全名 | ||
| 88 | + */ | ||
| 89 | + private String exceptionName; | ||
| 90 | + /** | ||
| 91 | + * 异常导致的消息 | ||
| 92 | + * | ||
| 93 | + * {@link cn.hutool.core.exceptions.ExceptionUtil#getMessage(Throwable)} | ||
| 94 | + */ | ||
| 95 | + private String exceptionMessage; | ||
| 96 | + /** | ||
| 97 | + * 异常导致的根消息 | ||
| 98 | + * | ||
| 99 | + * {@link cn.hutool.core.exceptions.ExceptionUtil#getRootCauseMessage(Throwable)} | ||
| 100 | + */ | ||
| 101 | + private String exceptionRootCauseMessage; | ||
| 102 | + /** | ||
| 103 | + * 异常的栈轨迹 | ||
| 104 | + * | ||
| 105 | + * {@link org.apache.commons.lang3.exception.ExceptionUtils#getStackTrace(Throwable)} | ||
| 106 | + */ | ||
| 107 | + private String exceptionStackTrace; | ||
| 108 | + /** | ||
| 109 | + * 异常发生的类全名 | ||
| 110 | + * | ||
| 111 | + * {@link StackTraceElement#getClassName()} | ||
| 112 | + */ | ||
| 113 | + private String exceptionClassName; | ||
| 114 | + /** | ||
| 115 | + * 异常发生的类文件 | ||
| 116 | + * | ||
| 117 | + * {@link StackTraceElement#getFileName()} | ||
| 118 | + */ | ||
| 119 | + private String exceptionFileName; | ||
| 120 | + /** | ||
| 121 | + * 异常发生的方法名 | ||
| 122 | + * | ||
| 123 | + * {@link StackTraceElement#getMethodName()} | ||
| 124 | + */ | ||
| 125 | + private String exceptionMethodName; | ||
| 126 | + /** | ||
| 127 | + * 异常发生的方法所在行 | ||
| 128 | + * | ||
| 129 | + * {@link StackTraceElement#getLineNumber()} | ||
| 130 | + */ | ||
| 131 | + private Integer exceptionLineNumber; | ||
| 132 | + | ||
| 133 | + // ========== 处理相关字段 ========== | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * 处理状态 | ||
| 137 | + * | ||
| 138 | + * 枚举 {@link InfApiErrorLogProcessStatusEnum} | ||
| 139 | + */ | ||
| 140 | + private Integer processStatus; | ||
| 141 | + /** | ||
| 142 | + * 处理时间 | ||
| 143 | + */ | ||
| 144 | + private Date processTime; | ||
| 145 | + /** | ||
| 146 | + * 处理用户编号 | ||
| 147 | + * | ||
| 148 | + * 关联 cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO.SysUserDO#getId() | ||
| 149 | + */ | ||
| 150 | + private Long processUserId; | ||
| 151 | + | ||
| 152 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/mysql/config/InfConfigDAOImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.mysql.config; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apollo.internals.ConfigFrameworkDAO; | ||
| 4 | +import cn.iocoder.yudao.framework.apollo.internals.dto.ConfigRespDTO; | ||
| 5 | +import org.springframework.jdbc.core.BeanPropertyRowMapper; | ||
| 6 | +import org.springframework.jdbc.core.JdbcTemplate; | ||
| 7 | +import org.springframework.jdbc.datasource.DriverManagerDataSource; | ||
| 8 | + | ||
| 9 | +import javax.sql.DataSource; | ||
| 10 | +import java.sql.ResultSet; | ||
| 11 | +import java.util.Date; | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * ConfigFrameworkDAO 实现类 | ||
| 16 | + * | ||
| 17 | + * @author 芋道源码 | ||
| 18 | + */ | ||
| 19 | +public class InfConfigDAOImpl implements ConfigFrameworkDAO { | ||
| 20 | + | ||
| 21 | + private final JdbcTemplate jdbcTemplate; | ||
| 22 | + | ||
| 23 | + public InfConfigDAOImpl(String jdbcUrl, String username, String password) { | ||
| 24 | + DataSource dataSource = new DriverManagerDataSource(jdbcUrl, username, password); | ||
| 25 | + this.jdbcTemplate = new JdbcTemplate(dataSource); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) { | ||
| 30 | + return jdbcTemplate.query("SELECT id FROM inf_config WHERE update_time > ? LIMIT 1", | ||
| 31 | + ResultSet::next, maxUpdateTime); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public List<ConfigRespDTO> selectList() { | ||
| 36 | + return jdbcTemplate.query("SELECT `key`, `value`, update_time, deleted FROM inf_config", new BeanPropertyRowMapper<>(ConfigRespDTO.class)); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/mysql/file/InfFileMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.mysql.file; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.file.InfFileDO; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +@Mapper | ||
| 8 | +public interface InfFileMapper extends BaseMapperX<InfFileDO> { | ||
| 9 | + | ||
| 10 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/mysql/logger/InfApiAccessLogMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.mysql.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger.InfApiAccessLogDO; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * API 访问日志 Mapper | ||
| 11 | + * | ||
| 12 | + * @author 芋道源码 | ||
| 13 | + */ | ||
| 14 | +@Mapper | ||
| 15 | +public interface InfApiAccessLogMapper extends BaseMapperX<InfApiAccessLogDO> { | ||
| 16 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/dal/mysql/logger/InfApiErrorLogMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.dal.mysql.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger.InfApiErrorLogDO; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * API 错误日志 Mapper | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Mapper | ||
| 13 | +public interface InfApiErrorLogMapper extends BaseMapperX<InfApiErrorLogDO> { | ||
| 14 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/enums/logger/InfApiErrorLogProcessStatusEnum.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.enums.logger; | ||
| 2 | + | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Getter; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * API 异常数据的处理状态 | ||
| 8 | + * | ||
| 9 | + * @author 芋道源码 | ||
| 10 | + */ | ||
| 11 | +@AllArgsConstructor | ||
| 12 | +@Getter | ||
| 13 | +public enum InfApiErrorLogProcessStatusEnum { | ||
| 14 | + | ||
| 15 | + INIT(0, "未处理"), | ||
| 16 | + DONE(1, "已处理"), | ||
| 17 | + IGNORE(2, "已忽略"); | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 状态 | ||
| 21 | + */ | ||
| 22 | + private final Integer status; | ||
| 23 | + /** | ||
| 24 | + * 资源类型名 | ||
| 25 | + */ | ||
| 26 | + private final String name; | ||
| 27 | + | ||
| 28 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/enums/package-info.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/package-info.java
0 → 100644
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/service/auth/SysAuthService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.service.auth; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.security.core.service.SecurityAuthFrameworkService; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 认证 Service 接口 | ||
| 7 | + * | ||
| 8 | + * 提供用户的账号密码登陆、token 的校验等认证相关的功能 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public interface SysAuthService extends SecurityAuthFrameworkService { | ||
| 13 | + | ||
| 14 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/service/auth/impl/SysAuthServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.service.auth.impl; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.security.core.LoginUser; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.service.auth.SysAuthService; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.springframework.security.core.userdetails.UserDetails; | ||
| 7 | +import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
| 8 | +import org.springframework.stereotype.Service; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * Auth Service 实现类 | ||
| 12 | + * | ||
| 13 | + * @author 芋道源码 | ||
| 14 | + */ | ||
| 15 | +@Service | ||
| 16 | +@Slf4j | ||
| 17 | +public class SysAuthServiceImpl implements SysAuthService { | ||
| 18 | + | ||
| 19 | + @Override | ||
| 20 | + public LoginUser verifyTokenAndRefresh(String token) { | ||
| 21 | + return null; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public LoginUser mockLogin(Long userId) { | ||
| 26 | + return null; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public void logout(String token) { | ||
| 31 | + | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Override | ||
| 35 | + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | ||
| 36 | + return null; | ||
| 37 | + } | ||
| 38 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/service/logger/InfApiAccessLogService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.service.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * API 访问日志 Service 接口 | ||
| 7 | + * | ||
| 8 | + * @author 芋道源码 | ||
| 9 | + */ | ||
| 10 | +public interface InfApiAccessLogService extends ApiAccessLogFrameworkService { | ||
| 11 | + | ||
| 12 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/service/logger/InfApiErrorLogService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.service.logger; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * API 错误日志 Service 接口 | ||
| 7 | + * | ||
| 8 | + * @author 芋道源码 | ||
| 9 | + */ | ||
| 10 | +public interface InfApiErrorLogService extends ApiErrorLogFrameworkService { | ||
| 11 | + | ||
| 12 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/service/logger/impl/InfApiAccessLogServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.service.logger.impl; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiAccessLogCreateDTO; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.convert.logger.InfApiAccessLogConvert; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger.InfApiAccessLogDO; | ||
| 6 | +import cn.iocoder.yudao.userserver.modules.infra.dal.mysql.logger.InfApiAccessLogMapper; | ||
| 7 | +import cn.iocoder.yudao.userserver.modules.infra.service.logger.InfApiAccessLogService; | ||
| 8 | +import lombok.extern.slf4j.Slf4j; | ||
| 9 | +import org.springframework.scheduling.annotation.AsyncResult; | ||
| 10 | +import org.springframework.stereotype.Service; | ||
| 11 | +import org.springframework.validation.annotation.Validated; | ||
| 12 | + | ||
| 13 | +import javax.annotation.Resource; | ||
| 14 | +import java.util.concurrent.Future; | ||
| 15 | + | ||
| 16 | +/** | ||
| 17 | + * API 访问日志 Service 实现类 | ||
| 18 | + * | ||
| 19 | + * @author 芋道源码 | ||
| 20 | + */ | ||
| 21 | +@Service | ||
| 22 | +@Validated | ||
| 23 | +@Slf4j | ||
| 24 | +public class InfApiAccessLogServiceImpl implements InfApiAccessLogService { | ||
| 25 | + | ||
| 26 | + @Resource | ||
| 27 | + private InfApiAccessLogMapper apiAccessLogMapper; | ||
| 28 | + | ||
| 29 | + @Override | ||
| 30 | + public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { | ||
| 31 | + InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO); | ||
| 32 | + int insert = apiAccessLogMapper.insert(apiAccessLog); | ||
| 33 | + return new AsyncResult<>(insert > 1); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/infra/service/logger/impl/InfApiErrorLogServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.infra.service.logger.impl; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.apilog.core.service.dto.ApiErrorLogCreateDTO; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.infra.convert.logger.InfApiErrorLogConvert; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.infra.dal.dataobject.logger.InfApiErrorLogDO; | ||
| 6 | +import cn.iocoder.yudao.userserver.modules.infra.dal.mysql.logger.InfApiErrorLogMapper; | ||
| 7 | +import cn.iocoder.yudao.userserver.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; | ||
| 8 | +import cn.iocoder.yudao.userserver.modules.infra.service.logger.InfApiErrorLogService; | ||
| 9 | +import lombok.extern.slf4j.Slf4j; | ||
| 10 | +import org.springframework.scheduling.annotation.AsyncResult; | ||
| 11 | +import org.springframework.stereotype.Service; | ||
| 12 | +import org.springframework.validation.annotation.Validated; | ||
| 13 | + | ||
| 14 | +import javax.annotation.Resource; | ||
| 15 | +import java.util.concurrent.Future; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * API 错误日志 Service 实现类 | ||
| 19 | + * | ||
| 20 | + * @author 芋道源码 | ||
| 21 | + */ | ||
| 22 | +@Service | ||
| 23 | +@Validated | ||
| 24 | +@Slf4j | ||
| 25 | +public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { | ||
| 26 | + | ||
| 27 | + @Resource | ||
| 28 | + private InfApiErrorLogMapper apiErrorLogMapper; | ||
| 29 | + | ||
| 30 | + @Override | ||
| 31 | + public Future<Boolean> createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) { | ||
| 32 | + InfApiErrorLogDO apiErrorLog = InfApiErrorLogConvert.INSTANCE.convert(createDTO); | ||
| 33 | + apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus()); | ||
| 34 | + int insert = apiErrorLogMapper.insert(apiErrorLog); | ||
| 35 | + return new AsyncResult<>(insert == 1); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/dict/SysDictDataConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.convert.dict; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO; | ||
| 4 | +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.dict.SysDictDataDO; | ||
| 5 | +import org.mapstruct.Mapper; | ||
| 6 | +import org.mapstruct.factory.Mappers; | ||
| 7 | + | ||
| 8 | +import java.util.Collection; | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +@Mapper | ||
| 12 | +public interface SysDictDataConvert { | ||
| 13 | + | ||
| 14 | + SysDictDataConvert INSTANCE = Mappers.getMapper(SysDictDataConvert.class); | ||
| 15 | + | ||
| 16 | + DictDataRespDTO convert02(SysDictDataDO bean); | ||
| 17 | + | ||
| 18 | + List<DictDataRespDTO> convertList03(Collection<SysDictDataDO> list); | ||
| 19 | + | ||
| 20 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.convert; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/dict/SysDictDataDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.dataobject.dict; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import lombok.EqualsAndHashCode; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 字典数据表 | ||
| 12 | + * | ||
| 13 | + * @author ruoyi | ||
| 14 | + */ | ||
| 15 | +@TableName("sys_dict_data") | ||
| 16 | +@Data | ||
| 17 | +@EqualsAndHashCode(callSuper = true) | ||
| 18 | +public class SysDictDataDO extends BaseDO { | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * 字典数据编号 | ||
| 22 | + */ | ||
| 23 | + @TableId | ||
| 24 | + private Long id; | ||
| 25 | + /** | ||
| 26 | + * 字典排序 | ||
| 27 | + */ | ||
| 28 | + private Integer sort; | ||
| 29 | + /** | ||
| 30 | + * 字典标签 | ||
| 31 | + */ | ||
| 32 | + private String label; | ||
| 33 | + /** | ||
| 34 | + * 字典值 | ||
| 35 | + */ | ||
| 36 | + private String value; | ||
| 37 | + /** | ||
| 38 | + * 字典类型 | ||
| 39 | + * | ||
| 40 | + * 冗余 {@link SysDictDataDO#getDictType()} | ||
| 41 | + */ | ||
| 42 | + private String dictType; | ||
| 43 | + /** | ||
| 44 | + * 状态 | ||
| 45 | + * | ||
| 46 | + * 枚举 {@link CommonStatusEnum} | ||
| 47 | + */ | ||
| 48 | + private Integer status; | ||
| 49 | + /** | ||
| 50 | + * 备注 | ||
| 51 | + */ | ||
| 52 | + private String remark; | ||
| 53 | + | ||
| 54 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.dataobject; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/dict/SysDictDataMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.mysql.dict; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 5 | +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.dict.SysDictDataDO; | ||
| 6 | +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||
| 7 | +import org.apache.ibatis.annotations.Mapper; | ||
| 8 | + | ||
| 9 | +import java.util.Date; | ||
| 10 | + | ||
| 11 | +@Mapper | ||
| 12 | +public interface SysDictDataMapper extends BaseMapperX<SysDictDataDO> { | ||
| 13 | + | ||
| 14 | + default SysDictDataDO selectByDictTypeAndValue(String dictType, String value) { | ||
| 15 | + return selectOne(new QueryWrapper<SysDictDataDO>().eq("dict_type", dictType) | ||
| 16 | + .eq("value", value)); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + default int selectCountByDictType(String dictType) { | ||
| 20 | + return selectCount("dict_type", dictType); | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + default boolean selectExistsByUpdateTimeAfter(Date maxUpdateTime) { | ||
| 24 | + return selectOne(new QueryWrapper<SysDictDataDO>().select("id") | ||
| 25 | + .gt("update_time", maxUpdateTime).last("LIMIT 1")) != null; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dal.mysql; |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dict/SysDictDataService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dict; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.dict.core.service.DictDataFrameworkService; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 字典数据 Service 接口 | ||
| 7 | + * | ||
| 8 | + * @author ruoyi | ||
| 9 | + */ | ||
| 10 | +public interface SysDictDataService extends DictDataFrameworkService { | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * 初始化字典数据的本地缓存 | ||
| 14 | + */ | ||
| 15 | + void initLocalCache(); | ||
| 16 | + | ||
| 17 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dict/impl/SysDictDataServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.userserver.modules.system.dict.impl; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO; | ||
| 5 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 6 | +import cn.iocoder.yudao.userserver.modules.system.convert.dict.SysDictDataConvert; | ||
| 7 | +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.dict.SysDictDataDO; | ||
| 8 | +import cn.iocoder.yudao.userserver.modules.system.dal.mysql.dict.SysDictDataMapper; | ||
| 9 | +import cn.iocoder.yudao.userserver.modules.system.dict.SysDictDataService; | ||
| 10 | +import com.google.common.collect.ImmutableTable; | ||
| 11 | +import lombok.extern.slf4j.Slf4j; | ||
| 12 | +import org.springframework.scheduling.annotation.Scheduled; | ||
| 13 | +import org.springframework.stereotype.Service; | ||
| 14 | + | ||
| 15 | +import javax.annotation.PostConstruct; | ||
| 16 | +import javax.annotation.Resource; | ||
| 17 | +import java.util.Comparator; | ||
| 18 | +import java.util.Date; | ||
| 19 | +import java.util.List; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * 字典数据 Service 实现类 | ||
| 23 | + * | ||
| 24 | + * @author ruoyi | ||
| 25 | + */ | ||
| 26 | +@Service | ||
| 27 | +@Slf4j | ||
| 28 | +public class SysDictDataServiceImpl implements SysDictDataService { | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 定时执行 {@link #schedulePeriodicRefresh()} 的周期 | ||
| 32 | + * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高 | ||
| 33 | + */ | ||
| 34 | + private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L; | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 字典数据缓存,第二个 key 使用 label | ||
| 38 | + * | ||
| 39 | + * key1:字典类型 dictType | ||
| 40 | + * key2:字典标签 label | ||
| 41 | + */ | ||
| 42 | + private ImmutableTable<String, String, SysDictDataDO> labelDictDataCache; | ||
| 43 | + /** | ||
| 44 | + * 字典数据缓存,第二个 key 使用 value | ||
| 45 | + * | ||
| 46 | + * key1:字典类型 dictType | ||
| 47 | + * key2:字典值 value | ||
| 48 | + */ | ||
| 49 | + private ImmutableTable<String, String, SysDictDataDO> valueDictDataCache; | ||
| 50 | + /** | ||
| 51 | + * 缓存字典数据的最大更新时间,用于后续的增量轮询,判断是否有更新 | ||
| 52 | + */ | ||
| 53 | + private volatile Date maxUpdateTime; | ||
| 54 | + | ||
| 55 | + @Resource | ||
| 56 | + private SysDictDataMapper dictDataMapper; | ||
| 57 | + | ||
| 58 | + @Override | ||
| 59 | + @PostConstruct | ||
| 60 | + public synchronized void initLocalCache() { | ||
| 61 | + // 获取字典数据列表,如果有更新 | ||
| 62 | + List<SysDictDataDO> dataList = this.loadDictDataIfUpdate(maxUpdateTime); | ||
| 63 | + if (CollUtil.isEmpty(dataList)) { | ||
| 64 | + return; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + // 构建缓存 | ||
| 68 | + ImmutableTable.Builder<String, String, SysDictDataDO> labelDictDataBuilder = ImmutableTable.builder(); | ||
| 69 | + ImmutableTable.Builder<String, String, SysDictDataDO> valueDictDataBuilder = ImmutableTable.builder(); | ||
| 70 | + dataList.forEach(dictData -> { | ||
| 71 | + labelDictDataBuilder.put(dictData.getDictType(), dictData.getLabel(), dictData); | ||
| 72 | + valueDictDataBuilder.put(dictData.getDictType(), dictData.getValue(), dictData); | ||
| 73 | + }); | ||
| 74 | + labelDictDataCache = labelDictDataBuilder.build(); | ||
| 75 | + valueDictDataCache = valueDictDataBuilder.build(); | ||
| 76 | + assert dataList.size() > 0; // 断言,避免告警 | ||
| 77 | + maxUpdateTime = dataList.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime(); | ||
| 78 | + log.info("[initLocalCache][缓存字典数据,数量为:{}]", dataList.size()); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD) | ||
| 82 | + public void schedulePeriodicRefresh() { | ||
| 83 | + initLocalCache(); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + /** | ||
| 87 | + * 如果字典数据发生变化,从数据库中获取最新的全量字典数据。 | ||
| 88 | + * 如果未发生变化,则返回空 | ||
| 89 | + * | ||
| 90 | + * @param maxUpdateTime 当前字典数据的最大更新时间 | ||
| 91 | + * @return 字典数据列表 | ||
| 92 | + */ | ||
| 93 | + private List<SysDictDataDO> loadDictDataIfUpdate(Date maxUpdateTime) { | ||
| 94 | + // 第一步,判断是否要更新。 | ||
| 95 | + if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 | ||
| 96 | + log.info("[loadDictDataIfUpdate][首次加载全量字典数据]"); | ||
| 97 | + } else { // 判断数据库中是否有更新的字典数据 | ||
| 98 | + if (!dictDataMapper.selectExistsByUpdateTimeAfter(maxUpdateTime)) { | ||
| 99 | + return null; | ||
| 100 | + } | ||
| 101 | + log.info("[loadDictDataIfUpdate][增量加载全量字典数据]"); | ||
| 102 | + } | ||
| 103 | + // 第二步,如果有更新,则从数据库加载所有字典数据 | ||
| 104 | + return dictDataMapper.selectList(); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + @Override | ||
| 108 | + public DictDataRespDTO getDictDataFromCache(String type, String value) { | ||
| 109 | + return SysDictDataConvert.INSTANCE.convert02(valueDictDataCache.get(type, value)); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + @Override | ||
| 113 | + public DictDataRespDTO parseDictDataFromCache(String type, String label) { | ||
| 114 | + return SysDictDataConvert.INSTANCE.convert02(labelDictDataCache.get(type, label)); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + @Override | ||
| 118 | + public List<DictDataRespDTO> listDictDatasFromCache(String type) { | ||
| 119 | + return SysDictDataConvert.INSTANCE.convertList03(labelDictDataCache.row(type).values()); | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | +} |
yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/package-info.java
0 → 100644
yudao-user-server/src/main/resources/application-dev.yaml
0 → 100644
| 1 | +server: | ||
| 2 | + port: 28080 | ||
| 3 | + | ||
| 4 | +--- #################### 数据库相关配置 #################### | ||
| 5 | + | ||
| 6 | +spring: | ||
| 7 | + # 数据源配置项 | ||
| 8 | + autoconfigure: | ||
| 9 | + exclude: | ||
| 10 | + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源 | ||
| 11 | + datasource: | ||
| 12 | + druid: # Druid 【监控】相关的全局配置 | ||
| 13 | + web-stat-filter: | ||
| 14 | + enabled: true | ||
| 15 | + stat-view-servlet: | ||
| 16 | + enabled: true | ||
| 17 | + allow: # 设置白名单,不填则允许所有访问 | ||
| 18 | + url-pattern: /druid/* | ||
| 19 | + login-username: # 控制台管理用户名和密码 | ||
| 20 | + login-password: | ||
| 21 | + filter: | ||
| 22 | + stat: | ||
| 23 | + enabled: true | ||
| 24 | + log-slow-sql: true # 慢 SQL 记录 | ||
| 25 | + slow-sql-millis: 100 | ||
| 26 | + merge-sql: true | ||
| 27 | + wall: | ||
| 28 | + config: | ||
| 29 | + multi-statement-allow: true | ||
| 30 | + dynamic: # 多数据源配置 | ||
| 31 | + druid: # Druid 【连接池】相关的全局配置 | ||
| 32 | + initial-size: 5 # 初始连接数 | ||
| 33 | + min-idle: 10 # 最小连接池数量 | ||
| 34 | + max-active: 20 # 最大连接池数量 | ||
| 35 | + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 | ||
| 36 | + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 | ||
| 37 | + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 | ||
| 38 | + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 | ||
| 39 | + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效 | ||
| 40 | + test-while-idle: true | ||
| 41 | + test-on-borrow: false | ||
| 42 | + test-on-return: false | ||
| 43 | + primary: master | ||
| 44 | + datasource: | ||
| 45 | + master: | ||
| 46 | + name: ruoyi-vue-pro | ||
| 47 | + url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT | ||
| 48 | + driver-class-name: com.mysql.jdbc.Driver | ||
| 49 | + username: root | ||
| 50 | + password: 3WLiVUBEwTbvAfsh | ||
| 51 | + slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改 | ||
| 52 | + name: ruoyi-vue-pro | ||
| 53 | + url: jdbc:mysql://400-infra.server.iocoder.cn:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT | ||
| 54 | + driver-class-name: com.mysql.jdbc.Driver | ||
| 55 | + username: root | ||
| 56 | + password: 3WLiVUBEwTbvAfsh | ||
| 57 | + | ||
| 58 | + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 | ||
| 59 | + redis: | ||
| 60 | + host: 400-infra.server.iocoder.cn # 地址 | ||
| 61 | + port: 6379 # 端口 | ||
| 62 | + database: 1 # 数据库索引 | ||
| 63 | + | ||
| 64 | +--- #################### 定时任务相关配置 #################### | ||
| 65 | + | ||
| 66 | +--- #################### 配置中心相关配置 #################### | ||
| 67 | + | ||
| 68 | +# Apollo 配置中心 | ||
| 69 | +apollo: | ||
| 70 | + bootstrap: | ||
| 71 | + enabled: true # 设置 Apollo 在启动阶段生效 | ||
| 72 | + eagerLoad: | ||
| 73 | + enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置 | ||
| 74 | + jdbc: # 自定义的 JDBC 配置项,用于数据库的地址 | ||
| 75 | + dao: cn.iocoder.yudao.userserver.modules.infra.dal.mysql.config.InfConfigDAOImpl | ||
| 76 | + url: ${spring.datasource.dynamic.datasource.master.url} | ||
| 77 | + username: ${spring.datasource.dynamic.datasource.master.username} | ||
| 78 | + password: ${spring.datasource.dynamic.datasource.master.password} | ||
| 79 | + | ||
| 80 | +--- #################### 服务保障相关配置 #################### | ||
| 81 | + | ||
| 82 | +# Lock4j 配置项 | ||
| 83 | +lock4j: | ||
| 84 | + acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒 | ||
| 85 | + expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒 | ||
| 86 | + | ||
| 87 | +# Resilience4j 配置项 | ||
| 88 | +resilience4j: | ||
| 89 | + ratelimiter: | ||
| 90 | + instances: | ||
| 91 | + backendA: | ||
| 92 | + limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50 | ||
| 93 | + limit-refresh-period: 60s # 每个周期的时长,单位:微秒。默认为 500 | ||
| 94 | + timeout-duration: 1s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s | ||
| 95 | + register-health-indicator: true # 是否注册到健康监测 | ||
| 96 | + | ||
| 97 | +--- #################### 监控相关配置 #################### | ||
| 98 | + | ||
| 99 | +# Actuator 监控端点的配置项 | ||
| 100 | +management: | ||
| 101 | + endpoints: | ||
| 102 | + web: | ||
| 103 | + base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator | ||
| 104 | + exposure: | ||
| 105 | + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 | ||
| 106 | + | ||
| 107 | +# Spring Boot Admin 配置项 | ||
| 108 | +spring: | ||
| 109 | + boot: | ||
| 110 | + admin: | ||
| 111 | + # Spring Boot Admin Client 客户端的相关配置 | ||
| 112 | + client: | ||
| 113 | + url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 | ||
| 114 | + instance: | ||
| 115 | + prefer-ip: true # 注册实例时,优先使用 IP | ||
| 116 | + | ||
| 117 | +# 日志文件配置 | ||
| 118 | +logging: | ||
| 119 | + file: | ||
| 120 | + name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 | ||
| 121 | + | ||
| 122 | +--- #################### 芋道相关配置 #################### | ||
| 123 | + | ||
| 124 | +# 芋道配置项,设置当前项目所有自定义的配置 | ||
| 125 | +yudao: | ||
| 126 | + security: | ||
| 127 | + token-header: Authorization | ||
| 128 | + token-secret: abcdefghijklmnopqrstuvwxyz | ||
| 129 | + token-timeout: 1d | ||
| 130 | + session-timeout: 30m | ||
| 131 | + mock-enable: true | ||
| 132 | + mock-secret: test | ||
| 133 | + file: | ||
| 134 | + base-path: http://api-dashboard.yudao.iocoder.cn${yudao.web.api-prefix}/infra/file/get/ | ||
| 135 | + xss: | ||
| 136 | + enable: false | ||
| 137 | + exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 | ||
| 138 | + - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 | ||
| 139 | + - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 | ||
| 140 | + demo: true # 开启演示模式 |
yudao-user-server/src/main/resources/application-local.yaml
0 → 100644
| 1 | +server: | ||
| 2 | + port: 28080 | ||
| 3 | + | ||
| 4 | +--- #################### 数据库相关配置 #################### | ||
| 5 | + | ||
| 6 | +spring: | ||
| 7 | + # 数据源配置项 | ||
| 8 | + autoconfigure: | ||
| 9 | + exclude: | ||
| 10 | + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源 | ||
| 11 | + datasource: | ||
| 12 | + druid: # Druid 【监控】相关的全局配置 | ||
| 13 | + web-stat-filter: | ||
| 14 | + enabled: true | ||
| 15 | + stat-view-servlet: | ||
| 16 | + enabled: true | ||
| 17 | + allow: # 设置白名单,不填则允许所有访问 | ||
| 18 | + url-pattern: /druid/* | ||
| 19 | + login-username: # 控制台管理用户名和密码 | ||
| 20 | + login-password: | ||
| 21 | + filter: | ||
| 22 | + stat: | ||
| 23 | + enabled: true | ||
| 24 | + log-slow-sql: true # 慢 SQL 记录 | ||
| 25 | + slow-sql-millis: 100 | ||
| 26 | + merge-sql: true | ||
| 27 | + wall: | ||
| 28 | + config: | ||
| 29 | + multi-statement-allow: true | ||
| 30 | + dynamic: # 多数据源配置 | ||
| 31 | + druid: # Druid 【连接池】相关的全局配置 | ||
| 32 | + initial-size: 5 # 初始连接数 | ||
| 33 | + min-idle: 10 # 最小连接池数量 | ||
| 34 | + max-active: 20 # 最大连接池数量 | ||
| 35 | + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒 | ||
| 36 | + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒 | ||
| 37 | + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒 | ||
| 38 | + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒 | ||
| 39 | + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效 | ||
| 40 | + test-while-idle: true | ||
| 41 | + test-on-borrow: false | ||
| 42 | + test-on-return: false | ||
| 43 | + primary: master | ||
| 44 | + datasource: | ||
| 45 | + master: | ||
| 46 | + name: ruoyi-vue-pro | ||
| 47 | + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT | ||
| 48 | + driver-class-name: com.mysql.jdbc.Driver | ||
| 49 | + username: root | ||
| 50 | + password: 123456 | ||
| 51 | + slave: # 模拟从库,可根据自己需要修改 | ||
| 52 | + name: ruoyi-vue-pro | ||
| 53 | + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT | ||
| 54 | + driver-class-name: com.mysql.jdbc.Driver | ||
| 55 | + username: root | ||
| 56 | + password: 123456 | ||
| 57 | + | ||
| 58 | + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 | ||
| 59 | + redis: | ||
| 60 | + host: 127.0.0.1 # 地址 | ||
| 61 | + port: 6379 # 端口 | ||
| 62 | + database: 0 # 数据库索引 | ||
| 63 | + | ||
| 64 | +--- #################### 定时任务相关配置 #################### | ||
| 65 | + | ||
| 66 | +--- #################### 配置中心相关配置 #################### | ||
| 67 | + | ||
| 68 | +# Apollo 配置中心 | ||
| 69 | +apollo: | ||
| 70 | + bootstrap: | ||
| 71 | + enabled: true # 设置 Apollo 在启动阶段生效 | ||
| 72 | + eagerLoad: | ||
| 73 | + enabled: true # 设置 Apollo 在日志初始化前生效,可以实现日志的动态级别配置 | ||
| 74 | + jdbc: # 自定义的 JDBC 配置项,用于数据库的地址 | ||
| 75 | + dao: cn.iocoder.yudao.userserver.modules.infra.dal.mysql.config.InfConfigDAOImpl | ||
| 76 | + url: ${spring.datasource.dynamic.datasource.master.url} | ||
| 77 | + username: ${spring.datasource.dynamic.datasource.master.username} | ||
| 78 | + password: ${spring.datasource.dynamic.datasource.master.password} | ||
| 79 | + | ||
| 80 | +--- #################### 服务保障相关配置 #################### | ||
| 81 | + | ||
| 82 | +# Lock4j 配置项 | ||
| 83 | +lock4j: | ||
| 84 | + acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒 | ||
| 85 | + expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒 | ||
| 86 | + | ||
| 87 | +# Resilience4j 配置项 | ||
| 88 | +resilience4j: | ||
| 89 | + ratelimiter: | ||
| 90 | + instances: | ||
| 91 | + backendA: | ||
| 92 | + limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50 | ||
| 93 | + limit-refresh-period: 60s # 每个周期的时长,单位:微秒。默认为 500 | ||
| 94 | + timeout-duration: 1s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s | ||
| 95 | + register-health-indicator: true # 是否注册到健康监测 | ||
| 96 | + | ||
| 97 | +--- #################### 监控相关配置 #################### | ||
| 98 | + | ||
| 99 | +# Actuator 监控端点的配置项 | ||
| 100 | +management: | ||
| 101 | + endpoints: | ||
| 102 | + web: | ||
| 103 | + base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator | ||
| 104 | + exposure: | ||
| 105 | + include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 | ||
| 106 | + | ||
| 107 | +# Spring Boot Admin 配置项 | ||
| 108 | +spring: | ||
| 109 | + boot: | ||
| 110 | + admin: | ||
| 111 | + # Spring Boot Admin Client 客户端的相关配置 | ||
| 112 | + client: | ||
| 113 | + url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址 | ||
| 114 | + instance: | ||
| 115 | + prefer-ip: true # 注册实例时,优先使用 IP | ||
| 116 | + # Spring Boot Admin Server 服务端的相关配置 | ||
| 117 | + context-path: /admin # 配置 Spring | ||
| 118 | + | ||
| 119 | +# 日志文件配置 | ||
| 120 | +logging: | ||
| 121 | + file: | ||
| 122 | + name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 | ||
| 123 | + | ||
| 124 | +--- #################### 芋道相关配置 #################### | ||
| 125 | + | ||
| 126 | +# 芋道配置项,设置当前项目所有自定义的配置 | ||
| 127 | +yudao: | ||
| 128 | + security: | ||
| 129 | + token-header: Authorization | ||
| 130 | + token-secret: abcdefghijklmnopqrstuvwxyz | ||
| 131 | + token-timeout: 1d | ||
| 132 | + session-timeout: 30m | ||
| 133 | + mock-enable: true | ||
| 134 | + mock-secret: test | ||
| 135 | + file: | ||
| 136 | + base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/infra/file/get/ | ||
| 137 | + xss: | ||
| 138 | + enable: false | ||
| 139 | + exclude-urls: # 如下两个 url,仅仅是为了演示,去掉配置也没关系 | ||
| 140 | + - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求 | ||
| 141 | + - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求 | ||
| 142 | + demo: false # 关闭演示模式 |
yudao-user-server/src/main/resources/application.yaml
0 → 100644
| 1 | +spring: | ||
| 2 | + application: | ||
| 3 | + name: yudao-user-server | ||
| 4 | + | ||
| 5 | + profiles: | ||
| 6 | + active: local | ||
| 7 | + | ||
| 8 | + # Servlet 配置 | ||
| 9 | + servlet: | ||
| 10 | + # 文件上传相关配置项 | ||
| 11 | + multipart: | ||
| 12 | + max-file-size: 16MB # 单个文件大小 | ||
| 13 | + max-request-size: 32MB # 设置总上传的文件大小 | ||
| 14 | + | ||
| 15 | + # Jackson 配置项 | ||
| 16 | + jackson: | ||
| 17 | + serialization: | ||
| 18 | + write-dates-as-timestamps: true # 设置 Date 的格式,使用时间戳 | ||
| 19 | + write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401 | ||
| 20 | + write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳 | ||
| 21 | + fail-on-empty-beans: false # 允许序列化无属性的 Bean | ||
| 22 | + | ||
| 23 | +# MyBatis Plus 的配置项 | ||
| 24 | +mybatis-plus: | ||
| 25 | + configuration: | ||
| 26 | + map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。 | ||
| 27 | + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印日志 | ||
| 28 | + global-config: | ||
| 29 | + db-config: | ||
| 30 | + id-type: AUTO # 自增 ID | ||
| 31 | + logic-delete-value: 1 # 逻辑已删除值(默认为 1) | ||
| 32 | + logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) | ||
| 33 | + mapper-locations: classpath*:mapper/*.xml | ||
| 34 | + type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject | ||
| 35 | + | ||
| 36 | +--- #################### 芋道相关配置 #################### | ||
| 37 | + | ||
| 38 | +yudao: | ||
| 39 | + info: | ||
| 40 | + version: 1.0.0 | ||
| 41 | + base-package: cn.iocoder.yudao.userserver | ||
| 42 | + web: | ||
| 43 | + api-prefix: /api | ||
| 44 | + controller-package: ${yudao.info.base-package} | ||
| 45 | + swagger: | ||
| 46 | + title: 管理后台 | ||
| 47 | + description: 提供管理员管理的所有功能 | ||
| 48 | + version: ${yudao.info.version} | ||
| 49 | + base-package: ${yudao.info.base-package}.modules | ||
| 50 | + captcha: | ||
| 51 | + timeout: 5m | ||
| 52 | + width: 160 | ||
| 53 | + height: 60 | ||
| 54 | + codegen: | ||
| 55 | + base-package: ${yudao.info.base-package} | ||
| 56 | + db-schemas: ${spring.datasource.dynamic.datasource.master.name} | ||
| 57 | + error-code: # 错误码相关配置项 | ||
| 58 | + constants-class-list: | ||
| 59 | + | ||
| 60 | +debug: false |
yudao-user-server/src/main/resources/banner.txt
0 → 100644
| 1 | +芋道源码 http://www.iocoder.cn | ||
| 2 | +Application Version: ${yudao.info.version} | ||
| 3 | +Spring Boot Version: ${spring-boot.version} | ||
| 4 | + | ||
| 5 | +.__ __. ______ .______ __ __ _______ | ||
| 6 | +| \ | | / __ \ | _ \ | | | | / _____| | ||
| 7 | +| \| | | | | | | |_) | | | | | | | __ | ||
| 8 | +| . ` | | | | | | _ < | | | | | | |_ | | ||
| 9 | +| |\ | | `--' | | |_) | | `--' | | |__| | | ||
| 10 | +|__| \__| \______/ |______/ \______/ \______| | ||
| 11 | + | ||
| 12 | +███╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗ | ||
| 13 | +████╗ ██║██╔═══██╗ ██╔══██╗██║ ██║██╔════╝ | ||
| 14 | +██╔██╗ ██║██║ ██║ ██████╔╝██║ ██║██║ ███╗ | ||
| 15 | +██║╚██╗██║██║ ██║ ██╔══██╗██║ ██║██║ ██║ | ||
| 16 | +██║ ╚████║╚██████╔╝ ██████╔╝╚██████╔╝╚██████╔╝ | ||
| 17 | +╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ |
yudao-user-server/src/main/resources/logback-spring.xml
0 → 100644
| 1 | +<configuration> | ||
| 2 | + <!-- 引用 Spring Boot 的 logback 基础配置 --> | ||
| 3 | + <include resource="org/springframework/boot/logging/logback/defaults.xml" /> | ||
| 4 | + <!-- 变量 yudao.info.base-package,基础业务包 --> | ||
| 5 | + <springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/> | ||
| 6 | + <!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 --> | ||
| 7 | + <property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%thread] [%tid] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> | ||
| 8 | + | ||
| 9 | + <!-- 控制台 Appender --> | ||
| 10 | + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
| 11 | + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | ||
| 12 | + <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> | ||
| 13 | + <pattern>${PATTERN_DEFAULT}</pattern> | ||
| 14 | + </layout> | ||
| 15 | + </encoder> | ||
| 16 | + </appender> | ||
| 17 | + | ||
| 18 | + <!-- 文件 Appender --> | ||
| 19 | + <!-- 参考 Spring Boot 的 file-appender.xml 编写 --> | ||
| 20 | + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||
| 21 | + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | ||
| 22 | + <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> | ||
| 23 | + <pattern>${PATTERN_DEFAULT}</pattern> | ||
| 24 | + </layout> | ||
| 25 | + </encoder> | ||
| 26 | + <!-- 日志文件名 --> | ||
| 27 | + <file>${LOG_FILE}</file> | ||
| 28 | + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||
| 29 | + <!-- 滚动后的日志文件名 --> | ||
| 30 | + <fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern> | ||
| 31 | + <!-- 启动服务时,是否清理历史日志,一般不建议清理 --> | ||
| 32 | + <cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart> | ||
| 33 | + <!-- 日志文件,到达多少容量,进行滚动 --> | ||
| 34 | + <maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize> | ||
| 35 | + <!-- 日志文件的总大小,0 表示不限制 --> | ||
| 36 | + <totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap> | ||
| 37 | + <!-- 日志文件的保留天数 --> | ||
| 38 | + <maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory> | ||
| 39 | + </rollingPolicy> | ||
| 40 | + </appender> | ||
| 41 | + <!-- 异步写入日志,提升性能 --> | ||
| 42 | + <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> | ||
| 43 | + <!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 --> | ||
| 44 | + <discardingThreshold>0</discardingThreshold> | ||
| 45 | + <!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 --> | ||
| 46 | + <queueSize>256</queueSize> | ||
| 47 | + <appender-ref ref="FILE"/> | ||
| 48 | + </appender> | ||
| 49 | + | ||
| 50 | + <!-- SkyWalking GRPC 日志收集,实现日志中心。注意:SkyWalking 8.4.0 版本开始支持 --> | ||
| 51 | + <appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender"> | ||
| 52 | + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> | ||
| 53 | + <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout"> | ||
| 54 | + <pattern>${PATTERN_DEFAULT}</pattern> | ||
| 55 | + </layout> | ||
| 56 | + </encoder> | ||
| 57 | + </appender> | ||
| 58 | + | ||
| 59 | + <!-- 本地环境 --> | ||
| 60 | + <springProfile name="local"> | ||
| 61 | + <root level="INFO"> | ||
| 62 | + <appender-ref ref="STDOUT"/> | ||
| 63 | + <appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 --> | ||
| 64 | + <appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 --> | ||
| 65 | + </root> | ||
| 66 | + </springProfile> | ||
| 67 | + <!-- 其它环境 --> | ||
| 68 | + <springProfile name="default"> | ||
| 69 | + <root level="INFO"> | ||
| 70 | + <appender-ref ref="STDOUT"/> | ||
| 71 | + <appender-ref ref="ASYNC"/> | ||
| 72 | + <appender-ref ref="GRPC"/> | ||
| 73 | + </root> | ||
| 74 | + </springProfile> | ||
| 75 | + | ||
| 76 | +</configuration> |