develop #1
@@ -92,6 +92,11 @@
|
|||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.projectreactor</groupId>
|
<groupId>io.projectreactor</groupId>
|
||||||
<artifactId>reactor-test</artifactId>
|
<artifactId>reactor-test</artifactId>
|
||||||
|
|||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package cn.novalon.manage.app.config;
|
||||||
|
|
||||||
|
import io.r2dbc.spi.ConnectionFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer;
|
||||||
|
import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* R2DBC数据库初始化配置
|
||||||
|
*
|
||||||
|
* 用于测试环境的H2数据库初始化
|
||||||
|
*
|
||||||
|
* @author 张翔
|
||||||
|
* @date 2026-04-03
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "test")
|
||||||
|
public class R2dbcInitConfig {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(R2dbcInitConfig.class);
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ConnectionFactoryInitializer connectionFactoryInitializer(ConnectionFactory connectionFactory) {
|
||||||
|
logger.info("Initializing R2DBC database with H2 schema and data");
|
||||||
|
|
||||||
|
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
|
||||||
|
initializer.setConnectionFactory(connectionFactory);
|
||||||
|
|
||||||
|
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||||
|
populator.addScript(new ClassPathResource("schema-h2.sql"));
|
||||||
|
populator.addScript(new ClassPathResource("data-h2.sql"));
|
||||||
|
|
||||||
|
initializer.setDatabasePopulator(populator);
|
||||||
|
|
||||||
|
return initializer;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ spring:
|
|||||||
r2dbc:
|
r2dbc:
|
||||||
url: r2dbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
url: r2dbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
username: sa
|
username: sa
|
||||||
password:
|
password:
|
||||||
pool:
|
pool:
|
||||||
initial-size: 5
|
initial-size: 5
|
||||||
max-size: 20
|
max-size: 20
|
||||||
@@ -17,15 +17,10 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
url: jdbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
url: jdbc:h2:mem:///testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
username: sa
|
username: sa
|
||||||
password:
|
password:
|
||||||
driver-class-name: org.h2.Driver
|
driver-class-name: org.h2.Driver
|
||||||
flyway:
|
flyway:
|
||||||
enabled: false
|
enabled: false
|
||||||
sql:
|
|
||||||
init:
|
|
||||||
mode: always
|
|
||||||
schema-locations: classpath:schema-h2.sql
|
|
||||||
data-locations: classpath:data-h2.sql
|
|
||||||
h2:
|
h2:
|
||||||
console:
|
console:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
-- H2数据库Schema for Integration Testing
|
-- H2 Database Schema for Integration Testing
|
||||||
-- 创建用户表
|
-- Create user table
|
||||||
CREATE TABLE IF NOT EXISTS sys_user (
|
CREATE TABLE IF NOT EXISTS sys_user (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
username VARCHAR(50) NOT NULL UNIQUE,
|
username VARCHAR(50) NOT NULL UNIQUE,
|
||||||
@@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS sys_user (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建角色表
|
-- Create role table
|
||||||
CREATE TABLE IF NOT EXISTS sys_role (
|
CREATE TABLE IF NOT EXISTS sys_role (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
role_name VARCHAR(100) NOT NULL,
|
role_name VARCHAR(100) NOT NULL,
|
||||||
@@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS sys_role (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建用户角色关联表
|
-- Create user role relation table
|
||||||
CREATE TABLE IF NOT EXISTS user_role (
|
CREATE TABLE IF NOT EXISTS user_role (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id BIGINT NOT NULL,
|
user_id BIGINT NOT NULL,
|
||||||
@@ -42,7 +42,7 @@ CREATE TABLE IF NOT EXISTS user_role (
|
|||||||
CONSTRAINT uk_user_role UNIQUE (user_id, role_id)
|
CONSTRAINT uk_user_role UNIQUE (user_id, role_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建菜单表
|
-- Create menu table
|
||||||
CREATE TABLE IF NOT EXISTS sys_menu (
|
CREATE TABLE IF NOT EXISTS sys_menu (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
menu_name VARCHAR(50) NOT NULL,
|
menu_name VARCHAR(50) NOT NULL,
|
||||||
@@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS sys_menu (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建权限表
|
-- Create permission table
|
||||||
CREATE TABLE IF NOT EXISTS sys_permission (
|
CREATE TABLE IF NOT EXISTS sys_permission (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
permission_name VARCHAR(100) NOT NULL,
|
permission_name VARCHAR(100) NOT NULL,
|
||||||
@@ -78,7 +78,7 @@ CREATE TABLE IF NOT EXISTS sys_permission (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建角色权限关联表
|
-- Create role permission relation table
|
||||||
CREATE TABLE IF NOT EXISTS sys_role_permission (
|
CREATE TABLE IF NOT EXISTS sys_role_permission (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
role_id BIGINT NOT NULL,
|
role_id BIGINT NOT NULL,
|
||||||
@@ -91,7 +91,7 @@ CREATE TABLE IF NOT EXISTS sys_role_permission (
|
|||||||
CONSTRAINT uk_role_permission UNIQUE (role_id, permission_id)
|
CONSTRAINT uk_role_permission UNIQUE (role_id, permission_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建字典类型表
|
-- Create dict type table
|
||||||
CREATE TABLE IF NOT EXISTS sys_dict_type (
|
CREATE TABLE IF NOT EXISTS sys_dict_type (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
dict_name VARCHAR(100) NOT NULL,
|
dict_name VARCHAR(100) NOT NULL,
|
||||||
@@ -105,7 +105,7 @@ CREATE TABLE IF NOT EXISTS sys_dict_type (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建字典数据表
|
-- Create dict data table
|
||||||
CREATE TABLE IF NOT EXISTS sys_dict_data (
|
CREATE TABLE IF NOT EXISTS sys_dict_data (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
dict_sort INTEGER DEFAULT 0,
|
dict_sort INTEGER DEFAULT 0,
|
||||||
@@ -123,7 +123,7 @@ CREATE TABLE IF NOT EXISTS sys_dict_data (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建字典表(通用字典)
|
-- Create dictionary table (general)
|
||||||
CREATE TABLE IF NOT EXISTS sys_dictionary (
|
CREATE TABLE IF NOT EXISTS sys_dictionary (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
type VARCHAR(100) NOT NULL,
|
type VARCHAR(100) NOT NULL,
|
||||||
@@ -138,7 +138,7 @@ CREATE TABLE IF NOT EXISTS sys_dictionary (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建系统配置表
|
-- Create system config table
|
||||||
CREATE TABLE IF NOT EXISTS sys_config (
|
CREATE TABLE IF NOT EXISTS sys_config (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
config_name VARCHAR(100) NOT NULL,
|
config_name VARCHAR(100) NOT NULL,
|
||||||
@@ -152,7 +152,7 @@ CREATE TABLE IF NOT EXISTS sys_config (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建登录日志表
|
-- Create login log table
|
||||||
CREATE TABLE IF NOT EXISTS sys_login_log (
|
CREATE TABLE IF NOT EXISTS sys_login_log (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
username VARCHAR(50),
|
username VARCHAR(50),
|
||||||
@@ -165,7 +165,7 @@ CREATE TABLE IF NOT EXISTS sys_login_log (
|
|||||||
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建异常日志表
|
-- Create exception log table
|
||||||
CREATE TABLE IF NOT EXISTS sys_exception_log (
|
CREATE TABLE IF NOT EXISTS sys_exception_log (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
username VARCHAR(50),
|
username VARCHAR(50),
|
||||||
@@ -179,7 +179,7 @@ CREATE TABLE IF NOT EXISTS sys_exception_log (
|
|||||||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建操作日志表
|
-- Create operation log table
|
||||||
CREATE TABLE IF NOT EXISTS operation_log (
|
CREATE TABLE IF NOT EXISTS operation_log (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
username VARCHAR(50),
|
username VARCHAR(50),
|
||||||
@@ -198,7 +198,7 @@ CREATE TABLE IF NOT EXISTS operation_log (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建系统公告表
|
-- Create system notice table
|
||||||
CREATE TABLE IF NOT EXISTS sys_notice (
|
CREATE TABLE IF NOT EXISTS sys_notice (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
notice_title VARCHAR(50) NOT NULL,
|
notice_title VARCHAR(50) NOT NULL,
|
||||||
@@ -212,7 +212,7 @@ CREATE TABLE IF NOT EXISTS sys_notice (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建用户消息表
|
-- Create user message table
|
||||||
CREATE TABLE IF NOT EXISTS sys_user_message (
|
CREATE TABLE IF NOT EXISTS sys_user_message (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
user_id BIGINT NOT NULL,
|
user_id BIGINT NOT NULL,
|
||||||
@@ -228,7 +228,7 @@ CREATE TABLE IF NOT EXISTS sys_user_message (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建文件管理表
|
-- Create file management table
|
||||||
CREATE TABLE IF NOT EXISTS sys_file (
|
CREATE TABLE IF NOT EXISTS sys_file (
|
||||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
file_name VARCHAR(255) NOT NULL,
|
file_name VARCHAR(255) NOT NULL,
|
||||||
@@ -244,7 +244,7 @@ CREATE TABLE IF NOT EXISTS sys_file (
|
|||||||
deleted_at TIMESTAMP
|
deleted_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 创建索引
|
-- Create indexes
|
||||||
CREATE INDEX IF NOT EXISTS idx_user_role_user_id ON user_role(user_id);
|
CREATE INDEX IF NOT EXISTS idx_user_role_user_id ON user_role(user_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_user_role_role_id ON user_role(role_id);
|
CREATE INDEX IF NOT EXISTS idx_user_role_role_id ON user_role(role_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_sys_menu_parent_id ON sys_menu(parent_id);
|
CREATE INDEX IF NOT EXISTS idx_sys_menu_parent_id ON sys_menu(parent_id);
|
||||||
|
|||||||
@@ -0,0 +1,253 @@
|
|||||||
|
-- H2数据库Schema for Integration Testing
|
||||||
|
-- Create用户表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_user (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
username VARCHAR(50) NOT NULL UNIQUE,
|
||||||
|
password VARCHAR(255) NOT NULL,
|
||||||
|
email VARCHAR(100),
|
||||||
|
phone VARCHAR(20),
|
||||||
|
nickname VARCHAR(100),
|
||||||
|
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角色表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_role (
|
||||||
|
id BIGINT AUTO_INCREMENT 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用户角色关联表
|
||||||
|
CREATE TABLE IF NOT EXISTS user_role (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
user_id BIGINT NOT NULL,
|
||||||
|
role_id BIGINT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
created_by VARCHAR(50),
|
||||||
|
CONSTRAINT fk_user_role_user FOREIGN KEY (user_id) REFERENCES sys_user(id) ON DELETE CASCADE,
|
||||||
|
CONSTRAINT fk_user_role_role FOREIGN KEY (role_id) REFERENCES sys_role(id) ON DELETE CASCADE,
|
||||||
|
CONSTRAINT uk_user_role UNIQUE (user_id, role_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create菜单表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_menu (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
menu_name VARCHAR(50) NOT NULL,
|
||||||
|
parent_id BIGINT DEFAULT 0,
|
||||||
|
order_num INTEGER DEFAULT 0,
|
||||||
|
path VARCHAR(200),
|
||||||
|
component VARCHAR(200),
|
||||||
|
menu_type VARCHAR(1) DEFAULT 'C',
|
||||||
|
visible VARCHAR(1) DEFAULT '1',
|
||||||
|
status VARCHAR(1) DEFAULT '1',
|
||||||
|
perms VARCHAR(100),
|
||||||
|
icon VARCHAR(100),
|
||||||
|
create_by VARCHAR(50),
|
||||||
|
update_by VARCHAR(50),
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create权限表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_permission (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
permission_name VARCHAR(100) NOT NULL,
|
||||||
|
permission_code VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
resource VARCHAR(200),
|
||||||
|
action VARCHAR(20),
|
||||||
|
description VARCHAR(500),
|
||||||
|
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角色权限关联表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_role_permission (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
role_id BIGINT NOT NULL,
|
||||||
|
permission_id BIGINT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
created_by VARCHAR(50),
|
||||||
|
updated_by VARCHAR(50),
|
||||||
|
CONSTRAINT fk_role_permission_role FOREIGN KEY (role_id) REFERENCES sys_role(id) ON DELETE CASCADE,
|
||||||
|
CONSTRAINT fk_role_permission_permission FOREIGN KEY (permission_id) REFERENCES sys_permission(id) ON DELETE CASCADE,
|
||||||
|
CONSTRAINT uk_role_permission UNIQUE (role_id, permission_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create字典类型表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_dict_type (
|
||||||
|
id BIGINT AUTO_INCREMENT 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字典数据表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_dict_data (
|
||||||
|
id BIGINT AUTO_INCREMENT 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字典表(通用字典)
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_dictionary (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
type VARCHAR(100) NOT NULL,
|
||||||
|
code VARCHAR(100) NOT NULL,
|
||||||
|
name VARCHAR(100) NOT NULL,
|
||||||
|
dict_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系统配置表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_config (
|
||||||
|
id BIGINT AUTO_INCREMENT 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登录日志表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_login_log (
|
||||||
|
id BIGINT AUTO_INCREMENT 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异常日志表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_exception_log (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
username VARCHAR(50),
|
||||||
|
title VARCHAR(100),
|
||||||
|
exception_name VARCHAR(100),
|
||||||
|
method_name VARCHAR(255),
|
||||||
|
method_params TEXT,
|
||||||
|
exception_msg TEXT,
|
||||||
|
exception_stack TEXT,
|
||||||
|
ip VARCHAR(50),
|
||||||
|
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create操作日志表
|
||||||
|
CREATE TABLE IF NOT EXISTS operation_log (
|
||||||
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
username VARCHAR(50),
|
||||||
|
operation VARCHAR(100),
|
||||||
|
method VARCHAR(200),
|
||||||
|
params TEXT,
|
||||||
|
result TEXT,
|
||||||
|
ip VARCHAR(50),
|
||||||
|
duration BIGINT,
|
||||||
|
status VARCHAR(1) DEFAULT '0',
|
||||||
|
error_msg TEXT,
|
||||||
|
create_by VARCHAR(50),
|
||||||
|
update_by VARCHAR(50),
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create系统公告表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_notice (
|
||||||
|
id BIGINT AUTO_INCREMENT 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用户消息表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_user_message (
|
||||||
|
id BIGINT AUTO_INCREMENT 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文件管理表
|
||||||
|
CREATE TABLE IF NOT EXISTS sys_file (
|
||||||
|
id BIGINT AUTO_INCREMENT 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),
|
||||||
|
storage_type VARCHAR(50),
|
||||||
|
create_by VARCHAR(50),
|
||||||
|
update_by VARCHAR(50),
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
deleted_at TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create索引
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_role_user_id ON user_role(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_role_role_id ON user_role(role_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sys_menu_parent_id ON sys_menu(parent_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sys_dict_type ON sys_dict_data(dict_type);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sys_login_log_username ON sys_login_log(username);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_operation_log_username ON operation_log(username);
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
package cn.novalon.manage.app.integration;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库初始化验证测试
|
||||||
|
*
|
||||||
|
* @author 张翔
|
||||||
|
* @date 2026-04-03
|
||||||
|
*/
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
class DatabaseInitTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private R2dbcEntityTemplate r2dbcEntityTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSysUserTableExists() {
|
||||||
|
r2dbcEntityTemplate.getDatabaseClient()
|
||||||
|
.sql("SELECT COUNT(*) FROM sys_user")
|
||||||
|
.fetch()
|
||||||
|
.one()
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.expectNextCount(1)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOperationLogTableExists() {
|
||||||
|
r2dbcEntityTemplate.getDatabaseClient()
|
||||||
|
.sql("SELECT COUNT(*) FROM operation_log")
|
||||||
|
.fetch()
|
||||||
|
.one()
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.expectNextCount(1)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAllTablesCreated() {
|
||||||
|
r2dbcEntityTemplate.getDatabaseClient()
|
||||||
|
.sql("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC'")
|
||||||
|
.fetch()
|
||||||
|
.all()
|
||||||
|
.map(row -> row.get("TABLE_NAME"))
|
||||||
|
.collectList()
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.assertNext(tables -> {
|
||||||
|
System.out.println("Created tables: " + tables);
|
||||||
|
assert tables.contains("SYS_USER") : "SYS_USER table not found";
|
||||||
|
assert tables.contains("OPERATION_LOG") : "OPERATION_LOG table not found";
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
package cn.novalon.manage.app.integration;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动创建表测试
|
||||||
|
*
|
||||||
|
* @author 张翔
|
||||||
|
* @date 2026-04-03
|
||||||
|
*/
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
class ManualTableCreationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private R2dbcEntityTemplate r2dbcEntityTemplate;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
r2dbcEntityTemplate.getDatabaseClient()
|
||||||
|
.sql("CREATE TABLE IF NOT EXISTS operation_log (" +
|
||||||
|
"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
||||||
|
"username VARCHAR(50), " +
|
||||||
|
"operation VARCHAR(100), " +
|
||||||
|
"method VARCHAR(200), " +
|
||||||
|
"params TEXT, " +
|
||||||
|
"result TEXT, " +
|
||||||
|
"ip VARCHAR(50), " +
|
||||||
|
"duration BIGINT, " +
|
||||||
|
"status VARCHAR(1) DEFAULT '0', " +
|
||||||
|
"error_msg TEXT, " +
|
||||||
|
"create_by VARCHAR(50), " +
|
||||||
|
"update_by VARCHAR(50), " +
|
||||||
|
"created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " +
|
||||||
|
"updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " +
|
||||||
|
"deleted_at TIMESTAMP)")
|
||||||
|
.then()
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOperationLogTableExists() {
|
||||||
|
r2dbcEntityTemplate.getDatabaseClient()
|
||||||
|
.sql("SELECT COUNT(*) FROM operation_log")
|
||||||
|
.fetch()
|
||||||
|
.one()
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.expectNextCount(1)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
+156
@@ -0,0 +1,156 @@
|
|||||||
|
package cn.novalon.manage.app.integration;
|
||||||
|
|
||||||
|
import cn.novalon.manage.sys.core.domain.OperationLog;
|
||||||
|
import cn.novalon.manage.sys.core.service.IOperationLogService;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作日志集成测试
|
||||||
|
*
|
||||||
|
* @author 张翔
|
||||||
|
* @date 2026-04-03
|
||||||
|
*/
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@ActiveProfiles("test")
|
||||||
|
class OperationLogIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WebTestClient webTestClient;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IOperationLogService logService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private R2dbcEntityTemplate r2dbcEntityTemplate;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
webTestClient = webTestClient.mutate()
|
||||||
|
.responseTimeout(Duration.ofSeconds(10))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
r2dbcEntityTemplate.getDatabaseClient()
|
||||||
|
.sql("CREATE TABLE IF NOT EXISTS operation_log (" +
|
||||||
|
"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
|
||||||
|
"username VARCHAR(50), " +
|
||||||
|
"operation VARCHAR(100), " +
|
||||||
|
"method VARCHAR(200), " +
|
||||||
|
"params TEXT, " +
|
||||||
|
"result TEXT, " +
|
||||||
|
"ip VARCHAR(50), " +
|
||||||
|
"duration BIGINT, " +
|
||||||
|
"status VARCHAR(1) DEFAULT '0', " +
|
||||||
|
"error_msg TEXT, " +
|
||||||
|
"create_by VARCHAR(50), " +
|
||||||
|
"update_by VARCHAR(50), " +
|
||||||
|
"created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " +
|
||||||
|
"updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, " +
|
||||||
|
"deleted_at TIMESTAMP)")
|
||||||
|
.then()
|
||||||
|
.as(StepVerifier::create)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "test_user", roles = {"admin"})
|
||||||
|
void testCreateUserOperation_ShouldLogOperation() {
|
||||||
|
String userJson = """
|
||||||
|
{
|
||||||
|
"username": "test_integration_user",
|
||||||
|
"password": "Test123!@#",
|
||||||
|
"email": "test@example.com",
|
||||||
|
"phone": "13900139000",
|
||||||
|
"nickname": "集成测试用户"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
webTestClient.post()
|
||||||
|
.uri("/api/users")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.bodyValue(userJson)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isCreated()
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.id").exists()
|
||||||
|
.jsonPath("$.username").isEqualTo("test_integration_user");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "test_user", roles = {"admin"})
|
||||||
|
void testDeleteUserOperation_ShouldLogOperation() {
|
||||||
|
String userJson = """
|
||||||
|
{
|
||||||
|
"username": "test_delete_user",
|
||||||
|
"password": "Test123!@#",
|
||||||
|
"email": "delete@example.com",
|
||||||
|
"phone": "13900139001",
|
||||||
|
"nickname": "待删除用户"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
webTestClient.post()
|
||||||
|
.uri("/api/users")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.bodyValue(userJson)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isCreated()
|
||||||
|
.expectBody()
|
||||||
|
.jsonPath("$.id").value(id -> {
|
||||||
|
Long userId = Long.valueOf(id.toString());
|
||||||
|
|
||||||
|
webTestClient.delete()
|
||||||
|
.uri("/api/users/{id}", userId)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isNoContent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "test_user", roles = {"admin"})
|
||||||
|
void testFailedOperation_ShouldLogError() {
|
||||||
|
String userJson = """
|
||||||
|
{
|
||||||
|
"username": "admin",
|
||||||
|
"password": "Test123!@#",
|
||||||
|
"email": "duplicate@example.com",
|
||||||
|
"phone": "13900139002",
|
||||||
|
"nickname": "重复用户"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
webTestClient.post()
|
||||||
|
.uri("/api/users")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.bodyValue(userJson)
|
||||||
|
.exchange()
|
||||||
|
.expectStatus().isCreated();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testFindAllOperationLogs_ShouldReturnLogs() {
|
||||||
|
StepVerifier.create(logService.findAll().take(5))
|
||||||
|
.expectNextCount(0)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCountOperationLogs_ShouldReturnCount() {
|
||||||
|
StepVerifier.create(logService.count())
|
||||||
|
.expectNextCount(1)
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,6 +47,11 @@
|
|||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.projectreactor</groupId>
|
<groupId>io.projectreactor</groupId>
|
||||||
<artifactId>reactor-test</artifactId>
|
<artifactId>reactor-test</artifactId>
|
||||||
|
|||||||
Reference in New Issue
Block a user