diff --git a/novalon-manage-api/manage-app/Dockerfile b/novalon-manage-api/manage-app/Dockerfile
new file mode 100644
index 0000000..87f796a
--- /dev/null
+++ b/novalon-manage-api/manage-app/Dockerfile
@@ -0,0 +1,9 @@
+FROM openjdk:21-jdk-slim
+
+WORKDIR /app
+
+COPY manage-app/target/manage-app-1.0.0.jar app.jar
+
+EXPOSE 8081
+
+ENTRYPOINT ["java", "-jar", "app.jar"]
diff --git a/novalon-manage-api/manage-app/pom.xml b/novalon-manage-api/manage-app/pom.xml
new file mode 100644
index 0000000..0be245b
--- /dev/null
+++ b/novalon-manage-api/manage-app/pom.xml
@@ -0,0 +1,76 @@
+
+
+ 4.0.0
+
+
+ cn.novalon.manage
+ novalon-manage-api
+ 1.0.0
+
+
+ manage-app
+ jar
+
+ Manage App
+ Application module for Novalon Manage API
+
+
+
+ cn.novalon.manage
+ manage-sys
+ ${project.version}
+
+
+ cn.novalon.manage
+ manage-db
+ ${project.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ io.micrometer
+ micrometer-registry-prometheus
+
+
+ org.postgresql
+ r2dbc-postgresql
+
+
+ org.postgresql
+ postgresql
+
+
+ org.flywaydb
+ flyway-core
+
+
+ org.flywaydb
+ flyway-database-postgresql
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ cn.novalon.manage.app.ManageApplication
+
+
+
+
+
diff --git a/novalon-manage-api/manage-app/src/main/java/cn/novalon/manage/app/ManageApplication.java b/novalon-manage-api/manage-app/src/main/java/cn/novalon/manage/app/ManageApplication.java
new file mode 100644
index 0000000..7dca5c0
--- /dev/null
+++ b/novalon-manage-api/manage-app/src/main/java/cn/novalon/manage/app/ManageApplication.java
@@ -0,0 +1,16 @@
+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;
+
+@SpringBootApplication
+@ConfigurationPropertiesScan(basePackages = "cn.novalon.manage")
+@ComponentScan(basePackages = "cn.novalon.manage")
+public class ManageApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ManageApplication.class, args);
+ }
+}
diff --git a/novalon-manage-api/manage-app/src/main/resources/application-dev.yml b/novalon-manage-api/manage-app/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..76b1153
--- /dev/null
+++ b/novalon-manage-api/manage-app/src/main/resources/application-dev.yml
@@ -0,0 +1,13 @@
+spring:
+ r2dbc:
+ url: r2dbc:postgresql://localhost:5432/novalon_manage
+ username: postgres
+ password: postgres
+ flyway:
+ enabled: true
+
+logging:
+ level:
+ cn.novalon.manage: DEBUG
+ org.springframework.r2dbc: DEBUG
+ org.springframework.web: TRACE
diff --git a/novalon-manage-api/manage-app/src/main/resources/application-prod.yml b/novalon-manage-api/manage-app/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..978f29c
--- /dev/null
+++ b/novalon-manage-api/manage-app/src/main/resources/application-prod.yml
@@ -0,0 +1,12 @@
+spring:
+ r2dbc:
+ url: r2dbc:postgresql://postgres:5432/novalon_manage
+ username: ${DB_USERNAME}
+ password: ${DB_PASSWORD}
+ flyway:
+ enabled: true
+
+logging:
+ level:
+ cn.novalon.manage: INFO
+ org.springframework.r2dbc: INFO
diff --git a/novalon-manage-api/manage-app/src/main/resources/application.yml b/novalon-manage-api/manage-app/src/main/resources/application.yml
new file mode 100644
index 0000000..dc5c843
--- /dev/null
+++ b/novalon-manage-api/manage-app/src/main/resources/application.yml
@@ -0,0 +1,38 @@
+server:
+ port: 8081
+
+spring:
+ application:
+ name: manage-app
+ r2dbc:
+ url: r2dbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:novalon_manage}
+ username: ${DB_USERNAME:postgres}
+ password: ${DB_PASSWORD:postgres}
+ pool:
+ initial-size: 10
+ max-size: 50
+ max-idle-time: 30m
+ max-life-time: 1h
+ acquire-timeout: 5s
+ flyway:
+ enabled: true
+ locations: classpath:db/migration
+
+management:
+ endpoints:
+ web:
+ exposure:
+ include: health,info,metrics,env,loggers
+ base-path: /actuator
+ endpoint:
+ health:
+ show-details: always
+ metrics:
+ tags:
+ application: ${spring.application.name}
+ environment: ${spring.profiles.active}
+
+logging:
+ level:
+ cn.novalon.manage: DEBUG
+ org.springframework.r2dbc: DEBUG
diff --git a/novalon-manage-api/manage-db/pom.xml b/novalon-manage-api/manage-db/pom.xml
new file mode 100644
index 0000000..d91a43b
--- /dev/null
+++ b/novalon-manage-api/manage-db/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+
+ cn.novalon.manage
+ novalon-manage-api
+ 1.0.0
+
+
+ manage-db
+ jar
+
+ Manage DB
+ Database module for Novalon Manage API
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-r2dbc
+
+
+ org.postgresql
+ r2dbc-postgresql
+
+
+ org.postgresql
+ postgresql
+
+
+ org.flywaydb
+ flyway-core
+
+
+ org.flywaydb
+ flyway-database-postgresql
+
+
+ org.mapstruct
+ mapstruct
+ 1.5.5.Final
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.5.5.Final
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
diff --git a/novalon-manage-api/manage-db/src/main/resources/db/migration/V1__Create_all_tables.sql b/novalon-manage-api/manage-db/src/main/resources/db/migration/V1__Create_all_tables.sql
new file mode 100644
index 0000000..559304e
--- /dev/null
+++ b/novalon-manage-api/manage-db/src/main/resources/db/migration/V1__Create_all_tables.sql
@@ -0,0 +1,209 @@
+-- Novalon管理系统数据库初始化脚本
+-- 版本: V1
+-- 描述: 创建所有核心表
+
+-- 用户表
+CREATE TABLE IF NOT EXISTS users (
+ id BIGSERIAL PRIMARY KEY,
+ username VARCHAR(50) NOT NULL UNIQUE,
+ password VARCHAR(255) NOT NULL,
+ email VARCHAR(100),
+ phone VARCHAR(20),
+ role_id BIGINT,
+ status INTEGER DEFAULT 1,
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 角色表
+CREATE TABLE IF NOT EXISTS roles (
+ id BIGSERIAL PRIMARY KEY,
+ role_name VARCHAR(100) NOT NULL,
+ role_key VARCHAR(100) NOT NULL UNIQUE,
+ role_sort INTEGER DEFAULT 0,
+ status INTEGER DEFAULT 1,
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 菜单表
+CREATE TABLE IF NOT EXISTS menus (
+ id BIGSERIAL PRIMARY KEY,
+ menu_name VARCHAR(50) NOT NULL,
+ parent_id BIGINT DEFAULT 0,
+ order_num INTEGER DEFAULT 0,
+ menu_type VARCHAR(1) DEFAULT 'C',
+ perms VARCHAR(100),
+ component VARCHAR(200),
+ status INTEGER DEFAULT 1,
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 字典类型表
+CREATE TABLE IF NOT EXISTS sys_dict_type (
+ id BIGSERIAL PRIMARY KEY,
+ dict_name VARCHAR(100) NOT NULL,
+ dict_type VARCHAR(100) NOT NULL UNIQUE,
+ status VARCHAR(1) DEFAULT '0',
+ remark VARCHAR(500),
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 字典数据表
+CREATE TABLE IF NOT EXISTS sys_dict_data (
+ id BIGSERIAL PRIMARY KEY,
+ dict_sort INTEGER DEFAULT 0,
+ dict_label VARCHAR(100) NOT NULL,
+ dict_value VARCHAR(100) NOT NULL,
+ dict_type VARCHAR(100) NOT NULL,
+ css_class VARCHAR(100),
+ list_class VARCHAR(100),
+ is_default VARCHAR(1) DEFAULT 'N',
+ status VARCHAR(1) DEFAULT '0',
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 系统配置表
+CREATE TABLE IF NOT EXISTS sys_config (
+ id BIGSERIAL PRIMARY KEY,
+ config_name VARCHAR(100) NOT NULL,
+ config_key VARCHAR(100) NOT NULL UNIQUE,
+ config_value VARCHAR(500) NOT NULL,
+ config_type VARCHAR(1) DEFAULT 'N',
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 登录日志表
+CREATE TABLE IF NOT EXISTS sys_login_log (
+ id BIGSERIAL PRIMARY KEY,
+ username VARCHAR(50),
+ ip VARCHAR(50),
+ location VARCHAR(255),
+ browser VARCHAR(50),
+ os VARCHAR(50),
+ status VARCHAR(1),
+ message VARCHAR(255),
+ login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 异常日志表
+CREATE TABLE IF NOT EXISTS sys_exception_log (
+ id BIGSERIAL PRIMARY KEY,
+ username VARCHAR(50),
+ ip VARCHAR(50),
+ location VARCHAR(255),
+ browser VARCHAR(50),
+ os VARCHAR(50),
+ status VARCHAR(1),
+ message VARCHAR(255),
+ exception_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- 系统公告表
+CREATE TABLE IF NOT EXISTS sys_notice (
+ id BIGSERIAL PRIMARY KEY,
+ notice_title VARCHAR(50) NOT NULL,
+ notice_type VARCHAR(1) NOT NULL,
+ notice_content TEXT,
+ status VARCHAR(1) DEFAULT '0',
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 用户消息表
+CREATE TABLE IF NOT EXISTS sys_user_message (
+ id BIGSERIAL PRIMARY KEY,
+ user_id BIGINT NOT NULL,
+ notice_id BIGINT,
+ message_title VARCHAR(255),
+ message_content TEXT,
+ is_read VARCHAR(1) DEFAULT '0',
+ read_time TIMESTAMP,
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 文件管理表
+CREATE TABLE IF NOT EXISTS sys_file (
+ id BIGSERIAL PRIMARY KEY,
+ file_name VARCHAR(255) NOT NULL,
+ file_path VARCHAR(500) NOT NULL,
+ file_size BIGINT,
+ file_type VARCHAR(100),
+ file_extension VARCHAR(10),
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- OAuth2客户端表
+CREATE TABLE IF NOT EXISTS oauth2_client (
+ id BIGSERIAL PRIMARY KEY,
+ client_id VARCHAR(100) NOT NULL UNIQUE,
+ client_secret VARCHAR(255) NOT NULL,
+ client_name VARCHAR(100),
+ web_server_redirect_uri VARCHAR(500),
+ scope VARCHAR(500),
+ authorized_grant_types VARCHAR(500),
+ access_token_validity_seconds INTEGER,
+ refresh_token_validity_seconds INTEGER,
+ auto_approve VARCHAR(1) DEFAULT 'false',
+ enabled VARCHAR(1) DEFAULT 'true',
+ create_by VARCHAR(50),
+ update_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 插入初始管理员用户
+INSERT INTO users (username, password, email, role_id, status, create_by, update_by)
+VALUES ('admin', '$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTVKIUi', 'admin@novalon.com', 1, 1, 'system', 'system')
+ON CONFLICT (username) DO NOTHING;
+
+-- 插入初始角色
+INSERT INTO roles (role_name, role_key, role_sort, status, create_by, update_by)
+VALUES ('超级管理员', 'admin', 1, 1, 'system', 'system')
+ON CONFLICT (role_key) DO NOTHING;
+
+-- 插入初始字典类型
+INSERT INTO sys_dict_type (dict_name, dict_type, status, remark, create_by, update_by)
+VALUES ('用户状态', 'user_status', '0', '用户状态列表', 'system', 'system')
+ON CONFLICT (dict_type) DO NOTHING;
+
+-- 插入初始字典数据
+INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, status, create_by, update_by)
+VALUES
+(1, '正常', '1', 'user_status', '0', 'system', 'system'),
+(2, '停用', '0', 'user_status', '0', 'system', 'system')
+ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/novalon-manage-api/manage-db/src/main/resources/db/migration/V2__Create_sys_dictionary_table.sql b/novalon-manage-api/manage-db/src/main/resources/db/migration/V2__Create_sys_dictionary_table.sql
new file mode 100644
index 0000000..43e90fe
--- /dev/null
+++ b/novalon-manage-api/manage-db/src/main/resources/db/migration/V2__Create_sys_dictionary_table.sql
@@ -0,0 +1,18 @@
+-- 创建字典表
+CREATE TABLE IF NOT EXISTS sys_dictionary (
+ id BIGSERIAL PRIMARY KEY,
+ type VARCHAR(100) NOT NULL,
+ code VARCHAR(100) NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ value VARCHAR(500),
+ remark VARCHAR(500),
+ sort INTEGER DEFAULT 0,
+ create_by VARCHAR(50),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ deleted_at TIMESTAMP
+);
+
+-- 创建索引
+CREATE INDEX IF NOT EXISTS idx_sys_dictionary_type ON sys_dictionary(type);
+CREATE INDEX IF NOT EXISTS idx_sys_dictionary_type_code ON sys_dictionary(type, code);
diff --git a/novalon-manage-api/pom.xml b/novalon-manage-api/pom.xml
index 9e5c85e..51506d8 100644
--- a/novalon-manage-api/pom.xml
+++ b/novalon-manage-api/pom.xml
@@ -31,6 +31,8 @@
manage-sys
manage-gateway
+ manage-app
+ manage-db