refactor: migrate SysNotice to manage-notify module

This commit is contained in:
张翔
2026-03-14 10:24:06 +08:00
parent 4f4331f2d9
commit 4f1caaf758
155 changed files with 3272 additions and 865 deletions
+14
View File
@@ -17,6 +17,16 @@
<description>Database module for Novalon Manage API</description>
<dependencies>
<dependency>
<groupId>cn.novalon.manage</groupId>
<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-common</artifactId>
@@ -26,6 +36,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>r2dbc-postgresql</artifactId>
@@ -0,0 +1,9 @@
package cn.novalon.manage.db.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "cn.novalon.manage.db.repository")
public class RepositoryScanConfig {
}
@@ -1,12 +1,18 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.Dictionary;
import cn.novalon.manage.sys.core.domain.Dictionary;
import cn.novalon.manage.db.entity.DictionaryEntity;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 字典实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class DictionaryConverter {
@@ -1,12 +1,19 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.OperationLog;
import cn.novalon.manage.sys.core.domain.OperationLog;
import cn.novalon.manage.db.entity.OperationLogEntity;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 操作日志实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class OperationLogConverter {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysConfig;
import cn.novalon.manage.sys.core.domain.SysConfig;
import cn.novalon.manage.db.entity.SysConfigEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 系统配置实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysConfigConverter {
public SysConfig toDomain(SysConfigEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysDictData;
import cn.novalon.manage.sys.core.domain.SysDictData;
import cn.novalon.manage.db.entity.SysDictDataEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 字典数据实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysDictDataConverter {
public SysDictData toDomain(SysDictDataEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysDictType;
import cn.novalon.manage.sys.core.domain.SysDictType;
import cn.novalon.manage.db.entity.SysDictTypeEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 字典类型实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysDictTypeConverter {
public SysDictType toDomain(SysDictTypeEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.domain.SysExceptionLog;
import cn.novalon.manage.db.entity.SysExceptionLogEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 异常日志实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysExceptionLogConverter {
public SysExceptionLog toDomain(SysExceptionLogEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysFile;
import cn.novalon.manage.sys.core.domain.SysFile;
import cn.novalon.manage.db.entity.SysFileEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 文件实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysFileConverter {
public SysFile toDomain(SysFileEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysLoginLog;
import cn.novalon.manage.sys.core.domain.SysLoginLog;
import cn.novalon.manage.db.entity.SysLoginLogEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录日志实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysLoginLogConverter {
public SysLoginLog toDomain(SysLoginLogEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysMenu;
import cn.novalon.manage.sys.core.domain.SysMenu;
import cn.novalon.manage.db.entity.SysMenuEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 菜单实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysMenuConverter {
public SysMenu toDomain(SysMenuEntity entity) {
@@ -25,6 +30,8 @@ public class SysMenuConverter {
domain.setPerms(entity.getPerms());
domain.setComponent(entity.getComponent());
domain.setStatus(entity.getStatus());
domain.setCreateBy(entity.getCreateBy());
domain.setUpdateBy(entity.getUpdateBy());
domain.setCreatedAt(entity.getCreatedAt());
domain.setUpdatedAt(entity.getUpdatedAt());
domain.setDeletedAt(entity.getDeletedAt());
@@ -44,6 +51,8 @@ public class SysMenuConverter {
entity.setPerms(domain.getPerms());
entity.setComponent(domain.getComponent());
entity.setStatus(domain.getStatus());
entity.setCreateBy(domain.getCreateBy());
entity.setUpdateBy(domain.getUpdateBy());
entity.setCreatedAt(domain.getCreatedAt());
entity.setUpdatedAt(domain.getUpdatedAt());
entity.setDeletedAt(domain.getDeletedAt());
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysNotice;
import cn.novalon.manage.notify.core.domain.SysNotice;
import cn.novalon.manage.db.entity.SysNoticeEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 通知公告实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysNoticeConverter {
public SysNotice toDomain(SysNoticeEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysRole;
import cn.novalon.manage.sys.core.domain.SysRole;
import cn.novalon.manage.db.entity.SysRoleEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 角色实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysRoleConverter {
public SysRole toDomain(SysRoleEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysUser;
import cn.novalon.manage.sys.core.domain.SysUser;
import cn.novalon.manage.db.entity.SysUserEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysUserConverter {
public SysUser toDomain(SysUserEntity entity) {
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.converter;
import cn.novalon.manage.common.domain.SysUserMessage;
import cn.novalon.manage.sys.core.domain.SysUserMessage;
import cn.novalon.manage.db.entity.SysUserMessageEntity;
import org.springframework.stereotype.Component;
@@ -8,8 +8,13 @@ import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户消息实体转换器
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SysUserMessageConverter {
public SysUserMessage toDomain(SysUserMessageEntity entity) {
@@ -6,6 +6,12 @@ import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典数据访问接口
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public interface DictionaryDao extends R2dbcRepository<DictionaryEntity, Long> {
@@ -6,11 +6,11 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author zhangxiang
* @version 1.0
* @description 查询字段注解
* @date 2026/03/11
**/
* 查询字段注解
*
* @author 张翔
* @date 2026-03-13
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryField {
@@ -15,11 +15,11 @@ import java.util.Collection;
import java.util.List;
/**
* @author zhangxiang
* @version 1.0
* @description 查询工具类
* @date 2026/03/11
**/
* 查询工具类
*
* @author 张翔
* @date 2026-03-13
*/
public class QueryUtil {
private static final Logger log = LoggerFactory.getLogger(QueryUtil.class);
@@ -7,6 +7,12 @@ import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 用户数据访问接口
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public interface SysUserDao extends R2dbcRepository<SysUserEntity, Long> {
@@ -23,4 +29,6 @@ public interface SysUserDao extends R2dbcRepository<SysUserEntity, Long> {
Flux<SysUserEntity> findByDeletedAtIsNull(Sort sort);
Mono<Long> countByDeletedAtIsNull();
Flux<SysUserEntity> findByRoleId(Long roleId);
}
@@ -7,6 +7,12 @@ import org.springframework.data.relational.core.mapping.Column;
import java.time.LocalDateTime;
/**
* 数据库实体基类
*
* @author 张翔
* @date 2026-03-13
*/
public abstract class BaseEntity {
@Id
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 字典数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_dictionary")
public class DictionaryEntity {
@Id
@@ -3,6 +3,12 @@ package cn.novalon.manage.db.entity;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
/**
* 操作日志数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("operation_log")
public class OperationLogEntity extends BaseEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 系统配置数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_config")
public class SysConfigEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 字典数据数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_dict_data")
public class SysDictDataEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 字典类型数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_dict_type")
public class SysDictTypeEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 异常日志数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_exception_log")
public class SysExceptionLogEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 文件管理数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_file")
public class SysFileEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 登录日志数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_login_log")
public class SysLoginLogEntity {
@@ -3,7 +3,13 @@ package cn.novalon.manage.db.entity;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Table("sys_menu")
/**
* 菜单数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("menus")
public class SysMenuEntity extends BaseEntity {
@Column("menu_name")
@@ -25,7 +31,7 @@ public class SysMenuEntity extends BaseEntity {
private String component;
@Column("status")
private String status;
private Integer status;
public String getMenuName() {
return menuName;
@@ -75,11 +81,11 @@ public class SysMenuEntity extends BaseEntity {
this.component = component;
}
public String getStatus() {
public Integer getStatus() {
return status;
}
public void setStatus(String status) {
public void setStatus(Integer status) {
this.status = status;
}
}
@@ -4,11 +4,11 @@ import cn.novalon.manage.common.domain.query.SysMenuQuery;
import cn.novalon.manage.db.dao.QueryField;
/**
* @author zhangxiang
* @version 1.0
* @description 菜单查询条件对象
* @date 2026/03/11
**/
* 菜单查询条件对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysMenuQueryCriteria {
@QueryField(propName = "menuName", type = QueryField.Type.INNER_LIKE)
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 通知公告数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_notice")
public class SysNoticeEntity {
@@ -3,6 +3,12 @@ package cn.novalon.manage.db.entity;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
/**
* 角色数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("roles")
public class SysRoleEntity extends BaseEntity {
@@ -1,14 +1,14 @@
package cn.novalon.manage.db.entity;
import cn.novalon.manage.common.domain.query.SysRoleQuery;
import cn.novalon.manage.sys.core.query.SysRoleQuery;
import cn.novalon.manage.db.dao.QueryField;
/**
* @author zhangxiang
* @version 1.0
* @description 角色查询条件对象
* @date 2026/03/11
**/
* 角色查询条件对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysRoleQueryCriteria {
@QueryField(propName = "roleName", type = QueryField.Type.INNER_LIKE)
@@ -3,6 +3,12 @@ package cn.novalon.manage.db.entity;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
/**
* 用户数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("users")
public class SysUserEntity extends BaseEntity {
@@ -6,6 +6,12 @@ import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDateTime;
/**
* 用户消息数据库实体类
*
* @author 张翔
* @date 2026-03-13
*/
@Table("sys_user_message")
public class SysUserMessageEntity {
@@ -1,14 +1,14 @@
package cn.novalon.manage.db.entity;
import cn.novalon.manage.common.domain.query.SysUserQuery;
import cn.novalon.manage.sys.core.query.SysUserQuery;
import cn.novalon.manage.db.dao.QueryField;
/**
* @author zhangxiang
* @version 1.0
* @description 用户查询条件对象
* @date 2026/03/11
**/
* 用户查询条件对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysUserQueryCriteria {
@QueryField(propName = "username", type = QueryField.Type.INNER_LIKE)
@@ -23,6 +23,9 @@ public class SysUserQueryCriteria {
@QueryField(propName = "status", type = QueryField.Type.EQUAL)
private Integer status;
@QueryField(blurry = "username,email", type = QueryField.Type.INNER_LIKE)
private String keyword;
public String getUsername() {
return username;
}
@@ -55,6 +58,14 @@ public class SysUserQueryCriteria {
this.status = status;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
/**
* 从领域查询对象转换
*
@@ -68,5 +79,6 @@ public class SysUserQueryCriteria {
this.email = query.getEmail();
this.roleId = query.getRoleId();
this.status = query.getStatus();
this.keyword = query.getKeyword();
}
}
@@ -1,22 +1,30 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.Dictionary;
import cn.novalon.manage.sys.core.domain.Dictionary;
import cn.novalon.manage.sys.core.repository.IDictionaryRepository;
import cn.novalon.manage.db.converter.DictionaryConverter;
import cn.novalon.manage.db.dao.DictionaryDao;
import cn.novalon.manage.db.entity.DictionaryEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class DictionaryRepository implements IDictionaryRepository {
@Autowired
private DictionaryDao dictionaryDao;
private final DictionaryDao dictionaryDao;
private final DictionaryConverter dictionaryConverter;
@Autowired
private DictionaryConverter dictionaryConverter;
public DictionaryRepository(DictionaryDao dictionaryDao, DictionaryConverter dictionaryConverter) {
this.dictionaryDao = dictionaryDao;
this.dictionaryConverter = dictionaryConverter;
}
@Override
public Flux<Dictionary> findAll() {
@@ -1,24 +1,32 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.OperationLog;
import cn.novalon.manage.sys.core.domain.OperationLog;
import cn.novalon.manage.sys.core.repository.IOperationLogRepository;
import cn.novalon.manage.db.converter.OperationLogConverter;
import cn.novalon.manage.db.entity.OperationLogEntity;
import cn.novalon.manage.db.dao.OperationLogDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* 操作日志仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class OperationLogRepository implements IOperationLogRepository {
@Autowired
private OperationLogDao operationLogDao;
private final OperationLogDao operationLogDao;
private final OperationLogConverter operationLogConverter;
@Autowired
private OperationLogConverter operationLogConverter;
public OperationLogRepository(OperationLogDao operationLogDao, OperationLogConverter operationLogConverter) {
this.operationLogDao = operationLogDao;
this.operationLogConverter = operationLogConverter;
}
@Override
public Mono<OperationLog> findById(Long id) {
@@ -3,21 +3,29 @@ package cn.novalon.manage.db.repository;
import cn.novalon.manage.db.converter.SysConfigConverter;
import cn.novalon.manage.db.dao.SysConfigDao;
import cn.novalon.manage.db.entity.SysConfigEntity;
import cn.novalon.manage.common.domain.SysConfig;
import org.springframework.beans.factory.annotation.Autowired;
import cn.novalon.manage.sys.core.domain.SysConfig;
import cn.novalon.manage.sys.core.repository.ISysConfigRepository;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 系统配置仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysConfigRepository implements ISysConfigRepository {
@Autowired
private SysConfigDao sysConfigDao;
private final SysConfigDao sysConfigDao;
private final SysConfigConverter sysConfigConverter;
@Autowired
private SysConfigConverter sysConfigConverter;
public SysConfigRepository(SysConfigDao sysConfigDao, SysConfigConverter sysConfigConverter) {
this.sysConfigDao = sysConfigDao;
this.sysConfigConverter = sysConfigConverter;
}
@Override
public Mono<SysConfig> findById(Long id) {
@@ -1,22 +1,30 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysDictData;
import cn.novalon.manage.sys.core.domain.SysDictData;
import cn.novalon.manage.sys.core.repository.ISysDictDataRepository;
import cn.novalon.manage.db.converter.SysDictDataConverter;
import cn.novalon.manage.db.dao.SysDictDataDao;
import cn.novalon.manage.db.entity.SysDictDataEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典数据仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysDictDataRepository implements ISysDictDataRepository {
@Autowired
private SysDictDataDao sysDictDataDao;
private final SysDictDataDao sysDictDataDao;
private final SysDictDataConverter sysDictDataConverter;
@Autowired
private SysDictDataConverter sysDictDataConverter;
public SysDictDataRepository(SysDictDataDao sysDictDataDao, SysDictDataConverter sysDictDataConverter) {
this.sysDictDataDao = sysDictDataDao;
this.sysDictDataConverter = sysDictDataConverter;
}
@Override
public Flux<SysDictData> findByDeletedAtIsNull() {
@@ -1,22 +1,30 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysDictType;
import cn.novalon.manage.sys.core.domain.SysDictType;
import cn.novalon.manage.sys.core.repository.ISysDictTypeRepository;
import cn.novalon.manage.db.converter.SysDictTypeConverter;
import cn.novalon.manage.db.dao.SysDictTypeDao;
import cn.novalon.manage.db.entity.SysDictTypeEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典类型仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysDictTypeRepository implements ISysDictTypeRepository {
@Autowired
private SysDictTypeDao sysDictTypeDao;
private final SysDictTypeDao sysDictTypeDao;
private final SysDictTypeConverter sysDictTypeConverter;
@Autowired
private SysDictTypeConverter sysDictTypeConverter;
public SysDictTypeRepository(SysDictTypeDao sysDictTypeDao, SysDictTypeConverter sysDictTypeConverter) {
this.sysDictTypeDao = sysDictTypeDao;
this.sysDictTypeConverter = sysDictTypeConverter;
}
@Override
public Flux<SysDictType> findByDeletedAtIsNull() {
@@ -1,24 +1,32 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.repository.ISysExceptionLogRepository;
import cn.novalon.manage.db.converter.SysExceptionLogConverter;
import cn.novalon.manage.db.dao.SysExceptionLogDao;
import cn.novalon.manage.db.entity.SysExceptionLogEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* 异常日志仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysExceptionLogRepository implements ISysExceptionLogRepository {
@Autowired
private SysExceptionLogDao sysExceptionLogDao;
private final SysExceptionLogDao sysExceptionLogDao;
private final SysExceptionLogConverter sysExceptionLogConverter;
@Autowired
private SysExceptionLogConverter sysExceptionLogConverter;
public SysExceptionLogRepository(SysExceptionLogDao sysExceptionLogDao, SysExceptionLogConverter sysExceptionLogConverter) {
this.sysExceptionLogDao = sysExceptionLogDao;
this.sysExceptionLogConverter = sysExceptionLogConverter;
}
@Override
public Flux<SysExceptionLog> findAllByOrderByCreateTimeDesc() {
@@ -1,22 +1,30 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysFile;
import cn.novalon.manage.sys.core.domain.SysFile;
import cn.novalon.manage.sys.core.repository.ISysFileRepository;
import cn.novalon.manage.db.converter.SysFileConverter;
import cn.novalon.manage.db.dao.SysFileDao;
import cn.novalon.manage.db.entity.SysFileEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 文件管理仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysFileRepository implements ISysFileRepository {
@Autowired
private SysFileDao sysFileDao;
private final SysFileDao sysFileDao;
private final SysFileConverter sysFileConverter;
@Autowired
private SysFileConverter sysFileConverter;
public SysFileRepository(SysFileDao sysFileDao, SysFileConverter sysFileConverter) {
this.sysFileDao = sysFileDao;
this.sysFileConverter = sysFileConverter;
}
@Override
public Flux<SysFile> findByDeletedAtIsNullOrderByCreatedAtDesc() {
@@ -1,24 +1,32 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysLoginLog;
import cn.novalon.manage.sys.core.domain.SysLoginLog;
import cn.novalon.manage.sys.core.repository.ISysLoginLogRepository;
import cn.novalon.manage.db.converter.SysLoginLogConverter;
import cn.novalon.manage.db.dao.SysLoginLogDao;
import cn.novalon.manage.db.entity.SysLoginLogEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* 登录日志仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysLoginLogRepository implements ISysLoginLogRepository {
@Autowired
private SysLoginLogDao sysLoginLogDao;
private final SysLoginLogDao sysLoginLogDao;
private final SysLoginLogConverter sysLoginLogConverter;
@Autowired
private SysLoginLogConverter sysLoginLogConverter;
public SysLoginLogRepository(SysLoginLogDao sysLoginLogDao, SysLoginLogConverter sysLoginLogConverter) {
this.sysLoginLogDao = sysLoginLogDao;
this.sysLoginLogConverter = sysLoginLogConverter;
}
@Override
public Flux<SysLoginLog> findAllByOrderByLoginTimeDesc() {
@@ -1,12 +1,13 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysMenu;
import cn.novalon.manage.sys.core.domain.SysMenu;
import cn.novalon.manage.sys.core.repository.ISysMenuRepository;
import cn.novalon.manage.sys.core.query.SysMenuQuery;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import cn.novalon.manage.db.converter.SysMenuConverter;
import cn.novalon.manage.db.dao.SysMenuDao;
import cn.novalon.manage.db.entity.SysMenuEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.relational.core.query.Query;
import org.springframework.stereotype.Repository;
@@ -15,14 +16,22 @@ import reactor.core.publisher.Mono;
import java.util.List;
/**
* 菜单仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysMenuRepository implements ISysMenuRepository {
@Autowired
private SysMenuDao sysMenuDao;
private final SysMenuDao sysMenuDao;
private final SysMenuConverter sysMenuConverter;
@Autowired
private SysMenuConverter sysMenuConverter;
public SysMenuRepository(SysMenuDao sysMenuDao, SysMenuConverter sysMenuConverter) {
this.sysMenuDao = sysMenuDao;
this.sysMenuConverter = sysMenuConverter;
}
@Override
public Flux<SysMenu> findByParentId(Long parentId) {
@@ -72,8 +81,27 @@ public class SysMenuRepository implements ISysMenuRepository {
}
@Override
public Mono<PageResponse<SysMenu>> findByQueryWithPagination(Query query, PageRequest pageRequest) {
return Mono.just(new PageResponse<>());
public Mono<PageResponse<SysMenu>> findByQueryWithPagination(SysMenuQuery query, PageRequest pageRequest) {
int page = pageRequest.getPage();
int size = pageRequest.getSize();
return sysMenuDao.count()
.flatMap(count -> {
int totalPages = (int) Math.ceil((double) count / size);
int offset = page * size;
Flux<SysMenuEntity> menuFlux = sysMenuDao.findByDeletedAtIsNull()
.skip(offset)
.take(size);
return menuFlux.collectList()
.map(menus -> {
List<SysMenu> menuList = menus.stream()
.map(sysMenuConverter::toDomain)
.toList();
return new PageResponse<>(menuList, totalPages, count, page, size);
});
});
}
@Override
@@ -1,22 +1,30 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysNotice;
import cn.novalon.manage.notify.core.domain.SysNotice;
import cn.novalon.manage.notify.core.repository.ISysNoticeRepository;
import cn.novalon.manage.db.converter.SysNoticeConverter;
import cn.novalon.manage.db.dao.SysNoticeDao;
import cn.novalon.manage.db.entity.SysNoticeEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 通知公告仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysNoticeRepository implements ISysNoticeRepository {
@Autowired
private SysNoticeDao sysNoticeDao;
private final SysNoticeDao sysNoticeDao;
private final SysNoticeConverter sysNoticeConverter;
@Autowired
private SysNoticeConverter sysNoticeConverter;
public SysNoticeRepository(SysNoticeDao sysNoticeDao, SysNoticeConverter sysNoticeConverter) {
this.sysNoticeDao = sysNoticeDao;
this.sysNoticeConverter = sysNoticeConverter;
}
@Override
public Flux<SysNotice> findByDeletedAtIsNull() {
@@ -1,26 +1,42 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysRole;
import cn.novalon.manage.sys.core.domain.SysRole;
import cn.novalon.manage.sys.core.repository.ISysRoleRepository;
import cn.novalon.manage.sys.core.query.SysRoleQuery;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import cn.novalon.manage.db.converter.SysRoleConverter;
import cn.novalon.manage.db.dao.SysRoleDao;
import cn.novalon.manage.common.dao.QueryUtil;
import cn.novalon.manage.db.entity.SysRoleEntity;
import org.springframework.beans.factory.annotation.Autowired;
import cn.novalon.manage.db.entity.SysRoleQueryCriteria;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Query;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* 角色仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysRoleRepository implements ISysRoleRepository {
@Autowired
private SysRoleDao sysRoleDao;
private final SysRoleDao sysRoleDao;
private final SysRoleConverter sysRoleConverter;
private final R2dbcEntityTemplate r2dbcEntityTemplate;
@Autowired
private SysRoleConverter sysRoleConverter;
public SysRoleRepository(SysRoleDao sysRoleDao, SysRoleConverter sysRoleConverter, R2dbcEntityTemplate r2dbcEntityTemplate) {
this.sysRoleDao = sysRoleDao;
this.sysRoleConverter = sysRoleConverter;
this.r2dbcEntityTemplate = r2dbcEntityTemplate;
}
@Override
public Mono<SysRole> findById(Long id) {
@@ -75,8 +91,37 @@ public class SysRoleRepository implements ISysRoleRepository {
}
@Override
public Mono<PageResponse<SysRole>> findByQueryWithPagination(Query query, PageRequest pageRequest) {
return Mono.just(new PageResponse<>());
public Mono<PageResponse<SysRole>> findByQueryWithPagination(SysRoleQuery query, PageRequest pageRequest) {
int page = pageRequest.getPage();
int size = pageRequest.getSize();
String sort = pageRequest.getSort();
String order = pageRequest.getOrder();
Sort sortObj = Sort.unsorted();
if (sort != null && !sort.isEmpty()) {
sortObj = Sort.by(Sort.Direction.fromString(order), sort);
}
org.springframework.data.domain.PageRequest pageable = org.springframework.data.domain.PageRequest.of(page,
size, sortObj);
SysRoleQueryCriteria criteria = new SysRoleQueryCriteria();
criteria.convert(query);
Query dbQuery = QueryUtil.getQuery(criteria);
return r2dbcEntityTemplate.select(SysRoleEntity.class)
.matching(dbQuery.with(pageable))
.all()
.collectList()
.zipWith(r2dbcEntityTemplate.count(dbQuery, SysRoleEntity.class))
.map(tuple -> {
long total = tuple.getT2();
int totalPages = (int) Math.ceil((double) total / size);
List<SysRole> roleList = tuple.getT1().stream()
.map(sysRoleConverter::toDomain)
.toList();
return new PageResponse<>(roleList, totalPages, total, page, size);
});
}
@Override
@@ -1,22 +1,30 @@
package cn.novalon.manage.db.repository;
import cn.novalon.manage.common.domain.SysUserMessage;
import cn.novalon.manage.sys.core.domain.SysUserMessage;
import cn.novalon.manage.sys.core.repository.ISysUserMessageRepository;
import cn.novalon.manage.db.converter.SysUserMessageConverter;
import cn.novalon.manage.db.entity.SysUserMessageEntity;
import cn.novalon.manage.db.dao.SysUserMessageDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 用户消息仓储实现类
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysUserMessageRepository implements ISysUserMessageRepository {
@Autowired
private SysUserMessageDao sysUserMessageDao;
private final SysUserMessageDao sysUserMessageDao;
private final SysUserMessageConverter sysUserMessageConverter;
@Autowired
private SysUserMessageConverter sysUserMessageConverter;
public SysUserMessageRepository(SysUserMessageDao sysUserMessageDao, SysUserMessageConverter sysUserMessageConverter) {
this.sysUserMessageDao = sysUserMessageDao;
this.sysUserMessageConverter = sysUserMessageConverter;
}
@Override
public Flux<SysUserMessage> findByUserIdOrderByCreateTimeDesc(Long userId) {
@@ -3,11 +3,15 @@ package cn.novalon.manage.db.repository;
import cn.novalon.manage.db.converter.SysUserConverter;
import cn.novalon.manage.db.dao.SysUserDao;
import cn.novalon.manage.db.entity.SysUserEntity;
import cn.novalon.manage.common.domain.SysUser;
import cn.novalon.manage.db.entity.SysUserQueryCriteria;
import cn.novalon.manage.common.dao.QueryUtil;
import cn.novalon.manage.sys.core.domain.SysUser;
import cn.novalon.manage.sys.core.query.SysUserQuery;
import cn.novalon.manage.sys.core.repository.ISysUserRepository;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Query;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
@@ -15,14 +19,29 @@ import reactor.core.publisher.Mono;
import java.util.List;
/**
* 用户仓储实现类
*
* 文件定义:用户数据访问层的仓储实现,负责用户数据的持久化操作
* 涉及业务:用户增删改查、分页查询、条件查询、逻辑删除等数据访问业务
* 算法:使用R2DBC进行响应式数据库操作,支持分页算法、条件查询算法
*
* @author 张翔
* @date 2026-03-13
*/
@Repository
public class SysUserRepository implements ISysUserRepository {
@Autowired
private SysUserDao sysUserDao;
private final SysUserDao sysUserDao;
private final SysUserConverter sysUserConverter;
private final R2dbcEntityTemplate r2dbcEntityTemplate;
@Autowired
private SysUserConverter sysUserConverter;
public SysUserRepository(SysUserDao sysUserDao, SysUserConverter sysUserConverter,
R2dbcEntityTemplate r2dbcEntityTemplate) {
this.sysUserDao = sysUserDao;
this.sysUserConverter = sysUserConverter;
this.r2dbcEntityTemplate = r2dbcEntityTemplate;
}
@Override
public Mono<SysUser> findByUsername(String username) {
@@ -90,8 +109,42 @@ public class SysUserRepository implements ISysUserRepository {
}
@Override
public Mono<PageResponse<SysUser>> findByQueryWithPagination(Query query, PageRequest pageRequest) {
return Mono.just(new PageResponse<>());
public Mono<PageResponse<SysUser>> findByQueryWithPagination(SysUserQuery query, PageRequest pageRequest) {
int page = pageRequest.getPage();
int size = pageRequest.getSize();
String sort = pageRequest.getSort();
String order = pageRequest.getOrder();
String keyword = pageRequest.getKeyword();
SysUserQuery sysUserQuery = new SysUserQuery();
sysUserQuery.setKeyword(keyword);
SysUserQueryCriteria criteria = new SysUserQueryCriteria();
criteria.convert(sysUserQuery);
Query queryObj = QueryUtil.getQuery(criteria);
Sort sortObj = Sort.unsorted();
if (sort != null && !sort.isEmpty()) {
sortObj = Sort.by(Sort.Direction.fromString(order), sort);
}
org.springframework.data.domain.PageRequest pageable = org.springframework.data.domain.PageRequest.of(page,
size, sortObj);
return r2dbcEntityTemplate.select(SysUserEntity.class)
.matching(queryObj.with(pageable))
.all()
.collectList()
.zipWith(r2dbcEntityTemplate.count(queryObj, SysUserEntity.class))
.map(tuple -> {
long total = tuple.getT2();
int totalPages = (int) Math.ceil((double) total / size);
List<SysUser> userList = tuple.getT1().stream()
.map(sysUserConverter::toDomain)
.toList();
return new PageResponse<>(userList, totalPages, total, page, size);
});
}
@Override
@@ -139,4 +192,14 @@ public class SysUserRepository implements ISysUserRepository {
.flatMap(id -> restoreById(id))
.then();
}
@Override
public Mono<Void> updateRoleIdToNullByRoleId(Long roleId) {
return sysUserDao.findByRoleId(roleId)
.flatMap(entity -> {
entity.setRoleId(null);
return sysUserDao.save(entity);
})
.then();
}
}
@@ -0,0 +1,97 @@
package cn.novalon.manage.notify.core.domain;
import java.time.LocalDateTime;
public class SysNotice {
private Long id;
private String noticeTitle;
private String noticeType;
private String noticeContent;
private String status;
private String createBy;
private String updateBy;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime deletedAt;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNoticeTitle() {
return noticeTitle;
}
public void setNoticeTitle(String noticeTitle) {
this.noticeTitle = noticeTitle;
}
public String getNoticeType() {
return noticeType;
}
public void setNoticeType(String noticeType) {
this.noticeType = noticeType;
}
public String getNoticeContent() {
return noticeContent;
}
public void setNoticeContent(String noticeContent) {
this.noticeContent = noticeContent;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public LocalDateTime getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(LocalDateTime deletedAt) {
this.deletedAt = deletedAt;
}
}
@@ -1,6 +1,6 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.notify.core.repository;
import cn.novalon.manage.common.domain.SysNotice;
import cn.novalon.manage.notify.core.domain.SysNotice;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -15,4 +15,4 @@ public interface ISysNoticeRepository {
Mono<SysNotice> save(SysNotice notice);
Mono<Void> deleteByIdAndDeletedAtIsNull(Long id);
}
}
+22 -10
View File
@@ -22,11 +22,6 @@
<artifactId>manage-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.novalon.manage</groupId>
<artifactId>manage-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
@@ -53,16 +48,33 @@
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>cn.novalon.manage.sys.ManageSysApplication</mainClass>
</configuration>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -1,18 +0,0 @@
package cn.novalon.manage.sys;
import cn.novalon.manage.common.config.JwtProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
@SpringBootApplication
@EnableConfigurationProperties(JwtProperties.class)
@ComponentScan(basePackages = {"cn.novalon.manage.sys", "cn.novalon.manage.db"})
@EnableR2dbcRepositories(basePackages = "cn.novalon.manage.db.dao")
public class ManageSysApplication {
public static void main(String[] args) {
SpringApplication.run(ManageSysApplication.class, args);
}
}
@@ -0,0 +1,21 @@
package cn.novalon.manage.sys.config;
import cn.novalon.manage.common.handler.ExceptionLogService;
import cn.novalon.manage.sys.handler.ExceptionLogServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 异常日志配置类
*
* @author 张翔
* @date 2026-03-13
*/
@Configuration
public class ExceptionLogConfig {
@Bean
public ExceptionLogService exceptionLogService(ExceptionLogServiceImpl exceptionLogServiceImpl) {
return exceptionLogServiceImpl;
}
}
@@ -1,19 +0,0 @@
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);
}
}
@@ -1,45 +0,0 @@
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("系统统计相关操作")));
}
}
@@ -11,6 +11,12 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;
/**
* 安全配置类
*
* @author 张翔
* @date 2026-03-13
*/
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@@ -1,173 +0,0 @@
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.file.SysFileHandler;
import cn.novalon.manage.sys.handler.log.SysLogHandler;
import cn.novalon.manage.sys.handler.message.SysUserMessageHandler;
import cn.novalon.manage.sys.handler.notice.SysNoticeHandler;
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;
@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> 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> noticeRoutes(SysNoticeHandler noticeHandler) {
return route()
.GET("/api/notices", noticeHandler::getAllNotices)
.GET("/api/notices/{id}", noticeHandler::getNoticeById)
.GET("/api/notices/status/{status}", noticeHandler::getNoticesByStatus)
.POST("/api/notices", noticeHandler::createNotice)
.PUT("/api/notices/{id}", noticeHandler::updateNotice)
.DELETE("/api/notices/{id}", noticeHandler::deleteNotice)
.build();
}
@Bean
public RouterFunction<ServerResponse> fileRoutes(SysFileHandler fileHandler) {
return route()
.GET("/api/files", fileHandler::getAllFiles)
.GET("/api/files/{id}", fileHandler::getFileById)
.POST("/api/files/upload", fileHandler::uploadFile)
.GET("/api/files/{id}/download", fileHandler::downloadFile)
.GET("/api/files/download/{fileName}", fileHandler::downloadFileByName)
.GET("/api/files/{id}/preview", fileHandler::previewFile)
.GET("/api/files/preview/{fileName}", fileHandler::previewFileByName)
.DELETE("/api/files/{id}", fileHandler::deleteFile)
.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> messageRoutes(SysUserMessageHandler messageHandler) {
return route()
.GET("/api/messages/user/{userId}", messageHandler::getMessagesByUser)
.GET("/api/messages/user/{userId}/unread", messageHandler::getUnreadCount)
.GET("/api/messages/user/{userId}/unread/list", messageHandler::getUnreadList)
.POST("/api/messages", messageHandler::createMessage)
.PUT("/api/messages/{id}/read", messageHandler::markAsRead)
.DELETE("/api/messages/{id}", messageHandler::deleteMessage)
.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();
}
}
@@ -1,14 +0,0 @@
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);
}
}
@@ -3,6 +3,7 @@ package cn.novalon.manage.sys.config;
import cn.novalon.manage.sys.websocket.SysWebSocketHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.reactive.socket.WebSocketHandler;
@@ -11,6 +12,12 @@ import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAd
import java.util.HashMap;
import java.util.Map;
/**
* WebSocket配置类
*
* @author 张翔
* @date 2026-03-13
*/
@Configuration
public class WebSocketConfig {
@@ -20,7 +27,7 @@ public class WebSocketConfig {
map.put("/ws", webSocketHandler);
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(1);
handlerMapping.setOrder(Ordered.HIGHEST_PRECEDENCE);
handlerMapping.setUrlMap(map);
return handlerMapping;
}
@@ -0,0 +1,21 @@
package cn.novalon.manage.sys.core.command;
/**
* 创建菜单命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record CreateMenuCommand(
Long parentId,
String menuName,
String menuType,
Integer orderNum,
String component,
String perms,
Integer status) {
public static CreateMenuCommand of(Long parentId, String menuName, String menuType, Integer orderNum,
String component, String perms, Integer status) {
return new CreateMenuCommand(parentId, menuName, menuType, orderNum, component, perms, status);
}
}
@@ -0,0 +1,39 @@
package cn.novalon.manage.sys.core.command;
/**
* 创建公告命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record CreateNoticeCommand(
String noticeTitle,
String noticeContent,
String noticeType,
String status) {
public static CreateNoticeCommand of(String noticeTitle, String noticeContent, String noticeType, String status) {
validateNoticeTitle(noticeTitle);
validateNoticeContent(noticeContent);
validateNoticeType(noticeType);
return new CreateNoticeCommand(noticeTitle, noticeContent, noticeType, status);
}
private static void validateNoticeTitle(String noticeTitle) {
if (noticeTitle == null || noticeTitle.trim().isEmpty()) {
throw new IllegalArgumentException("Notice title is required");
}
}
private static void validateNoticeContent(String noticeContent) {
if (noticeContent == null || noticeContent.trim().isEmpty()) {
throw new IllegalArgumentException("Notice content is required");
}
}
private static void validateNoticeType(String noticeType) {
if (noticeType != null && !noticeType.equals("1") && !noticeType.equals("2")) {
throw new IllegalArgumentException(
"Invalid notice type. Notice type must be 1 (notification) or 2 (announcement)");
}
}
}
@@ -0,0 +1,27 @@
package cn.novalon.manage.sys.core.command;
import cn.novalon.manage.common.util.StatusConstants;
/**
* 创建角色命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record CreateRoleCommand(
String roleName,
String roleKey,
Integer roleSort,
Integer status
) {
public static CreateRoleCommand of(String roleName, String roleKey, Integer roleSort, Integer status) {
validateStatus(status);
return new CreateRoleCommand(roleName, roleKey, roleSort, status);
}
private static void validateStatus(Integer status) {
if (status != null && status != StatusConstants.ENABLED && status != StatusConstants.DISABLED) {
throw new IllegalArgumentException("Invalid status value. Status must be 0 (disabled) or 1 (enabled)");
}
}
}
@@ -0,0 +1,29 @@
package cn.novalon.manage.sys.core.command;
import cn.novalon.manage.sys.primitive.Email;
import cn.novalon.manage.sys.primitive.Password;
import cn.novalon.manage.sys.primitive.Username;
/**
* 创建用户命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record CreateUserCommand(
Username username,
Password password,
Email email,
Long roleId,
Integer status
) {
public static CreateUserCommand of(String username, String password, String email, Long roleId, Integer status) {
return new CreateUserCommand(
Username.of(username),
Password.of(password),
Email.of(email),
roleId,
status
);
}
}
@@ -0,0 +1,23 @@
package cn.novalon.manage.sys.core.command;
/**
* 更新菜单命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record UpdateMenuCommand(
Long id,
Long parentId,
String menuName,
String menuType,
Integer orderNum,
String component,
String perms,
Integer status
) {
public static UpdateMenuCommand of(Long id, Long parentId, String menuName, String menuType, Integer orderNum,
String component, String perms, Integer status) {
return new UpdateMenuCommand(id, parentId, menuName, menuType, orderNum, component, perms, status);
}
}
@@ -0,0 +1,19 @@
package cn.novalon.manage.sys.core.command;
/**
* 更新角色命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record UpdateRoleCommand(
Long id,
String roleName,
String roleKey,
Integer roleSort,
Integer status
) {
public static UpdateRoleCommand of(Long id, String roleName, String roleKey, Integer roleSort, Integer status) {
return new UpdateRoleCommand(id, roleName, roleKey, roleSort, status);
}
}
@@ -0,0 +1,20 @@
package cn.novalon.manage.sys.core.command;
/**
* 更新用户命令对象
*
* @author 张翔
* @date 2026-03-13
*/
public record UpdateUserCommand(
Long id,
String username,
String password,
String email,
Long roleId,
Integer status
) {
public static UpdateUserCommand of(Long id, String username, String password, String email, Long roleId, Integer status) {
return new UpdateUserCommand(id, username, password, email, roleId, status);
}
}
@@ -0,0 +1,67 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 基础领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public abstract class BaseDomain {
protected Long id;
protected String createBy;
protected String updateBy;
protected LocalDateTime createdAt;
protected LocalDateTime updatedAt;
protected LocalDateTime deletedAt;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public LocalDateTime getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(LocalDateTime deletedAt) {
this.deletedAt = deletedAt;
}
}
@@ -0,0 +1,123 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 字典领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class Dictionary {
private Long id;
private String type;
private String code;
private String name;
private String value;
private String remark;
private Integer sort;
private String createBy;
private String updateBy;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime deletedAt;
public Dictionary() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public LocalDateTime getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(LocalDateTime deletedAt) {
this.deletedAt = deletedAt;
}
}
@@ -0,0 +1,92 @@
package cn.novalon.manage.sys.core.domain;
/**
* 操作日志领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class OperationLog extends BaseDomain {
private String username;
private String operation;
private String method;
private String params;
private String result;
private String ip;
private Long duration;
private String status;
private String errorMsg;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Long getDuration() {
return duration;
}
public void setDuration(Long duration) {
this.duration = duration;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
@@ -0,0 +1,44 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 系统配置领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysConfig {
private Long id;
private String configName;
private String configKey;
private String configValue;
private String configType;
private String createBy;
private String updateBy;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime deletedAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getConfigName() { return configName; }
public void setConfigName(String configName) { this.configName = configName; }
public String getConfigKey() { return configKey; }
public void setConfigKey(String configKey) { this.configKey = configKey; }
public String getConfigValue() { return configValue; }
public void setConfigValue(String configValue) { this.configValue = configValue; }
public String getConfigType() { return configType; }
public void setConfigType(String configType) { this.configType = configType; }
public String getCreateBy() { return createBy; }
public void setCreateBy(String createBy) { this.createBy = createBy; }
public String getUpdateBy() { return updateBy; }
public void setUpdateBy(String updateBy) { this.updateBy = updateBy; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
public LocalDateTime getDeletedAt() { return deletedAt; }
public void setDeletedAt(LocalDateTime deletedAt) { this.deletedAt = deletedAt; }
}
@@ -0,0 +1,59 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 字典数据领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysDictData {
private Long id;
private Long dictTypeId;
private String dictLabel;
private String dictValue;
private Integer dictSort;
private String dictType;
private String cssClass;
private String listClass;
private String isDefault;
private String status;
private String createBy;
private String updateBy;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime deletedAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getDictTypeId() { return dictTypeId; }
public void setDictTypeId(Long dictTypeId) { this.dictTypeId = dictTypeId; }
public String getDictLabel() { return dictLabel; }
public void setDictLabel(String dictLabel) { this.dictLabel = dictLabel; }
public String getDictValue() { return dictValue; }
public void setDictValue(String dictValue) { this.dictValue = dictValue; }
public Integer getDictSort() { return dictSort; }
public void setDictSort(Integer dictSort) { this.dictSort = dictSort; }
public String getDictType() { return dictType; }
public void setDictType(String dictType) { this.dictType = dictType; }
public String getCssClass() { return cssClass; }
public void setCssClass(String cssClass) { this.cssClass = cssClass; }
public String getListClass() { return listClass; }
public void setListClass(String listClass) { this.listClass = listClass; }
public String getIsDefault() { return isDefault; }
public void setIsDefault(String isDefault) { this.isDefault = isDefault; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getCreateBy() { return createBy; }
public void setCreateBy(String createBy) { this.createBy = createBy; }
public String getUpdateBy() { return updateBy; }
public void setUpdateBy(String updateBy) { this.updateBy = updateBy; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
public LocalDateTime getDeletedAt() { return deletedAt; }
public void setDeletedAt(LocalDateTime deletedAt) { this.deletedAt = deletedAt; }
}
@@ -0,0 +1,44 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 字典类型领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysDictType {
private Long id;
private String dictName;
private String dictType;
private String status;
private String remark;
private String createBy;
private String updateBy;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime deletedAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getDictName() { return dictName; }
public void setDictName(String dictName) { this.dictName = dictName; }
public String getDictType() { return dictType; }
public void setDictType(String dictType) { this.dictType = dictType; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getRemark() { return remark; }
public void setRemark(String remark) { this.remark = remark; }
public String getCreateBy() { return createBy; }
public void setCreateBy(String createBy) { this.createBy = createBy; }
public String getUpdateBy() { return updateBy; }
public void setUpdateBy(String updateBy) { this.updateBy = updateBy; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
public LocalDateTime getDeletedAt() { return deletedAt; }
public void setDeletedAt(LocalDateTime deletedAt) { this.deletedAt = deletedAt; }
}
@@ -0,0 +1,44 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 异常日志领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysExceptionLog {
private Long id;
private String username;
private String title;
private String exceptionName;
private String methodName;
private String methodParams;
private String exceptionMsg;
private String exceptionStack;
private String ip;
private LocalDateTime createTime;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getExceptionName() { return exceptionName; }
public void setExceptionName(String exceptionName) { this.exceptionName = exceptionName; }
public String getMethodName() { return methodName; }
public void setMethodName(String methodName) { this.methodName = methodName; }
public String getMethodParams() { return methodParams; }
public void setMethodParams(String methodParams) { this.methodParams = methodParams; }
public String getExceptionMsg() { return exceptionMsg; }
public void setExceptionMsg(String exceptionMsg) { this.exceptionMsg = exceptionMsg; }
public String getExceptionStack() { return exceptionStack; }
public void setExceptionStack(String exceptionStack) { this.exceptionStack = exceptionStack; }
public String getIp() { return ip; }
public void setIp(String ip) { this.ip = ip; }
public LocalDateTime getCreateTime() { return createTime; }
public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
}
@@ -0,0 +1,44 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 文件管理领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysFile {
private Long id;
private String fileName;
private String filePath;
private String fileSize;
private String fileType;
private String storageType;
private String createBy;
private String updateBy;
private LocalDateTime createdAt;
private LocalDateTime deletedAt;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getFileName() { return fileName; }
public void setFileName(String fileName) { this.fileName = fileName; }
public String getFilePath() { return filePath; }
public void setFilePath(String filePath) { this.filePath = filePath; }
public String getFileSize() { return fileSize; }
public void setFileSize(String fileSize) { this.fileSize = fileSize; }
public String getFileType() { return fileType; }
public void setFileType(String fileType) { this.fileType = fileType; }
public String getStorageType() { return storageType; }
public void setStorageType(String storageType) { this.storageType = storageType; }
public String getCreateBy() { return createBy; }
public void setCreateBy(String createBy) { this.createBy = createBy; }
public String getUpdateBy() { return updateBy; }
public void setUpdateBy(String updateBy) { this.updateBy = updateBy; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getDeletedAt() { return deletedAt; }
public void setDeletedAt(LocalDateTime deletedAt) { this.deletedAt = deletedAt; }
}
@@ -0,0 +1,41 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 登录日志领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysLoginLog {
private Long id;
private String username;
private String ip;
private String location;
private String browser;
private String os;
private String status;
private String message;
private LocalDateTime loginTime;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getIp() { return ip; }
public void setIp(String ip) { this.ip = ip; }
public String getLocation() { return location; }
public void setLocation(String location) { this.location = location; }
public String getBrowser() { return browser; }
public void setBrowser(String browser) { this.browser = browser; }
public String getOs() { return os; }
public void setOs(String os) { this.os = os; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public LocalDateTime getLoginTime() { return loginTime; }
public void setLoginTime(LocalDateTime loginTime) { this.loginTime = loginTime; }
}
@@ -0,0 +1,103 @@
package cn.novalon.manage.sys.core.domain;
import java.util.List;
/**
* 菜单领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysMenu extends BaseDomain {
private String menuName;
private Long parentId;
private Integer orderNum;
private String menuType;
private String perms;
private String component;
private Integer status;
private String createBy;
private String updateBy;
private List<SysMenu> children;
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public Integer getOrderNum() {
return orderNum;
}
public void setOrderNum(Integer orderNum) {
this.orderNum = orderNum;
}
public String getMenuType() {
return menuType;
}
public void setMenuType(String menuType) {
this.menuType = menuType;
}
public String getPerms() {
return perms;
}
public void setPerms(String perms) {
this.perms = perms;
}
public String getComponent() {
return component;
}
public void setComponent(String component) {
this.component = component;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getCreateBy() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy = createBy;
}
public String getUpdateBy() {
return updateBy;
}
public void setUpdateBy(String updateBy) {
this.updateBy = updateBy;
}
public List<SysMenu> getChildren() {
return children;
}
public void setChildren(List<SysMenu> children) {
this.children = children;
}
}
@@ -0,0 +1,75 @@
package cn.novalon.manage.sys.core.domain;
import cn.novalon.manage.common.util.SnowflakeId;
import java.time.LocalDateTime;
/**
* 角色领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysRole extends BaseDomain {
private String roleName;
private String roleKey;
private Integer roleSort;
private Integer status;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleKey() {
return roleKey;
}
public void setRoleKey(String roleKey) {
this.roleKey = roleKey;
}
public Integer getRoleSort() {
return roleSort;
}
public void setRoleSort(Integer roleSort) {
this.roleSort = roleSort;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
/**
* 生成主键ID
*
* @return 主键ID
*/
public Long generateId() {
this.id = SnowflakeId.nextId();
return this.id;
}
/**
* 删除角色
*/
public void delete() {
this.deletedAt = LocalDateTime.now();
}
/**
* 恢复角色
*/
public void restore() {
this.deletedAt = null;
}
}
@@ -0,0 +1,77 @@
package cn.novalon.manage.sys.core.domain;
import cn.novalon.manage.common.util.SnowflakeId;
import java.time.LocalDateTime;
/**
* 用户领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysUser extends BaseDomain {
private String username;
private String password;
private String email;
private Long roleId;
private Integer status;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
/**
* 生成主键ID
*
* @return 主键ID
*/
public Long generateId() {
this.id = SnowflakeId.nextId();
return this.id;
}
/**
* 删除用户
*/
public void delete() {
this.deletedAt = LocalDateTime.now();
}
}
@@ -0,0 +1,35 @@
package cn.novalon.manage.sys.core.domain;
import java.time.LocalDateTime;
/**
* 用户消息领域对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysUserMessage {
private Long id;
private Long userId;
private String title;
private String content;
private String messageType;
private String isRead;
private LocalDateTime createTime;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Long getUserId() { return userId; }
public void setUserId(Long userId) { this.userId = userId; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public String getMessageType() { return messageType; }
public void setMessageType(String messageType) { this.messageType = messageType; }
public String getIsRead() { return isRead; }
public void setIsRead(String isRead) { this.isRead = isRead; }
public LocalDateTime getCreateTime() { return createTime; }
public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
}
@@ -1,5 +1,11 @@
package cn.novalon.manage.sys.core.exception;
/**
* 字典已存在异常
*
* @author 张翔
* @date 2026-03-13
*/
public class DictionaryAlreadyExistsException extends RuntimeException {
private final String type;
@@ -0,0 +1,56 @@
package cn.novalon.manage.sys.core.query;
/**
* 菜单查询对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysMenuQuery {
private String menuName;
private String menuType;
private Integer status;
private Long parentId;
private String keyword;
public String getMenuName() {
return menuName;
}
public void setMenuName(String menuName) {
this.menuName = menuName;
}
public String getMenuType() {
return menuType;
}
public void setMenuType(String menuType) {
this.menuType = menuType;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
}
@@ -0,0 +1,50 @@
package cn.novalon.manage.sys.core.query;
/**
* 角色查询对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysRoleQuery {
private String roleName;
private String roleKey;
private Integer status;
private String keyword;
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleKey() {
return roleKey;
}
public void setRoleKey(String roleKey) {
this.roleKey = roleKey;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
}
@@ -0,0 +1,60 @@
package cn.novalon.manage.sys.core.query;
/**
* 用户查询对象
*
* @author 张翔
* @date 2026-03-13
*/
public class SysUserQuery {
private String username;
private String email;
private Long roleId;
private Integer status;
private String keyword;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getRoleId() {
return roleId;
}
public void setRoleId(Long roleId) {
this.roleId = roleId;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
}
@@ -1,9 +1,15 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.Dictionary;
import cn.novalon.manage.sys.core.domain.Dictionary;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface IDictionaryRepository {
Flux<Dictionary> findAll();
@@ -1,11 +1,17 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.OperationLog;
import cn.novalon.manage.sys.core.domain.OperationLog;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* 操作日志仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface IOperationLogRepository {
Mono<OperationLog> findById(Long id);
@@ -1,10 +1,16 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysConfig;
import cn.novalon.manage.sys.core.domain.SysConfig;
import org.springframework.data.domain.Sort;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 系统配置仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysConfigRepository {
Mono<SysConfig> findById(Long id);
@@ -1,9 +1,15 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysDictData;
import cn.novalon.manage.sys.core.domain.SysDictData;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典数据仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysDictDataRepository {
Flux<SysDictData> findByDeletedAtIsNull();
@@ -1,9 +1,15 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysDictType;
import cn.novalon.manage.sys.core.domain.SysDictType;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典类型仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysDictTypeRepository {
Flux<SysDictType> findByDeletedAtIsNull();
@@ -1,11 +1,17 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.domain.SysExceptionLog;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* 异常日志仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysExceptionLogRepository {
Flux<SysExceptionLog> findAllByOrderByCreateTimeDesc();
@@ -1,9 +1,15 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysFile;
import cn.novalon.manage.sys.core.domain.SysFile;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 文件仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysFileRepository {
Flux<SysFile> findByDeletedAtIsNullOrderByCreatedAtDesc();
@@ -1,11 +1,17 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysLoginLog;
import cn.novalon.manage.sys.core.domain.SysLoginLog;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
* 登录日志仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysLoginLogRepository {
Flux<SysLoginLog> findAllByOrderByLoginTimeDesc();
@@ -1,15 +1,19 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysMenu;
import cn.novalon.manage.sys.core.domain.SysMenu;
import cn.novalon.manage.sys.core.query.SysMenuQuery;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import org.springframework.data.domain.Sort;
import org.springframework.data.relational.core.query.Query;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* 菜单仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysMenuRepository {
Flux<SysMenu> findByParentId(Long parentId);
@@ -28,7 +32,7 @@ public interface ISysMenuRepository {
Mono<Long> count();
Mono<PageResponse<SysMenu>> findByQueryWithPagination(Query query, PageRequest pageRequest);
Mono<PageResponse<SysMenu>> findByQueryWithPagination(SysMenuQuery query, PageRequest pageRequest);
Flux<SysMenu> findByStatus(String status);
}
@@ -1,13 +1,19 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysRole;
import cn.novalon.manage.sys.core.domain.SysRole;
import cn.novalon.manage.sys.core.query.SysRoleQuery;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import org.springframework.data.domain.Sort;
import org.springframework.data.relational.core.query.Query;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 角色仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysRoleRepository {
Mono<SysRole> findById(Long id);
@@ -28,7 +34,7 @@ public interface ISysRoleRepository {
Mono<Long> countByRoleNameLikeOrRoleKeyLike(String roleName, String roleKey);
Mono<PageResponse<SysRole>> findByQueryWithPagination(Query query, PageRequest pageRequest);
Mono<PageResponse<SysRole>> findByQueryWithPagination(SysRoleQuery query, PageRequest pageRequest);
Mono<SysRole> findByRoleName(String roleName);
@@ -1,9 +1,15 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysUserMessage;
import cn.novalon.manage.sys.core.domain.SysUserMessage;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 用户消息仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysUserMessageRepository {
Flux<SysUserMessage> findByUserIdOrderByCreateTimeDesc(Long userId);
@@ -1,15 +1,21 @@
package cn.novalon.manage.db.repository;
package cn.novalon.manage.sys.core.repository;
import cn.novalon.manage.common.domain.SysUser;
import cn.novalon.manage.sys.core.domain.SysUser;
import cn.novalon.manage.sys.core.query.SysUserQuery;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import org.springframework.data.domain.Sort;
import org.springframework.data.relational.core.query.Query;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* 用户仓储接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysUserRepository {
Mono<SysUser> findByUsername(String username);
@@ -34,7 +40,7 @@ public interface ISysUserRepository {
Mono<Long> count();
Mono<PageResponse<SysUser>> findByQueryWithPagination(Query query, PageRequest pageRequest);
Mono<PageResponse<SysUser>> findByQueryWithPagination(SysUserQuery query, PageRequest pageRequest);
Mono<Boolean> existsByUsername(String username);
@@ -47,4 +53,6 @@ public interface ISysUserRepository {
Mono<Void> restoreById(Long id);
Mono<Void> restoreByIds(List<Long> ids);
Mono<Void> updateRoleIdToNullByRoleId(Long roleId);
}
@@ -1,6 +1,6 @@
package cn.novalon.manage.sys.core.service;
import cn.novalon.manage.common.domain.Dictionary;
import cn.novalon.manage.sys.core.domain.Dictionary;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -1,9 +1,15 @@
package cn.novalon.manage.sys.core.service;
import cn.novalon.manage.common.domain.OperationLog;
import cn.novalon.manage.sys.core.domain.OperationLog;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 操作日志服务接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface IOperationLogService {
Mono<OperationLog> save(OperationLog log);
Flux<OperationLog> findAll();
@@ -1,9 +1,15 @@
package cn.novalon.manage.sys.core.service;
import cn.novalon.manage.common.domain.SysConfig;
import cn.novalon.manage.sys.core.domain.SysConfig;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 系统配置服务接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysConfigService {
Flux<SysConfig> findAll();
Mono<SysConfig> findById(Long id);
@@ -1,9 +1,15 @@
package cn.novalon.manage.sys.core.service;
import cn.novalon.manage.common.domain.SysDictData;
import cn.novalon.manage.sys.core.domain.SysDictData;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* 字典数据服务接口
*
* @author 张翔
* @date 2026-03-13
*/
public interface ISysDictDataService {
Flux<SysDictData> findAll();
Flux<SysDictData> findByDictType(String dictType);

Some files were not shown because too many files have changed in this diff Show More