refactor: add manage-notify and manage-file dependencies to manage-app
This commit is contained in:
@@ -22,6 +22,16 @@
|
||||
<artifactId>manage-sys</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.novalon.manage</groupId>
|
||||
<artifactId>manage-notify</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.novalon.manage</groupId>
|
||||
<artifactId>manage-file</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.novalon.manage</groupId>
|
||||
<artifactId>manage-db</artifactId>
|
||||
@@ -35,6 +45,16 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.resilience4j</groupId>
|
||||
<artifactId>resilience4j-spring-boot3</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.resilience4j</groupId>
|
||||
<artifactId>resilience4j-reactor</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
|
||||
+1
-3
@@ -3,13 +3,11 @@ package cn.novalon.manage.app;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
|
||||
|
||||
@SpringBootApplication
|
||||
@ConfigurationPropertiesScan(basePackages = "cn.novalon.manage")
|
||||
@ComponentScan(basePackages = "cn.novalon.manage")
|
||||
@EnableR2dbcRepositories(basePackages = "cn.novalon.manage.db.dao")
|
||||
@EnableR2dbcRepositories(basePackages = {"cn.novalon.manage.db.dao"})
|
||||
public class ManageApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cn.novalon.manage.sys.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
|
||||
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
|
||||
|
||||
@Configuration
|
||||
public class MultipartConfig {
|
||||
|
||||
@Bean
|
||||
public MultipartHttpMessageReader multipartHttpMessageReader() {
|
||||
DefaultPartHttpMessageReader partReader = new DefaultPartHttpMessageReader();
|
||||
partReader.setMaxHeadersSize(8192);
|
||||
partReader.setMaxDiskUsagePerPart(10 * 1024 * 1024);
|
||||
partReader.setEnableLoggingRequestDetails(true);
|
||||
return new MultipartHttpMessageReader(partReader);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package cn.novalon.manage.sys.config;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import io.swagger.v3.oas.models.servers.Server;
|
||||
import io.swagger.v3.oas.models.tags.Tag;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class OpenApiConfig {
|
||||
|
||||
@Bean
|
||||
public OpenAPI customOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("Novalon Manage System API")
|
||||
.version("1.0.0")
|
||||
.description("Novalon 管理系统 RESTful API 文档")
|
||||
.contact(new Contact()
|
||||
.name("Novalon Team")
|
||||
.email("support@novalon.cn"))
|
||||
.license(new License()
|
||||
.name("Apache 2.0")
|
||||
.url("https://www.apache.org/licenses/LICENSE-2.0")))
|
||||
.servers(List.of(
|
||||
new Server().url("http://localhost:8080").description("开发环境"),
|
||||
new Server().url("https://api.novalon.cn").description("生产环境")))
|
||||
.tags(Arrays.asList(
|
||||
new Tag().name("用户管理").description("用户相关操作"),
|
||||
new Tag().name("角色管理").description("角色相关操作"),
|
||||
new Tag().name("配置管理").description("系统配置相关操作"),
|
||||
new Tag().name("字典管理").description("字典数据相关操作"),
|
||||
new Tag().name("通知管理").description("系统通知相关操作"),
|
||||
new Tag().name("文件管理").description("文件上传下载相关操作"),
|
||||
new Tag().name("日志管理").description("操作日志相关操作"),
|
||||
new Tag().name("认证管理").description("登录认证相关操作"),
|
||||
new Tag().name("统计信息").description("系统统计相关操作")));
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package cn.novalon.manage.app.config;
|
||||
|
||||
import io.github.resilience4j.ratelimiter.RateLimiter;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
|
||||
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Configuration
|
||||
public class RateLimitConfig {
|
||||
|
||||
@Value("${rate.limit.limit-for-period:100}")
|
||||
private int limitForPeriod;
|
||||
|
||||
@Value("${rate.limit.limit-refresh-period:1s}")
|
||||
private Duration limitRefreshPeriod;
|
||||
|
||||
@Value("${rate.limit.timeout-duration:0}")
|
||||
private Duration timeoutDuration;
|
||||
|
||||
@Bean
|
||||
public RateLimiterRegistry rateLimiterRegistry() {
|
||||
RateLimiterConfig config = RateLimiterConfig.custom()
|
||||
.limitForPeriod(limitForPeriod)
|
||||
.limitRefreshPeriod(limitRefreshPeriod)
|
||||
.timeoutDuration(timeoutDuration)
|
||||
.build();
|
||||
|
||||
return RateLimiterRegistry.of(config);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Qualifier("apiRateLimiter")
|
||||
public RateLimiter apiRateLimiter(RateLimiterRegistry registry) {
|
||||
return registry.rateLimiter("apiRateLimiter");
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
package cn.novalon.manage.sys.config;
|
||||
|
||||
import cn.novalon.manage.sys.handler.auth.SysAuthHandler;
|
||||
import cn.novalon.manage.sys.handler.config.SysConfigHandler;
|
||||
import cn.novalon.manage.sys.handler.dictionary.DictionaryHandler;
|
||||
import cn.novalon.manage.sys.handler.dict.SysDictHandler;
|
||||
import cn.novalon.manage.sys.handler.log.SysLogHandler;
|
||||
import cn.novalon.manage.sys.handler.menu.MenuHandler;
|
||||
import cn.novalon.manage.sys.handler.role.SysRoleHandler;
|
||||
import cn.novalon.manage.sys.handler.stats.StatsHandler;
|
||||
import cn.novalon.manage.sys.handler.user.SysUserHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
|
||||
/**
|
||||
* 系统路由配置类
|
||||
*
|
||||
* 文件定义:配置WebFlux函数式路由,将HTTP请求映射到对应的Handler方法
|
||||
* 涉及业务:用户、角色、字典、菜单、公告、文件等所有RESTful API路由
|
||||
* 算法:使用RouterFunctions.route()构建函数式路由规则
|
||||
*
|
||||
* @author 张翔
|
||||
* @date 2026-03-13
|
||||
*/
|
||||
@Configuration
|
||||
public class SystemRouter {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> dictionaryRoutes(DictionaryHandler dictionaryHandler) {
|
||||
return route()
|
||||
.GET("/api/dictionaries", dictionaryHandler::getAllDictionaries)
|
||||
.GET("/api/dictionaries/{id}", dictionaryHandler::getDictionaryById)
|
||||
.GET("/api/dictionaries/type/{type}", dictionaryHandler::getDictionariesByType)
|
||||
.GET("/api/dictionaries/check/exists", dictionaryHandler::checkTypeAndCodeExists)
|
||||
.POST("/api/dictionaries", dictionaryHandler::createDictionary)
|
||||
.PUT("/api/dictionaries/{id}", dictionaryHandler::updateDictionary)
|
||||
.DELETE("/api/dictionaries/{id}", dictionaryHandler::deleteDictionary)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> userRoutes(SysUserHandler userHandler) {
|
||||
return route()
|
||||
.GET("/api/users", userHandler::getAllUsers)
|
||||
.GET("/api/users/page", userHandler::getUsersByPage)
|
||||
.GET("/api/users/count", userHandler::getUserCount)
|
||||
.GET("/api/users/{id}", userHandler::getUserById)
|
||||
.GET("/api/users/username/{username}", userHandler::getUserByUsername)
|
||||
.POST("/api/users", userHandler::createUser)
|
||||
.PUT("/api/users/{id}", userHandler::updateUser)
|
||||
.DELETE("/api/users/{id}", userHandler::deleteUser)
|
||||
.POST("/api/users/{id}/password", userHandler::changePassword)
|
||||
.DELETE("/api/users/{id}/logical", userHandler::logicalDeleteUser)
|
||||
.POST("/api/users/logical-delete", userHandler::logicalDeleteUsers)
|
||||
.POST("/api/users/{id}/restore", userHandler::restoreUser)
|
||||
.POST("/api/users/restore", userHandler::restoreUsers)
|
||||
.GET("/api/users/check/username", userHandler::checkUsernameExists)
|
||||
.GET("/api/users/check/email", userHandler::checkEmailExists)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> menuRoutes(MenuHandler menuHandler) {
|
||||
return route()
|
||||
.GET("/api/menus", menuHandler::getAllMenus)
|
||||
.GET("/api/menus/tree", menuHandler::getMenuTree)
|
||||
.GET("/api/menus/{id}", menuHandler::getMenuById)
|
||||
.POST("/api/menus", menuHandler::createMenu)
|
||||
.PUT("/api/menus/{id}", menuHandler::updateMenu)
|
||||
.DELETE("/api/menus/{id}", menuHandler::deleteMenu)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> roleRoutes(SysRoleHandler roleHandler) {
|
||||
return route()
|
||||
.GET("/api/roles", roleHandler::getAllRoles)
|
||||
.GET("/api/roles/page", roleHandler::getRolesByPage)
|
||||
.GET("/api/roles/count", roleHandler::getRoleCount)
|
||||
.GET("/api/roles/name/{roleName}", roleHandler::getRoleByName)
|
||||
.GET("/api/roles/check-name", roleHandler::checkNameExists)
|
||||
.GET("/api/roles/{id}", roleHandler::getRoleById)
|
||||
.POST("/api/roles", roleHandler::createRole)
|
||||
.PUT("/api/roles/{id}", roleHandler::updateRole)
|
||||
.DELETE("/api/roles/{id}", roleHandler::deleteRole)
|
||||
.POST("/api/roles/{id}/restore", roleHandler::restoreRole)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> configRoutes(SysConfigHandler configHandler) {
|
||||
return route()
|
||||
.GET("/api/config", configHandler::getAllConfigs)
|
||||
.GET("/api/config/{id}", configHandler::getConfigById)
|
||||
.GET("/api/config/key/{configKey}", configHandler::getConfigByKey)
|
||||
.POST("/api/config", configHandler::createConfig)
|
||||
.PUT("/api/config/{id}", configHandler::updateConfig)
|
||||
.DELETE("/api/config/{id}", configHandler::deleteConfig)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> logRoutes(SysLogHandler logHandler) {
|
||||
return route()
|
||||
.GET("/api/logs/login", logHandler::getAllLoginLogs)
|
||||
.GET("/api/logs/login/page", logHandler::getLoginLogsByPage)
|
||||
.GET("/api/logs/login/count", logHandler::getLoginLogCount)
|
||||
.GET("/api/logs/login/{id}", logHandler::getLoginLogById)
|
||||
.POST("/api/logs/login", logHandler::createLoginLog)
|
||||
.GET("/api/logs/exception", logHandler::getAllExceptionLogs)
|
||||
.GET("/api/logs/exception/page", logHandler::getExceptionLogsByPage)
|
||||
.GET("/api/logs/exception/count", logHandler::getExceptionLogCount)
|
||||
.GET("/api/logs/exception/{id}", logHandler::getExceptionLogById)
|
||||
.POST("/api/logs/exception", logHandler::createExceptionLog)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> authRoutes(SysAuthHandler authHandler) {
|
||||
return route()
|
||||
.POST("/api/auth/login", authHandler::login)
|
||||
.POST("/api/auth/register", authHandler::register)
|
||||
.POST("/api/auth/logout", authHandler::logout)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> statsRoutes(StatsHandler statsHandler) {
|
||||
return route()
|
||||
.GET("/api/stats/overview", statsHandler::getOverview)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> dictRoutes(SysDictHandler dictHandler) {
|
||||
return route()
|
||||
.GET("/api/dict/types", dictHandler::getAllDictTypes)
|
||||
.GET("/api/dict/types/{id}", dictHandler::getDictTypeById)
|
||||
.GET("/api/dict/types/type/{dictType}", dictHandler::getDictTypeByType)
|
||||
.POST("/api/dict/types", dictHandler::createDictType)
|
||||
.PUT("/api/dict/types/{id}", dictHandler::updateDictType)
|
||||
.DELETE("/api/dict/types/{id}", dictHandler::deleteDictType)
|
||||
.GET("/api/dict/data", dictHandler::getAllDictData)
|
||||
.GET("/api/dict/data/type/{dictType}", dictHandler::getDictDataByType)
|
||||
.GET("/api/dict/data/{id}", dictHandler::getDictDataById)
|
||||
.POST("/api/dict/data", dictHandler::createDictData)
|
||||
.PUT("/api/dict/data/{id}", dictHandler::updateDictData)
|
||||
.DELETE("/api/dict/data/{id}", dictHandler::deleteDictData)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package cn.novalon.manage.sys.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.codec.ServerCodecConfigurer;
|
||||
import org.springframework.web.reactive.config.WebFluxConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebFluxConfig implements WebFluxConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
|
||||
configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ spring:
|
||||
application:
|
||||
name: manage-app
|
||||
r2dbc:
|
||||
url: r2dbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:novalon_manage}
|
||||
url: r2dbc:postgresql://${DB_HOST:localhost}:${DB_PORT:55432}/${DB_NAME:manage_system}
|
||||
username: ${DB_USERNAME:postgres}
|
||||
password: ${DB_PASSWORD:postgres}
|
||||
pool:
|
||||
|
||||
Reference in New Issue
Block a user