refactor(test): 重构测试套件结构并优化测试配置

feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置
fix(api): 修复数据库实体和仓库的删除操作返回值
style(api): 统一数据库表名和字段命名
perf(api): 添加缓存注解提升配置查询性能
test(api): 添加H2测试数据库配置支持
chore: 清理旧的测试文件和脚本
This commit is contained in:
张翔
2026-04-01 20:57:24 +08:00
parent 24422c2c19
commit 1e3dc11d59
180 changed files with 15421 additions and 3797 deletions
+10
View File
@@ -57,6 +57,16 @@
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
@@ -42,8 +42,11 @@ public class SysConfigConverter {
entity.setConfigKey(domain.getConfigKey());
entity.setConfigValue(domain.getConfigValue());
entity.setConfigType(domain.getConfigType());
entity.setCreateBy(domain.getCreateBy());
entity.setUpdateBy(domain.getUpdateBy());
entity.setCreatedAt(domain.getCreatedAt());
entity.setUpdatedAt(domain.getUpdatedAt());
entity.setDeletedAt(domain.getDeletedAt());
return entity;
}
@@ -1,6 +1,7 @@
package cn.novalon.manage.db.dao;
import cn.novalon.manage.db.entity.SysRolePermissionEntity;
import org.springframework.data.r2dbc.repository.Modifying;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
@@ -17,23 +18,27 @@ public interface SysRolePermissionDao extends R2dbcRepository<SysRolePermissionE
Flux<Long> findRoleIdsByPermissionId(Long permissionId);
@Modifying
@org.springframework.data.r2dbc.repository.Query("""
DELETE FROM sys_role_permission
WHERE role_id = :roleId AND permission_id IN (:permissionIds)
""")
Mono<Void> deleteByRoleIdAndPermissionIds(Long roleId, java.util.List<Long> permissionIds);
@Modifying
@org.springframework.data.r2dbc.repository.Query("""
DELETE FROM sys_role_permission
WHERE permission_id = :permissionId AND role_id IN (:roleIds)
""")
Mono<Void> deleteByPermissionIdAndRoleIds(Long permissionId, java.util.List<Long> roleIds);
@Modifying
@org.springframework.data.r2dbc.repository.Query("""
DELETE FROM sys_role_permission WHERE role_id = :roleId
""")
Mono<Void> deleteByRoleId(Long roleId);
@Modifying
@org.springframework.data.r2dbc.repository.Query("""
DELETE FROM sys_role_permission WHERE permission_id = :permissionId
""")
@@ -2,6 +2,8 @@ package cn.novalon.manage.db.dao;
import cn.novalon.manage.db.entity.UserRoleEntity;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.repository.Modifying;
import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -20,7 +22,11 @@ public interface UserRoleDao extends R2dbcRepository<UserRoleEntity, Long> {
Mono<Long> countByRoleId(Long roleId);
Mono<Void> deleteByUserId(Long userId);
@Modifying
@Query("DELETE FROM user_role WHERE user_id = :userId")
Mono<Integer> deleteByUserId(Long userId);
Mono<Void> deleteByRoleId(Long roleId);
@Modifying
@Query("DELETE FROM user_role WHERE role_id = :roleId")
Mono<Integer> deleteByRoleId(Long roleId);
}
@@ -1,8 +1,6 @@
package cn.novalon.manage.db.entity;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.relational.core.mapping.Column;
import java.time.LocalDateTime;
@@ -24,11 +22,9 @@ public abstract class BaseEntity {
@Column("update_by")
private String updateBy;
@CreatedDate
@Column("created_at")
private LocalDateTime createdAt;
@LastModifiedDate
@Column("updated_at")
private LocalDateTime updatedAt;
@@ -9,7 +9,7 @@ import org.springframework.data.relational.core.mapping.Table;
* @author 张翔
* @date 2026-03-13
*/
@Table("menus")
@Table("sys_menu")
public class SysMenuEntity extends BaseEntity {
@Column("menu_name")
@@ -11,16 +11,16 @@ import cn.novalon.manage.db.dao.QueryField;
*/
public class SysMenuQueryCriteria {
@QueryField(propName = "menuName", type = QueryField.Type.INNER_LIKE)
@QueryField(type = QueryField.Type.INNER_LIKE)
private String menuName;
@QueryField(propName = "menuType", type = QueryField.Type.EQUAL)
@QueryField(type = QueryField.Type.EQUAL)
private String menuType;
@QueryField(propName = "status", type = QueryField.Type.EQUAL)
@QueryField(type = QueryField.Type.EQUAL)
private Integer status;
@QueryField(propName = "parentId", type = QueryField.Type.EQUAL)
@QueryField(type = QueryField.Type.EQUAL)
private Long parentId;
@QueryField(blurry = "menuName,perms,component", type = QueryField.Type.INNER_LIKE)
@@ -35,12 +35,12 @@ public class UserRoleRepository implements IUserRoleRepository {
@Override
public Mono<Void> deleteByUserId(Long userId) {
return userRoleDao.deleteByUserId(userId);
return userRoleDao.deleteByUserId(userId).then();
}
@Override
public Mono<Void> deleteByRoleId(Long roleId) {
return userRoleDao.deleteByRoleId(roleId);
return userRoleDao.deleteByRoleId(roleId).then();
}
@Override
@@ -0,0 +1,41 @@
-- Novalon管理系统审计日志表
-- 版本: V7
-- 描述: 创建审计日志表,记录数据变更前后的完整对比
CREATE TABLE IF NOT EXISTS audit_log (
id BIGSERIAL PRIMARY KEY,
entity_type VARCHAR(100) NOT NULL,
entity_id BIGINT,
operation_type VARCHAR(20) NOT NULL,
operator VARCHAR(100),
operation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
before_data JSONB,
after_data JSONB,
changed_fields TEXT[],
ip_address VARCHAR(50),
user_agent TEXT,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_audit_log_entity_type ON audit_log(entity_type);
CREATE INDEX idx_audit_log_entity_id ON audit_log(entity_id);
CREATE INDEX idx_audit_log_operation_type ON audit_log(operation_type);
CREATE INDEX idx_audit_log_operator ON audit_log(operator);
CREATE INDEX idx_audit_log_operation_time ON audit_log(operation_time);
CREATE INDEX idx_audit_log_entity ON audit_log(entity_type, entity_id);
COMMENT ON TABLE audit_log IS '审计日志表';
COMMENT ON COLUMN audit_log.id IS '主键ID';
COMMENT ON COLUMN audit_log.entity_type IS '实体类型(如User, Role等)';
COMMENT ON COLUMN audit_log.entity_id IS '实体ID';
COMMENT ON COLUMN audit_log.operation_type IS '操作类型(CREATE, UPDATE, DELETE';
COMMENT ON COLUMN audit_log.operator IS '操作人';
COMMENT ON COLUMN audit_log.operation_time IS '操作时间';
COMMENT ON COLUMN audit_log.before_data IS '变更前数据(JSON格式)';
COMMENT ON COLUMN audit_log.after_data IS '变更后数据(JSON格式)';
COMMENT ON COLUMN audit_log.changed_fields IS '变更字段列表';
COMMENT ON COLUMN audit_log.ip_address IS 'IP地址';
COMMENT ON COLUMN audit_log.user_agent IS '用户代理';
COMMENT ON COLUMN audit_log.description IS '操作描述';
COMMENT ON COLUMN audit_log.created_at IS '记录创建时间';
@@ -0,0 +1,43 @@
-- Novalon管理系统审计日志归档表
-- 版本: V8
-- 描述: 创建审计日志归档表,用于存储历史审计日志
CREATE TABLE IF NOT EXISTS audit_log_archive (
id BIGSERIAL PRIMARY KEY,
entity_type VARCHAR(100) NOT NULL,
entity_id BIGINT,
operation_type VARCHAR(20) NOT NULL,
operator VARCHAR(100),
operation_time TIMESTAMP,
before_data JSONB,
after_data JSONB,
changed_fields TEXT[],
ip_address VARCHAR(50),
user_agent TEXT,
description TEXT,
created_at TIMESTAMP,
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_audit_log_archive_entity_type ON audit_log_archive(entity_type);
CREATE INDEX idx_audit_log_archive_entity_id ON audit_log_archive(entity_id);
CREATE INDEX idx_audit_log_archive_operation_type ON audit_log_archive(operation_type);
CREATE INDEX idx_audit_log_archive_operator ON audit_log_archive(operator);
CREATE INDEX idx_audit_log_archive_operation_time ON audit_log_archive(operation_time);
CREATE INDEX idx_audit_log_archive_archived_at ON audit_log_archive(archived_at);
COMMENT ON TABLE audit_log_archive IS '审计日志归档表';
COMMENT ON COLUMN audit_log_archive.id IS '主键ID';
COMMENT ON COLUMN audit_log_archive.entity_type IS '实体类型(如User, Role等)';
COMMENT ON COLUMN audit_log_archive.entity_id IS '实体ID';
COMMENT ON COLUMN audit_log_archive.operation_type IS '操作类型(CREATE, UPDATE, DELETE';
COMMENT ON COLUMN audit_log_archive.operator IS '操作人';
COMMENT ON COLUMN audit_log_archive.operation_time IS '操作时间';
COMMENT ON COLUMN audit_log_archive.before_data IS '变更前数据(JSON格式)';
COMMENT ON COLUMN audit_log_archive.after_data IS '变更后数据(JSON格式)';
COMMENT ON COLUMN audit_log_archive.changed_fields IS '变更字段列表';
COMMENT ON COLUMN audit_log_archive.ip_address IS 'IP地址';
COMMENT ON COLUMN audit_log_archive.user_agent IS '用户代理';
COMMENT ON COLUMN audit_log_archive.description IS '操作描述';
COMMENT ON COLUMN audit_log_archive.created_at IS '记录创建时间';
COMMENT ON COLUMN audit_log_archive.archived_at IS '归档时间';